     1                                  ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
     2                                  ; (re-write kernel for test by using previous version without a major defect)
     3                                  ; ****************************************************************************
     4                                  ; UNIX386.ASM (RETRO UNIX 386 Kernel) - v0.2.2.3
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; NASM version 2.15 (unix386.s)
     7                                  ;
     8                                  ; RETRO UNIX 386 (Retro Unix == Turkish Rational Unix)
     9                                  ; Operating System Project (v0.2) by ERDOGAN TAN (Beginning: 24/12/2013)
    10                                  ;
    11                                  ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
    12                                  ; (v0.1 - Beginning: 11/07/2012)
    13                                  ;
    14                                  ; [ Last Modification: 24/07/2022 ]
    15                                  ;
    16                                  ; Derived from UNIX Operating System (v1.0 for PDP-11) 
    17                                  ; (Original) Source Code by Ken Thompson (1971-1972)
    18                                  ; <Bell Laboratories (17/3/1972)>
    19                                  ; <Preliminary Release of UNIX Implementation Document>
    20                                  ;
    21                                  ; Derived from 'UNIX v7/x86' source code by Robert Nordier (1999)
    22                                  ; UNIX V7/x86 source code: see www.nordier.com/v7x86 for details.
    23                                  ;
    24                                  ; ****************************************************************************
    25                                  
    26                                  ; 24/12/2013
    27                                  
    28                                  ; Entering protected mode:
    29                                  ; Derived from 'simple_asm.txt' source code file and 
    30                                  ; 'The world of Protected mode' tutorial/article by Gregor Brunmar (2003)
    31                                  ; (gregor.brunmar@home.se)
    32                                  ; http://www.osdever.net/tutorials/view/the-world-of-protected-mode
    33                                  ;
    34                                  
    35                                  ; "The Real, Protected, Long mode assembly tutorial for PCs" 
    36                                  ; by Michael Chourdakis (2009) 
    37                                  ; http://www.codeproject.com/Articles/45788/
    38                                  ; http://www.michaelchourdakis.com
    39                                  ;
    40                                  
    41                                  ; Global Descriptor Table:
    42                                  ; Derived from 'head.s" source code of Linux v1.0 kernel
    43                                  ; by Linus Torvalds (1991-1992)
    44                                  ;
    45                                  
    46                                  KLOAD	equ 10000h ; Kernel loading address
    47                                  	; NOTE: Retro UNIX 8086 v1 /boot code loads kernel at 1000h:0000h
    48                                  KCODE	equ 08h	; Code segment descriptor (ring 0)
    49                                  KDATA	equ 10h	; Data segment descriptor (ring 0)
    50                                  ; 19/03/2015
    51                                  UCODE	equ 1Bh ; 18h + 3h  (ring 3)
    52                                  UDATA	equ 23h ; 20h + 3h  (ring 3)
    53                                  ; 24/03/2015
    54                                  TSS	equ 28h	; Task state segment descriptor (ring 0)
    55                                  ; 19/03/2015
    56                                  CORE	equ 400000h  ; Start of USER's virtual/linear address space 
    57                                  		     ; (at the end of the 1st 4MB)
    58                                  ECORE	equ 0FFC00000h ; End of USER's virtual address space (4GB - 4MB)
    59                                  		     ; ULIMIT = (ECORE/4096) - 1 = 0FFBFFh (in GDT)
    60                                  
    61                                  ; 01/01/2022 (Retro UNIX 386 v1.2)
    62                                  ;; 27/12/2013
    63                                  ;KEND	equ KLOAD + 65536 ; (28/12/2013) (end of kernel space)
    64                                  
    65                                  ; IBM PC/AT BIOS ----- 10/06/85 (postequ.inc)
    66                                  ;--------- CMOS TABLE LOCATION ADDRESS'S -------------------------------------
    67                                  CMOS_SECONDS	EQU	00H		; SECONDS (BCD)
    68                                  CMOS_MINUTES	EQU	02H		; MINUTES (BCD)	
    69                                  CMOS_HOURS	EQU	04H		; HOURS (BCD)
    70                                  CMOS_DAY_WEEK	EQU	06H		; DAY OF THE WEEK  (BCD)
    71                                  CMOS_DAY_MONTH	EQU	07H		; DAY OF THE MONTH (BCD) 
    72                                  CMOS_MONTH	EQU	08H		; MONTH (BCD)
    73                                  CMOS_YEAR	EQU	09H		; YEAR (TWO DIGITS) (BCD)
    74                                  CMOS_CENTURY	EQU	32H		; DATE CENTURY BYTE (BCD)
    75                                  CMOS_REG_A	EQU	0AH		; STATUS REGISTER A
    76                                  CMOS_REG_B	EQU	00BH		; STATUS REGISTER B  ALARM
    77                                  CMOS_REG_C	EQU	00CH		; STATUS REGISTER C  FLAGS
    78                                  CMOS_REG_D	EQU	0DH		; STATUS REGISTER D  BATTERY
    79                                  CMOS_SHUT_DOWN	EQU	0FH		; SHUTDOWN STATUS COMMAND BYTE
    80                                  ;----------------------------------------
    81                                  ;	CMOS EQUATES FOR THIS SYSTEM	;
    82                                  ;-----------------------------------------------------------------------------
    83                                  CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
    84                                  CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
    85                                  NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
    86                                  					; HIGH BIT OF CMOS LOCATION ADDRESS
    87                                  
    88                                  ; Memory Allocation Table Address
    89                                  ; 05/11/2014
    90                                  ; 31/10/2014
    91                                  MEM_ALLOC_TBL	equ	100000h		; Memory Allocation Table at the end of
    92                                  					; the 1st 1 MB memory space.
    93                                  					; (This address must be aligned
    94                                  					;  on 128 KB boundary, if it will be
    95                                  					;  changed later.)
    96                                  					; ((lower 17 bits of 32 bit M.A.T.
    97                                  					;   address must be ZERO)).
    98                                  					; ((((Reason: 32 bit allocation 
    99                                  					;     instructions, dword steps)))
   100                                  					; (((byte >> 12 --> page >> 5)))  
   101                                  ;04/11/2014	
   102                                  PDE_A_PRESENT	equ	1		; Present flag for PDE
   103                                  PDE_A_WRITE	equ 	2		; Writable (write permission) flag
   104                                  PDE_A_USER	equ	4		; User (non-system/kernel) page flag
   105                                  ;
   106                                  PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
   107                                  PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
   108                                  PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
   109                                  PTE_A_ACCESS    equ	32		; Accessed flag (bit 5) ; 09/03/2015
   110                                  
   111                                  ; 17/02/2015 (unix386.s)
   112                                  ; 10/12/2014 - 30/12/2014 (0B000h -> 9000h) (dsectrm2.s)
   113                                  DPT_SEGM equ 09000h  ; FDPT segment (EDD v1.1, EDD v3)
   114                                  ;
   115                                  HD0_DPT	 equ 0	    ; Disk parameter table address for hd0
   116                                  HD1_DPT	 equ 32	    ; Disk parameter table address for hd1
   117                                  HD2_DPT	 equ 64	    ; Disk parameter table address for hd2
   118                                  HD3_DPT	 equ 96	    ; Disk parameter table address for hd3
   119                                  
   120                                  
   121                                  ; FDPT (Phoenix, Enhanced Disk Drive Specification v1.1, v3.0)
   122                                  ;      (HDPT: Programmer's Guide to the AMIBIOS, 1993)
   123                                  ;
   124                                  FDPT_CYLS	equ 0 ; 1 word, number of cylinders
   125                                  FDPT_HDS	equ 2 ; 1 byte, number of heads
   126                                  FDPT_TT		equ 3 ; 1 byte, A0h = translated FDPT with logical values
   127                                  		      ; otherwise it is standard FDPT with physical values 	
   128                                  FDPT_PCMP	equ 5 ; 1 word, starting write precompensation cylinder
   129                                  		      ; (obsolete for IDE/ATA drives)
   130                                  FDPT_CB		equ 8 ; 1 byte, drive control byte
   131                                  			; Bits 7-6 : Enable or disable retries (00h = enable)
   132                                  			; Bit 5	: 1 = Defect map is located at last cyl. + 1
   133                                  			; Bit 4 : Reserved. Always 0
   134                                  			; Bit 3 : Set to 1 if more than 8 heads
   135                                  			; Bit 2-0 : Reserved. Alsways 0
   136                                  FDPT_LZ		equ 12 ; 1 word, landing zone (obsolete for IDE/ATA drives)
   137                                  FDPT_SPT	equ 14 ; 1 byte, sectors per track
   138                                  
   139                                  ; Floppy Drive Parameters Table (Programmer's Guide to the AMIBIOS, 1993)
   140                                  ; (11 bytes long) will be used by diskette handler/bios
   141                                  ; which is derived from IBM PC-AT BIOS (DISKETTE.ASM, 21/04/1986).						 	  		 	  
   142                                  
   143                                  [BITS 16]       ; We need 16-bit intructions for Real mode
   144                                  
   145                                  [ORG 0] 
   146                                  
   147                                  KSTART: ; 01/01/2022
   148                                  
   149                                  	; 12/11/2014
   150                                  	; Save boot drive number (that is default root drive)
   151 00000000 8816[2862]              	mov	[boot_drv], dl ; physical drv number
   152                                  
   153                                  	; Determine installed memory
   154                                  	; 31/10/2014
   155                                  	;
   156 00000004 B801E8                  	mov	ax, 0E801h ; Get memory size 
   157 00000007 CD15                    	int	15h	   ; for large configurations
   158 00000009 7308                    	jnc	short chk_ms
   159 0000000B B488                    	mov	ah, 88h    ; Get extended memory size 
   160 0000000D CD15                    	int	15h
   161                                  	;	   
   162                                  	;mov	al, 17h	; Extended memory (1K blocks) low byte
   163                                  	;out	70h, al ; select CMOS register
   164                                  	;in	al, 71h ; read data (1 byte)
   165                                  	;mov	cl, al
   166                                  	;mov	al, 18h ; Extended memory (1K blocks) high byte
   167                                  	;out	70h, al ; select CMOS register
   168                                  	;in	al, 71h ; read data (1 byte)
   169                                  	;mov	ch, al
   170                                   	;      
   171 0000000F 89C1                    	mov	cx, ax
   172 00000011 31D2                    	xor	dx, dx
   173                                  chk_ms:
   174 00000013 890E[9464]              	mov	[mem_1m_1k], cx
   175 00000017 8916[9864]              	mov	[mem_16m_64k], dx
   176                                  	; 05/11/2014
   177                                  	;and	dx, dx
   178                                  	;jz	short L2
   179 0000001B 81F90004                        cmp     cx, 1024
   180 0000001F 7351                    	jnb	short L0
   181                                  		 ; insufficient memory_error	
   182                                  		 ; Minimum 2 MB memory is needed...
   183                                  oom_0: 
   184                                  	; 05/11/2014
   185                                  	; (real mode error printing)
   186 00000021 FB                      	sti
   187 00000022 BE[3600]                	mov	si, msg_out_of_memory
   188 00000025 BB0700                  	mov	bx, 7
   189 00000028 B40E                    	mov	ah, 0Eh	; write tty
   190                                  oom_1:
   191 0000002A AC                      	lodsb
   192 0000002B 08C0                    	or	al, al
   193 0000002D 7404                    	jz	short oom_2
   194 0000002F CD10                    	int	10h
   195 00000031 EBF7                    	jmp	short oom_1
   196                                  oom_2:
   197 00000033 F4                              hlt
   198 00000034 EBFD                    	jmp	short oom_2
   199                                  
   200                                  ; 28/11/2021 - Retro UNIX 386 v2 compatibility modification (on v1.1)
   201                                  ; 11/04/2021 - Retro UNIX 386 v2
   202                                  ; ((Real mode messages and buffers must be in the 1st 64K of the kernel))
   203                                  ; 20/02/2017 (TRDOS 386 v2)
   204                                  ; 05/11/2014
   205                                  msg_out_of_memory:
   206 00000036 070D0A                  	db 	07h, 0Dh, 0Ah
   207 00000039 496E73756666696369-             db      'Insufficient memory !'
   207 00000042 656E74206D656D6F72-
   207 0000004B 792021             
   208 0000004E 0D0A                    	db	0Dh, 0Ah
   209                                  _int13h_48h_buffer: ; 07/07/2016
   210 00000050 284D696E696D756D20-     	db	'(Minimum 2MB memory is needed.)'
   210 00000059 324D42206D656D6F72-
   210 00000062 79206973206E656564-
   210 0000006B 65642E29           
   211 0000006F 0D0A00                   	db	0Dh, 0Ah, 0
   212                                  
   213                                  L0:
   214                                  %include 'diskinit.s' ; 07/03/2015
   215                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
   216                              <1> ; (re-write kernel for test by using previous version without a major defect)
   217                              <1> ; ****************************************************************************
   218                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKINIT.INC
   219                              <1> ; Last Modification: 12/07/2022
   220                              <1> 
   221                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
   222                              <1> 
   223                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
   224                              <1> 
   225                              <1> 	; 02/01/2022 (Retro UNIX 386 v1.2)
   226                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
   227                              <1> ;L0:
   228                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
   229                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
   230 00000072 BA7F00              <1> 	mov	dx, 7Fh
   231                              <1> L1:	
   232 00000075 FEC2                <1> 	inc	dl
   233 00000077 B441                <1> 	mov	ah, 41h ; Check extensions present
   234                              <1> 			; Phoenix EDD v1.1 - EDD v3
   235 00000079 BBAA55              <1> 	mov	bx, 55AAh
   236 0000007C CD13                <1> 	int 	13h
   237 0000007E 721A                <1> 	jc	short L2
   238                              <1> 
   239 00000080 81FB55AA            <1> 	cmp	bx, 0AA55h
   240 00000084 7514                <1> 	jne	short L2
   241 00000086 FE06[2B62]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   242 0000008A 8816[2A62]          <1>         mov     [last_drv], dl  ; last hard disk number
   243 0000008E BB[AE61]            <1> 	mov	bx, hd0_type - 80h
   244 00000091 01D3                <1> 	add	bx, dx	 
   245 00000093 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
   246                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
   247                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
   248                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
   249                              <1>                          ;            (EDD) ready (DPTE ready)
   250                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
   251                              <1>                          ;            (EDD-3)
   252                              <1> 			 ; Bit 4 to 15 - 0, Reserved
   253 00000095 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
   254 00000098 72DB                <1> 	jb	short L1
   255                              <1> L2:
   256                              <1> 	; 23/11/2014
   257                              <1> 	; 19/11/2014
   258 0000009A 30D2                <1> 	xor	dl, dl  ; 0
   259                              <1> 	; 04/02/2016 (esi -> si)
   260 0000009C BE[2C62]            <1> 	mov	si, fd0_type
   261                              <1> L3:
   262                              <1> 	; 14/01/2015
   263 0000009F 8816[2962]          <1> 	mov	[drv], dl
   264                              <1> 	;
   265 000000A3 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   266 000000A5 CD13                <1> 	int	13h	
   267 000000A7 7210                <1> 	jc	short L4
   268                              <1> 		; BL = drive type (for floppy drives)
   269                              <1> 		; DL = number of floppy drives
   270                              <1> 		;		
   271                              <1> 		; ES:DI = Address of DPT from BIOS
   272                              <1> 		;
   273 000000A9 881C                <1> 	mov	[si], bl ;  Drive type
   274                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
   275                              <1> 	; 14/01/2015
   276 000000AB E8BB01              <1> 	call	set_disk_parms
   277                              <1> 	; 10/12/2014
   278 000000AE 81FE[2C62]          <1> 	cmp	si, fd0_type
   279 000000B2 7705                <1> 	ja	short L4
   280 000000B4 46                  <1> 	inc	si ; fd1_type
   281 000000B5 B201                <1> 	mov	dl, 1
   282 000000B7 EBE6                <1> 	jmp	short L3
   283                              <1> L4:
   284                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   285 000000B9 B27F                <1> 	mov	dl, 7Fh
   286                              <1> 	; 24/12/2014 (Temporary)
   287 000000BB 803E[2B62]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
   288                              <1> 	;ja	L10       ; yes, all fixed disk operations
   289                              <1> 			  ; will be performed according to
   290                              <1> 			  ; present EDD specification
   291                              <1> 	; 02/01/2022
   292 000000C0 7603                <1> 	jna	short L5
   293 000000C2 E99100              <1> 	jmp	L10
   294                              <1> L5:
   295 000000C5 FEC2                <1> 	inc 	dl
   296 000000C7 8816[2962]          <1>         mov     [drv], dl
   297 000000CB 8816[2A62]          <1>         mov     [last_drv], dl ; 14/01/2015
   298 000000CF B408                <1> 	mov 	ah, 08h ; Return drive parameters
   299 000000D1 CD13                <1> 	int	13h	; (conventional function)
   300                              <1> 	;jc	L13	; fixed disk drive not ready
   301                              <1> 	; 02/01/2022
   302 000000D3 7303                <1> 	jnc	short L6
   303 000000D5 E98301              <1> 	jmp	L13
   304                              <1> L6:
   305 000000D8 8816[2B62]          <1>         mov     [hdc], dl ; number of drives
   306                              <1> 	;; 14/01/2013
   307                              <1> 	;;push	cx
   308 000000DC E88A01              <1> 	call	set_disk_parms
   309                              <1> 	;;pop	cx
   310                              <1> 	;
   311                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   312 000000DF 8A16[2962]          <1>         mov     dl, [drv]
   313 000000E3 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   314 000000E6 80FA80              <1> 	cmp	dl, 80h
   315 000000E9 7603                <1> 	jna	short L7
   316 000000EB 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   317                              <1> L7:	
   318 000000EE 31C0                <1> 	xor	ax, ax
   319 000000F0 8ED8                <1> 	mov	ds, ax
   320 000000F2 8B37                <1>         mov     si, [bx]
   321 000000F4 8B4702              <1>         mov     ax, [bx+2] 
   322 000000F7 8ED8                <1> 	mov	ds, ax
   323 000000F9 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   324                              <1> 	;jne	L12 ; invalid FDPT
   325                              <1> 	; 02/01/2022
   326 000000FC 7403                <1> 	je	short L7_8
   327 000000FE E95601              <1> 	jmp	L12
   328                              <1> L7_8:
   329 00000101 BF0000              <1> 	mov	di, HD0_DPT
   330 00000104 80FA80              <1> 	cmp	dl, 80h
   331 00000107 7603                <1> 	jna	short L8
   332 00000109 BF2000              <1> 	mov	di, HD1_DPT 
   333                              <1> L8:
   334                              <1> 	; 30/12/2014
   335 0000010C B80090              <1> 	mov	ax, DPT_SEGM
   336 0000010F 8EC0                <1> 	mov	es, ax
   337                              <1> 	; 24/12/2014
   338 00000111 B90800              <1> 	mov	cx, 8
   339 00000114 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   340 00000116 8CC8                <1> 	mov	ax, cs
   341 00000118 8ED8                <1> 	mov	ds, ax
   342                              <1> 	; 02/02/2015
   343 0000011A 8A0E[2962]          <1>         mov     cl, [drv]
   344 0000011E 88CB                <1> 	mov	bl, cl
   345 00000120 B8F001              <1> 	mov	ax, 1F0h
   346 00000123 80E301              <1> 	and	bl, 1
   347 00000126 7406                <1> 	jz	short L9
   348 00000128 C0E304              <1> 	shl	bl, 4
   349 0000012B 2D8000              <1> 	sub	ax, 1F0h-170h
   350                              <1> L9:
   351 0000012E AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   352 0000012F 050602              <1> 	add	ax, 206h
   353 00000132 AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   354 00000133 88D8                <1> 	mov	al, bl
   355 00000135 04A0                <1> 	add	al, 0A0h
   356 00000137 AA                  <1> 	stosb	; Device/Head Register upper nibble
   357                              <1> 	;
   358 00000138 FE06[2962]          <1> 	inc	byte [drv]
   359 0000013C BB[AE61]            <1> 	mov	bx, hd0_type - 80h
   360 0000013F 01CB                <1> 	add	bx, cx
   361 00000141 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   362 00000144 A0[2B62]            <1> 	mov	al, [hdc]
   363 00000147 FEC8                <1> 	dec	al
   364                              <1> 	;jz	L13
   365                              <1> 	; 02/01/2022
   366 00000149 7408                <1> 	jz	short L9_10
   367 0000014B 80FA80              <1> 	cmp	dl, 80h
   368                              <1>         ;jna	L5
   369                              <1> 	;jmp	L13
   370                              <1> 	; 02/01/2022
   371 0000014E 7703                <1> 	ja	short L9_10
   372 00000150 E972FF              <1> 	jmp	L5
   373                              <1> L9_10:
   374 00000153 E90501              <1>         jmp     L13
   375                              <1> L10:
   376 00000156 FEC2                <1> 	inc 	dl
   377                              <1> 	; 25/12/2014
   378 00000158 8816[2962]          <1> 	mov	[drv], dl
   379 0000015C B408                <1> 	mov 	ah, 08h ; Return drive parameters
   380 0000015E CD13                <1> 	int	13h	; (conventional function)
   381                              <1> 	;jc	L13
   382                              <1> 	; 02/01/2022
   383 00000160 72F1                <1> 	jc	short L9_10
   384                              <1> 	; 14/01/2015
   385 00000162 8A16[2962]          <1> 	mov	dl, [drv]
   386 00000166 52                  <1> 	push	dx
   387 00000167 51                  <1> 	push	cx
   388 00000168 E8FE00              <1> 	call	set_disk_parms
   389 0000016B 59                  <1> 	pop	cx
   390 0000016C 5A                  <1> 	pop	dx
   391                              <1> 	; 02/01/2022 - Retro UNIX 386 v1.2
   392                              <1> 	; 04/02/2016 (esi -> si)
   393                              <1> 	;mov	si, _end ; 30 byte temporary buffer address
   394                              <1> 	;		 ; at the '_end' of kernel.
   395                              <1> 	;mov	word [si], 30
   396                              <1> 	; 06/07/2016
   397 0000016D BE[5000]            <1> 	mov	si, _int13h_48h_buffer
   398                              <1> 	; 09/07/2016
   399 00000170 B81E00              <1> 	mov	ax, 001Eh
   400 00000173 8824                <1> 	mov	[si], ah ; 0
   401 00000175 46                  <1> 	inc	si
   402 00000176 8904                <1> 	mov	word [si], ax
   403                              <1>  	; word [si] = 30
   404                              <1> 	;
   405 00000178 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   406 0000017A CD13                <1> 	int	13h
   407                              <1>         ;jc	L13
   408                              <1> 	; 02/01/2022
   409 0000017C 72D5                <1> 	jc	short L9_10
   410                              <1> 	; 04/02/2016 (ebx -> bx)
   411                              <1> 	; 14/01/2015
   412                              <1> 	;sub	bx, bx
   413 0000017E 28FF                <1> 	sub	bh, bh ; 02/01/2022
   414 00000180 88D3                <1> 	mov	bl, dl
   415 00000182 80EB80              <1> 	sub	bl, 80h
   416 00000185 81C3[2E62]          <1> 	add	bx, hd0_type
   417 00000189 8A07                <1> 	mov 	al, [bx]
   418 0000018B 0C80                <1> 	or	al, 80h
   419 0000018D 8807                <1> 	mov 	[bx], al	
   420 0000018F 81EB[2C62]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   421 00000193 81C3[4E62]          <1> 	add	bx, drv.status
   422 00000197 8807                <1> 	mov	[bx], al
   423                              <1> 	; 04/02/2016 (eax -> ax)
   424 00000199 8B4410              <1> 	mov	ax, [si+16]
   425 0000019C 854412              <1> 	test	ax, [si+18]
   426 0000019F 7413                <1> 	jz	short L10_A0h 
   427                              <1> 			; 'CHS only' disks on EDD system 
   428                              <1> 			;  are reported with ZERO disk size
   429 000001A1 81EB[4E62]          <1> 	sub	bx, drv.status
   430 000001A5 C1E302              <1> 	shl	bx, 2
   431 000001A8 81C3[3262]          <1> 	add	bx, drv.size ; disk size (in sectors)
   432 000001AC 8907                <1> 	mov	[bx], ax
   433 000001AE 8B4412              <1> 	mov	ax, [si+18]
   434                              <1> 	;mov	[bx], ax
   435                              <1> 	; 02/01/2022 (BugFix)
   436 000001B1 894702              <1> 	mov	[bx+2], ax
   437                              <1> 
   438                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   439                              <1> 	 ; for CHS disks (28/02/2015)
   440                              <1> 	; 30/12/2014
   441 000001B4 BF0000              <1> 	mov	di, HD0_DPT
   442 000001B7 88D0                <1> 	mov	al, dl
   443 000001B9 83E003              <1> 	and 	ax, 3
   444 000001BC C0E005              <1> 	shl	al, 5 ; *32
   445 000001BF 01C7                <1> 	add 	di, ax
   446 000001C1 B80090              <1> 	mov	ax, DPT_SEGM
   447 000001C4 8EC0                <1> 	mov	es, ax
   448                              <1> 	;
   449 000001C6 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   450 000001C8 88CC                <1> 	mov	ah, cl	
   451 000001CA C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   452 000001CD 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   453 000001CE AB                  <1> 	stosw		
   454 000001CF 88F0                <1> 	mov	al, dh	; max. head number
   455 000001D1 FEC0                <1> 	inc	al
   456 000001D3 AA                  <1> 	stosb		; logical heads (limits 256)
   457 000001D4 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   458 000001D6 AA                  <1> 	stosb
   459 000001D7 8A440C              <1> 	mov	al, [si+12]
   460 000001DA AA                  <1> 	stosb		 ; physical sectors per track
   461 000001DB 31C0                <1>  	xor	ax, ax
   462                              <1> 	;dec	ax	 ; 02/01/2015 
   463 000001DD AB                  <1> 	stosw		 ; precompensation (obsolete)
   464                              <1> 	;xor	al, al	 ; 02/01/2015	
   465 000001DE AA                  <1> 	stosb		 ; reserved
   466 000001DF B008                <1> 	mov	al, 8	 ; drive control byte
   467                              <1> 		         ; (do not disable retries, 
   468                              <1> 			 ; more than 8 heads)
   469 000001E1 AA                  <1> 	stosb
   470 000001E2 8B4404              <1> 	mov	ax, [si+4]
   471 000001E5 AB                  <1> 	stosw		 ; physical number of cylinders	
   472                              <1> 	;push	ax	 ; 02/01/2015
   473 000001E6 8A4408              <1> 	mov	al, [si+8]
   474 000001E9 AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   475 000001EA 29C0                <1> 	sub 	ax, ax
   476                              <1> 	;pop	ax	 ; 02/01/2015	
   477 000001EC AB                  <1> 	stosw		 ; landing zone (obsolete)
   478 000001ED 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   479 000001EF 243F                <1> 	and 	al, 3Fh	
   480 000001F1 AA                  <1> 	stosb
   481                              <1> 	;sub	al, al	 ; checksum
   482                              <1> 	;stosb
   483                              <1> 	;
   484 000001F2 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   485 000001F5 AD                  <1> 	lodsw
   486 000001F6 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   487 000001F7 AD                  <1> 	lodsw
   488 000001F8 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   489                              <1> 	;
   490                              <1> 	; checksum calculation
   491 000001F9 89FE                <1> 	mov	si, di
   492 000001FB 06                  <1> 	push	es
   493 000001FC 1F                  <1> 	pop	ds
   494                              <1> 	;mov	cx, 16
   495 000001FD B90F00              <1> 	mov 	cx, 15
   496 00000200 29CE                <1> 	sub	si, cx
   497 00000202 30E4                <1> 	xor	ah, ah
   498                              <1> 	;del	cl
   499                              <1> L11:		
   500 00000204 AC                  <1> 	lodsb
   501 00000205 00C4                <1> 	add	ah, al
   502 00000207 E2FB                <1> 	loop	L11
   503                              <1> 	;
   504 00000209 88E0                <1> 	mov	al, ah
   505 0000020B F6D8                <1> 	neg	al	; -x+x = 0
   506 0000020D AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   507                              <1> 	;
   508 0000020E 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   509 0000020F 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   510                              <1> 	;
   511                              <1> 	; 23/02/2015
   512 00000210 57                  <1> 	push	di
   513                              <1> 	; ES:DI points to DPTE (FDPTE) location
   514                              <1> 	;mov	cx, 8
   515 00000211 B108                <1> 	mov	cl, 8
   516 00000213 F3A5                <1> 	rep	movsw	
   517                              <1> 	;
   518                              <1> 	; 23/02/2015
   519                              <1> 	; (P)ATA drive and LBA validation
   520                              <1> 	; (invalidating SATA drives and setting
   521                              <1> 	; CHS type I/O for old type fixed disks)
   522 00000215 5B                  <1> 	pop	bx
   523 00000216 8CC8                <1> 	mov	ax, cs
   524 00000218 8ED8                <1> 	mov	ds, ax
   525 0000021A 268B07              <1> 	mov	ax, [es:bx]
   526 0000021D 3DF001              <1> 	cmp	ax, 1F0h
   527 00000220 7418                <1> 	je	short L11a
   528 00000222 3D7001              <1> 	cmp	ax, 170h
   529 00000225 7413                <1> 	je	short L11a
   530                              <1> 	; invalidation 
   531                              <1> 	; (because base port address is not 1F0h or 170h)
   532 00000227 30FF                <1> 	xor	bh, bh
   533 00000229 88D3                <1> 	mov	bl, dl
   534 0000022B 80EB80              <1> 	sub	bl, 80h
   535 0000022E C687[2E62]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   536 00000233 808F[5062]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   537 00000238 EB14                <1> 	jmp	short L11b
   538                              <1> L11a:	
   539                              <1> 	; LBA validation
   540 0000023A 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   541 0000023E A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   542 00000240 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   543                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   544 00000242 28FF                <1> 	sub	bh, bh
   545 00000244 88D3                <1> 	mov	bl, dl
   546 00000246 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   547 00000249 80A7[5062]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   548                              <1> 				; bit 0 = LBA ready bit
   549                              <1> 	; 'diskio' procedure will check this bit !
   550                              <1> L11b:
   551 0000024E 3A16[2A62]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   552 00000252 7307                <1>         jnb     short L13
   553 00000254 E9FFFE              <1>         jmp     L10
   554                              <1> L12:
   555                              <1> 	; Restore data registers
   556 00000257 8CC8                <1> 	mov	ax, cs
   557 00000259 8ED8                <1> 	mov	ds, ax	
   558                              <1> L13:
   559                              <1> 	; 13/12/2014
   560 0000025B 0E                  <1> 	push	cs
   561 0000025C 07                  <1> 	pop	es
   562                              <1> L14:
   563 0000025D B411                <1> 	mov 	ah, 11h
   564 0000025F CD16                <1> 	int 	16h
   565                              <1> 	;jz 	short L15 ; no keys in keyboard buffer
   566                              <1> 	; 02/01/2022
   567 00000261 7447                <1> 	jz	short L16
   568 00000263 B010                <1> 	mov	al, 10h
   569 00000265 CD16                <1> 	int 	16h
   570 00000267 EBF4                <1> 	jmp 	short L14
   571                              <1> L15:
   572                              <1> 
   573                              <1> ; //////
   574                              <1> 
   575                              <1> ; 02/01/2022 - Retro UNIX 386 v1.2
   576                              <1> %if 0
   577                              <1> 	; 24/11/2014
   578                              <1> 	; 19/11/2014
   579                              <1> 	; 14/11/2014
   580                              <1> 	; Temporary code for disk searching code check
   581                              <1> 	;
   582                              <1> 	; This code will show existing (usable) drives and also
   583                              <1> 	; will show EDD interface support status for hard disks		
   584                              <1> 	; (If status bit 7 is 1, Identify Device info is ready,
   585                              <1> 	; no need to get it again in protected mode...) 
   586                              <1> 	;	
   587                              <1> 	; 13/11/2014
   588                              <1> 	mov	bx, 7
   589                              <1> 	mov	ah, 0Eh
   590                              <1> 	mov	al, [fd0_type]
   591                              <1> 	and	al, al
   592                              <1> 	jz	short L15a
   593                              <1> 	mov	dl, al
   594                              <1> 	mov	al, 'F'
   595                              <1> 	int 	10h
   596                              <1> 	mov	al, 'D'
   597                              <1> 	int 	10h
   598                              <1> 	mov	al, '0'
   599                              <1> 	int 	10h
   600                              <1> 	mov	al, ' '
   601                              <1> 	int	10h
   602                              <1> 	call	L15c
   603                              <1> 	mov	al, ' '
   604                              <1> 	int	10h
   605                              <1> 	;
   606                              <1> 	mov	al, [fd1_type]
   607                              <1> 	and	al, al
   608                              <1> 	jz	short L15a
   609                              <1> 	mov	dl, al
   610                              <1> 	mov	al, 'F'
   611                              <1> 	int 	10h
   612                              <1> 	mov	al, 'D'
   613                              <1> 	int 	10h
   614                              <1> 	mov	al, '1'
   615                              <1> 	int 	10h
   616                              <1> 	mov	al, ' '
   617                              <1> 	int	10h
   618                              <1> 	call	L15c
   619                              <1> 	mov	al, ' '
   620                              <1> 	int	10h
   621                              <1> 	mov	al, ' '
   622                              <1> 	int	10h
   623                              <1> L15a:
   624                              <1> 	mov	al, [hd0_type]
   625                              <1> 	and	al, al
   626                              <1> 	jz	short L15b
   627                              <1> 	mov	dl, al
   628                              <1> 	mov	al, 'H'
   629                              <1> 	int 	10h
   630                              <1> 	mov	al, 'D'
   631                              <1> 	int 	10h
   632                              <1> 	mov	al, '0'
   633                              <1> 	int 	10h
   634                              <1> 	mov	al, ' '
   635                              <1> 	int 	10h
   636                              <1> 	call	L15c
   637                              <1> 	mov	al, ' '
   638                              <1> 	int	10h
   639                              <1> 	;
   640                              <1> 	mov	al, [hd1_type]
   641                              <1> 	and	al, al
   642                              <1> 	jz	short L15b
   643                              <1> 	mov	dl, al
   644                              <1> 	mov	al, 'H'
   645                              <1> 	int 	10h
   646                              <1> 	mov	al, 'D'
   647                              <1> 	int 	10h
   648                              <1> 	mov	al, '1'
   649                              <1> 	int 	10h
   650                              <1> 	mov	al, ' '
   651                              <1> 	int 	10h
   652                              <1> 	call	L15c
   653                              <1> 	mov	al, ' '
   654                              <1> 	int	10h
   655                              <1> 	;
   656                              <1> 	mov	al, [hd2_type]
   657                              <1> 	and	al, al
   658                              <1> 	jz	short L15b
   659                              <1> 	mov	dl, al
   660                              <1> 	mov	al, 'H'
   661                              <1> 	int 	10h
   662                              <1> 	mov	al, 'D'
   663                              <1> 	int 	10h
   664                              <1> 	mov	al, '2'
   665                              <1> 	int 	10h
   666                              <1> 	mov	al, ' '
   667                              <1> 	int 	10h
   668                              <1> 	call	L15c
   669                              <1> 	mov	al, ' '
   670                              <1> 	int	10h
   671                              <1> 	;
   672                              <1> 	mov	al, [hd3_type]
   673                              <1> 	and	al, al
   674                              <1> 	jz	short L15b
   675                              <1> 	mov	dl, al
   676                              <1> 	mov	al, 'H'
   677                              <1> 	int 	10h
   678                              <1> 	mov	al, 'D'
   679                              <1> 	int 	10h
   680                              <1> 	mov	al, '3'
   681                              <1> 	int 	10h
   682                              <1> 	mov	al, ' '
   683                              <1> 	int 	10h
   684                              <1> 	call	L15c
   685                              <1> 	mov	al, ' '
   686                              <1> 	int	10h
   687                              <1> 	;
   688                              <1> L15b:
   689                              <1> 	mov	al, 0Dh
   690                              <1> 	int 	10h	
   691                              <1> 	mov	al, 0Ah
   692                              <1> 	int 	10h
   693                              <1> 	;;xor	ah, ah
   694                              <1> 	;;int 	16h	
   695                              <1> 	;
   696                              <1>         ;jmp	L16  ; jmp short L16
   697                              <1>         ; 02/01/2022
   698                              <1> 	jmp	short L16
   699                              <1> 	;
   700                              <1> L15c:
   701                              <1> 	mov	dh, dl
   702                              <1> 	shr	dh, 4
   703                              <1> 	add	dh, 30h
   704                              <1> 	and	dl, 15
   705                              <1> 	add	dl, 30h
   706                              <1> 	mov	al, dh
   707                              <1> 	int	10h
   708                              <1> 	mov	al, dl
   709                              <1> 	int	10h
   710                              <1> 	retn
   711                              <1> 	;
   712                              <1> 	; end of temporary code for disk searching code check
   713                              <1> 
   714                              <1> %endif
   715                              <1> 
   716                              <1> ; //////
   717                              <1> 
   718                              <1> set_disk_parms:
   719                              <1> 	; 12/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
   720                              <1> 	; 12/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
   721                              <1> 	; 09/05/2022
   722                              <1> 	;	disksize = cylinders*spt*heads (*)
   723                              <1> 	; (fd0&fd1 drv.size is calculated with total cylinders) 
   724                              <1> 	;
   725                              <1> 	; 04/02/2016 (ebx -> bx)
   726                              <1> 	; 10/07/2015
   727                              <1> 	; 14/01/2015
   728                              <1> 	;push	bx
   729 00000269 28FF                <1> 	sub	bh, bh
   730 0000026B 8A1E[2962]          <1> 	mov	bl, [drv]
   731 0000026F 80FB80              <1> 	cmp	bl, 80h
   732 00000272 7203                <1> 	jb	short sdp0
   733 00000274 80EB7E              <1> 	sub	bl, 7Eh
   734                              <1> sdp0:	
   735 00000277 81C3[4E62]          <1> 	add	bx, drv.status
   736 0000027B C60780              <1>   	mov	byte [bx], 80h ; 'Present' flag
   737                              <1> 	;
   738 0000027E 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   739 00000280 88CC                <1> 	mov	ah, cl ; 
   740 00000282 C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   741 00000285 81EB[4E62]          <1> 	sub	bx, drv.status
   742 00000289 D0E3                <1> 	shl	bl, 1
   743                              <1> 	; 12/07/2022
   744                              <1> 	;add	bx, drv.cylinders
   745 0000028B 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count
   746                              <1> 	;mov	[bx], ax
   747 0000028C 50                  <1> 	push	ax ; ** cylinders
   748                              <1> 	;sub	bx, drv.cylinders
   749                              <1> 	;add	bx, drv.heads
   750 0000028D 30E4                <1> 	xor	ah, ah
   751 0000028F 88F0                <1> 	mov	al, dh ; heads
   752 00000291 40                  <1> 	inc	ax
   753                              <1> 	;mov	[bx], ax
   754                              <1>         ;sub	bx, drv.heads
   755                              <1>         ;add	bx, drv.spt
   756 00000292 30ED                <1> 	xor	ch, ch
   757 00000294 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   758                              <1> 	;mov	[bx], cx
   759                              <1>         ;sub	bx, drv.spt
   760 00000297 D1E3                <1> 	shl	bx, 1
   761 00000299 81C3[3262]          <1> 	add	bx, drv.size ; disk size (in sectors)
   762                              <1> 	; LBA size = cylinders * heads * secpertrack
   763 0000029D F7E1                <1> 	mul	cx 
   764 0000029F 89C2                <1> 	mov	dx, ax	; heads*spt
   765 000002A1 58                  <1> 	pop	ax ; ** cylinders
   766                              <1> 	; 09/05/2022 (fd0&fd1 drv.size = cyls*spt*heads)
   767                              <1> 	;dec	ax ; 1 cylinder reserved (!?) ; (*)
   768 000002A2 F7E2                <1> 	mul	dx ; cylinders * (heads*spt)
   769 000002A4 8907                <1> 	mov	[bx], ax
   770 000002A6 895702              <1> 	mov	[bx+2], dx
   771                              <1> 	;
   772                              <1> 	;pop	bx
   773 000002A9 C3                  <1> 	retn
   774                              <1> 
   775                              <1> ;align 2
   776                              <1> 
   777                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   778                              <1> ;heads     :  dw 0, 0, 0, 0, 0, 0
   779                              <1> ;spt       :  dw 0, 0, 0, 0, 0, 0
   780                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   781                              <1> 
   782                              <1> ;last_drv:
   783                              <1> ;	db  0
   784                              <1> ;drv_status:
   785                              <1> ;	db  0,0,0,0,0,0
   786                              <1> ;	db 0
   787                              <1> 
   788                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   789                              <1> 
   790                              <1> L16:
   215                                  _L0:	
   216                                  	; 10/11/2014
   217 000002AA FA                           	cli	; Disable interrupts (clear interrupt flag)
   218                                  		; Reset Interrupt MASK Registers (Master&Slave)
   219                                  	;mov	al, 0FFh	; mask off all interrupts
   220                                  	;out	21h, al		; on master PIC (8259)
   221                                  	;jmp 	$+2  ; (delay)
   222                                  	;out	0A1h, al	; on slave PIC (8259)
   223                                  	;
   224                                  	; Disable NMI 
   225 000002AB B080                    	mov   	al, 80h 
   226 000002AD E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   227                                  	; 23/02/2015
   228 000002AF 90                      	nop			;
   229                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   230                                  				; for preventing unknown state (!?)
   231                                  
   232                                  	; 01/01/2022 (Retro UNIX 386 v1.2)
   233                                  	%define KERNELFSIZE KEND-KSTART 
   234                                  	;
   235                                   	; 20/08/2014
   236                                  	; Moving the kernel 64 KB back (to physical address 0)
   237                                  	; DS = CS = 1000h
   238                                  	; 05/11/2014
   239 000002B0 31C0                    	xor	ax, ax
   240 000002B2 8EC0                    	mov	es, ax ; ES = 0
   241                                  	;
   242                                  	;;mov	cx, (KEND - KLOAD)/4
   243                                  	;mov	cx, (KERNELFSIZE+3)/4 ; 01/01/2022
   244 000002B4 B94E32                  	mov	cx, (KERNELFSIZE+1)/2 ; 02/01/2022
   245 000002B7 31F6                    	xor	si, si
   246 000002B9 31FF                    	xor	di, di
   247                                  	;rep	movsd
   248 000002BB F3A5                    	rep	movsw ; 02/01/2022
   249                                  	;
   250 000002BD 06                      	push	es ; 0
   251 000002BE 68[C202]                	push	L17
   252 000002C1 CB                      	retf
   253                                  	;
   254                                  L17:
   255                                  	; Turn off the floppy drive motor
   256 000002C2 BAF203                          mov     dx, 3F2h
   257 000002C5 EE                              out     dx, al ; 0 ; 31/12/2013
   258                                  
   259                                  	; Enable access to memory above one megabyte
   260                                  L18:
   261 000002C6 E464                    	in	al, 64h
   262 000002C8 A802                    	test	al, 2
   263 000002CA 75FA                            jnz     short L18
   264 000002CC B0D1                    	mov	al, 0D1h	; Write output port
   265 000002CE E664                    	out	64h, al
   266                                  L19:
   267 000002D0 E464                    	in	al, 64h
   268 000002D2 A802                    	test	al, 2
   269 000002D4 75FA                            jnz     short L19
   270 000002D6 B0DF                    	mov	al, 0DFh	; Enable A20 line
   271 000002D8 E660                    	out	60h, al
   272                                  ;L20:
   273                                  	;
   274                                  	; Load global descriptor table register
   275                                  
   276                                          ;mov	ax, cs
   277                                          ;mov	ds, ax
   278                                  
   279 000002DA 2E0F0116[505F]                  lgdt    [cs:gdtd]
   280                                  
   281 000002E0 0F20C0                          mov     eax, cr0
   282                                  	;or 	eax, 1
   283 000002E3 40                      	inc     ax
   284 000002E4 0F22C0                  	mov     cr0, eax
   285                                  
   286                                  	; Jump to 32 bit code
   287                                  	
   288 000002E7 66                      	db	66h 		; Prefix for 32-bit
   289 000002E8 EA                      	db	0EAh 		; Opcode for far jump
   290 000002E9 [EF020000]              	dd	StartPM 	; Offset to start, 32-bit
   291                                  				; (1000h:StartPM = StartPM + 10000h)
   292 000002ED 0800                    	dw	KCODE		; This is the selector for CODE32_DESCRIPTOR,
   293                                  				; assuming that StartPM resides in code32
   294                                  
   295                                  [BITS 32] 
   296                                  
   297                                  StartPM:
   298                                  	; Kernel Base Address = 0 ; 30/12/2013
   299 000002EF 66B81000                	mov	ax, KDATA	; Save data segment identifier
   300 000002F3 8ED8                            mov	ds, ax		; Move a valid data segment into DS register
   301 000002F5 8EC0                           	mov	es, ax		; Move data segment into ES register
   302 000002F7 8EE0                           	mov	fs, ax		; Move data segment into FS register
   303 000002F9 8EE8                          	mov	gs, ax		; Move data segment into GS register
   304 000002FB 8ED0                            mov	ss, ax		; Move data segment into SS register
   305 000002FD BC00000900                      mov	esp, 90000h	; Move the stack pointer to 090000h
   306                                  
   307                                  clear_bss: ; Clear uninitialized data area
   308                                  	; 11/03/2015
   309 00000302 31C0                    	xor	eax, eax ; 0
   310                                  	;mov	ecx, (bss_end - bss_start)/4
   311                                  	;;shr	ecx, 2 ; bss section is already aligned for double words
   312                                  	; 12/12/2021
   313 00000304 B9B90C0000              	mov	ecx, BSS_SIZE/4
   314 00000309 BF[A0640000]            	mov	edi, bss_start	
   315 0000030E F3AB                    	rep	stosd  		
   316                                  
   317                                  memory_init:
   318                                  	; Initialize memory allocation table and page tables
   319                                  	;
   320                                  	; 02/01/2022 (Retro UNIX 386 v1.2)
   321                                  	; 16/11/2014
   322                                  	; 15/11/2014
   323                                  	; 07/11/2014
   324                                  	; 06/11/2014
   325                                  	; 05/11/2014
   326                                  	; 04/11/2014
   327                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   328                                  	;
   329                                  ;	xor	eax, eax
   330                                  ;	xor 	ecx, ecx
   331 00000310 B108                    	mov	cl, 8
   332 00000312 BF00001000              	mov	edi, MEM_ALLOC_TBL	
   333 00000317 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   334                                  				   ; for the first 1 MB memory
   335                                  	;
   336 00000319 8B0D[94640000]          	mov	ecx, [mem_1m_1k]   ; 02/01/2022	
   337                                  	;mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   338                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   339                                  	;shr	cx, 2		   ; convert 1 KB count to 4 KB count
   340 0000031F C1E902                  	shr	ecx, 2	; 02/01/2022
   341 00000322 890D[10670000]          	mov	[free_pages], ecx
   342 00000328 8B15[98640000]          	mov	edx, [mem_16m_64k] ; 02/01/2022
   343                                  	;mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   344                                  				   ; between 16 MB and 4 GB.
   345                                  	;or	dx, dx
   346 0000032E 09D2                    	or	edx, edx ; 02/01/2022
   347 00000330 7412                    	jz	short mi_0
   348                                  	;
   349                                  	;mov	ax, dx
   350 00000332 89D0                    	mov	eax, edx ; 02/01/2022
   351 00000334 C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   352 00000337 0105[10670000]          	add	[free_pages], eax
   353 0000033D 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   354 00000342 EB06                    	jmp	short mi_1
   355                                  mi_0:
   356                                  	;mov	ax, cx
   357 00000344 89C8                    	mov	eax, ecx ; 02/01/2022	 
   358 00000346 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB
   359                                  mi_1:
   360 0000034A A3[0C670000]            	mov	[memory_size], eax ; Total available memory in pages
   361                                  				   ; 1 alloc. tbl. bit = 1 memory page
   362                                  				   ; 32 allocation bits = 32 mem. pages
   363                                  	;
   364 0000034F 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page
   365 00000354 C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   366                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   367                                  				   ;  --> x M.A.T. pages, if y = 0
   368                                  	;mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages
   369 00000357 A3[20670000]            	mov	[mat_size], eax ; 02/01/2022
   370 0000035C C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   371                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   372 0000035F 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   373                                  	; Set/Calculate Kernel's Page Directory Address
   374 00000361 81C300001000            	add	ebx, MEM_ALLOC_TBL
   375 00000367 891D[08670000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   376                                  				   ; just after the last M.A.T. page
   377                                  	;
   378 0000036D 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   379 00000370 A3[18670000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   380                                  	;			   ; (allocation status search must be
   381                                  				   ; stopped after here)
   382 00000375 31C0                    	xor	eax, eax
   383 00000377 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)
   384                                  	;push	cx
   385 00000378 51                      	push	ecx ; 02/01/2022 
   386 00000379 C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to
   387                                  				   ; count of 32 allocation bits
   388 0000037C F3AB                    	rep	stosd
   389                                  	;pop	cx
   390 0000037E 59                      	pop	ecx ; 02/01/2022
   391 0000037F 40                      	inc	eax		   ; 0
   392 00000380 80E11F                  	and	cl, 31		   ; remain bits
   393 00000383 7412                    	jz	short mi_4
   394 00000385 8907                    	mov	[edi], eax	   ; reset
   395                                  mi_2:
   396 00000387 0FAB07                  	bts	[edi], eax	   ; 06/11/2014
   397 0000038A FEC9                    	dec	cl
   398 0000038C 7404                    	jz	short mi_3
   399 0000038E FEC0                    	inc	al
   400 00000390 EBF5                    	jmp	short mi_2
   401                                  mi_3:
   402 00000392 28C0                    	sub	al, al	   	   ; 0
   403 00000394 83C704                  	add	edi, 4		   ; 15/11/2014
   404                                  mi_4:
   405 00000397 09D2                    	or	edx, edx ; 02/01/2022
   406                                  	;or	dx, dx		  ; check 16M to 4G memory space
   407 00000399 741F                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   408                                  	;	
   409 0000039B B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   410                                  	;	
   411 000003A0 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   412 000003A2 7405                    	jz	short mi_5	  ; jump if EDI points to 
   413                                  				  ;         end of first 16 MB	
   414                                  	;shr	ecx, 1		  ; convert to dword count
   415                                  	;shr	ecx, 1		  ; (shift 2 bits right) 
   416 000003A4 C1E902                  	shr	ecx, 2	; 02/01/2022
   417 000003A7 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   418                                  				  ; (memory hole under 16 MB)
   419                                  mi_5:
   420 000003A9 89D1                    	mov	ecx, edx ; 02/01/2022
   421                                  	;mov	cx, dx		  ; count of 64 KB memory blocks
   422 000003AB D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   423 000003AD 9C                      	pushf			  ; 16/11/2014		
   424 000003AE 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   425 000003AF F3AB                    	rep	stosd
   426 000003B1 40                      	inc	eax		  ; 0
   427 000003B2 9D                      	popf			  ; 16/11/2014
   428 000003B3 7305                    	jnc	short mi_6
   429 000003B5 6648                    	dec	ax		  ; eax = 0000FFFFh
   430 000003B7 AB                      	stosd
   431 000003B8 6640                    	inc	ax		  ; 0		
   432                                  mi_6:
   433 000003BA 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   434 000003BC 7309                    	jnb	short mi_7	  ; end of memory allocation table
   435                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   436 000003BE 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   437 000003C0 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   438                                  	;shr	ecx, 1		  ; to dword count
   439                                  	;shr	ecx, 1		  ; (shift 2 bits right) 
   440 000003C2 C1E902                  	shr	ecx, 2 ; 02/01/2022	
   441 000003C5 F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   442                                  mi_7:
   443                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   444 000003C7 BA00001000              	mov	edx, MEM_ALLOC_TBL
   445                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   446                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   447 000003CC 8B0D[20670000]          	mov	ecx, [mat_size] ; 02/01/2022
   448                                  	;mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   449 000003D2 89D7                    	mov	edi, edx
   450 000003D4 C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   451                                  				  ; byte offset in M.A.T.
   452                                  				  ; (1 M.A.T. byte points to 
   453                                  				  ;	      32768 bytes)
   454                                  				  ; Note: MEM_ALLOC_TBL address 
   455                                  				  ; must be aligned on 128 KB 
   456                                  				  ; boundary!
   457 000003D7 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   458                                  	; eax = 0
   459 000003D9 290D[10670000]          	sub	[free_pages], ecx ; 07/11/2014
   460                                  mi_8:
   461 000003DF 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   462                                  	;dec	bl
   463 000003E2 FEC9                    	dec	cl
   464 000003E4 7404                    	jz	short mi_9
   465 000003E6 FEC0                    	inc	al
   466 000003E8 EBF5                    	jmp	short mi_8
   467                                  mi_9:
   468                                  	;
   469                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   470                                  	;		(allocate pages for system page tables)
   471                                  
   472                                  	; edx = MEM_ALLOC_TBL
   473 000003EA 8B0D[0C670000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   474 000003F0 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)
   475 000003F6 C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   476                                  				 ; page table count (PDE count)
   477                                  	;
   478 000003F9 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   479                                  	;
   480 000003FA 41                      	inc	ecx		 ; +1 for kernel page directory	
   481                                  	;
   482 000003FB 290D[10670000]          	sub	[free_pages], ecx ; 07/11/2014
   483                                  	;
   484 00000401 8B35[08670000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   485 00000407 C1EE0C                  	shr	esi, 12		 ; convert to page number
   486                                  mi_10:
   487 0000040A 89F0                    	mov	eax, esi	 ; allocation bit offset
   488 0000040C 89C3                    	mov	ebx, eax
   489 0000040E C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   490 00000411 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   491                                  				 ;   to align on dword boundary
   492 00000414 83E01F                  	and	eax, 31		 ; set allocation bit position 
   493                                  				 ;  (bit 0 to bit 31)
   494                                  	;
   495 00000417 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   496                                  	;
   497 00000419 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   498                                  	;
   499 0000041C 46                      	inc	esi		 ; next page table
   500 0000041D E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   501                                  				 ; (ecx = page table count + 1)
   502                                  	;
   503 0000041F 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
   504                                  	;
   505                                  	; Initialize Kernel Page Directory and Kernel Page Tables
   506                                  	;
   507                                  	; Initialize Kernel's Page Directory
   508 00000420 8B3D[08670000]          	mov	edi, [k_page_dir]
   509 00000426 89F8                    	mov	eax, edi
   510 00000428 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   511                                  		     	      ; supervisor + read&write + present
   512 0000042A 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)
   513                                  mi_11:
   514 0000042C 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   515                                  			        ; EAX points to next page table
   516 00000431 AB                      	stosd
   517 00000432 E2F8                    	loop	mi_11
   518 00000434 29C0                    	sub	eax, eax	; Empty PDE
   519                                  	;mov	cx, 1024	; Entry count (PGSZ/4)
   520                                  	; 02/01/2022
   521 00000436 B504                    	mov	ch, 4 ; cx = 4*256 = 1024
   522 00000438 29D1                    	sub	ecx, edx
   523 0000043A 7402                    	jz	short mi_12
   524 0000043C F3AB                    	rep	stosd 		; clear remain (empty) PDEs
   525                                  	;
   526                                  	; Initialization of Kernel's Page Directory is OK, here.
   527                                  mi_12:
   528                                  	; Initialize Kernel's Page Tables
   529                                  	;
   530                                  	; (EDI points to address of page table 0)
   531                                  	; eax = 0
   532 0000043E 8B0D[0C670000]          	mov	ecx, [memory_size] ; memory size in pages
   533 00000444 89CA                    	mov	edx, ecx	; (***)
   534 00000446 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
   535                                  			     ; supervisor + read&write + present
   536                                  mi_13:
   537 00000448 AB                      	stosd
   538 00000449 0500100000              	add	eax, 4096	
   539 0000044E E2F8                    	loop	mi_13
   540                                  	; 02/01/2022
   541 00000450 66B9FF03                	mov	cx, 1023
   542 00000454 21CA                    	and	edx, ecx
   543                                  	;and	dx, 1023	; (***)
   544 00000456 7407                    	jz	short mi_14
   545                                  	;mov	cx, 1024	
   546                                  	; 02/01/2022
   547                                  	;mov	ch, 4 ; cx = 4*256 = 1024
   548 00000458 41                      	inc	ecx ; ecx = 1024
   549 00000459 29D1                    	sub	ecx, edx
   550                                  	;sub	cx, dx		; from dx (<= 1023) to 1024
   551 0000045B 31C0                    	xor	eax, eax
   552 0000045D F3AB                    	rep	stosd		; clear remain (empty) PTEs 
   553                                  				; of the last page table
   554                                  mi_14:
   555                                  	;  Initialization of Kernel's Page Tables is OK, here.
   556                                  	;
   557 0000045F 89F8                    	mov	eax, edi	; end of the last page table page
   558                                  			        ; (beginging of user space pages)
   559 00000461 C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
   560 00000464 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
   561                                  				; aligning on dword boundary
   562                                  	 
   563 00000466 A3[1C670000]            	mov	[first_page], eax
   564 0000046B A3[14670000]            	mov	[next_page], eax ; The first free page pointer
   565                                  				 ; for user programs
   566                                  				 ; (Offset in Mem. Alloc. Tbl.)	
   567                                  	;
   568                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
   569                                  	;
   570                                  	
   571                                  	; Enable paging
   572                                  	;
   573 00000470 A1[08670000]                    mov     eax, [k_page_dir]
   574 00000475 0F22D8                  	mov	cr3, eax
   575 00000478 0F20C0                  	mov	eax, cr0
   576 0000047B 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
   577 00000480 0F22C0                  	mov	cr0, eax
   578                                          ;jmp    KCODE:StartPMP
   579                                  
   580 00000483 EA                      	db 0EAh 		; Opcode for far jump
   581 00000484 [8A040000]                      dd StartPMP		; 32 bit offset
   582 00000488 0800                    	dw KCODE		; kernel code segment descriptor
   583                                  
   584                                  StartPMP:
   585                                  	; 06/11//2014
   586                                  	; Clear video page 0
   587                                  	;
   588                                  	; Temporary Code
   589                                  	;
   590                                  	;mov	ecx, 80*25/2
   591 0000048A 66B9E803                	mov	cx, (80*25)/2 ; 02/01/2022
   592 0000048E BF00800B00              	mov	edi, 0B8000h
   593 00000493 57                      	push	edi ; * ; 02/01/2022
   594 00000494 31C0                    	xor	eax, eax	; black background, black fore color
   595 00000496 F3AB                    	rep	stosd
   596                                  	
   597                                  	; 19/08/2014
   598                                  	; Kernel Base Address = 0
   599                                  	; It is mapped to (physically) 0 in the page table.
   600                                  	; So, here is exactly 'StartPMP' address.
   601                                  	;
   602                                  	;;mov	ah, 4Eh	; Red background, yellow forecolor
   603                                  	;;mov	esi, msgPM
   604                                  	;; 14/08/2015 (kernel version message will appear
   605                                  	;;	       when protected mode and paging is enabled)
   606 00000498 B40B                    	mov	ah, 0Bh ; Black background, light cyan forecolor
   607 0000049A BE[64620000]            	mov	esi, msgKVER
   608 0000049F 5F                      	pop	edi ; * ; 02/01/2022
   609                                  	;mov	edi, 0B8000h ; 27/08/2014
   610                                  	; 20/08/2014
   611 000004A0 E88F010000              	call	printk
   612                                  
   613                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
   614                                  	; // Set IRQ offsets
   615                                  	;
   616                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
   617                                  	;
   618                                  					;; ICW1
   619 000004A5 B011                    	mov	al, 11h			; Initialization sequence
   620 000004A7 E620                    	out	20h, al			; 	8259A-1
   621                                  	; jmp 	$+2
   622 000004A9 E6A0                    	out	0A0h, al		; 	8259A-2
   623                                  					;; ICW2
   624 000004AB B020                    	mov	al, 20h			; Start of hardware ints (20h)
   625 000004AD E621                    	out	21h, al			;	for 8259A-1
   626                                  	; jmp 	$+2
   627 000004AF B028                    	mov	al, 28h			; Start of hardware ints (28h)
   628 000004B1 E6A1                    	out	0A1h, al		; 	for 8259A-2
   629                                  					;
   630 000004B3 B004                    	mov	al, 04h			;; ICW3
   631 000004B5 E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
   632                                  	; jmp 	$+2
   633 000004B7 B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
   634 000004B9 E6A1                    	out	0A1h, al		;
   635                                  					;; ICW4
   636 000004BB B001                    	mov	al, 01h	 		;
   637 000004BD E621                    	out	21h, al			; 	8086 mode, normal EOI	
   638                                  	; jmp 	$+2
   639 000004BF E6A1                    	out	0A1h, al		;	for both chips.
   640                                  
   641                                  	;mov	al, 0FFh	; mask off all interrupts for now
   642                                  	;out	21h, al
   643                                  	;; jmp 	$+2
   644                                  	;out	0A1h, al
   645                                  
   646                                  	; 02/04/2015
   647                                  	; 26/03/2015 System call (INT 30h) modification
   648                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
   649                                  	;
   650                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
   651                                  	;  setup_idt:
   652                                  	;
   653                                          ;; 16/02/2015
   654                                  	;;mov	dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
   655                                  	; 21/08/2014 (timer_int)
   656 000004C1 BE[5C5F0000]            	mov	esi, ilist
   657 000004C6 8D3D[A0640000]          	lea	edi, [idt]
   658                                  	; 26/03/2015
   659                                  	;mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
   660                                  	; 02/01/2022
   661 000004CC B130                    	mov	cl, 48 ; ecx = 48
   662                                  	; 02/04/2015
   663 000004CE BB00000800              	mov	ebx, 80000h
   664                                  rp_sidt1:
   665 000004D3 AD                      	lodsd
   666 000004D4 89C2                    	mov	edx, eax
   667 000004D6 66BA008E                	mov	dx, 8E00h
   668 000004DA 6689C3                  	mov	bx, ax
   669 000004DD 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
   670                                         			        ; /* interrupt gate - dpl=0, present */
   671 000004DF AB                      	stosd	; selector & offset bits 0-15 	
   672 000004E0 89D0                    	mov	eax, edx
   673 000004E2 AB                      	stosd	; attributes & offset bits 16-23
   674 000004E3 E2EE                    	loop	rp_sidt1
   675 000004E5 B110                    	mov	cl, 16		; 16 software interrupts (INT 30h to INT 3Fh)
   676                                  rp_sidt2:
   677 000004E7 AD                      	lodsd
   678 000004E8 21C0                    	and	eax, eax
   679 000004EA 7413                    	jz	short rp_sidt3
   680 000004EC 89C2                    	mov	edx, eax
   681 000004EE 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   682 000004F2 6689C3                  	mov	bx, ax
   683 000004F5 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   684 000004F7 AB                      	stosd
   685 000004F8 89D0                    	mov	eax, edx
   686 000004FA AB                      	stosd
   687 000004FB E2EA                    	loop	rp_sidt2
   688 000004FD EB16                    	jmp	short sidt_OK
   689                                  rp_sidt3:
   690 000004FF B8[58090000]            	mov	eax, ignore_int
   691 00000504 89C2                    	mov	edx, eax
   692 00000506 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   693 0000050A 6689C3                  	mov	bx, ax
   694 0000050D 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   695                                  rp_sidt4:
   696 0000050F AB                      	stosd
   697 00000510 92                      	xchg	eax, edx
   698 00000511 AB                      	stosd
   699 00000512 92                      	xchg	edx, eax
   700 00000513 E2FA                    	loop	rp_sidt4
   701                                  sidt_OK: 
   702 00000515 0F011D[565F0000]        	lidt 	[idtd]
   703                                  	;
   704                                  	; TSS descriptor setup ; 24/03/2015
   705 0000051C B8[A0660000]            	mov	eax, task_state_segment
   706 00000521 66A3[4A5F0000]          	mov	[gdt_tss0], ax
   707 00000527 C1C010                  	rol	eax, 16
   708 0000052A A2[4C5F0000]            	mov	[gdt_tss1], al
   709 0000052F 8825[4F5F0000]          	mov	[gdt_tss2], ah
   710 00000535 66C705[06670000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
   710 0000053D 00                 
   711                                  		; 
   712                                  		; IO Map Base address (When this address points
   713                                  		; to end of the TSS, CPU does not use IO port 
   714                                  		; permission bit map for RING 3 IO permissions, 
   715                                  		; access to any IO ports in ring 3 will be forbidden.)
   716                                   		;
   717                                  	;mov	[tss.esp0], esp ; TSS offset 4
   718                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
   719 0000053E 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
   720                                  			 ; occurs (or a system call -software INT- is requested)
   721                                  			 ; while cpu running in ring 3 (in user mode).				
   722                                  			 ; (Kernel stack pointer and segment will be loaded
   723                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
   724 00000542 0F00D8                  	ltr	ax  ; Load task register
   725                                  	;
   726                                  esp0_set0:
   727                                  	; 30/07/2015
   728 00000545 8B0D[0C670000]          	mov 	ecx, [memory_size] ; memory size in pages
   729 0000054B C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
   730 0000054E 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
   731                                  			  ; (kernel mode virtual address)
   732 00000554 7605                    	jna	short esp0_set1
   733                                  	;
   734                                  	; If available memory > CORE (end of the 1st 4 MB)
   735                                  	; set stack pointer to CORE
   736                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
   737                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
   738 00000556 B900004000              	mov	ecx, CORE
   739                                  esp0_set1:
   740 0000055B 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
   741                                  esp0_set_ok:
   742                                  	; 30/07/2015 (**tss.esp0**) 
   743 0000055D 8925[A4660000]          	mov	[tss.esp0], esp
   744 00000563 66C705[A8660000]10-             mov     word [tss.ss0], KDATA
   744 0000056B 00                 
   745                                  	; 14/08/2015
   746                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
   747                                  	;
   748                                  	;cli	; Disable interrupts (for CPU)
   749                                  	;    (CPU will not handle hardware interrupts, except NMI!)
   750                                  	;
   751 0000056C 30C0                    	xor	al, al		; Enable all hardware interrupts!
   752 0000056E E621                    	out	21h, al		; (IBM PC-AT compatibility)
   753 00000570 EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
   754 00000572 E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
   755                                  				; (Even if related hardware component
   756                                  				;  does not exist!)
   757                                  	; Enable NMI 
   758 00000574 B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
   759 00000576 E670                    	out  	70h, al
   760                                  	; 23/02/2015
   761 00000578 90                      	nop
   762 00000579 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
   763                                  				; for preventing unknown state (!?)
   764                                  	;
   765                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
   766                                  	;
   767                                  	; 02/09/2014
   768 0000057B 6631DB                  	xor	bx, bx
   769 0000057E 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
   770 00000582 E81D0E0000              	call	set_cpos
   771                                  	;
   772                                  	; 06/11/2014
   773                                  	; Temporary Code
   774                                  	;
   775 00000587 E8920F0000              	call	memory_info
   776                                  	; 14/08/2015
   777                                  	;call	getch ; 28/02/2015
   778                                  drv_init:
   779 0000058C FB                      	sti	; Enable Interrupts 
   780                                  	; 06/02/2015
   781 0000058D 8B15[2E620000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
   782 00000593 668B1D[2C620000]        	mov	bx, [fd0_type] ; fd0, fd1
   783                                  	; 22/02/2015
   784 0000059A 6621DB                  	and	bx, bx
   785 0000059D 751B                    	jnz	short di1
   786                                  	;
   787 0000059F 09D2                    	or 	edx, edx
   788 000005A1 7529                    	jnz	short di2
   789                                  	;
   790                                  setup_error:
   791 000005A3 BE[4D630000]            	mov 	esi, setup_error_msg
   792                                  psem:	
   793 000005A8 AC                      	lodsb
   794 000005A9 08C0                    	or	al, al
   795                                  	;jz	short haltx ; 22/02/2015
   796 000005AB 7426                    	jz	short di3
   797 000005AD 56                      	push	esi
   798 000005AE 31DB                    	xor	ebx, ebx ; 0
   799                                  			; Video page 0 (bl=0)
   800 000005B0 B407                    	mov	ah, 07h ; Black background, 
   801                                  			; light gray forecolor
   802 000005B2 E8E30C0000              	call	write_tty
   803 000005B7 5E                      	pop	esi
   804 000005B8 EBEE                    	jmp	short psem
   805                                  
   806                                  di1:
   807                                  	; supress 'jmp short T6'
   808                                  	;  (activate fdc motor control code)
   809 000005BA 66C705[B5060000]90-     	mov	word [T5], 9090h ; nop
   809 000005C2 90                 
   810                                  	;
   811                                  	;mov	ax, int_0Eh	; IRQ 6 handler
   812                                  	;mov	di, 0Eh*4	; IRQ 6 vector
   813                                  	;stosw
   814                                  	;mov 	ax, cs
   815                                  	;stosw
   816                                  	;; 16/02/2015
   817                                          ;;mov	dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
   818                                  	;
   819 000005C3 E8FC180000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
   820                                  	;
   821 000005C8 09D2                    	or	edx, edx
   822 000005CA 7407                            jz      short di3
   823                                  di2:
   824 000005CC E825190000              	call   	DISK_SETUP	; Initialize Fixed Disks
   825 000005D1 72D0                            jc      short setup_error
   826                                  di3:
   827 000005D3 E81A0F0000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
   828                                  	;
   829 000005D8 E89F580000              	call	display_disks ; 07/03/2015  (Temporary)
   830                                  ;haltx:
   831                                  	; 14/08/2015
   832                                  	;call	getch ; 22/02/2015
   833 000005DD FB                      	sti	; Enable interrupts (for CPU)
   834                                  	; 14/08/2015
   835                                  	;mov 	ecx, 0FFFFFFFh
   836                                  	; 22/11/2021
   837 000005DE B9FFFF2F00              	mov 	ecx, 02FFFFFh
   838                                  md_info_msg_wait:
   839 000005E3 51                      	push 	ecx
   840 000005E4 B001                    	mov	al, 1
   841 000005E6 8A25[36670000]          	mov 	ah, [ptty] ; active (current) video page
   842 000005EC E860550000              	call	getc_n
   843 000005F1 59                      	pop	ecx
   844 000005F2 7502                    	jnz	short md_info_msg_ok
   845 000005F4 E2ED                    	loop	md_info_msg_wait
   846                                  md_info_msg_ok:
   847                                  	; 30/06/2015
   848 000005F6 E8BF220000              	call	sys_init
   849                                  	;
   850                                  	;jmp 	cpu_reset ; 22/02/2015
   851                                  hang:
   852                                  	; 04/12/2021
   853 000005FB 29C0                    	sub	eax, eax
   854                                  _hang:	
   855                                  	; 23/02/2015
   856                                  	;sti			; Enable interrupts
   857 000005FD F4                      	hlt
   858                                  	;
   859                                  	;nop
   860                                  	;; 03/12/2014
   861                                  	;; 28/08/2014
   862                                  	;mov	ah, 11h
   863                                  	;call	getc
   864                                  	;jz     _c8
   865                                  	;
   866                                  	; 23/02/2015
   867                                  	; 06/02/2015
   868                                  	; 07/09/2014
   869 000005FE 31DB                    	xor	ebx, ebx
   870 00000600 8A1D[36670000]          	mov	bl, [ptty]	; active_page
   871 00000606 89DE                    	mov	esi, ebx
   872                                  	;shl 	si, 1
   873                                  	; 17/07/2022
   874 00000608 D1E6                    	shl	esi, 1
   875 0000060A 81C6[38670000]          	add	esi, ttychr
   876 00000610 668B06                  	mov	ax, [esi]
   877                                  	;and	ax, ax
   878                                  	;;jz	short _c8
   879                                  	;jz	short hang
   880                                  	; 04/12/2021
   881 00000613 21C0                    	and	eax, eax
   882 00000615 74E6                    	jz	short _hang
   883 00000617 66C7060000              	mov	word [esi], 0
   884 0000061C 80FB03                  	cmp	bl, 3		; Video page 3
   885                                  	;jb	short _c8
   886 0000061F 72DA                    	jb	short hang
   887                                  	;	
   888                                  	; 02/09/2014
   889 00000621 B40E                    	mov	ah, 0Eh		; Yellow character 
   890                                  				; on black background
   891                                  	; 30/11/2021 (32 bit reg push-pop)
   892                                  	; 07/09/2014
   893                                  nxtl:
   894 00000623 53                      	push	ebx
   895                                  	;
   896                                  	;xor	ebx, ebx	; bl = 0 (video page 0)
   897                                  				; bh = 0 (video mode)
   898                                  				; Retro UNIX 386 v1 - Video Mode 0
   899                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
   900 00000624 50                      	push	eax
   901 00000625 E8700C0000              	call 	write_tty
   902 0000062A 58                      	pop	eax
   903                                  	;pop	bx
   904 0000062B 5B                      	pop	ebx
   905 0000062C 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
   906                                  	;jne	short _c8
   907 0000062E 75CB                    	jne	short hang
   908 00000630 B00A                    	mov	al, 0Ah		; next line
   909 00000632 EBEF                    	jmp	short nxtl
   910                                  	
   911                                  ;_c8:
   912                                  ;	; 25/08/2014
   913                                  ;	cli			; Disable interrupts
   914                                  ;	mov	al, [scounter + 1]
   915                                  ;	and	al, al
   916                                  ;	jnz	hang
   917                                  ;	call	rtc_p
   918                                  ;	jmp     hang
   919                                  
   920                                  
   921                                  	; 27/08/2014
   922                                  	; 20/08/2014
   923                                  printk:
   924                                          ;mov    edi, [scr_row]
   925                                  pkl:
   926 00000634 AC                      	lodsb
   927 00000635 08C0                    	or 	al, al
   928 00000637 7404                    	jz	short pkr
   929 00000639 66AB                    	stosw
   930 0000063B EBF7                    	jmp	short pkl
   931                                  pkr:
   932 0000063D C3                      	retn
   933                                  
   934                                  ; 25/07/2015
   935                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
   936                                  ; 17/02/2015
   937                                  ; 06/02/2015 (unix386.s)
   938                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
   939                                  ;
   940                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
   941                                  ;
   942                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
   943                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
   944                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
   945                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
   946                                  ;									       :
   947                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
   948                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
   949                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
   950                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
   951                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
   952                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
   953                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
   954                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
   955                                  ;-------------------------------------------------------------------------------
   956                                  ;
   957                                  
   958                                  timer_int:	; IRQ 0
   959                                  ;int_08h:	; Timer
   960                                  	; 14/10/2015
   961                                  	; Here, we are simulating system call entry (for task switch)
   962                                  	; (If multitasking is enabled, 
   963                                  	; 'clock' procedure may jump to 'sysrelease')
   964 0000063E 1E                      	push	ds
   965 0000063F 06                      	push	es
   966 00000640 0FA0                    	push	fs
   967 00000642 0FA8                    	push	gs
   968 00000644 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
   969 00000645 66B91000                	mov     cx, KDATA
   970 00000649 8ED9                            mov     ds, cx
   971 0000064B 8EC1                            mov     es, cx
   972 0000064D 8EE1                            mov     fs, cx
   973 0000064F 8EE9                            mov     gs, cx
   974                                  	;
   975 00000651 0F20D9                  	mov	ecx, cr3
   976 00000654 890D[F7060000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
   977                                  	;
   978 0000065A 3B0D[08670000]          	cmp 	ecx, [k_page_dir]
   979 00000660 741F                    	je	short T3
   980                                  	;
   981                                  	; timer interrupt has been occurred while OS is in user mode
   982 00000662 A3[446C0000]            	mov 	[u.r0], eax
   983 00000667 89E1                    	mov	ecx, esp
   984 00000669 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
   985 0000066C 890D[3C6C0000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
   986 00000672 8925[406C0000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
   987                                  	;
   988 00000678 8B0D[08670000]          	mov	ecx, [k_page_dir]
   989 0000067E 0F22D9                  	mov	cr3, ecx
   990                                  T3:
   991 00000681 FB                      	sti				; INTERRUPTS BACK ON
   992 00000682 66FF05[84670000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
   993 00000689 7507                    	JNZ	short T4		; GO TO TEST_DAY
   994 0000068B 66FF05[86670000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
   995                                  T4:					; TEST_DAY
   996 00000692 66833D[86670000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
   997 0000069A 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
   998 0000069C 66813D[84670000]B0-     	CMP	word [TIMER_LOW],0B0H
   998 000006A4 00                 
   999 000006A5 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1000                                  
  1001                                  ;-----	TIMER HAS GONE 24 HOURS
  1002                                  	;;SUB	AX,AX
  1003                                  	;MOV	[TIMER_HIGH],AX
  1004                                  	;MOV	[TIMER_LOW],AX
  1005 000006A7 29C0                    	sub	eax, eax
  1006 000006A9 A3[84670000]            	mov	[TIMER_LH], eax
  1007                                  	;	
  1008 000006AE C605[88670000]01        	MOV	byte [TIMER_OFL],1
  1009                                  
  1010                                  ;-----	TEST FOR DISKETTE TIME OUT
  1011                                  
  1012                                  T5:
  1013                                  	; 23/12/2014
  1014 000006B5 EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1015                                  					; (9090h) if a floppy disk
  1016                                  					; is detected.
  1017                                  	;mov	al,[CS:MOTOR_COUNT]
  1018 000006B7 A0[8B670000]            	mov	al, [MOTOR_COUNT]
  1019 000006BC FEC8                    	dec	al
  1020                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1021 000006BE A2[8B670000]            	mov	[MOTOR_COUNT], al
  1022                                  	;mov	[ORG_MOTOR_COUNT], al
  1023 000006C3 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1024 000006C5 B0F0                    	mov 	al,0F0h
  1025                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1026 000006C7 2005[8A670000]          	and	[MOTOR_STATUS], al
  1027                                  	;and	[ORG_MOTOR_STATUS], al
  1028 000006CD B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1029                                  					; bit 2 = enable controller
  1030                                  					;	1 = normal operation
  1031                                  					;	0 = reset	
  1032                                  					; bit 0, 1 = drive select
  1033                                  					; bit 4-7 = motor running bits 
  1034 000006CF 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1035 000006D3 EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1036                                  T6:	
  1037                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1038                                  					; TIMER TICK INTERRUPT
  1039                                  	;;inc	word [wait_count] ;;27/02/2015
  1040                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1041                                  	;;;;cli
  1042                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1043 000006D4 FF15[EF060000]          	call	[x_timer] ; 14/05/2015
  1044                                  T7:
  1045                                  	; 14/10/2015
  1046 000006DA B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1047 000006DC FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1048 000006DD E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1049                                  	;
  1050 000006DF A1[F7060000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1051 000006E4 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1052                                  	;
  1053 000006E7 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1054                                  	;
  1055 000006E8 0FA9                    	pop	gs
  1056 000006EA 0FA1                    	pop	fs
  1057 000006EC 07                      	pop	es
  1058 000006ED 1F                      	pop	ds
  1059 000006EE CF                      	iretd	; return from interrupt
  1060                                  
  1061                                  
  1062                                  ; ////////////////
  1063                                  
  1064                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1065                                  x_timer:
  1066 000006EF [FB060000]              	dd 	u_timer	; (temporary demo code)	; 14/05/2015
  1067                                  	;dd	clock
  1068                                  
  1069                                  ; 23/02/2022 - Real time clock (digital) output demo (sys emt)
  1070                                  x_rtci:
  1071 000006F3 [310A0000]              	dd	rtc_p	; (temporary demo code)	; 23/02/2022
  1072                                  
  1073                                  ; 14/10/2015
  1074 000006F7 00000000                cr3reg: dd 0
  1075                                  
  1076                                  	; 04/12/2021 - Retro UNIX 386 v1.2
  1077                                  	; 06/02/2015
  1078                                  	; 07/09/2014
  1079                                  	; 21/08/2014
  1080                                  u_timer:
  1081                                  ;timer_int:	; IRQ 0
  1082                                  	; 06/02/2015
  1083                                  	;push	eax
  1084                                  	;push	edx
  1085                                  	;push	ecx
  1086                                  	;push	ebx
  1087                                  	;push	ds
  1088                                  	;push	es
  1089                                  	;mov	eax, KDATA
  1090                                  	;mov	ds, ax
  1091                                  	;mov	es, ax
  1092 000006FB FF05[4C670000]          	inc	dword [tcount]
  1093 00000701 BB[D6620000]            	mov	ebx, tcountstr + 4
  1094                                  	;mov	ax, [tcount]
  1095                                  	; 04/12/2021
  1096 00000706 A1[4C670000]            	mov	eax, [tcount]
  1097 0000070B B90A000000              	mov	ecx, 10
  1098                                  rp_divtcnt:
  1099 00000710 31D2                    	xor	edx, edx
  1100 00000712 F7F1                    	div	ecx
  1101 00000714 80C230                  	add	dl, 30h
  1102 00000717 8813                    	mov	[ebx], dl
  1103                                  	;or	ax, ax
  1104                                  	; 04/12/2021
  1105 00000719 09C0                    	or	eax, eax
  1106 0000071B 7403                    	jz	short print_lzero
  1107 0000071D 4B                      	dec	ebx
  1108 0000071E EBF0                    	jmp	short rp_divtcnt
  1109                                  print_lzero:
  1110 00000720 81FB[D2620000]          	cmp	ebx, tcountstr
  1111 00000726 7606                    	jna	short print_tcount
  1112 00000728 4B                      	dec	ebx
  1113 00000729 C60330                   	mov	byte [ebx], 30h
  1114 0000072C EBF2                    	jmp	short print_lzero
  1115                                  print_tcount:
  1116 0000072E 56                      	push	esi
  1117 0000072F 57                      	push	edi
  1118 00000730 BE[AE620000]            	mov	esi, timer_msg ; Timer interrupt message
  1119                                  	; 07/09/2014
  1120                                  	;mov	bx, 1	; Video page 1
  1121                                  	; 04/12/2021
  1122 00000735 29DB                    	sub	ebx, ebx
  1123                                  	;inc	bl ; ebx = 1
  1124                                  	; 02/01/2022
  1125 00000737 B306                    	mov	bl, 6	; Video page 6
  1126                                  ptmsg:
  1127 00000739 AC                      	lodsb
  1128 0000073A 08C0                    	or	al, al
  1129 0000073C 740D                    	jz	short ptmsg_ok
  1130 0000073E 56                      	push	esi
  1131                                  	;push	bx
  1132                                  	; 04/12/2021
  1133 0000073F 53                              push	ebx
  1134 00000740 B42F                    	mov     ah, 2Fh ; Green background, white forecolor
  1135 00000742 E8530B0000              	call 	write_tty
  1136                                  	;pop	bx
  1137                                  	; 04/12/2021
  1138 00000747 5B                      	pop	ebx
  1139 00000748 5E                      	pop	esi
  1140 00000749 EBEE                    	jmp	short ptmsg
  1141                                  	;; 27/08/2014
  1142                                  	;mov	edi, 0B8000h + 0A0h ; Row 1
  1143                                  	;call	printk
  1144                                  	;
  1145                                  ptmsg_ok:
  1146                                  	; 07/09/2014
  1147                                  	;xor	dx, dx		; column 0, row 0
  1148                                  	; 04/12/2021
  1149 0000074B 31D2                    	xor	edx, edx
  1150 0000074D E8520C0000              	call	set_cpos	; set cursor position to 0,0 
  1151                                  	; 23/02/2015
  1152                                  	; 25/08/2014
  1153                                  	;mov	ebx, scounter		; (seconds counter)
  1154                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1155                                  ;	dec	byte [scounter+1]
  1156                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1157                                  ;	jns	short u_timer_retn
  1158                                  	; 26/02/2015
  1159                                  ;	call	rtc_p
  1160                                  ;	mov	ebx, scounter		; (seconds counter)
  1161                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1162                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1163                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1164                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1165                                  ;	mov	byte [ebx], 5
  1166                                  ;	inc	byte [ebx+1] ; 19
  1167                                  ;;timer_eoi:
  1168                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1169                                  ;;	out	20h, al	; 8259 PORT
  1170                                  	;
  1171                                  ;u_timer_retn:  ; 06/02/2015
  1172 00000752 5F                      	pop	edi
  1173 00000753 5E                      	pop	esi
  1174                                  	;pop	es
  1175                                  	;pop	ds
  1176                                  	;pop	ebx
  1177                                  	;pop	ecx
  1178                                  	;pop	edx
  1179                                  	;pop	eax
  1180                                  	;iret
  1181 00000754 C3                      	retn	; 06/02/2015
  1182                                  
  1183                                  	; 28/08/2014
  1184                                  irq0:
  1185 00000755 6A00                            push 	dword 0
  1186 00000757 EB48                    	jmp	short which_irq
  1187                                  irq1:
  1188 00000759 6A01                            push 	dword 1
  1189 0000075B EB44                    	jmp	short which_irq
  1190                                  irq2:
  1191 0000075D 6A02                            push 	dword 2
  1192 0000075F EB40                    	jmp	short which_irq
  1193                                  irq3:
  1194                                  	; 20/11/2015
  1195                                  	; 24/10/2015
  1196 00000761 2EFF15[3E300000]        	call	dword [cs:com2_irq3]
  1197 00000768 6A03                    	push 	dword 3
  1198 0000076A EB35                    	jmp	short which_irq
  1199                                  irq4:
  1200                                  	; 20/11/2015
  1201                                  	; 24/10/2015
  1202 0000076C 2EFF15[3A300000]        	call	dword [cs:com1_irq4]
  1203 00000773 6A04                            push 	dword 4
  1204 00000775 EB2A                    	jmp	short which_irq
  1205                                  irq5:
  1206 00000777 6A05                            push 	dword 5
  1207 00000779 EB26                    	jmp	short which_irq
  1208                                  irq6:
  1209 0000077B 6A06                            push 	dword 6
  1210 0000077D EB22                    	jmp	short which_irq
  1211                                  irq7:
  1212 0000077F 6A07                            push 	dword 7
  1213 00000781 EB1E                    	jmp	short which_irq
  1214                                  irq8:
  1215 00000783 6A08                            push 	dword 8
  1216 00000785 EB1A                    	jmp	short which_irq
  1217                                  irq9:
  1218 00000787 6A09                            push 	dword 9
  1219 00000789 EB16                    	jmp	short which_irq
  1220                                  irq10:
  1221 0000078B 6A0A                            push 	dword 10
  1222 0000078D EB12                    	jmp	short which_irq
  1223                                  irq11:
  1224 0000078F 6A0B                            push 	dword 11
  1225 00000791 EB0E                    	jmp	short which_irq
  1226                                  irq12:
  1227 00000793 6A0C                            push 	dword 12
  1228 00000795 EB0A                    	jmp	short which_irq
  1229                                  irq13:
  1230 00000797 6A0D                            push 	dword 13
  1231 00000799 EB06                    	jmp	short which_irq
  1232                                  irq14:
  1233 0000079B 6A0E                            push 	dword 14
  1234 0000079D EB02                    	jmp	short which_irq
  1235                                  irq15:
  1236 0000079F 6A0F                            push 	dword 15
  1237                                  	;jmp	short which_irq
  1238                                  
  1239                                  	; 19/10/2015
  1240                                  	; 29/08/2014
  1241                                  	; 21/08/2014
  1242                                  which_irq:
  1243 000007A1 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1244 000007A4 53                      	push	ebx
  1245 000007A5 56                      	push	esi
  1246 000007A6 57                      	push	edi
  1247 000007A7 1E                      	push 	ds
  1248 000007A8 06                      	push 	es
  1249                                  	;
  1250 000007A9 88C3                    	mov	bl, al
  1251                                  	;
  1252 000007AB B810000000              	mov	eax, KDATA
  1253 000007B0 8ED8                    	mov	ds, ax
  1254 000007B2 8EC0                    	mov	es, ax
  1255                                  	; 19/10/2015
  1256 000007B4 FC                      	cld
  1257                                          ; 27/08/2014
  1258 000007B5 8105[5C620000]A000-             add     dword [scr_row], 0A0h
  1258 000007BD 0000               
  1259                                  	;
  1260 000007BF B417                    	mov	ah, 17h	; blue (1) background, 
  1261                                  			; light gray (7) forecolor
  1262 000007C1 8B3D[5C620000]                  mov     edi, [scr_row]
  1263 000007C7 B049                    	mov	al, 'I'
  1264 000007C9 66AB                    	stosw
  1265 000007CB B052                    	mov	al, 'R'
  1266 000007CD 66AB                    	stosw
  1267 000007CF B051                    	mov	al, 'Q'
  1268 000007D1 66AB                    	stosw
  1269 000007D3 B020                    	mov	al, ' '
  1270 000007D5 66AB                    	stosw
  1271 000007D7 88D8                    	mov	al, bl
  1272 000007D9 3C0A                    	cmp	al, 10
  1273 000007DB 7208                    	jb	short iix
  1274 000007DD B031                    	mov	al, '1'
  1275 000007DF 66AB                    	stosw
  1276 000007E1 88D8                    	mov	al, bl
  1277 000007E3 2C0A                    	sub	al, 10
  1278                                  iix:
  1279 000007E5 0430                    	add	al, '0'
  1280 000007E7 66AB                    	stosw
  1281 000007E9 B020                    	mov	al, ' '
  1282 000007EB 66AB                    	stosw
  1283 000007ED B021                    	mov	al, '!'
  1284 000007EF 66AB                    	stosw
  1285 000007F1 B020                    	mov	al, ' '
  1286 000007F3 66AB                    	stosw
  1287                                  	; 23/02/2015
  1288 000007F5 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1289                                  	;jna	iiret
  1290                                  	; 04/12/2021
  1291 000007F8 7604                    	jna	short iiz
  1292                                  iiy:
  1293 000007FA B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1294 000007FC E6A0                    	out	0A0h, al ; the 2nd 8259
  1295                                  iiz:
  1296 000007FE E983010000              	jmp     iiret
  1297                                  	;
  1298                                  	; 22/08/2014
  1299                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1300                                  	;out	20h, al	; 8259 PORT
  1301                                  	;
  1302                                  	;pop	es
  1303                                  	;pop	ds
  1304                                  	;pop	edi
  1305                                  	;pop	esi
  1306                                  	;pop	ebx
  1307                                  	;pop 	eax
  1308                                  	;iret
  1309                                  
  1310                                  	; 02/04/2015
  1311                                  	; 25/08/2014
  1312                                  exc0:
  1313 00000803 6A00                            push 	dword 0
  1314 00000805 E990000000                      jmp     cpu_except
  1315                                  exc1:
  1316 0000080A 6A01                            push 	dword 1
  1317 0000080C E989000000                      jmp     cpu_except
  1318                                  exc2:
  1319 00000811 6A02                            push 	dword 2
  1320 00000813 E982000000                      jmp     cpu_except
  1321                                  exc3:
  1322 00000818 6A03                            push 	dword 3
  1323 0000081A EB7E                            jmp     cpu_except
  1324                                  exc4:
  1325 0000081C 6A04                            push 	dword 4
  1326 0000081E EB7A                            jmp     cpu_except
  1327                                  exc5:
  1328 00000820 6A05                            push 	dword 5
  1329 00000822 EB76                            jmp     cpu_except
  1330                                  exc6:
  1331 00000824 6A06                            push 	dword 6
  1332 00000826 EB72                            jmp     cpu_except
  1333                                  exc7:
  1334 00000828 6A07                            push 	dword 7
  1335 0000082A EB6E                            jmp     cpu_except
  1336                                  exc8:
  1337                                  	; [esp] = Error code
  1338 0000082C 6A08                            push 	dword 8
  1339 0000082E EB5C                            jmp     cpu_except_en
  1340                                  exc9:
  1341 00000830 6A09                            push 	dword 9
  1342 00000832 EB66                            jmp     cpu_except
  1343                                  exc10:
  1344                                  	; [esp] = Error code
  1345 00000834 6A0A                            push 	dword 10
  1346 00000836 EB54                            jmp     cpu_except_en
  1347                                  exc11:
  1348                                  	; [esp] = Error code
  1349 00000838 6A0B                            push 	dword 11
  1350 0000083A EB50                            jmp     cpu_except_en
  1351                                  exc12:
  1352                                  	; [esp] = Error code
  1353 0000083C 6A0C                            push 	dword 12
  1354 0000083E EB4C                            jmp     cpu_except_en
  1355                                  exc13:
  1356                                  	; [esp] = Error code
  1357 00000840 6A0D                            push 	dword 13
  1358 00000842 EB48                            jmp     cpu_except_en
  1359                                  exc14:
  1360                                  	; [esp] = Error code
  1361 00000844 6A0E                            push 	dword 14
  1362 00000846 EB44                    	jmp	short cpu_except_en
  1363                                  exc15:
  1364 00000848 6A0F                            push 	dword 15
  1365 0000084A EB4E                            jmp     cpu_except
  1366                                  exc16:
  1367 0000084C 6A10                            push 	dword 16
  1368 0000084E EB4A                            jmp     cpu_except
  1369                                  exc17:
  1370                                  	; [esp] = Error code
  1371 00000850 6A11                            push 	dword 17
  1372 00000852 EB38                    	jmp	short cpu_except_en
  1373                                  exc18:
  1374 00000854 6A12                            push 	dword 18
  1375 00000856 EB42                    	jmp	short cpu_except
  1376                                  exc19:
  1377 00000858 6A13                            push 	dword 19
  1378 0000085A EB3E                    	jmp	short cpu_except
  1379                                  exc20:
  1380 0000085C 6A14                            push 	dword 20
  1381 0000085E EB3A                    	jmp	short cpu_except
  1382                                  exc21:
  1383 00000860 6A15                            push 	dword 21
  1384 00000862 EB36                    	jmp	short cpu_except
  1385                                  exc22:
  1386 00000864 6A16                            push 	dword 22
  1387 00000866 EB32                    	jmp	short cpu_except
  1388                                  exc23:
  1389 00000868 6A17                            push 	dword 23
  1390 0000086A EB2E                    	jmp	short cpu_except
  1391                                  exc24:
  1392 0000086C 6A18                            push 	dword 24
  1393 0000086E EB2A                    	jmp	short cpu_except
  1394                                  exc25:
  1395 00000870 6A19                            push 	dword 25
  1396 00000872 EB26                    	jmp	short cpu_except
  1397                                  exc26:
  1398 00000874 6A1A                            push 	dword 26
  1399 00000876 EB22                    	jmp	short cpu_except
  1400                                  exc27:
  1401 00000878 6A1B                            push 	dword 27
  1402 0000087A EB1E                    	jmp	short cpu_except
  1403                                  exc28:
  1404 0000087C 6A1C                            push 	dword 28
  1405 0000087E EB1A                    	jmp	short cpu_except
  1406                                  exc29:
  1407 00000880 6A1D                            push 	dword 29
  1408 00000882 EB16                    	jmp	short cpu_except
  1409                                  exc30:
  1410 00000884 6A1E                            push 	dword 30
  1411 00000886 EB04                    	jmp	short cpu_except_en
  1412                                  exc31:
  1413 00000888 6A1F                            push 	dword 31
  1414 0000088A EB0E                            jmp     short cpu_except
  1415                                  
  1416                                  	; 02/01/2022 (Retro UNIX 386 v1.2)
  1417                                  	; 19/10/2015
  1418                                  	; 19/09/2015
  1419                                  	; 01/09/2015
  1420                                  	; 28/08/2015
  1421                                  	; 28/08/2014
  1422                                  cpu_except_en:
  1423 0000088C 87442404                	xchg	eax, [esp+4] ; Error code
  1424 00000890 36A3[B4670000]          	mov	[ss:error_code], eax
  1425 00000896 58                      	pop	eax  ; Exception number
  1426 00000897 870424                  	xchg	eax, [esp]
  1427                                  		; eax = eax before exception
  1428                                  		; [esp] -> exception number
  1429                                  		; [esp+4] -> EIP to return
  1430                                  	; 19/10/2015
  1431                                  	; 19/09/2015
  1432                                  	; 01/09/2015
  1433                                  	; 28/08/2015
  1434                                  	; 29/08/2014
  1435                                  	; 28/08/2014
  1436                                  	; 25/08/2014
  1437                                  	; 21/08/2014
  1438                                  cpu_except:	; CPU Exceptions
  1439 0000089A FC                      	cld
  1440 0000089B 870424                  	xchg	eax, [esp] 
  1441                                  		; eax = Exception number
  1442                                  		; [esp] = eax (before exception)
  1443 0000089E 53                      	push	ebx
  1444 0000089F 56                      	push	esi
  1445 000008A0 57                      	push	edi
  1446 000008A1 1E                      	push 	ds
  1447 000008A2 06                      	push 	es
  1448                                  	; 28/08/2015
  1449 000008A3 66BB1000                	mov	bx, KDATA
  1450 000008A7 8EDB                    	mov	ds, bx
  1451 000008A9 8EC3                    	mov	es, bx
  1452 000008AB 0F20DB                  	mov	ebx, cr3
  1453 000008AE 53                      	push	ebx ; (*) page directory
  1454                                  	; 19/10/2015
  1455 000008AF FC                      	cld
  1456                                  	; 25/03/2015
  1457 000008B0 8B1D[08670000]          	mov	ebx, [k_page_dir]
  1458 000008B6 0F22DB                  	mov	cr3, ebx
  1459                                  	; 28/08/2015
  1460 000008B9 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT
  1461 000008BC 7513                    	jne	short cpu_except_nfp
  1462 000008BE E8B31D0000              	call	page_fault_handler
  1463 000008C3 21C0                    	and 	eax, eax
  1464                                  	;jz	iiretp ; 01/09/2015
  1465                                  	; 02/01/2022
  1466 000008C5 7505                    	jnz	short cpu_except_pf
  1467 000008C7 E9B6000000              	jmp	iiretp
  1468                                  cpu_except_pf:
  1469 000008CC B80E000000              	mov	eax, 0Eh ; 14
  1470                                  cpu_except_nfp:
  1471                                  	; 02/04/2015
  1472 000008D1 BB[FB050000]            	mov	ebx, hang
  1473 000008D6 875C241C                	xchg	ebx, [esp+28]
  1474                                  		; EIP (points to instruction which faults)
  1475                                  	  	; New EIP (hang)
  1476 000008DA 891D[B8670000]          	mov	[FaultOffset], ebx
  1477 000008E0 C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1478 000008E8 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1479                                  	;
  1480 000008F0 88C4                    	mov	ah, al
  1481 000008F2 240F                    	and	al, 0Fh
  1482 000008F4 3C09                    	cmp	al, 9
  1483 000008F6 7602                    	jna	short h1ok
  1484 000008F8 0407                    	add	al, 'A'-':'
  1485                                  h1ok:
  1486 000008FA D0EC                    	shr	ah, 1
  1487 000008FC D0EC                    	shr	ah, 1
  1488 000008FE D0EC                    	shr	ah, 1
  1489 00000900 D0EC                    	shr	ah, 1
  1490 00000902 80FC09                  	cmp	ah, 9
  1491 00000905 7603                    	jna	short h2ok
  1492 00000907 80C407                  	add	ah, 'A'-':'
  1493                                  h2ok:	
  1494 0000090A 86E0                    	xchg 	ah, al	
  1495 0000090C 66053030                	add	ax, '00'
  1496 00000910 66A3[EA620000]          	mov	[excnstr], ax
  1497                                  	;
  1498                                  	; 29/08/2014
  1499 00000916 A1[B8670000]            	mov	eax, [FaultOffset]
  1500 0000091B 51                      	push	ecx
  1501 0000091C 52                      	push	edx
  1502 0000091D 89E3                    	mov	ebx, esp
  1503                                  	; 28/08/2015
  1504 0000091F B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1505                                  			  ; to hexadecimal string
  1506                                  	;mov	ecx, 10	    ; divisor to convert
  1507                                  			    ; binary number to decimal string
  1508                                  b2d1:
  1509 00000924 31D2                    	xor	edx, edx
  1510 00000926 F7F1                    	div	ecx
  1511                                  	;push	dx
  1512                                  	; 02/01/2022
  1513 00000928 52                      	push	edx
  1514 00000929 39C8                    	cmp	eax, ecx
  1515 0000092B 73F7                    	jnb	short b2d1
  1516 0000092D BF[F5620000]            	mov	edi, EIPstr ; EIP value
  1517                                  			    ; points to instruction which faults
  1518                                  	; 28/08/2015
  1519 00000932 89C2                    	mov	edx, eax
  1520                                  b2d2:
  1521                                  	;add	al, '0'
  1522 00000934 8A82[D6150000]          	mov	al, [edx+hexchrs]
  1523 0000093A AA                      	stosb		    ; write hexadecimal digit to its place
  1524 0000093B 39E3                    	cmp	ebx, esp
  1525 0000093D 7605                    	jna	short b2d3
  1526                                  	; 02/01/2022
  1527 0000093F 58                      	pop	eax
  1528                                  	;pop	ax
  1529 00000940 88C2                    	mov	dl, al
  1530 00000942 EBF0                    	jmp	short b2d2
  1531                                  b2d3:
  1532 00000944 B068                    	mov 	al, 'h' ; 28/08/2015
  1533 00000946 AA                      	stosb
  1534 00000947 B020                    	mov	al, 20h	    ; space
  1535 00000949 AA                      	stosb
  1536 0000094A 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1537 0000094C AA                      	stosb
  1538                                  	;
  1539 0000094D 5A                      	pop	edx
  1540 0000094E 59                      	pop	ecx
  1541                                  	;
  1542 0000094F B44F                    	mov	ah, 4Fh	; red (4) background, 
  1543                                  			; white (F) forecolor
  1544 00000951 BE[DA620000]            	mov	esi, exc_msg ; message offset
  1545                                  	;
  1546 00000956 EB11                    	jmp	short piemsg
  1547                                  	;
  1548                                          ;add    dword [scr_row], 0A0h
  1549                                          ;mov    edi, [scr_row]
  1550                                          ;
  1551                                  	;call 	printk
  1552                                  	;
  1553                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1554                                  	;out	20h, al	; 8259 PORT
  1555                                  	;
  1556                                  	;pop	es
  1557                                  	;pop	ds
  1558                                  	;pop	edi
  1559                                  	;pop	esi
  1560                                  	;pop 	eax
  1561                                  	;iret
  1562                                  	
  1563                                  	; 28/08/2015
  1564                                  	; 23/02/2015
  1565                                  	; 20/08/2014
  1566                                  ignore_int:
  1567 00000958 50                      	push	eax
  1568 00000959 53                      	push	ebx ; 23/02/2015
  1569 0000095A 56                      	push	esi
  1570 0000095B 57                      	push	edi
  1571 0000095C 1E                      	push 	ds
  1572 0000095D 06                      	push 	es
  1573                                  	; 28/08/2015
  1574 0000095E 0F20D8                  	mov	eax, cr3
  1575 00000961 50                      	push	eax ; (*) page directory
  1576                                  	;
  1577 00000962 B467                    	mov	ah, 67h	; brown (6) background, 
  1578                                  			; light gray (7) forecolor
  1579 00000964 BE[98620000]            	mov	esi, int_msg ; message offset
  1580                                  piemsg:
  1581                                          ; 27/08/2014
  1582 00000969 8105[5C620000]A000-             add     dword [scr_row], 0A0h
  1582 00000971 0000               
  1583 00000973 8B3D[5C620000]                  mov     edi, [scr_row]
  1584                                          ;
  1585 00000979 E8B6FCFFFF              	call 	printk
  1586                                  	;
  1587                                  	; 23/02/2015
  1588 0000097E B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1589 00000980 E6A0                    	out	0A0h, al ; the 2nd 8259
  1590                                  iiretp: ; 01/09/2015
  1591                                  	; 28/08/2015
  1592 00000982 58                      	pop	eax ; (*) page directory
  1593 00000983 0F22D8                  	mov	cr3, eax
  1594                                  	;
  1595                                  iiret:
  1596                                  	; 22/08/2014
  1597 00000986 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1598 00000988 E620                    	out	20h, al	; 8259 PORT
  1599                                  	;
  1600 0000098A 07                      	pop	es
  1601 0000098B 1F                      	pop	ds
  1602 0000098C 5F                      	pop	edi
  1603 0000098D 5E                      	pop	esi
  1604 0000098E 5B                      	pop	ebx ; 29/08/2014
  1605 0000098F 58                      	pop 	eax
  1606 00000990 CF                      	iretd
  1607                                  
  1608                                  	; 23/02/2022
  1609                                  	; 26/02/2015
  1610                                  	; 07/09/2014
  1611                                  	; 25/08/2014
  1612                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  1613                                  	; 22/08/2014
  1614 00000991 50                      	push	eax
  1615 00000992 53                      	push	ebx ; 29/08/2014
  1616 00000993 56                      	push	esi
  1617 00000994 57                      	push	edi
  1618 00000995 1E                      	push 	ds
  1619 00000996 06                      	push 	es
  1620                                  	;
  1621 00000997 B810000000              	mov	eax, KDATA
  1622 0000099C 8ED8                    	mov	ds, ax
  1623 0000099E 8EC0                    	mov	es, ax
  1624                                  	;
  1625                                  	; 25/08/2014
  1626                                  	;call	rtc_p
  1627                                  	; 23/02/2022
  1628 000009A0 FF15[F3060000]          	call	[x_rtci]
  1629                                  	;
  1630                                  	; 22/02/2015 - dsectpm.s
  1631                                  	; [ source: http://wiki.osdev.org/RTC ]
  1632                                  	; read status register C to complete procedure
  1633                                  	;(it is needed to get a next IRQ 8) 
  1634 000009A6 B00C                    	mov	al, 0Ch ; 
  1635 000009A8 E670                    	out	70h, al ; select register C
  1636 000009AA 90                      	nop
  1637 000009AB E471                    	in	al, 71h ; just throw away contents
  1638                                  	; 22/02/2015
  1639 000009AD B020                    	MOV	AL,EOI		; END OF INTERRUPT
  1640 000009AF E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  1641                                  	;
  1642 000009B1 EBD3                    	jmp	short iiret	
  1643                                  
  1644                                  	; 22/08/2014
  1645                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  1646                                  	; (INT 1Ah)
  1647                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  1648                                  time_of_day:
  1649 000009B3 E866010000              	call	UPD_IPR		; WAIT TILL UPDATE NOT IN PROGRESS
  1650 000009B8 726F                            jc      short rtc_retn 
  1651 000009BA B000                    	mov	al, CMOS_SECONDS
  1652 000009BC E847010000              	call	CMOS_READ
  1653 000009C1 A2[7C670000]            	mov	[time_seconds], al 
  1654 000009C6 B002                    	mov	al, CMOS_MINUTES
  1655 000009C8 E83B010000              	call	CMOS_READ
  1656 000009CD A2[7D670000]            	mov	[time_minutes], al 
  1657 000009D2 B004                    	mov	al, CMOS_HOURS
  1658 000009D4 E82F010000              	call	CMOS_READ
  1659 000009D9 A2[7E670000]                    mov     [time_hours], al
  1660 000009DE B006                    	mov	al, CMOS_DAY_WEEK 
  1661 000009E0 E823010000              	call	CMOS_READ
  1662 000009E5 A2[7F670000]            	mov	[date_wday], al
  1663 000009EA B007                     	mov	al, CMOS_DAY_MONTH
  1664 000009EC E817010000              	call	CMOS_READ
  1665 000009F1 A2[80670000]            	mov	[date_day], al
  1666 000009F6 B008                    	mov	al, CMOS_MONTH
  1667 000009F8 E80B010000              	call	CMOS_READ
  1668 000009FD A2[81670000]            	mov	[date_month], al
  1669 00000A02 B009                    	mov	al, CMOS_YEAR
  1670 00000A04 E8FF000000              	call	CMOS_READ
  1671 00000A09 A2[82670000]            	mov	[date_year], al
  1672 00000A0E B032                    	mov	al, CMOS_CENTURY
  1673 00000A10 E8F3000000              	call	CMOS_READ
  1674 00000A15 A2[83670000]            	mov	[date_century], al
  1675                                  	;
  1676 00000A1A B000                    	mov	al, CMOS_SECONDS
  1677 00000A1C E8E7000000              	call 	CMOS_READ
  1678 00000A21 3A05[7C670000]          	cmp	al, [time_seconds]
  1679 00000A27 758A                    	jne	short time_of_day
  1680                                  
  1681                                  rtc_retn:
  1682 00000A29 C3                      	retn
  1683                                  
  1684                                  rtci_default:
  1685                                  	; 23/02/2022 (Temporary!)
  1686                                  	; (default real time clock handler in multitasking mode)
  1687                                  	; ((2 rtc ticks per second after 'setup_rtc_int'))
  1688 00000A2A FF05[C0670000]          	inc	dword [rtc_ticks] ; real time clock counter
  1689                                  			; (not used in anywhere of kernel for now!)
  1690 00000A30 C3                      	retn
  1691                                  
  1692                                  rtc_p:
  1693                                  	; 27/12/2021 (Retro UNIX 386 v1.2)
  1694                                  	; 07/09/2014
  1695                                  	; 29/08/2014
  1696                                  	; 27/08/2014
  1697                                  	; 25/08/2014
  1698                                   	; Print Real Time Clock content
  1699                                  	;
  1700                                  	;
  1701 00000A31 E87DFFFFFF              	call	time_of_day
  1702 00000A36 72F1                    	jc	short rtc_retn
  1703                                  	;
  1704 00000A38 3A05[4C630000]          	cmp	al, [ptime_seconds]
  1705 00000A3E 74E9                            je      short rtc_retn ; 29/08/2014
  1706                                  	;
  1707 00000A40 A2[4C630000]            	mov	[ptime_seconds], al
  1708                                  	;
  1709 00000A45 A0[83670000]            	mov	al, [date_century]
  1710 00000A4A E8EA000000              	call	bcd_to_ascii
  1711 00000A4F 66A3[19630000]          	mov	[datestr+6], ax
  1712 00000A55 A0[82670000]            	mov	al, [date_year]
  1713 00000A5A E8DA000000              	call	bcd_to_ascii
  1714 00000A5F 66A3[1B630000]          	mov	[datestr+8], ax
  1715 00000A65 A0[81670000]            	mov	al, [date_month]
  1716 00000A6A E8CA000000              	call	bcd_to_ascii
  1717 00000A6F 66A3[16630000]          	mov	[datestr+3], ax
  1718 00000A75 A0[80670000]            	mov	al, [date_day]
  1719 00000A7A E8BA000000              	call	bcd_to_ascii
  1720 00000A7F 66A3[13630000]          	mov	[datestr], ax
  1721                                  	;
  1722 00000A85 0FB61D[7F670000]        	movzx	ebx, byte [date_wday]
  1723 00000A8C C0E302                  	shl 	bl, 2
  1724 00000A8F 81C3[2C630000]          	add	ebx, daytmp
  1725 00000A95 8B03                    	mov	eax, [ebx]
  1726 00000A97 A3[1E630000]            	mov	[daystr], eax
  1727                                  	;
  1728 00000A9C A0[7E670000]            	mov	al, [time_hours]
  1729 00000AA1 E893000000              	call	bcd_to_ascii
  1730 00000AA6 66A3[22630000]          	mov	[timestr], ax
  1731 00000AAC A0[7D670000]            	mov	al, [time_minutes]
  1732 00000AB1 E883000000              	call	bcd_to_ascii
  1733 00000AB6 66A3[25630000]          	mov	[timestr+3], ax
  1734 00000ABC A0[7C670000]            	mov	al, [time_seconds]
  1735 00000AC1 E873000000              	call	bcd_to_ascii
  1736 00000AC6 66A3[28630000]          	mov	[timestr+6], ax
  1737                                  	;		
  1738 00000ACC BE[01630000]            	mov	esi, rtc_msg ; message offset
  1739                                  	; 23/02/2015
  1740 00000AD1 52                      	push	edx
  1741 00000AD2 51                      	push	ecx
  1742                                  	; 07/09/2014
  1743                                  	;mov	bx, 2	; Video page 2
  1744                                  	; 27/12/2021
  1745 00000AD3 29DB                    	sub	ebx, ebx
  1746                                  	;mov	bl, 2
  1747                                  	; 15/02/2022
  1748 00000AD5 B307                    	mov	bl, 7	; Video page 7
  1749                                  prtmsg:
  1750 00000AD7 AC                      	lodsb
  1751 00000AD8 08C0                    	or	al, al
  1752 00000ADA 740D                    	jz	short prtmsg_ok
  1753 00000ADC 56                      	push	esi
  1754                                  	;push	bx
  1755 00000ADD 53                              push	ebx ; 27/12/2021
  1756 00000ADE B43F                    	mov	ah, 3Fh	; cyan (6) background, 
  1757                                  			; white (F) forecolor
  1758 00000AE0 E8B5070000              	call 	write_tty
  1759                                  	;pop	bx
  1760 00000AE5 5B                      	pop	ebx ; 27/12/2021
  1761 00000AE6 5E                      	pop	esi
  1762 00000AE7 EBEE                    	jmp	short prtmsg
  1763                                  	;
  1764                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  1765                                  	;call	printk
  1766                                  prtmsg_ok:
  1767                                  	; 07/09/2014
  1768                                  	;xor	dx, dx		; column 0, row 0
  1769                                  	; 27/12/2021
  1770 00000AE9 31D2                    	xor	edx, edx
  1771 00000AEB E8B4080000              	call	set_cpos	; set curspor position to 0,0 
  1772                                  	; 23/02/2015
  1773 00000AF0 59                      	pop	ecx
  1774 00000AF1 5A                      	pop	edx
  1775 00000AF2 C3                      	retn
  1776                                  
  1777                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  1778                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  1779                                  default_irq7:
  1780                                  	; 04/12/2021
  1781                                  	;push	ax
  1782 00000AF3 50                      	push	eax
  1783 00000AF4 B00B                    	mov	al, 0Bh  ; In-Service register
  1784 00000AF6 E620                    	out	20h, al
  1785 00000AF8 EB00                            jmp short $+2
  1786 00000AFA EB00                    	jmp short $+2
  1787 00000AFC E420                    	in	al, 20h
  1788 00000AFE 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  1789 00000B00 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  1790 00000B02 B020                            mov     al, 20h ; EOI
  1791 00000B04 E620                    	out	20h, al 
  1792                                  irq7_iret:
  1793                                  	;pop	ax
  1794                                  	; 04/12/2021
  1795 00000B06 58                      	pop	eax
  1796 00000B07 CF                      	iretd
  1797                                  	
  1798                                  	; 04/12/2021
  1799                                  	; 22/08/2014
  1800                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
  1801                                  CMOS_READ:
  1802 00000B08 9C                      	pushf		; SAVE INTERRUPT ENABLE STATUS AND FLAGS
  1803 00000B09 D0C0                    	rol	al, 1	; MOVE NMI BIT TO LOW POSITION
  1804 00000B0B F9                      	stc		; FORCE NMI BIT ON IN CARRY FLAG
  1805 00000B0C D0D8                    	rcr	al, 1	; HIGH BIT ON TO DISABLE NMI - OLD IN CY
  1806 00000B0E FA                      	cli		; DISABLE INTERRUPTS
  1807 00000B0F E670                    	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
  1808 00000B11 90                      	nop		; I/O DELAY
  1809 00000B12 E471                    	in	al, CMOS_DATA	; READ THE REQUESTED CMOS LOCATION
  1810                                  	;push	ax	; SAVE (AH) REGISTER VALUE AND CMOS BYTE
  1811                                  	; 04/12/2021
  1812 00000B14 50                      	push	eax
  1813                                  	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
  1814                                  		     ; ----- 10/06/85 (test4.asm)
  1815 00000B15 B01E                    	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
  1816                                  	;mov	al, CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
  1817 00000B17 D0D8                    	rcr	al, 1	; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
  1818 00000B19 E670                    	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
  1819                                  	;pop	ax	; RESTORE (AH) AND (AL), CMOS BYTE
  1820                                  	; 04/12/2021
  1821 00000B1B 58                      	pop	eax
  1822 00000B1C 9D                      	popf	
  1823 00000B1D C3                      	retn		; RETURN WITH FLAGS RESTORED
  1824                                  
  1825                                  	; 22/08/2014
  1826                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
  1827                                  UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
  1828 00000B1E 51                      	push	ecx
  1829 00000B1F B9FFFF0000              	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
  1830                                  		; mov cx, 800	
  1831                                  UPD_10:
  1832 00000B24 B00A                    	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
  1833 00000B26 FA                      	cli				; NO TIMER INTERRUPTS DURING UPDATES
  1834 00000B27 E8DCFFFFFF              	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
  1835 00000B2C A880                    	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
  1836 00000B2E 7406                    	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
  1837 00000B30 FB                      	sti				; ALLOW INTERRUPTS WHILE WAITING
  1838 00000B31 E2F1                    	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
  1839 00000B33 31C0                    	xor	eax, eax		; CLEAR RESULTS IF ERROR
  1840                                  		; xor ax, ax
  1841 00000B35 F9                      	stc				; SET CARRY FOR ERROR
  1842                                  UPD_90:
  1843 00000B36 59                      	pop	ecx			; RESTORE CALLERS REGISTER
  1844 00000B37 FA                      	cli				; INTERRUPTS OFF DURING SET
  1845 00000B38 C3                      	retn				; RETURN WITH CY FLAG SET
  1846                                  
  1847                                  bcd_to_ascii:
  1848                                  	; 25/08/2014
  1849                                  	; INPUT ->
  1850                                  	;	al = Packed BCD number
  1851                                  	; OUTPUT ->
  1852                                  	;	ax  = ASCII word/number
  1853                                  	;
  1854                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  1855                                  	;
  1856 00000B39 D410                    	db	0D4h, 10h		; Undocumented inst. AAM
  1857                                  					; AH = AL / 10h
  1858                                  					; AL = AL MOD 10h
  1859 00000B3B 660D3030                	or	ax, '00'		; Make it ASCII based
  1860                                  
  1861 00000B3F 86E0                            xchg	ah, al 
  1862                                  	
  1863 00000B41 C3                      	retn	
  1864                                  	
  1865                                  
  1866                                  %include 'keyboard.s' ; 07/03/2015
  1867                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  1868                              <1> ; (re-write kernel for test by using previous version without a major defect)
  1869                              <1> ; ****************************************************************************
  1870                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - KEYBOARD.INC
  1871                              <1> ; Last Modification: 24/07/2022
  1872                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
  1873                              <1> ;
  1874                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
  1875                              <1> 
  1876                              <1> ; 24/07/2022
  1877                              <1> ;	(Retro UNIX 386 v1.2, Kernel v0.2.2.3)	
  1878                              <1> ;	(Retro UNIX 386 v1.1, Kernel v0.2.1.6)
  1879                              <1> ;	(Retro UNIX 386 v1.0, Kernel v0.2.0.22)
  1880                              <1> ; 23/02/2022
  1881                              <1> ; 05/12/2021 (Retro UNIX 386 v1.2)
  1882                              <1> ; 30/06/2015
  1883                              <1> ; 11/03/2015
  1884                              <1> ; 28/02/2015
  1885                              <1> ; 25/02/2015
  1886                              <1> ; 20/02/2015
  1887                              <1> ; 18/02/2015
  1888                              <1> ; 03/12/2014
  1889                              <1> ; 07/09/2014
  1890                              <1> ; KEYBOARD INTERRUPT HANDLER
  1891                              <1> ; (kb_int - Retro UNIX 8086 v1 - U0.ASM, 30/06/2014)
  1892                              <1> 
  1893                              <1> ;getch:
  1894                              <1> ;	; 18/02/2015
  1895                              <1> ;	; This routine will be replaced with Retro UNIX 386
  1896                              <1> ;	; version of Retro UNIX 8086 getch (tty input)
  1897                              <1> ;	; routine, later... (multi tasking ability)
  1898                              <1> ;	; 28/02/2015
  1899                              <1> ;	sti	; enable interrupts
  1900                              <1> ;	;
  1901                              <1> ;	;push	esi
  1902                              <1> ;	;push	ebx
  1903                              <1> ;	;xor	ebx, ebx
  1904                              <1> ;	;mov	bl, [ptty]  ; active_page
  1905                              <1> ;	;mov	esi, ebx
  1906                              <1> ;	;shl 	si, 1
  1907                              <1> ;	;add	esi, ttychr
  1908                              <1> ;getch_1:
  1909                              <1> ;	;mov	ax, [esi]
  1910                              <1> ;	mov	ax, [ttychr] ; video page 0 (tty0)
  1911                              <1> ;	and	ax, ax
  1912                              <1> ;	jz	short getch_2
  1913                              <1> ;	mov	word [ttychr], 0
  1914                              <1> ;	;mov	word [esi], 0
  1915                              <1> ;	;pop	ebx
  1916                              <1> ;	;pop	esi
  1917                              <1> ;	retn
  1918                              <1> ;getch_2:
  1919                              <1> ;	hlt	; not proper for multi tasking!
  1920                              <1> ;		; (temporary halt for now)
  1921                              <1> ;		; 'sleep' on tty 
  1922                              <1> ;		; will (must) be located here		
  1923                              <1> ;	nop
  1924                              <1> ;	jmp	short getch_1
  1925                              <1> 
  1926                              <1> keyb_int:
  1927                              <1> 	; 24/07/2022
  1928                              <1> 	; 23/02/2022
  1929                              <1> 	; 30/06/2015
  1930                              <1> 	; 25/02/2015
  1931                              <1> 	; 20/02/2015
  1932                              <1> 	; 03/12/2014 (getc_int - INT 16h modifications)
  1933                              <1> 	; 07/09/2014 - Retro UNIX 386 v1
  1934                              <1> 	; 30/06/2014
  1935                              <1> 	; 10/05/2013	
  1936                              <1>       	; Retro Unix 8086 v1 feature only!
  1937                              <1> 	; 03/03/2014
  1938                              <1> 	
  1939 00000B42 1E                  <1> 	push	ds
  1940 00000B43 53                  <1> 	push	ebx
  1941 00000B44 50                  <1> 	push	eax
  1942                              <1> 	;
  1943                              <1> 	; 23/02/2022
  1944 00000B45 9C                  <1> 	pushfd
  1945 00000B46 0E                  <1> 	push	cs
  1946                              <1> 	;mov	ax, KDATA
  1947 00000B47 31C0                <1> 	xor	eax, eax
  1948 00000B49 B010                <1> 	mov	al, KDATA
  1949 00000B4B 8ED8                <1> 	mov	ds, ax
  1950                              <1> 	;
  1951                              <1> 	;pushfd
  1952                              <1> 	;push	cs
  1953 00000B4D E80A010000          <1> 	call	kb_int   ; int_09h
  1954                              <1> 	;
  1955                              <1> 	;mov	ah, 11h	 ; 03/12/2014	
  1956 00000B52 B401                <1> 	mov	ah, 1 ; 24/07/2022
  1957                              <1> 	;call	getc
  1958 00000B54 E854000000          <1> 	call	int_16h  ; 30/06/2015
  1959 00000B59 744E                <1> 	jz	short keyb_int4
  1960                              <1> 	;
  1961                              <1> 	;mov	ah, 10h	 ; 03/12/2014
  1962 00000B5B B400                <1> 	mov	ah, 0 ; 24/07/2022
  1963                              <1> 	;call	getc
  1964 00000B5D E84B000000          <1> 	call	int_16h  ; 30/06/2015
  1965                              <1> 	;
  1966                              <1> 	; 20/02/2015
  1967 00000B62 0FB61D[36670000]    <1>         movzx   ebx, byte [ptty]  ; active_page
  1968                              <1> 	;
  1969 00000B69 20C0                <1> 	and 	al, al
  1970 00000B6B 751D                <1> 	jnz	short keyb_int1
  1971                              <1> 	;
  1972 00000B6D 80FC68              <1> 	cmp	ah, 68h	 ; ALT + F1 key
  1973 00000B70 7218                <1> 	jb	short keyb_int1
  1974 00000B72 80FC6F              <1> 	cmp	ah, 6Fh  ; ALT + F8 key	
  1975 00000B75 7713                <1> 	ja	short keyb_int1
  1976                              <1> 	;
  1977 00000B77 88D8                <1> 	mov	al, bl
  1978 00000B79 0468                <1> 	add	al, 68h
  1979 00000B7B 38E0                <1> 	cmp	al, ah
  1980 00000B7D 7409                <1> 	je	short keyb_int0
  1981 00000B7F 88E0                <1> 	mov	al, ah
  1982 00000B81 2C68                <1> 	sub	al, 68h
  1983 00000B83 E831090000          <1> 	call	tty_sw
  1984                              <1> 	;movzx	ebx, [ptty]  ; active_page
  1985                              <1> keyb_int0: ; 30/06/2015
  1986                              <1> 	;xor	ax, ax
  1987                              <1> 	; 23/02/2022
  1988 00000B88 31C0                <1> 	xor	eax, eax
  1989                              <1> keyb_int1:
  1990 00000B8A D0E3                <1> 	shl	bl, 1
  1991 00000B8C 81C3[38670000]      <1> 	add	ebx, ttychr
  1992                              <1> 	;
  1993                              <1> 	;23/02/2022
  1994 00000B92 09C0                <1> 	or	eax, eax
  1995                              <1> 	;or	ax, ax
  1996 00000B94 7406                <1> 	jz	short keyb_int2
  1997                              <1> 	;
  1998 00000B96 66833B00            <1> 	cmp 	word [ebx], 0
  1999 00000B9A 7703                <1>         ja      short keyb_int3 
  2000                              <1> keyb_int2:
  2001 00000B9C 668903              <1>         mov	[ebx], ax  ; Save ascii code
  2002                              <1> 			   ; and scan code of the character
  2003                              <1> 			   ; for current tty (or last tty
  2004                              <1> 			   ; just before tty switch).
  2005                              <1> keyb_int3:
  2006 00000B9F A0[36670000]        <1>         mov     al, [ptty]
  2007 00000BA4 E88B3B0000          <1> 	call	wakeup
  2008                              <1> 	;
  2009                              <1> keyb_int4:
  2010 00000BA9 58                  <1> 	pop	eax
  2011 00000BAA 5B                  <1> 	pop	ebx
  2012 00000BAB 1F                  <1> 	pop	ds
  2013 00000BAC CF                  <1> 	iret
  2014                              <1> 
  2015                              <1> ; 18/02/2015
  2016                              <1> ; REMINDER: Only 'keyb_int' (IRQ 9) must call getc.
  2017                              <1> ; 'keyb_int' always handles 'getc' at 1st and puts the
  2018                              <1> ; scancode and ascii code of the character 
  2019                              <1> ; in the tty input (ttychr) buffer. 
  2020                              <1> ; Test procedures must call 'getch' for tty input
  2021                              <1> ; otherwise, 'getc' will not be able to return to the caller
  2022                              <1> ; due to infinite (key press) waiting loop.
  2023                              <1> ; 
  2024                              <1> ; 03/12/2014
  2025                              <1> ; 26/08/2014
  2026                              <1> ; KEYBOARD I/O
  2027                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
  2028                              <1> 
  2029                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
  2030                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
  2031                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
  2032                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
  2033                              <1> 
  2034                              <1> ; 24/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
  2035                              <1> ;int_16h: ; 30/06/2015
  2036                              <1> ;;getc:
  2037                              <1> ;	pushfd	; 28/08/2014
  2038                              <1> ;	push 	cs
  2039                              <1> ;	call 	getc_int
  2040                              <1> ;	retn
  2041                              <1> 
  2042                              <1> 	; 24/07/2022
  2043                              <1> %if 0
  2044                              <1> ; 24/12/2021
  2045                              <1> 
  2046                              <1> 	;-----	SHIFT STATUS
  2047                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
  2048                              <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2049                              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2050                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2051                              <1> 	;shl	ah, cl			; BIT 7 POSITION
  2052                              <1>         shl	ah, 5
  2053                              <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2054                              <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2055                              <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2056                              <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2057                              <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2058                              <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2059                              <1> _K3:
  2060                              <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2061                              <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2062                              <1> 
  2063                              <1> %endif
  2064                              <1> 
  2065                              <1> int_16h:
  2066                              <1> 	; 24/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
  2067                              <1> 	; 24/07/2022 - (near call return instead of interrupt return)
  2068                              <1> 	
  2069                              <1> 	; INPUT:
  2070                              <1> 	;	AL = Function (0 or 1)
  2071                              <1> 	;	     0 = Read Character
  2072                              <1> 	;	     1 = Get Keyboard Buffer Status
  2073                              <1> 	; OUTPUT:
  2074                              <1> 	;	Function 0 - AX = ASCII (AL) and SCAN CODE (AH)
  2075                              <1> 	;			  of the character (enterrd from the keyboard) 
  2076                              <1> 	;	Function 1 - If ZF = 0
  2077                              <1> 	;			AX = ASCII (AL) and SCAN CODE (AH) of the character
  2078                              <1> 	;			(which is waiting in keyboard buffer)
  2079                              <1> 	;		     If ZF = 1
  2080                              <1> 	;			there is not a character in the keyboard buffer
  2081                              <1> 	;
  2082                              <1> 	; Modified registers: eax, ebx
  2083                              <1> 	
  2084                              <1> getc_int:
  2085                              <1> 	; 24/07/2022 (Retro UNIX 386 v1.1 - Kernel v0.2.1.6)
  2086                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
  2087                              <1> 	; 28/02/2015
  2088                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2089                              <1> 	;	      instead of pc-at bios - 1985-)
  2090                              <1> 	; 28/08/2014 (_k1d)
  2091                              <1> 	; 30/06/2014
  2092                              <1> 	; 03/03/2014
  2093                              <1> 	; 28/02/2014
  2094                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
  2095                              <1> 	; rombios source code (21/04/1986)
  2096                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
  2097                              <1> 	;
  2098                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
  2099                              <1> 	;
  2100                              <1> 	;--- INT 16 H -----------------------------------------------------------------
  2101                              <1> 	; KEYBOARD I/O								      :
  2102                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
  2103                              <1> 	; INPUT									      :
  2104                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
  2105                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
  2106                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
  2107                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
  2108                              <1> 	;-----------------------------------------------------------------------------:
  2109                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
  2110                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
  2111                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
  2112                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
  2113                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
  2114                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
  2115                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
  2116                              <1> 	;-----------------------------------------------------------------------------:	
  2117                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
  2118                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
  2119                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
  2120                              <1> 	;-----------------------------------------------------------------------------:	
  2121                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
  2122                              <1> 	;	      (AL) = 05H                                                      :
  2123                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
  2124                              <1> 	;		       							      :
  2125                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
  2126                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
  2127                              <1> 	;                     --------------------------------------------            :
  2128                              <1> 	;			00H        30.0        10H        7.5                 :
  2129                              <1> 	;			01H        26.7        11H        6.7                 :
  2130                              <1> 	;			02H        24.0        12H        6.0                 :
  2131                              <1> 	;			03H        21.8        13H        5.5                 :
  2132                              <1> 	;			04H        20.0        14H        5.0                 :
  2133                              <1> 	;			05H        18.5        15H        4.6                 :
  2134                              <1> 	;			06H        17.1        16H        4.3                 :
  2135                              <1> 	;			07H        16.0        17H        4.0                 :
  2136                              <1> 	;			08H        15.0        18H        3.7                 :
  2137                              <1> 	;			09H        13.3        19H        3.3                 :
  2138                              <1> 	;			0AH        12.0        1AH        3.0                 :
  2139                              <1> 	;			0BH        10.9        1BH        2.7                 :
  2140                              <1>         ;			0CH        10.0        1CH        2.5                 :
  2141                              <1> 	;			0DH         9.2        1DH        2.3                 :
  2142                              <1> 	;			0EH         8.6        1EH        2.1                 :
  2143                              <1> 	;			0FH         8.0        1FH        2.0                 :
  2144                              <1> 	;									      :
  2145                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
  2146                              <1> 	;		       							      :
  2147                              <1> 	;                     REGISTER     DELAY                                      :
  2148                              <1> 	;                      VALUE       VALUE                                      :
  2149                              <1> 	;                     ------------------                                      :
  2150                              <1> 	;			00H        250 ms                                     :
  2151                              <1> 	;			01H        500 ms                                     :
  2152                              <1> 	;			02H        750 ms                                     :
  2153                              <1> 	;			03H       1000 ms                                     :
  2154                              <1> 	;-----------------------------------------------------------------------------:
  2155                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
  2156                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
  2157                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
  2158                              <1> 	;		           (CH) = SCAN CODE                                   :
  2159                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
  2160                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
  2161                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
  2162                              <1> 	;-----------------------------------------------------------------------------:		
  2163                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
  2164                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
  2165                              <1> 	;-----------------------------------------------------------------------------:
  2166                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
  2167                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
  2168                              <1> 	;-----------------------------------------------------------------------------:	
  2169                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
  2170                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
  2171                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
  2172                              <1> 	; OUTPUT					                              :
  2173                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
  2174                              <1> 	;	ALL REGISTERS RETAINED		                                      :
  2175                              <1> 	;------------------------------------------------------------------------------
  2176                              <1> 	
  2177 00000BAD FB                  <1> 	sti				; INTERRUPTS BACK ON
  2178                              <1> 
  2179                              <1> 	; 24/07/2022
  2180                              <1> 	;push	ds			; SAVE CURRENT DS
  2181                              <1> 	;push	ebx			; SAVE BX TEMPORARILY
  2182                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
  2183                              <1>         ;mov	bx, KDATA 
  2184                              <1> 	;mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
  2185                              <1> 
  2186                              <1> 	;or	ah, ah			; CHECK FOR (AH)= 00H
  2187                              <1> 	;jz	short _K1		; ASCII_READ
  2188                              <1> 	;dec	ah                      ; CHECK FOR (AH)= 01H
  2189                              <1> 	;jz	short _K2               ; ASCII_STATUS
  2190                              <1> 	;dec	ah			; CHECK FOR (AH)= 02H
  2191                              <1> 	;jz	short _K3               ; SHIFT STATUS
  2192                              <1> 	;dec	ah			; CHECK FOR (AH)= 03H	
  2193                              <1> 	;jz	short _K300             ; SET TYPAMATIC RATE/DELAY
  2194                              <1> 	;sub	ah, 2			; CHECK FOR (AH)= 05H	
  2195                              <1> 	;jz	short _K500             ; KEYBOARD WRITE         
  2196                              <1> ;_KIO1:	
  2197                              <1> 	;sub	ah, 11			; AH =  10H
  2198                              <1> 	;jz	short _K1E		; EXTENDED ASCII READ
  2199                              <1> 	;dec	ah			; CHECK FOR (AH)= 11H
  2200                              <1> 	;jz	short _K2E		; EXTENDED_ASCII_STATUS
  2201                              <1> 	;dec	ah			; CHECK FOR (AH)= 12H
  2202                              <1> 	;jz	short _K3E		; EXTENDED_SHIFT_STATUS
  2203                              <1> 
  2204                              <1> ;_KIO_EXIT:
  2205                              <1> 	;pop	ecx			; RECOVER REGISTER
  2206                              <1> 	;pop	ebx			; RECOVER REGISTER
  2207                              <1> 	; 24/07/2022
  2208                              <1> 	;retn
  2209                              <1> 	;pop	ds			; RECOVER SEGMENT
  2210                              <1> 	;iretd				; INVALID COMMAND, EXIT
  2211                              <1> 
  2212 00000BAE 08E4                <1> 	or	ah, ah
  2213 00000BB0 7507                <1> 	jnz	short _K2
  2214                              <1> 
  2215                              <1> 	;-----	ASCII CHARACTER
  2216                              <1> _K1:
  2217                              <1> _K1E:	
  2218 00000BB2 E81C000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
  2219                              <1> 	;call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2220                              <1> 	;;jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
  2221                              <1> 	; 24/07/2022
  2222                              <1> 	;retn
  2223 00000BB7 EB0F                <1> 	jmp	short _KIO_E_XLAT
  2224                              <1> ;_K1:	
  2225                              <1> 	;call	_K1S			; GET A CHARACTER FROM THE BUFFER
  2226                              <1> 	;call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2227                              <1> 	;jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
  2228                              <1> ;_K1A:
  2229                              <1> 	;jmp	short _KIO_EXIT         ; RETURN TO CALLER
  2230                              <1> 	; 24/07/2022
  2231                              <1> 	;retn
  2232                              <1> 
  2233                              <1> 	;-----	ASCII STATUS
  2234                              <1> _K2:
  2235                              <1> _K2E:	
  2236 00000BB9 E860000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
  2237 00000BBE 7407                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2238 00000BC0 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2239 00000BC1 E802000000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2240                              <1> 	;jmp	short _K2A	        ; GIVE IT TO THE CALLER
  2241                              <1> 	; 24/07/2022
  2242 00000BC6 9D                  <1> 	popf
  2243                              <1> _K2B:
  2244 00000BC7 C3                  <1> 	retn
  2245                              <1> ;_K2:	
  2246                              <1> 	;call	_K2S			; TEST FOR CHARACTER IN BUFFER
  2247                              <1> 	;jz	short _K2B		; RETURN IF BUFFER EMPTY
  2248                              <1> 	;pushf				; SAVE ZF FROM TEST
  2249                              <1> 	;call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2250                              <1> 	;jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
  2251                              <1> 	;popf				; INVALID CODE FOR THIS TYPE OF CALL
  2252                              <1> 	;call	_K1S			; THROW THE CHARACTER AWAY
  2253                              <1> 	;jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
  2254                              <1> ;_K2A:
  2255                              <1> 	;popf				; RESTORE ZF FROM TEST
  2256                              <1> ;_K2B:
  2257                              <1> 	;;pop	ecx			; RECOVER REGISTER
  2258                              <1> 	;pop	ebx			; RECOVER REGISTER
  2259                              <1> 	;pop	ds			; RECOVER SEGMENT
  2260                              <1> 	;retf	4			; THROW AWAY (E)FLAGS
  2261                              <1> 
  2262                              <1> ; 24/12/2021
  2263                              <1> ;	;-----	SHIFT STATUS
  2264                              <1> ;_K3E:                                  ; GET THE EXTENDED SHIFT STATUS FLAGS
  2265                              <1> ;	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2266                              <1> ;	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2267                              <1> ;	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2268                              <1> ;	;shl	ah, cl			; BIT 7 POSITION
  2269                              <1> ;       shl	ah, 5
  2270                              <1> ;	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2271                              <1> ;	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2272                              <1> ;	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2273                              <1> ;	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2274                              <1> ;	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2275                              <1> ;	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2276                              <1> ;_K3:
  2277                              <1> ;	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2278                              <1> ;	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2279                              <1> 
  2280                              <1> 	; 24/07/2022
  2281                              <1> %if 0
  2282                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
  2283                              <1> _K300:
  2284                              <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
  2285                              <1> 	jne	short _KIO_EXIT		; NO, RETURN
  2286                              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
  2287                              <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2288                              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
  2289                              <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2290                              <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
  2291                              <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2292                              <1> 	;mov	cx, 5			; SHIFT COUNT
  2293                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
  2294                              <1> 	shl	bh, 5
  2295                              <1> 	mov	al, bl			; PUT IN RATE
  2296                              <1> 	or	al, bh			; AND DELAY
  2297                              <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2298                              <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
  2299                              <1> 
  2300                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
  2301                              <1> _K500:
  2302                              <1> 	push	esi			; SAVE SI (esi)
  2303                              <1> 	cli				; 
  2304                              <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
  2305                              <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
  2306                              <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
  2307                              <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
  2308                              <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
  2309                              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
  2310                              <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
  2311                              <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
  2312                              <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
  2313                              <1> _K502:
  2314                              <1> 	mov	al, 01h			; BUFFER FULL INDICATION
  2315                              <1> _K504:
  2316                              <1> 	sti				
  2317                              <1> 	pop	esi			; RECOVER SI (esi)
  2318                              <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
  2319                              <1> %endif
  2320                              <1> 
  2321                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
  2322                              <1> _KIO_E_XLAT:
  2323 00000BC8 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2324 00000BCA 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
  2325 00000BCC 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
  2326 00000BCE 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
  2327 00000BD0 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
  2328                              <1> _KIO_E_RET:				
  2329 00000BD2 C3                  <1> 	retn				; GO BACK
  2330                              <1> 
  2331                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
  2332                              <1> _K1S:
  2333 00000BD3 FA                  <1> 	cli	; 03/12/2014
  2334 00000BD4 8B1D[70610000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2335 00000BDA 3B1D[74610000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2336                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
  2337 00000BE0 750F                <1> 	jne	short _k1x ; 03/12/2014
  2338                              <1> 	;
  2339                              <1> 	; 03/12/2014
  2340                              <1> 	; 28/08/2014
  2341                              <1> 	; PERFORM OTHER FUNCTION ?? here !
  2342                              <1> 	;;mov	ax, 9002h		; MOVE IN WAIT CODE & TYPE
  2343                              <1> 	;;int	15h			; PERFORM OTHER FUNCTION
  2344                              <1> _K1T:                                   ; ASCII READ
  2345 00000BE2 FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
  2346 00000BE3 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
  2347                              <1> _K1U:	
  2348 00000BE4 FA                  <1> 	cli				; INTERRUPTS BACK OFF
  2349 00000BE5 8B1D[70610000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2350 00000BEB 3B1D[74610000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2351                              <1> _k1x:
  2352 00000BF1 53                  <1> 	push	ebx			; SAVE ADDRESS		
  2353 00000BF2 9C                  <1> 	pushf				; SAVE FLAGS
  2354 00000BF3 E895060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2355 00000BF8 8A1D[65610000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2356 00000BFE 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2357 00000C00 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
  2358 00000C03 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
  2359 00000C05 E82F060000          <1> 	call	SND_LED1
  2360 00000C0A FA                  <1> 	cli				; DISABLE INTERRUPTS
  2361                              <1> _K1V:
  2362 00000C0B 9D                  <1> 	popf				; RESTORE FLAGS
  2363 00000C0C 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2364 00000C0D 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
  2365                              <1> 	;
  2366 00000C0F 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
  2367 00000C12 E834000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
  2368 00000C17 891D[70610000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
  2369 00000C1D C3                  <1> 	retn				; RETURN
  2370                              <1> 
  2371                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
  2372                              <1> _K2S:
  2373 00000C1E FA                  <1> 	cli				; INTERRUPTS OFF
  2374 00000C1F 8B1D[70610000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2375 00000C25 3B1D[74610000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
  2376 00000C2B 668B03              <1> 	mov	ax, [ebx]
  2377 00000C2E 9C                  <1> 	pushf				; SAVE FLAGS
  2378                              <1> 	;push	ax			; SAVE CODE
  2379                              <1> 	; 24/12/2021
  2380 00000C2F 50                  <1> 	push	eax
  2381 00000C30 E858060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2382 00000C35 8A1D[65610000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2383 00000C3B 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2384 00000C3D 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
  2385 00000C40 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
  2386 00000C42 E8DB050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2387                              <1> _K2T:
  2388                              <1> 	;pop	ax			; RESTORE CODE
  2389                              <1> 	; 24/12/2021
  2390 00000C47 58                  <1> 	pop	eax
  2391 00000C48 9D                  <1> 	popf				; RESTORE FLAGS
  2392 00000C49 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2393 00000C4A C3                  <1> 	retn				; RETURN
  2394                              <1> 
  2395                              <1> 	; 24/07/2022
  2396                              <1> %if 0
  2397                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
  2398                              <1> _KIO_S_XLAT:
  2399                              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
  2400                              <1> 	jne	short _KIO_S2		; NO, CONTINUE
  2401                              <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
  2402                              <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
  2403                              <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
  2404                              <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
  2405                              <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
  2406                              <1> _kio_ret: ; 03/12/2014
  2407                              <1> 	clc
  2408                              <1> 	retn
  2409                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2410                              <1> _KIO_S1:				
  2411                              <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
  2412                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2413                              <1> 	retn
  2414                              <1> _KIO_S2:		
  2415                              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
  2416                              <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
  2417                              <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2418                              <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
  2419                              <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2420                              <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
  2421                              <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
  2422                              <1> _KIO_S3:
  2423                              <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
  2424                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
  2425                              <1> 	jne	short _kio_ret
  2426                              <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2427                              <1>         jz	short _KIO_USE		; JUMP IF AH = 0
  2428                              <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
  2429                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
  2430                              <1> _KIO_USE:
  2431                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
  2432                              <1> 	retn				; RETURN	
  2433                              <1> _KIO_DIS:
  2434                              <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
  2435                              <1> 	retn				; RETURN
  2436                              <1> 
  2437                              <1> %endif
  2438                              <1> 
  2439                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
  2440                              <1> _K4:    
  2441 00000C4B 43                  <1> 	inc     ebx
  2442 00000C4C 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
  2443 00000C4D 3B1D[6C610000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
  2444                              <1>         ;jne    short _K5               ; NO, CONTINUE
  2445 00000C53 7206                <1> 	jb	short _K5
  2446 00000C55 8B1D[68610000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
  2447                              <1> _K5:
  2448 00000C5B C3                  <1> 	retn
  2449                              <1> 
  2450                              <1> ; 20/02/2015
  2451                              <1> ; 05/12/2014
  2452                              <1> ; 26/08/2014
  2453                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
  2454                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
  2455                              <1> ;
  2456                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
  2457                              <1> ; rombios source code (06/10/1985)
  2458                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
  2459                              <1> 
  2460                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
  2461                              <1> ENA_KBD		equ	0AEh	; ENABLE KEYBOARD COMMAND
  2462                              <1> DIS_KBD		equ	0ADh	; DISABLE KEYBOARD COMMAND
  2463                              <1> SHUT_CMD	equ	0FEh	; CAUSE A SHUTDOWN COMMAND
  2464                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  2465                              <1> STATUS_PORT	equ	064h	; 8042 STATUS PORT
  2466                              <1> INPT_BUF_FULL	equ	00000010b ; 1 = +INPUT BUFFER FULL
  2467                              <1> PORT_A		equ	060h	; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  2468                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
  2469                              <1> KB_ACK		equ	0FAh	; ACKNOWLEDGE PROM TRANSMISSION
  2470                              <1> KB_RESEND	equ	0FEh	; RESEND REQUEST
  2471                              <1> KB_OVER_RUN	equ	0FFh	; OVER RUN SCAN CODE
  2472                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
  2473                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
  2474                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
  2475                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
  2476                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
  2477                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
  2478                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
  2479                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
  2480                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
  2481                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
  2482                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
  2483                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
  2484                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
  2485                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
  2486                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
  2487                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
  2488                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
  2489                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
  2490                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
  2491                              <1> F11_M		equ	87		; F11 KEY MAKE
  2492                              <1> F12_M		equ	88		; F12 KEY MAKE
  2493                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
  2494                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
  2495                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
  2496                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
  2497                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
  2498                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
  2499                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
  2500                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
  2501                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
  2502                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
  2503                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
  2504                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
  2505                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
  2506                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
  2507                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
  2508                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
  2509                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
  2510                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
  2511                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
  2512                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
  2513                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
  2514                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
  2515                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
  2516                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
  2517                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
  2518                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
  2519                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
  2520                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
  2521                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
  2522                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
  2523                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
  2524                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
  2525                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
  2526                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
  2527                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
  2528                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
  2529                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
  2530                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
  2531                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
  2532                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
  2533                              <1> ;
  2534                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
  2535                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
  2536                              <1> INTA00		equ	020h		; 8259 PORT
  2537                              <1> 
  2538                              <1> 
  2539                              <1> kb_int:
  2540                              <1> 
  2541                              <1> ; 11/06/2022
  2542                              <1> ; 05/12/2021 (Retro UNIX 386 v1.2)
  2543                              <1> ; 17/10/2015 ('ctrlbrk') 
  2544                              <1> ; 05/12/2014
  2545                              <1> ; 04/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2546                              <1> ;	      instead of pc-at bios - 1985-)
  2547                              <1> ; 26/08/2014
  2548                              <1> ;
  2549                              <1> ; 03/06/86  KEYBOARD BIOS
  2550                              <1> ;
  2551                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
  2552                              <1> ;										;
  2553                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
  2554                              <1> ;										;
  2555                              <1> ;--------------------------------------------------------------------------------
  2556                              <1> 
  2557                              <1> KB_INT_1:
  2558 00000C5C FB                  <1> 	sti				; ENABLE INTERRUPTS
  2559                              <1> 	;push	ebp
  2560 00000C5D 50                  <1> 	push	eax
  2561 00000C5E 53                  <1> 	push	ebx
  2562 00000C5F 51                  <1> 	push	ecx
  2563 00000C60 52                  <1> 	push	edx
  2564 00000C61 56                  <1> 	push	esi
  2565 00000C62 57                  <1> 	push	edi
  2566 00000C63 1E                  <1> 	push	ds
  2567 00000C64 06                  <1> 	push	es
  2568 00000C65 FC                  <1> 	cld				; FORWARD DIRECTION
  2569 00000C66 66B81000            <1> 	mov	ax, KDATA
  2570 00000C6A 8ED8                <1> 	mov	ds, ax
  2571 00000C6C 8EC0                <1> 	mov	es, ax
  2572                              <1> 	;
  2573                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
  2574 00000C6E B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
  2575 00000C70 E852050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
  2576 00000C75 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2577 00000C76 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
  2578                              <1> KB_INT_01:
  2579 00000C7B E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
  2580 00000C7D A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
  2581 00000C7F E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
  2582                              <1> 	;
  2583                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
  2584 00000C81 E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
  2585                              <1> 	;
  2586                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
  2587                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
  2588                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
  2589                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
  2590                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
  2591                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
  2592                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
  2593                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
  2594                              <1> 	;
  2595                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
  2596                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
  2597 00000C83 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  2598 00000C84 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
  2599 00000C86 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
  2600                              <1> 	;
  2601                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
  2602 00000C88 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
  2603 00000C8A 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
  2604                              <1> 	;
  2605                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
  2606 00000C8C FA                  <1> 	cli				; DISABLE INTERRUPTS
  2607 00000C8D 800D[65610000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
  2608 00000C94 E963020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
  2609                              <1> 	;
  2610                              <1> 	;-----	RESEND THE LAST BYTE
  2611                              <1> KB_INT_4:
  2612 00000C99 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2613 00000C9A 800D[65610000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
  2614 00000CA1 E956020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
  2615                              <1> 	;
  2616                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
  2617                              <1> KB_INT_2:
  2618                              <1> 	;push 	ax			; SAVE DATA IN
  2619                              <1> 	; 05/12/2021
  2620 00000CA6 50                  <1> 	push	eax
  2621 00000CA7 E8E1050000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2622 00000CAC 8A1D[65610000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2623 00000CB2 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2624 00000CB4 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
  2625 00000CB7 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
  2626 00000CB9 E864050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2627                              <1> UP0:
  2628                              <1> 	;pop	ax			; RESTORE DATA IN
  2629                              <1> 	; 05/12/2021
  2630 00000CBE 58                  <1> 	pop	eax
  2631                              <1> ;------------------------------------------------------------------------
  2632                              <1> ;	START OF KEY PROCESSING						;
  2633                              <1> ;------------------------------------------------------------------------
  2634 00000CBF 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
  2635                              <1> 	;
  2636                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
  2637 00000CC1 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
  2638                              <1>         ;je	K62			; BUFFER_FULL_BEEP
  2639                              <1> 	; 05/12/2021
  2640 00000CC3 7505                <1> 	jne	short K16
  2641 00000CC5 E9E9040000          <1> 	jmp	K62
  2642                              <1> K16:	
  2643 00000CCA 8A3D[66610000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
  2644                              <1> 	;
  2645                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
  2646 00000CD0 F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
  2647 00000CD3 7442                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
  2648 00000CD5 7914                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
  2649 00000CD7 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
  2650 00000CD9 7507                <1> 	jne	short RST_RD_ID
  2651 00000CDB 800D[66610000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  2652                              <1> RST_RD_ID:
  2653 00000CE2 8025[66610000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
  2654 00000CE9 EB27                <1>         jmp    short ID_EX		; AND EXIT
  2655                              <1> 	; 05/12/2021
  2656                              <1> 	;jmp	K26
  2657                              <1> 	;
  2658                              <1> TST_ID_2:
  2659 00000CEB 8025[66610000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
  2660 00000CF2 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
  2661 00000CF4 7415                <1>         je	short KX_BIT		; JUMP IF SO
  2662 00000CF6 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
  2663 00000CF8 7518                <1>         jne	short ID_EX		; LEAVE IF NOT
  2664                              <1> 	; 05/12/2021
  2665                              <1> 	;jne	K26
  2666                              <1> 	;
  2667                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
  2668 00000CFA F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
  2669 00000CFD 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
  2670 00000CFF 800D[63610000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
  2671 00000D06 E817050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
  2672                              <1> KX_BIT:
  2673 00000D0B 800D[66610000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
  2674 00000D12 E9E5010000          <1> ID_EX:	jmp     K26			; EXIT
  2675                              <1> 	;
  2676                              <1> NOT_ID:
  2677 00000D17 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
  2678 00000D19 750E                <1> 	jne	short TEST_E1
  2679 00000D1B 800D[66610000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
  2680 00000D22 EB10                <1> 	jmp	short EXIT		; THROW AWAY THIS CODE
  2681                              <1> 	; 05/12/2021
  2682 00000D24 E9DA010000          <1> 	jmp	K26A	
  2683                              <1> TEST_E1:	
  2684 00000D29 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
  2685 00000D2B 750C                <1> 	jne	short NOT_HC
  2686 00000D2D 800D[66610000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
  2687 00000D34 E9CA010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
  2688                              <1> 	;
  2689                              <1> NOT_HC:
  2690 00000D39 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
  2691 00000D3B F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
  2692 00000D3E 740D                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
  2693                              <1> 	;
  2694 00000D40 BF[4E600000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
  2695 00000D45 AE                  <1> 	scasb
  2696                              <1> 	;je	K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
  2697                              <1> 	; 05/12/2021
  2698 00000D46 7458                <1> 	je	short K16B
  2699 00000D48 AE                  <1> 	scasb
  2700 00000D49 756A                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
  2701 00000D4B EB53                <1> 	jmp	short K16B		; YES, THROW AWAY & RESET FLAG
  2702                              <1> 	; 05/12/2021
  2703                              <1> 	;jmp	K26
  2704                              <1> 	;
  2705                              <1> NOT_LC_E0:
  2706 00000D4D F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
  2707 00000D50 7425                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
  2708 00000D52 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
  2709 00000D57 BF[4C600000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
  2710 00000D5C F2AE                <1> 	repne	scasb			; CHECK IT
  2711 00000D5E 74D4                <1> 	je	short EXIT		; THROW AWAY IF SO
  2712                              <1> 	; 05/12/2021
  2713                              <1> 	;je	K26A			
  2714                              <1> 	;
  2715 00000D60 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
  2716 00000D62 753C                <1> 	jne	short K16B		; NO, THROW AWAY & RESET FLAG
  2717                              <1> 	; 05/12/2021
  2718                              <1> 	;jne	K26
  2719 00000D64 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
  2720 00000D67 7537                <1> 	jnz	short K16B		; YES, THROW THIS AWAY, TOO	
  2721                              <1> 	; 05/12/2021
  2722                              <1> 	;jnz	K26
  2723                              <1>         ; 20/02/2015 
  2724 00000D69 F605[64610000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ; NO, ARE WE PAUSED ALREADY?
  2725 00000D70 752E                <1> 	jnz	short K16B		; YES, THROW AWAY
  2726                              <1> 	; 05/12/2021
  2727                              <1> 	;jnz	K26
  2728 00000D72 E9D2020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
  2729                              <1> 	;
  2730                              <1> 	;-----	TEST FOR SYSTEM KEY
  2731                              <1> T_SYS_KEY:
  2732 00000D77 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
  2733 00000D79 753A                <1> 	jnz	short K16A		; CONTINUE IF NOT
  2734                              <1> 	;
  2735 00000D7B F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
  2736 00000D7E 7525                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
  2737                              <1> 	;
  2738 00000D80 F605[64610000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
  2739 00000D87 7517                <1> 	jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
  2740                              <1> 	;jnz	K26			
  2741                              <1> 	;
  2742 00000D89 800D[64610000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
  2743 00000D90 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  2744 00000D92 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  2745                              <1> 					; INTERRUPT-RETURN-NO-EOI
  2746 00000D94 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  2747 00000D96 E82C040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  2748                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
  2749                              <1> 	;mov	al, 8500h		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
  2750                              <1> 	;sti				; MAKE SURE INTERRUPTS ENABLED
  2751                              <1> 	;int	15h			; USER INTERRUPT	
  2752 00000D9B E96F010000          <1>         jmp     K27A                    ; END PROCESSING
  2753                              <1> 	;
  2754 00000DA0 E957010000          <1> K16B:	jmp	K26			; IGNORE SYSTEM KEY
  2755                              <1> 	;
  2756                              <1> K16C:
  2757 00000DA5 8025[64610000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
  2758 00000DAC B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  2759 00000DAE E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
  2760                              <1> 					; INTERRUPT-RETURN-NO-EOI
  2761                              <1> 	;mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  2762                              <1> 	;call	SHIP_IT			; EXECUTE ENABLE
  2763                              <1> 	;
  2764                              <1> 	;mov	ax, 8501h		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
  2765                              <1> 	;sti				; MAKE SURE INTERRUPTS ENABLED
  2766                              <1> 	;int	15h			; USER INTERRUPT
  2767                              <1> 	;jmp	K27A			; IGNORE SYSTEM KEY
  2768                              <1> 	;
  2769 00000DB0 E953010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
  2770                              <1> 	;
  2771                              <1> 	;-----	TEST FOR SHIFT KEYS
  2772                              <1> K16A:
  2773 00000DB5 8A1D[63610000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  2774 00000DBB BF[48600000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
  2775 00000DC0 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
  2776 00000DC5 F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
  2777 00000DC7 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
  2778                              <1>         ;jne    K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
  2779                              <1> 	; 05/12/2021
  2780 00000DC9 7405                <1> 	je	short K17
  2781 00000DCB E914010000          <1> 	jmp	K25
  2782                              <1> 	;
  2783                              <1> 	;------	SHIFT KEY FOUND
  2784                              <1> K17:
  2785 00000DD0 81EF[49600000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  2786 00000DD6 8AA7[50600000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
  2787 00000DDC B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
  2788 00000DDE A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
  2789                              <1>         ;jnz	K23                     ; JUMP OF BREAK
  2790                              <1> 	; 05/12/2021
  2791 00000DE0 7405                <1> 	jz	short K17C
  2792 00000DE2 E999000000          <1> 	jmp	K23
  2793                              <1> 	;
  2794                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
  2795                              <1> K17C:
  2796 00000DE7 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
  2797 00000DEA 732C                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
  2798                              <1> 	;
  2799                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
  2800 00000DEC 0825[63610000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
  2801 00000DF2 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
  2802 00000DF4 7505                <1> 	jnz	short K17D		; YES, MORE FLAGS TO SET
  2803                              <1> 	;jz	K26			; NO, INTERRUPT RETURN
  2804                              <1> 	; 05/12/2021
  2805 00000DF6 E901010000          <1> 	jmp	K26
  2806                              <1> K17D:
  2807 00000DFB F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
  2808 00000DFE 740B                <1> 	jz 	short K17E		; NO, JUMP
  2809 00000E00 0825[66610000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
  2810 00000E06 E9F1000000          <1> 	jmp	K26			; INTERRUPT RETURN
  2811                              <1> K17E:
  2812 00000E0B D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
  2813 00000E0D 0825[64610000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
  2814 00000E13 E9E4000000          <1> 	jmp	K26
  2815                              <1> 	;
  2816                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
  2817                              <1> K18:					; SHIFT-TOGGLE
  2818 00000E18 F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
  2819 00000E1B 7405                <1>         jz    	short K18A              ; JUMP IF NOT CTL STATE
  2820                              <1>         ;jnz	K25                     ; JUMP IF CTL STATE
  2821                              <1> 	; 05/12/2021
  2822 00000E1D E9C2000000          <1> 	jmp	K25
  2823                              <1> K18A:
  2824 00000E22 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
  2825 00000E24 7525                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
  2826 00000E26 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
  2827 00000E29 7405                <1>       	jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
  2828                              <1> 	;jnz	K25                     ; JUMP IF ALTERNATE SHIFT
  2829                              <1> 	; 05/12/2021
  2830 00000E2B E9B4000000          <1> 	jmp	K25
  2831                              <1> K18B:
  2832 00000E30 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
  2833 00000E33 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
  2834                              <1> K19:	
  2835 00000E35 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
  2836 00000E38 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
  2837 00000E3A F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
  2838 00000E3D 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
  2839                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
  2840 00000E3F 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
  2841 00000E41 E99E000000          <1>         jmp	K25               	; NUMERAL '0', STNDRD. PROCESSING
  2842                              <1> K21:					; MIGHT BE NUMERIC
  2843 00000E46 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
  2844 00000E49 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
  2845                              <1> 	;
  2846                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
  2847 00000E4B 8425[64610000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
  2848                              <1> 	;jnz	K26
  2849                              <1> 	; 05/12/2021
  2850 00000E51 7405                <1> 	jz	short K22A
  2851 00000E53 E9A4000000          <1> 	jmp	K26			; JUMP IF KEY ALREADY DEPRESSED
  2852                              <1> K22A:
  2853 00000E58 0825[64610000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  2854 00000E5E 3025[63610000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
  2855                              <1> 	;
  2856                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
  2857 00000E64 F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
  2858 00000E67 7407                <1> 	jz	short K22B		; GO IF NOT
  2859                              <1> 	;
  2860                              <1> 	; 05/12/2021
  2861                              <1> 	;push	ax			; SAVE SCAN CODE AND SHIFT MASK
  2862 00000E69 50                  <1> 	push	eax
  2863 00000E6A E8B3030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
  2864                              <1> 	;pop	ax			; RESTORE SCAN CODE
  2865 00000E6F 58                  <1> 	pop	eax
  2866                              <1> K22B:
  2867 00000E70 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
  2868                              <1>         ;jne	K26			; JUMP IF NOT INSERT KEY
  2869                              <1> 	; 05/12/2021
  2870 00000E72 7405                <1> 	je	short K22C
  2871 00000E74 E983000000          <1> 	jmp	K26			; JUMP IF NOT INSERT KEY
  2872                              <1> K22C:
  2873 00000E79 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
  2874 00000E7B E999000000          <1>         jmp	K28			; FLAGS UPDATED, PROC. FOR BUFFER
  2875                              <1> 	;
  2876                              <1> 	;-----	BREAK SHIFT FOUND
  2877                              <1> K23:					; BREAK-SHIFT-FOUND
  2878 00000E80 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
  2879 00000E83 F6D4                <1> 	not	ah			; INVERT MASK
  2880 00000E85 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
  2881 00000E87 2025[63610000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
  2882 00000E8D 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
  2883 00000E90 7730                <1> 	ja	short K23D		; NO, ALL DONE
  2884                              <1> 	;
  2885 00000E92 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
  2886 00000E95 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
  2887 00000E97 2025[66610000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
  2888 00000E9D EB08                <1> 	jmp	short K23B		; CONTINUE
  2889                              <1> K23A:
  2890 00000E9F D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
  2891 00000EA1 2025[64610000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
  2892                              <1> K23B:
  2893 00000EA7 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
  2894 00000EA9 A0[66610000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
  2895 00000EAE D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
  2896 00000EB0 0A05[64610000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
  2897 00000EB6 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
  2898 00000EB8 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
  2899 00000EBA 0805[63610000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
  2900 00000EC0 88E0                <1> 	mov	al, ah
  2901                              <1> K23D:
  2902 00000EC2 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
  2903 00000EC4 7536                <1> 	jne	short K26		; INTERRUPT RETURN
  2904                              <1> 	;	
  2905                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
  2906 00000EC6 A0[67610000]        <1> 	mov	al, [ALT_INPUT]
  2907 00000ECB B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  2908 00000ECD 8825[67610000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
  2909 00000ED3 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
  2910 00000ED5 7425                <1> 	je	short K26		; INTERRUPT_RETURN
  2911 00000ED7 E9B4020000          <1>         jmp     K61                     ; IT WASN'T, SO PUT IN BUFFER
  2912                              <1> 	;
  2913                              <1> K24:					; BREAK-TOGGLE
  2914 00000EDC 2025[64610000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
  2915 00000EE2 EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
  2916                              <1> 	;
  2917                              <1> 	;-----	TEST FOR HOLD STATE
  2918                              <1> 					; AL, AH = SCAN CODE
  2919                              <1> K25:					; NO-SHIFT-FOUND
  2920 00000EE4 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
  2921 00000EE6 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
  2922 00000EE8 F605[64610000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
  2923 00000EEF 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
  2924 00000EF1 3C45                <1> 	cmp	al, NUM_KEY
  2925 00000EF3 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
  2926 00000EF5 8025[64610000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  2927                              <1> 	;
  2928                              <1> K26:
  2929 00000EFC 8025[66610000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  2930                              <1> K26A:					; INTERRUPT-RETURN
  2931 00000F03 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  2932 00000F04 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  2933 00000F06 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  2934                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
  2935 00000F08 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  2936 00000F0A E8B8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  2937                              <1> K27A:
  2938 00000F0F FA                  <1> 	cli				; DISABLE INTERRUPTS
  2939 00000F10 07                  <1> 	pop	es			; RESTORE REGISTERS
  2940 00000F11 1F                  <1> 	pop	ds
  2941 00000F12 5F                  <1> 	pop	edi
  2942 00000F13 5E                  <1> 	pop	esi
  2943 00000F14 5A                  <1> 	pop	edx
  2944 00000F15 59                  <1> 	pop	ecx
  2945 00000F16 5B                  <1> 	pop	ebx
  2946 00000F17 58                  <1> 	pop	eax
  2947                              <1> 	;pop	ebp
  2948 00000F18 CF                  <1> 	iret				; RETURN
  2949                              <1> 
  2950                              <1> 	;-----	NOT IN	HOLD STATE
  2951                              <1> K28:					; NO-HOLD-STATE
  2952 00000F19 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
  2953 00000F1B 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
  2954                              <1> 	;
  2955 00000F1D F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
  2956 00000F20 740E                <1>         jz	short K28A		; IF NOT ALTERNATE
  2957                              <1>         ; 05/12/2021
  2958                              <1> 	;jz      K38
  2959                              <1> 	;
  2960 00000F22 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
  2961 00000F25 740E                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  2962                              <1> 	; 28/02/2015
  2963 00000F27 F605[64610000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
  2964 00000F2E 7405                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  2965                              <1> 	; 05/12/2021
  2966                              <1> 	;jnz	K38			; YES, THIS IS PHONY ALT STATE 
  2967                              <1>         ;				; DUE TO PRESSING SYSREQ	
  2968 00000F30 E9CD000000          <1> K28A:	jmp	K38
  2969                              <1> 	;
  2970                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
  2971                              <1> K29:					; TEST-RESET
  2972 00000F35 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
  2973 00000F38 740B                <1> 	jz	short K31		; NO_RESET
  2974 00000F3A 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
  2975 00000F3C 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
  2976                              <1> 	;
  2977                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
  2978                              <1>  	; 26/08/2014
  2979                              <1> cpu_reset:
  2980                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
  2981                              <1> 	; Send FEh (system reset command) to the keyboard controller.
  2982 00000F3E B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
  2983 00000F40 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
  2984                              <1> khere:
  2985 00000F42 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
  2986 00000F43 EBFD                <1> 	jmp 	short khere		; INSURE HALT
  2987                              <1> 
  2988                              <1> 	;
  2989                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
  2990                              <1> K31:					; NO-RESET
  2991 00000F45 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
  2992 00000F47 7507                <1> 	jne	short K311		; NOT THERE
  2993 00000F49 B020                <1> 	mov	al, ' '			; SET SPACE CHAR
  2994 00000F4B E932020000          <1>         jmp     K57                     ; BUFFER_FILL
  2995                              <1> K311:
  2996 00000F50 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
  2997 00000F52 7509                <1> 	jne	short K312		; NOT THERE
  2998 00000F54 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
  2999 00000F58 E925020000          <1>         jmp     K57                     ; BUFFER_FILL
  3000                              <1> K312:
  3001 00000F5D 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
  3002 00000F5F 7471                <1>         je	short K37B              ; GO PROCESS
  3003 00000F61 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
  3004 00000F63 746D                <1>         je	short K37B              ; GO PROCESS
  3005                              <1> 	;
  3006                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
  3007                              <1> K32:					; ALT-KEY-PAD
  3008 00000F65 BF[24600000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
  3009 00000F6A B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
  3010 00000F6F F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
  3011 00000F71 7523                <1> 	jne	short K33		; NO_ALT_KEYPAD
  3012 00000F73 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
  3013                              <1>         ;jnz	short K37C		; YES, JUMP, NOT NUMPAD KEY
  3014                              <1> 	; 05/12/2021
  3015 00000F76 751C                <1> 	jnz	short K32B
  3016 00000F78 81EF[25600000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3017 00000F7E A0[67610000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
  3018 00000F83 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
  3019 00000F85 F6E4                <1> 	mul	ah
  3020 00000F87 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
  3021 00000F8A A2[67610000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
  3022                              <1> K32A:
  3023 00000F8F E968FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
  3024                              <1> K32B:
  3025                              <1> 	; 05/12/2021
  3026 00000F94 EB66                <1> 	jmp	K37C
  3027                              <1> 	;
  3028                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
  3029                              <1> K33:					; NO-ALT-KEYPAD
  3030 00000F96 C605[67610000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
  3031 00000F9D B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
  3032 00000FA2 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
  3033 00000FA4 744F                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
  3034                              <1> 	;
  3035                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
  3036                              <1> K34:					; ALT-TOP-ROW
  3037 00000FA6 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
  3038 00000FA8 7228                <1> 	jb	short K37B		; MUST BE ESCAPE
  3039 00000FAA 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
  3040 00000FAC 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
  3041 00000FAE 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
  3042 00000FB1 EB42                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3043                              <1> 	;
  3044                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
  3045                              <1> K35:					; ALT-FUNCTION
  3046 00000FB3 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
  3047 00000FB5 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
  3048 00000FB7 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
  3049 00000FB9 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
  3050 00000FBB 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
  3051 00000FBE EB35                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3052                              <1> K35A:
  3053 00000FC0 F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  3054 00000FC3 7425                <1> 	jz	short K37		; NO, JUMP
  3055 00000FC5 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  3056 00000FC7 7510                <1>         jne     short K35B              ; NOT THERE
  3057 00000FC9 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  3058 00000FCD E9B0010000          <1> 	jmp	K57			; BUFFER FILL
  3059                              <1> K37B:
  3060 00000FD2 B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  3061 00000FD4 E9A9010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  3062                              <1> K35B:
  3063 00000FD9 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  3064 00000FDB 741F                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  3065 00000FDD 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  3066 00000FDF 75AE                <1> 	jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  3067                              <1>         ; 05/12/2021
  3068                              <1> 	;jne	K26
  3069 00000FE1 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  3070 00000FE5 E998010000          <1> 	jmp	K57			; BUFFER FILL
  3071                              <1> K37:
  3072 00000FEA 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  3073 00000FEC 72E4                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  3074 00000FEE 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  3075 00000FF0 779D                <1>         ja	short K32A		; IF SO, IGNORE
  3076                              <1> 	; 11/06/2022
  3077                              <1> 	;ja      K26
  3078 00000FF2 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  3079                              <1> K37A:
  3080 00000FF5 B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  3081 00000FF7 E986010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  3082                              <1> K37C:
  3083 00000FFC 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  3084 00000FFE 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  3085 00001000 EBF3                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  3086                              <1> 	;
  3087                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  3088                              <1> K38:					; NOT-ALT-SHIFT
  3089                              <1> 					; BL STILL HAS SHIFT FLAGS
  3090 00001002 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  3091 00001005 7505                <1> 	jnz	short K38A		; YES, START PROCESSING	
  3092                              <1>         ;jz	K44                     ; NOT-CTL-SHIFT
  3093                              <1> 	; 05/12/2021
  3094 00001007 E9AB000000          <1> 	jmp	K44
  3095                              <1> 	;
  3096                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  3097                              <1> 	;-----	TEST FOR BREAK
  3098                              <1> K38A:
  3099 0000100C 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  3100 0000100E 7530                <1> 	jne	short K39		; JUMP, NO-BREAK
  3101 00001010 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3102 00001013 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  3103 00001015 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3104 00001018 7426                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  3105                              <1> K38B:
  3106 0000101A 8B1D[70610000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3107 00001020 891D[74610000]      <1> 	mov	[BUFFER_TAIL], ebx
  3108 00001026 C605[62610000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  3109                              <1> 	;
  3110                              <1> 	;-----	ENABLE KEYBOARD
  3111 0000102D B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3112 0000102F E893010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3113                              <1> 	;
  3114                              <1> 	; CTRL+BREAK code here !!!
  3115                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  3116                              <1> 	; 17/10/2015	
  3117 00001034 E892190000          <1> 	call	ctrlbrk ; control+break subroutine
  3118                              <1> 	;
  3119                              <1> 	;sub	ax, ax			; PUT OUT DUMMY CHARACTER
  3120                              <1> 	; 05/12/2021
  3121 00001039 29C0                <1> 	sub	eax, eax
  3122 0000103B E942010000          <1> 	jmp     K57                     ; BUFFER_FILL
  3123                              <1> 	;
  3124                              <1> 	;-----	TEST FOR PAUSE
  3125                              <1> K39:					; NO_BREAK
  3126 00001040 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3127 00001043 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  3128 00001045 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  3129 00001047 7533                <1> 	jne	short K41		; NO-PAUSE
  3130                              <1> K39P:
  3131 00001049 800D[64610000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  3132                              <1> 	;
  3133                              <1> 	;-----	ENABLE KEYBOARD
  3134 00001050 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3135 00001052 E870010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3136                              <1> K39A:
  3137 00001057 B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  3138 00001059 E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  3139                              <1> 	;
  3140                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  3141 0000105B 803D[60610000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  3142 00001062 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  3143 00001064 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  3144 00001068 A0[61610000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  3145 0000106D EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  3146                              <1> 	;
  3147                              <1> K40:					; PAUSE-LOOP
  3148 0000106E F605[64610000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  3149 00001075 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  3150                              <1> 	;
  3151 00001077 E98CFEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  3152                              <1>         ;
  3153                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  3154                              <1> K41:					; NO-PAUSE
  3155 0000107C 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  3156 0000107E 7513                <1> 	jne	short K42		; NOT-KEY-55
  3157 00001080 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3158 00001083 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  3159 00001085 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3160 00001088 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  3161                              <1> K41A:	
  3162 0000108A 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  3163 0000108E E9EF000000          <1>         jmp     K57                     ; BUFFER_FILL
  3164                              <1> 	;
  3165                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  3166                              <1> K42:					; NOT-KEY-55
  3167 00001093 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  3168 00001095 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  3169 00001097 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  3170 00001099 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  3171 0000109B F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  3172 0000109E 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  3173 000010A0 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  3174 000010A4 E9D9000000          <1> 	jmp	K57			; BUFFER FILL	
  3175                              <1> K42A:
  3176                              <1> 	;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3177 000010A9 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  3178                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  3179                              <1> 	;;jb	K56 ; 20/02/2015
  3180                              <1> 	;;jmp	K64 ; 20/02/2015
  3181                              <1> K42B:
  3182 000010AB BB[58600000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3183                              <1> 	;;jmp	K64
  3184                              <1> 	;jb	K56 ;; 20/02/2015	
  3185                              <1> 	; 05/12/2021
  3186 000010B0 7267                <1> 	jb	short K45F
  3187 000010B2 E9B9000000          <1> 	jmp	K64	
  3188                              <1>         ;
  3189                              <1> 	;-----	NOT IN CONTROL SHIFT
  3190                              <1> K44:					; NOT-CTL-SHIFT
  3191 000010B7 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  3192 000010B9 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  3193 000010BB F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  3194 000010BE 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  3195 000010C0 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  3196 000010C3 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  3197 000010C5 EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3198                              <1> K44A:
  3199 000010C7 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  3200 000010CA 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3201                              <1> 	;
  3202                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  3203                              <1> K44B:
  3204 000010CC B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3205 000010CE E8F4000000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3206 000010D3 B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  3207 000010D5 E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  3208                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  3209                              <1> 	;PUSH 	BP			; SAVE POINTER
  3210                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  3211                              <1> 	;POP	BP			; RESTORE POINTER
  3212 000010D7 8025[66610000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  3213 000010DE E925FEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  3214                              <1> 	;
  3215                              <1> 	;-----	HANDLE IN-CORE KEYS
  3216                              <1> K45:					; NOT-PRINT-SCREEN
  3217 000010E3 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  3218 000010E5 7734                <1> 	ja	short K46		; JUMP IF NOT
  3219 000010E7 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  3220 000010E9 7505                <1> 	jne	short K45A		; NO, JUMP
  3221 000010EB F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  3222 000010EE 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  3223                              <1> K45A:
  3224 000010F0 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  3225 000010F5 BF[2E600000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  3226 000010FA F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  3227                              <1> 		; 20/02/2015
  3228 000010FC 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  3229                              <1> 	;
  3230 000010FE F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  3231 00001101 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  3232                              <1> K45B:
  3233 00001103 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3234 00001106 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  3235                              <1> 					; NO, LOWERCASE
  3236                              <1> K45C:
  3237 00001108 BB[B0600000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  3238 0000110D EB51                <1> 	jmp	short K56	
  3239                              <1> K45D:					; ALMOST-CAPS-STATE
  3240 0000110F F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  3241 00001112 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  3242                              <1> K45E:
  3243 00001114 BB[08610000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  3244 00001119 EB45                <1> K45F:	jmp	short K56
  3245                              <1> 	;
  3246                              <1> 	;-----	TEST FOR KEYS F1 - F10
  3247                              <1> K46:					; NOT IN-CORE AREA
  3248 0000111B 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  3249                              <1> 	;ja	short K47		; JUMP IF NOT
  3250                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  3251 0000111D 7635                <1> 	jna	short K53		
  3252                              <1> 	;
  3253                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  3254                              <1> K47:					; NOT F1 - F10
  3255 0000111F 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  3256 00001121 772D                <1> 	ja	short K52		; JUMP IF NOT
  3257                              <1> 	;
  3258                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  3259                              <1> K48:
  3260 00001123 3C4A                <1> 	cmp	al, 74			; SPECIAL CASE FOR MINUS
  3261 00001125 74ED                <1> 	je	short K45E		; GO TRANSLATE
  3262 00001127 3C4E                <1> 	cmp	al, 78			; SPECIAL CASE FOR PLUS
  3263 00001129 74E9                <1> 	je	short K45E		; GO TRANSLATE
  3264 0000112B F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  3265 0000112E 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  3266                              <1> 	;		
  3267 00001130 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  3268 00001133 7514                <1> 	jnz	short K50		; TEST FOR SURE
  3269 00001135 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3270                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  3271 00001138 75DA                <1> 	jnz	short K45E
  3272                              <1> 	;
  3273                              <1> 	;-----	BASE CASE FOR KEYPAD
  3274                              <1> K49:					
  3275 0000113A 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  3276 0000113C 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  3277 0000113E B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  3278 00001140 EB40                <1> 	jmp	short K57		; BUFFER FILL
  3279                              <1> K49A:
  3280 00001142 BB[B0600000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  3281 00001147 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  3282                              <1> 	;
  3283                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  3284                              <1> K50:					; ALMOST-NUM-STATE
  3285 00001149 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  3286 0000114C 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  3287 0000114E EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  3288                              <1> 	;
  3289                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  3290                              <1> K52:					; NOT A NUMPAD KEY
  3291 00001150 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  3292                              <1> 	;jne	short K53		; JUMP IF NOT
  3293                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  3294 00001152 74AF                <1> 	je	short K45B		
  3295                              <1> 	;
  3296                              <1> 	;-----	MUST BE F11 OR F12 
  3297                              <1> K53:					; F1 - F10 COME HERE, TOO
  3298 00001154 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  3299 00001157 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  3300                              <1> 		; 20/02/2015 
  3301 00001159 BB[08610000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  3302 0000115E EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  3303                              <1> 	;
  3304                              <1> 	;-----	TRANSLATE THE CHARACTER
  3305                              <1> K56:					; TRANSLATE-CHAR
  3306 00001160 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3307 00001162 D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  3308 00001163 F605[66610000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3309 0000116A 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3310 0000116C B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  3311 0000116E EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  3312                              <1> 	;
  3313                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  3314                              <1> K64:					; TRANSLATE-SCAN-ORGD
  3315 00001170 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3316 00001172 D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  3317 00001173 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  3318 00001175 B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  3319 00001177 F605[66610000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3320 0000117E 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3321 00001180 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  3322                              <1> 	;
  3323                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  3324                              <1> K57:					; BUFFER_FILL
  3325 00001182 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  3326 00001184 7405                <1>         je	short K59		; YES, DO NOTHING WITH IT
  3327                              <1> 	; 05/12/2021
  3328                              <1> 	;je	K26			; YES, DO NOTHING WITH IT
  3329 00001186 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  3330                              <1> 	; 05/12/2021
  3331 00001189 7505                <1>         jne	short K61		; NEAR_INTERRUPT_RETURN
  3332                              <1> 	;je	K26			; INTERRUPT_RETURN
  3333                              <1> K59:					; NEAR_INTERRUPT_RETURN
  3334 0000118B E96CFDFFFF          <1> 	jmp	K26			; INTERRUPT_RETURN
  3335                              <1> K61:					; NOT-CAPS-STATE
  3336 00001190 8B1D[74610000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  3337 00001196 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  3338 00001198 E8AEFAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  3339 0000119D 3B1D[70610000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  3340 000011A3 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  3341 000011A5 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  3342 000011A8 891D[74610000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  3343 000011AE E949FDFFFF          <1> 	jmp	K26
  3344                              <1> 	;;cli				; TURN OFF INTERRUPTS
  3345                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  3346                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  3347                              <1> 	;mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3348                              <1> 	;call	SHIP_IT			; EXECUTE ENABLE
  3349                              <1> 	;mov	ax, 9102h		; MOVE IN POST CODE & TYPE
  3350                              <1> 	;int	15h			; PERFORM OTHER FUNCTION
  3351                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3352                              <1> 	;jmp	K27A			; INTERRUPT_RETURN
  3353                              <1> 	;;jmp   K27                    
  3354                              <1> 	;
  3355                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  3356                              <1> K62:
  3357 000011B3 B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  3358 000011B5 E620                <1> 	out	INTA00, al
  3359 000011B7 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  3360 000011BB B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  3361 000011BD E883010000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  3362 000011C2 E941FDFFFF          <1> 	jmp     K27			; EXIT   
  3363                              <1> 
  3364                              <1> SHIP_IT:
  3365                              <1> 	;---------------------------------------------------------------------------------
  3366                              <1> 	; SHIP_IT
  3367                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3368                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  3369                              <1> 	;---------------------------------------------------------------------------------
  3370                              <1> 	;
  3371                              <1> 	;push	ax			; SAVE DATA TO SEND
  3372                              <1> 	; 05/12/2021
  3373 000011C7 50                  <1> 	push	eax
  3374                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  3375 000011C8 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  3376                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  3377 000011C9 B900000100          <1> 	mov	ecx, 10000h			
  3378                              <1> S10:
  3379 000011CE E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  3380 000011D0 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  3381 000011D2 E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  3382                              <1> 
  3383                              <1> 	;pop	ax			; GET DATA TO SEND
  3384                              <1> 	; 05/12/2021
  3385 000011D4 58                  <1> 	pop	eax
  3386 000011D5 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  3387 000011D7 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3388 000011D8 C3                  <1> 	retn				; RETURN TO CALLER
  3389                              <1> 
  3390                              <1> SND_DATA:
  3391                              <1> 	; ---------------------------------------------------------------------------------
  3392                              <1> 	; SND_DATA
  3393                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3394                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  3395                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  3396                              <1> 	; ---------------------------------------------------------------------------------
  3397                              <1> 	;
  3398                              <1> 	;push	ax			; SAVE REGISTERS
  3399                              <1> 	;push	bx
  3400                              <1> 	; 05/12/2021
  3401 000011D9 50                  <1> 	push	eax
  3402 000011DA 53                  <1> 	push	ebx
  3403 000011DB 51                  <1> 	push	ecx
  3404 000011DC 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  3405 000011DE B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  3406                              <1> SD0:
  3407 000011E0 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3408 000011E1 8025[65610000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  3409                              <1> 	;
  3410                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  3411 000011E8 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  3412                              <1> SD5:
  3413 000011ED E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  3414 000011EF A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  3415 000011F1 E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  3416                              <1> 	;
  3417 000011F3 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  3418 000011F5 E660                <1> 	out	PORT_A, al		; SEND BYTE
  3419 000011F7 FB                  <1> 	sti				; ENABLE INTERRUPTS
  3420                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  3421 000011F8 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  3422                              <1> SD1:
  3423 000011FD F605[65610000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  3424 00001204 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  3425 00001206 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  3426                              <1> SD2:
  3427 00001208 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  3428 0000120A 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  3429 0000120C 800D[65610000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  3430 00001213 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  3431                              <1> SD3:
  3432 00001215 F605[65610000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  3433 0000121C 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  3434                              <1> SD4:	
  3435 0000121E 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  3436                              <1> 	;pop	bx
  3437                              <1> 	;pop	ax
  3438                              <1> 	; 05/12/2021
  3439 0000121F 5B                  <1> 	pop	ebx
  3440 00001220 58                  <1> 	pop	eax
  3441 00001221 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  3442                              <1> 
  3443                              <1> SND_LED:
  3444                              <1> 	; ---------------------------------------------------------------------------------
  3445                              <1> 	; SND_LED
  3446                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  3447                              <1> 	;
  3448                              <1> 	;----------------------------------------------------------------------------------
  3449                              <1> 	;
  3450 00001222 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3451 00001223 F605[65610000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3452 0000122A 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3453                              <1> 	;
  3454 0000122C 800D[65610000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3455 00001233 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3456 00001235 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3457 00001237 EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  3458                              <1> SND_LED1:
  3459 00001239 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3460 0000123A F605[65610000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3461 00001241 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3462                              <1> 	;
  3463 00001243 800D[65610000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3464                              <1> SL0:
  3465 0000124A B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  3466 0000124C E888FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3467 00001251 FA                  <1> 	cli
  3468 00001252 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  3469 00001257 8025[65610000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  3470 0000125E 0805[65610000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  3471 00001264 F605[65610000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3472 0000126B 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  3473                              <1> 	;
  3474 0000126D E867FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3475 00001272 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3476 00001273 F605[65610000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3477 0000127A 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  3478                              <1> SL2:
  3479 0000127C B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  3480 0000127E E856FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3481 00001283 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3482                              <1> SL3:
  3483 00001284 8025[65610000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  3484                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  3485 0000128B FB                  <1> 	sti				; ENABLE INTERRUPTS
  3486 0000128C C3                  <1> 	retn				; RETURN TO CALLER
  3487                              <1> 
  3488                              <1> MAKE_LED:
  3489                              <1> 	;---------------------------------------------------------------------------------
  3490                              <1> 	; MAKE_LED
  3491                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  3492                              <1> 	;	THE MODE INDICATORS.
  3493                              <1> 	;---------------------------------------------------------------------------------
  3494                              <1> 	;
  3495                              <1> 	;push 	cx			; SAVE CX
  3496 0000128D A0[63610000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  3497 00001292 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  3498                              <1> 	;mov	cl, 4			; SHIFT COUNT
  3499                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  3500 00001294 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  3501 00001297 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  3502                              <1> 	;pop	cx
  3503 00001299 C3                  <1> 	retn				; RETURN TO CALLER
  3504                              <1> 
  3505                              <1> ; % include 'kybdata.inc'   ; KEYBOARD DATA ; 11/03/2015
  3506                              <1> 
  3507                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  1867                                  
  1868                                  %include 'video.s' ; 07/03/2015
  1869                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  1870                              <1> ; (re-write kernel for test by using previous version without a major defect)
  1871                              <1> ; ****************************************************************************
  1872                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - VIDEO.INC
  1873                              <1> ; Last Modification: 14/06/2022
  1874                              <1> ;		  (Video Data is in 'VIDATA.INC')
  1875                              <1> ;
  1876                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
  1877                              <1> 
  1878                              <1> ; 27/02/2022
  1879                              <1> ; 23/02/2022
  1880                              <1> ; 21/02/2022 (Retro UNIX 386 v1.2)
  1881                              <1> ; 07/02/2022 (Retro UNIX 386 V1&v1.1)
  1882                              <1> ; 02/02/2022 (simplified scroll up)
  1883                              <1> ; 16/01/2016
  1884                              <1> ; 30/06/2015
  1885                              <1> ; 27/06/2015
  1886                              <1> ; 11/03/2015
  1887                              <1> ; 02/09/2014
  1888                              <1> ; 30/08/2014
  1889                              <1> ; VIDEO FUNCTIONS
  1890                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  1891                              <1> 
  1892                              <1> write_tty:
  1893                              <1> 	; 02/02/2022
  1894                              <1> 	; 13/08/2015
  1895                              <1> 	; 02/09/2014
  1896                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1897                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  1898                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  1899                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  1900                              <1> 	;
  1901                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  1902                              <1> 	;	   AL = Character to be written
  1903                              <1> 	;	   EBX = Video Page (0 to 7)
  1904                              <1> 	;	   (BH = 0 --> Video Mode 3)
  1905                              <1> 
  1906                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  1907                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  1908                              <1> 
  1909                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  1910                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  1911                              <1> ;
  1912                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  1913                              <1> ;
  1914                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  1915                              <1> ;										:
  1916                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  1917                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  1918                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  1919                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  1920                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  1921                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  1922                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  1923                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  1924                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  1925                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  1926                              <1> ;   THE 0 COLOR IS USED.							:
  1927                              <1> ;   ENTRY --									:
  1928                              <1> ;     (AH) = CURRENT CRT MODE							:
  1929                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  1930                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  1931                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  1932                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  1933                              <1> ;   EXIT -- 									:
  1934                              <1> ;     ALL REGISTERS SAVED							:
  1935                              <1> ;--------------------------------------------------------------------------------
  1936                              <1> 
  1937 0000129A FA                  <1> 	cli
  1938                              <1> 	;
  1939                              <1> 	; READ CURSOR (04/12/2013)
  1940                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  1941 0000129B 08FF                <1> 	or	bh, bh
  1942                              <1> 	;jnz	beeper
  1943                              <1> 	; 02/02/2022
  1944 0000129D 7405                <1> 	jz	short u14
  1945 0000129F E992000000          <1> 	jmp	beeper
  1946                              <1> u14:
  1947                              <1> 	; 02/02/2022
  1948                              <1> 	;; 01/09/2014
  1949                              <1> 	;cmp	byte [CRT_MODE], 3
  1950                              <1> 	;je	short m3
  1951                              <1> 	;;
  1952                              <1> 	;call	set_mode
  1953                              <1> m3:
  1954 000012A4 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  1955                              <1> 	;shl	si, 1
  1956                              <1> 	; 02/02/2022
  1957 000012A6 D1E6                <1> 	shl	esi, 1
  1958 000012A8 81C6[26670000]      <1> 	add	esi, cursor_posn
  1959 000012AE 668B16              <1> 	mov	dx, [esi]
  1960                              <1> 	;
  1961                              <1> 	; dx now has the current cursor position
  1962                              <1> 	;
  1963 000012B1 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  1964 000012B3 7647                <1> 	jbe	short u8
  1965                              <1> 	;
  1966                              <1> 	; write the char to the screen
  1967                              <1> u0:	
  1968                              <1> 	; ah = attribute/color
  1969                              <1> 	; al = character
  1970                              <1> 	; bl = video page number (0 to 7)
  1971                              <1> 	; bh = 0
  1972                              <1> 	;
  1973 000012B5 E8D2010000          <1> 	call	write_c_current
  1974                              <1> 	;
  1975                              <1> 	; position the cursor for next char
  1976 000012BA FEC2                <1> 	inc	dl		; next column
  1977                              <1> 	;cmp	dl, [CRT_COLS]
  1978 000012BC 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  1979                              <1>         ;jne	set_cpos
  1980                              <1> 	; 02/02/2022
  1981 000012BF 7405                <1> 	je	short u13
  1982 000012C1 E9DE000000          <1> 	jmp	set_cpos
  1983                              <1> u13:
  1984 000012C6 B200                <1> 	mov	dl, 0		; column = 0
  1985                              <1> u10:				; (line feed found)
  1986 000012C8 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  1987 000012CB 7228                <1> 	jb 	short u6
  1988                              <1> 	;
  1989                              <1> 	; scroll required
  1990                              <1> u1:	
  1991                              <1> 	; SET CURSOR POSITION (04/12/2013)
  1992 000012CD E8D2000000          <1> 	call	set_cpos
  1993                              <1> 	;
  1994                              <1> 	; determine value to fill with during scroll
  1995                              <1> u2:
  1996                              <1> 	; READ_AC_CURRENT		:
  1997                              <1> 	;   THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER
  1998                              <1> 	;    AT THE CURRENT CURSOR POSITION
  1999                              <1> 	;
  2000                              <1> 	; INPUT				
  2001                              <1> 	;	(AH) = CURRENT CRT MODE
  2002                              <1> 	;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )
  2003                              <1> 	;	(DS) = DATA SEGMENT
  2004                              <1> 	;	(ES) = REGEN SEGMENT
  2005                              <1> 	; OUTPUT			
  2006                              <1> 	;	(AL) = CHARACTER READ
  2007                              <1> 	;	(AH) = ATTRIBUTE READ
  2008                              <1> 	;
  2009                              <1> 	; mov	ah, [CRT_MODE] ; move current mode into ah
  2010                              <1> 	;
  2011                              <1> 	; bl = video page number
  2012                              <1> 	;
  2013 000012D2 E829010000          <1> 	call	find_position	; get regen location and port address
  2014                              <1> 	; dx = status port
  2015                              <1> 	; esi = cursor location/address
  2016                              <1> p11:
  2017 000012D7 FB                  <1> 	sti			; enable interrupts
  2018 000012D8 90                  <1> 	nop			; allow for small interupts window
  2019 000012D9 FA                  <1> 	cli			; blocks interrupts for single loop
  2020 000012DA EC                  <1> 	in	al, dx		; get status from adapter
  2021 000012DB A801                <1> 	test	al, RHRZ	; is horizontal retrace low
  2022 000012DD 75F8                <1> 	jnz	short p11	; wait until it is
  2023                              <1> p12:				; now wait for either retrace high
  2024 000012DF EC                  <1> 	in	al, dx		; get status
  2025 000012E0 A809                <1> 	test	al, RVRT+RHRZ	; is horizontal or vertical retrace high
  2026 000012E2 74FB                <1> 	jz	short p12	; wait until either is active	
  2027                              <1> p13:
  2028 000012E4 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
  2029 000012EA 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
  2030                              <1> 	;
  2031                              <1> 	; al = character, ah = attribute
  2032                              <1> 	;
  2033 000012ED FB                  <1> 	sti
  2034                              <1> 	; bl = video page number 	
  2035                              <1> u3:
  2036                              <1> 	;;mov	ax, 0601h 	; scroll one line
  2037                              <1> 	;;sub	cx, cx		; upper left corner
  2038                              <1> 	;;mov	dh, 25-1 	; lower right row
  2039                              <1> 	;;;mov	dl, [CRT_COLS]
  2040                              <1> 	;mov	dl, 80		; lower right column	
  2041                              <1> 	;;dec	dl
  2042                              <1> 	;;mov	dl, 79
  2043                              <1> 
  2044                              <1> 	;;call	scroll_up	; 04/12/2013
  2045                              <1> 	;;; 11/03/2015
  2046                              <1> 	; 02/09/2014
  2047                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  2048                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  2049                              <1> 	; 11/03/2015
  2050                              <1> 	;sub	cx, cx
  2051                              <1> 	;mov	dx, 184Fh ; dl= 79 (column), dh = 24 (row)
  2052                              <1> 	;
  2053                              <1> 	; 02/02/2022 (simplied scroll up)
  2054                              <1> 	; ((retro unix 8086 v1 'scroll_up' in 'u9.s'))
  2055                              <1> 	;
  2056 000012EE B001                <1> 	mov	al, 1		; scroll 1 line up
  2057                              <1> 		; ah = attribute
  2058 000012F0 E935010000          <1> 	jmp	scroll_up
  2059                              <1> ;u4:
  2060                              <1> 	;;int	10h		; video-call return
  2061                              <1> 				; scroll up the screen
  2062                              <1> 				; tty return
  2063                              <1> ;u5:
  2064                              <1> 	;retn			; return to the caller
  2065                              <1> 
  2066                              <1> u6:				; set-cursor-inc
  2067 000012F5 FEC6                <1> 	inc	dh		; next row
  2068                              <1> 				; set cursor
  2069                              <1> ;u7:					
  2070                              <1> 	;;mov	ah, 02h
  2071                              <1> 	;;jmp	short u4 	; establish the new cursor
  2072                              <1> 	;call	set_cpos
  2073                              <1> 	;jmp 	short u5
  2074 000012F7 E9A8000000          <1> 	jmp     set_cpos
  2075                              <1> 
  2076                              <1> 	; check for control characters
  2077                              <1> u8:
  2078 000012FC 7434                <1> 	je	short u9
  2079 000012FE 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  2080 00001300 74C6                <1> 	je	short u10
  2081 00001302 3C07                <1> 	cmp	al, 07h 	; is it a bell
  2082 00001304 7430                <1> 	je	short u11
  2083 00001306 3C08                <1> 	cmp	al, 08h		; is it a backspace
  2084                              <1> 	;jne	short u0
  2085 00001308 7420                <1> 	je	short bs	; 12/12/2013
  2086                              <1> 	; 12/12/2013 (tab stop)
  2087 0000130A 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  2088 0000130C 75A7                <1> 	jne	short u0
  2089 0000130E 88D0                <1> 	mov	al, dl
  2090 00001310 6698                <1> 	cbw
  2091 00001312 B108                <1> 	mov	cl, 8
  2092 00001314 F6F1                <1> 	div	cl
  2093 00001316 28E1                <1> 	sub	cl, ah
  2094                              <1> ts:
  2095                              <1> 	; 02/09/2014
  2096                              <1> 	; 01/09/2014
  2097 00001318 B020                <1> 	mov	al, 20h
  2098                              <1> tsloop:
  2099                              <1> 	;push	cx
  2100                              <1> 	;push	ax
  2101                              <1> 	; 02/02/2022
  2102 0000131A 51                  <1> 	push	ecx
  2103 0000131B 50                  <1> 	push	eax
  2104 0000131C 30FF                <1> 	xor 	bh, bh
  2105                              <1> 	;mov	bl, [active_page]
  2106 0000131E E881FFFFFF          <1> 	call	m3
  2107                              <1> 	; 02/02/2022
  2108 00001323 58                  <1> 	pop	eax
  2109 00001324 59                  <1>  	pop	ecx
  2110                              <1> 	;pop	ax  ; ah = attribute/color
  2111                              <1> 	;pop	cx
  2112 00001325 FEC9                <1> 	dec	cl
  2113 00001327 75F1                <1> 	jnz	short tsloop
  2114 00001329 C3                  <1> 	retn
  2115                              <1> bs:	
  2116                              <1> 	; back space found
  2117 0000132A 08D2                <1> 	or	dl, dl 		; is it already at start of line
  2118                              <1> 	;je	short u7 	; set_cursor
  2119 0000132C 7476                <1> 	jz	short set_cpos
  2120                              <1> 	;dec	dx     		; no -- just move it back
  2121                              <1> 	; 02/02/2022
  2122 0000132E FECA                <1> 	dec	dl
  2123                              <1> 	;jmp	short u7
  2124 00001330 EB72                <1> 	jmp	short set_cpos
  2125                              <1> 
  2126                              <1> 	; carriage return found
  2127                              <1> u9:
  2128 00001332 B200                <1> 	mov	dl, 0 		; move to first column
  2129                              <1> 	;jmp	short u7
  2130 00001334 EB6E                <1> 	jmp	short set_cpos
  2131                              <1> 
  2132                              <1> 	; line feed found
  2133                              <1> ;u10:
  2134                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  2135                              <1> ;	jne	short u6 	; no, just set the cursor
  2136                              <1> ;       jmp     u1              ; yes, scroll the screen
  2137                              <1> 
  2138                              <1> beeper: 
  2139                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2140                              <1> 	; 18/01/2014
  2141                              <1> 	; 03/12/2013
  2142                              <1> 	; bell found
  2143                              <1> u11:
  2144 00001336 FB                  <1> 	sti
  2145 00001337 3A1D[36670000]      <1> 	cmp	bl, [active_page]
  2146 0000133D 7551                <1> 	jne	short u12	; Do not sound the beep 
  2147                              <1> 				; if it is not written on the active page
  2148 0000133F 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  2149 00001343 B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  2150                              <1> 	;call	beep		; sound the pod bell
  2151                              <1> 	;jmp	short u5 	; tty_return
  2152                              <1> 	;retn
  2153                              <1> 	
  2154                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  2155                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  2156                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  2157                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  2158                              <1> 
  2159                              <1> beep:
  2160                              <1> 	; 07/02/2015
  2161                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2162                              <1> 	; 18/01/2014
  2163                              <1> 	; 03/12/2013
  2164                              <1> 	;
  2165                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  2166                              <1> 	;
  2167                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  2168                              <1> 	;
  2169                              <1> 	; ENTRY:
  2170                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  2171                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  2172                              <1> 	; EXIT:			:
  2173                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  2174                              <1> 
  2175 00001345 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  2176 00001346 FA                  <1> 	cli			; block interrupts during update
  2177 00001347 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  2178 00001349 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  2179 0000134B EB00                <1> 	jmp	$+2		; I/O delay
  2180 0000134D 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  2181 0000134F E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  2182 00001351 EB00                <1> 	jmp	$+2		; I/O delay
  2183 00001353 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  2184 00001355 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  2185 00001357 E461                <1> 	in	al, PORT_B	; get current setting of port
  2186 00001359 88C4                <1> 	mov	ah, al		; save that setting
  2187 0000135B 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  2188 0000135D E661                <1> 	out	PORT_B, al	; and restore interrupt status
  2189                              <1> 	;popf	; 18/01/2014
  2190 0000135F FB                  <1> 	sti
  2191                              <1> g7:				; 1/64 second per count (bl)
  2192 00001360 B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  2193 00001365 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  2194 0000136A FECB                <1> 	dec	bl		; (bl) length count expired?
  2195 0000136C 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  2196                              <1> 	;
  2197                              <1> 	;pushf			; save interrupt status
  2198 0000136E FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  2199 0000136F E461                <1> 	in	al, PORT_B	; get current port value
  2200                              <1>         ;or	al, not (GATE2+SPK2) ; isolate current speaker bits in case
  2201 00001371 0CFC                <1>         or      al, ~(GATE2+SPK2)
  2202 00001373 20C4                <1>         and	ah, al		; someone turned them off during beep
  2203 00001375 88E0                <1> 	mov	al, ah		; recover value of port
  2204                              <1>         ;or	al, not (GATE2+SPK2) ; force speaker data off
  2205 00001377 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  2206 00001379 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  2207                              <1> 	;popf			; restore interrupt flag state
  2208 0000137B FB                  <1> 	sti
  2209 0000137C B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  2210 00001381 E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  2211                              <1> 	;pushf			; save interrupt status
  2212 00001386 FA                  <1> 	cli			; block interrupts during update
  2213 00001387 E461                <1> 	in	al, PORT_B	; get current port value in case	
  2214 00001389 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  2215 0000138B 08E0                <1> 	or	al, ah		; recover value of port_b
  2216 0000138D E661                <1> 	out	PORT_B, al	; restore speaker status
  2217 0000138F 9D                  <1> 	popf			; restore interrupt flag state
  2218                              <1> u12:	
  2219 00001390 C3                  <1> 	retn
  2220                              <1> 
  2221                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  2222                              <1> 
  2223                              <1> WAITF:
  2224                              <1> waitf:
  2225                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2226                              <1> 	; 03/12/2013
  2227                              <1> 	;
  2228                              <1> ;	push	ax		; save work register (ah)	
  2229                              <1> ;waitf1:
  2230                              <1> 				; use timer 1 output bits
  2231                              <1> ;	in	al, PORT_B	; read current counter output status
  2232                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  2233                              <1> ;	cmp	al, ah		; did it just change
  2234                              <1> ;	je	short waitf1	; wait for a change in output line
  2235                              <1> ;	;
  2236                              <1> ;	mov	ah, al		; save new lflag state
  2237                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  2238                              <1> ;	;
  2239                              <1> ;	pop	ax		; restore (ah)
  2240                              <1> ;	retn			; return (cx)=0
  2241                              <1> 
  2242                              <1> ; 02/02/2022
  2243                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  2244                              <1> ; 17/12/2014 (dsectrm2.s)
  2245                              <1> ; WAITF
  2246                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  2247                              <1> ;
  2248                              <1> ;---WAITF-----------------------------------------------------------------------
  2249                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  2250                              <1> ; ENTRY:
  2251                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  2252                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  2253                              <1> ; EXIT:
  2254                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  2255                              <1> ;	(CX) = 0	
  2256                              <1> ;-------------------------------------------------------------------------------
  2257                              <1> 
  2258                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  2259                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  2260                              <1> 
  2261                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  2262 00001391 50                  <1> 	push	eax ; 02/02/2022	; SAVE WORK REGISTER (AH)
  2263                              <1> 	;push	ax
  2264                              <1> 	; 16/12/2014
  2265                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  2266 00001392 D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  2267                              <1> ;17/12/2014	
  2268                              <1> ;WAITF1:
  2269                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  2270                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  2271                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  2272                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  2273                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  2274                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  2275                              <1> 	;
  2276                              <1> 	; 17/12/2014
  2277                              <1> 	;
  2278                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  2279                              <1> 	;
  2280                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  2281                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  2282                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  2283                              <1> WR_STATE_0:
  2284 00001394 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  2285 00001396 A810                <1> 	TEST	AL,010H
  2286 00001398 74FA                <1> 	JZ	SHORT WR_STATE_0
  2287                              <1> WR_STATE_1:
  2288 0000139A E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  2289 0000139C A810                <1> 	TEST	AL,010H
  2290 0000139E 75FA                <1> 	JNZ	SHORT WR_STATE_1
  2291 000013A0 E2F2                <1>         LOOP    WR_STATE_0
  2292                              <1> 	;
  2293                              <1> 	;pop	ax
  2294 000013A2 58                  <1> 	pop	eax ; 02/02/2022	; RESTORE (AH)
  2295 000013A3 C3                  <1> 	RETn				; (CX) = 0
  2296                              <1> 
  2297                              <1> set_cpos:
  2298                              <1> 	; 14/06/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.2)
  2299                              <1> 	; 27/02/2022
  2300                              <1> 	; 23/02/2022
  2301                              <1> 	; 02/02/2022
  2302                              <1> 	; 27/06/2015
  2303                              <1> 	; 01/09/2014
  2304                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  2305                              <1> 	;
  2306                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  2307                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  2308                              <1> 	;
  2309                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2310                              <1> 	;
  2311                              <1> 	; SET_CPOS
  2312                              <1> 	;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  2313                              <1> 	;	NEW X-Y VALUES PASSED
  2314                              <1> 	; INPUT
  2315                              <1> 	;	DX - ROW,COLUMN OF NEW CURSOR
  2316                              <1> 	;	BH - DISPLAY PAGE OF CURSOR
  2317                              <1> 	; OUTPUT
  2318                              <1> 	;	CURSOR IS SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  2319                              <1> 	;
  2320 000013A4 0FB6C3              <1>         movzx   eax, bl	; BL = video page number ; 27/06/2015 (movzx)
  2321 000013A7 D0E0                <1>         shl     al, 1   ; word offset
  2322 000013A9 BE[26670000]        <1> 	mov	esi, cursor_posn
  2323 000013AE 01C6                <1>         add     esi, eax
  2324 000013B0 668916              <1> 	mov	[esi], dx ; save the pointer
  2325 000013B3 381D[36670000]      <1> 	cmp	[active_page], bl
  2326 000013B9 7531                <1> 	jne	short m17
  2327                              <1> 
  2328                              <1> 	; 14/06/2022
  2329                              <1> 	;cli	; 27/02/2022
  2330                              <1> 
  2331                              <1> 	;call	m18	; CURSOR SET
  2332                              <1> ;m17:			; SET_CPOS_RETURN
  2333                              <1> 	; 01/09/2014
  2334                              <1> ;	retn
  2335                              <1> 		; DX = row/column
  2336                              <1> m18:
  2337 000013BB E832000000          <1> 	call	position ; determine location in regen buffer	
  2338                              <1> 	;mov	cx, [CRT_START]
  2339                              <1> 	; 23/02/2022
  2340 000013C0 0FB70D[24670000]    <1> 	movzx	ecx, word [CRT_START]
  2341 000013C7 01C1                <1> 	add	ecx, eax
  2342                              <1> 	;add	cx, ax  ; add char position in regen buffer
  2343                              <1> 			; to the start address (offset) for this page
  2344                              <1> 	;shr	cx, 1	; divide by 2 for char only count
  2345                              <1> 	; 23/02/2022
  2346 000013C9 D1E9                <1> 	shr	ecx, 1
  2347 000013CB B40E                <1> 	mov	ah, 14	; register number for cursor
  2348                              <1> 	
  2349                              <1> 	; 14/06/2022
  2350                              <1> 	;call	m16	; output value to the 6845
  2351                              <1> 	;sti	; 27/02/2022
  2352                              <1> 	;retn
  2353                              <1> 
  2354                              <1> 	; 14/06/2022
  2355                              <1> 	; 27/02/2022
  2356                              <1> 	; 02/02/2022
  2357                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  2358                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  2359                              <1> m16:
  2360                              <1> 	; 14/06/2022
  2361 000013CD FA                  <1> 	cli	; 27/02/2022
  2362                              <1> 	;mov	dx, [addr_6845] ; address register
  2363 000013CE 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  2364 000013D2 88E0                <1> 	mov	al, ah	; get value
  2365 000013D4 EE                  <1> 	out	dx, al	; register set
  2366                              <1> 	;inc	dx	; data register
  2367                              <1> 	; 02/02/2022
  2368 000013D5 FEC2                <1> 	inc	dl
  2369 000013D7 EB00                <1> 	jmp	$+2	; i/o delay
  2370 000013D9 88E8                <1> 	mov	al, ch	; data
  2371 000013DB EE                  <1> 	out	dx, al	
  2372                              <1> 	;dec	dx
  2373                              <1> 	; 02/02/2022	
  2374 000013DC FECA                <1> 	dec	dl
  2375 000013DE 88E0                <1> 	mov	al, ah
  2376 000013E0 FEC0                <1> 	inc	al	; point to other data register
  2377 000013E2 EE                  <1> 	out	dx, al	; set for second register
  2378                              <1> 	;inc	dx
  2379                              <1> 	; 02/02/2022
  2380 000013E3 FEC2                <1> 	inc	dl
  2381 000013E5 EB00                <1> 	jmp	$+2	; i/o delay
  2382 000013E7 88C8                <1> 	mov	al, cl	; second data value
  2383 000013E9 EE                  <1> 	out	dx, al
  2384                              <1> 	; 14/06/2022
  2385 000013EA FB                  <1> 	sti	; 27/02/2022
  2386                              <1> ;m17:
  2387 000013EB C3                  <1> 	retn
  2388                              <1> m17:
  2389                              <1> 	; 14/06/2022
  2390                              <1> 	; ('write_tty' must not return to 'putc' with cf)
  2391 000013EC F8                  <1> 	clc
  2392 000013ED C3                  <1> 	retn
  2393                              <1> 
  2394                              <1> set_ctype:
  2395                              <1> 	; 07/02/2022
  2396                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  2397                              <1> 	;
  2398                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2399                              <1> 
  2400                              <1> ;	CH) = BITS 4-0 = START LINE FOR CURSOR
  2401                              <1> ;       ** HARDWARE WILL ALWAYS CAUSE BLINK
  2402                              <1> ;       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  2403                              <1> ;          OR NO CURSOR AT ALL
  2404                              <1> ;	(CL) = BITS 4-0 = END LINE FOR CURSOR
  2405                              <1> 
  2406                              <1> ;------------------------------------------------
  2407                              <1> ; SET_CTYPE
  2408                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  2409                              <1> ; INPUT
  2410                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  2411                              <1> ; OUTPUT	
  2412                              <1> ;	NONE
  2413                              <1> ;------------------------------------------------
  2414                              <1> 
  2415 000013EE B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  2416                              <1> 	;mov	[CURSOR_MODE], cx ; save in data area
  2417                              <1> 	;call	m16	; output cx register
  2418                              <1> 	;retn
  2419                              <1> 	; 07/02/2022
  2420 000013F0 EBDB                <1> 	jmp	short m16
  2421                              <1> 
  2422                              <1> position:
  2423                              <1> 	; 23/02/2022
  2424                              <1> 	; 02/02/2022
  2425                              <1> 	; 27/06/2015
  2426                              <1> 	; 02/09/2014
  2427                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2428                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  2429                              <1> 	;
  2430                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2431                              <1> 	;
  2432                              <1> 	; POSITION
  2433                              <1> 	;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  2434                              <1> 	;	OF A CHARACTER IN THE ALPHA MODE
  2435                              <1> 	; INPUT
  2436                              <1> 	;	AX = ROW, COLUMN POSITION
  2437                              <1> 	; OUTPUT
  2438                              <1> 	;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  2439                              <1> 
  2440                              <1> 		; DX = ROW, COLUMN POSITION
  2441                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
  2442 000013F2 31C0                <1> 	xor	eax, eax ; 02/09/2014
  2443 000013F4 B050                <1> 	mov	al, 80	; determine bytes to row	
  2444 000013F6 F6E6                <1> 	mul	dh	; row value
  2445                              <1> 	;xor	dh, dh	; 0
  2446                              <1> 	;add	ax, dx	; add column value to the result
  2447                              <1> 	; 23/02/2022
  2448 000013F8 00D0                <1> 	add	al, dl
  2449 000013FA 80D400              <1> 	adc	ah, 0	
  2450                              <1> 	;shl	ax, 1	; * 2 for attribute bytes
  2451                              <1> 	; 02/02/2022
  2452 000013FD D1E0                <1> 	shl	eax, 1
  2453                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  2454 000013FF C3                  <1> 	retn
  2455                              <1> 
  2456                              <1> find_position:
  2457                              <1> 	; 02/02/2022
  2458                              <1> 	; 27/06/2015
  2459                              <1> 	; 07/09/2014
  2460                              <1> 	; 02/09/2014
  2461                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2462                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2463 00001400 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
  2464 00001403 89CE                <1> 	mov	esi, ecx
  2465                              <1> 	;shl	si, 1
  2466                              <1> 	; 02/02/2022
  2467 00001405 D1E6                <1> 	shl	esi, 1
  2468 00001407 668B96[26670000]    <1> 	mov	dx, [esi+cursor_posn]
  2469 0000140E 7409                <1> 	jz	short p21
  2470                              <1> 	;xor	si, si
  2471                              <1> 	; 02/02/2022
  2472 00001410 31F6                <1> 	xor	esi, esi
  2473                              <1> p20:
  2474                              <1> 	;add	si, [CRT_LEN]
  2475 00001412 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
  2476 00001417 E2F9                <1> 	loop	p20
  2477                              <1> p21:
  2478 00001419 6621D2              <1> 	and	dx, dx
  2479 0000141C 7407                <1> 	jz	short p22
  2480 0000141E E8CFFFFFFF          <1> 	call 	position ; determine location in regen in page
  2481 00001423 01C6                <1> 	add	esi, eax ; add location to start of regen page
  2482                              <1> p22:	
  2483                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  2484                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  2485                              <1> 	;add	dx, 6	; point at status port
  2486 00001425 66BADA03            <1> 	mov	dx, 03DAh ; status port
  2487                              <1> 	; cx = 0
  2488 00001429 C3                  <1> 	retn
  2489                              <1> 
  2490                              <1> scroll_up:
  2491                              <1> 	; 02/02/2022 (simplified scroll up)
  2492                              <1> 	;	((retro unix 8086 v1 'scroll_up' in 'u9.s'))
  2493                              <1> 	; 16/01/2016
  2494                              <1> 	; 07/09/2014
  2495                              <1> 	; 02/09/2014
  2496                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  2497                              <1> 	; 04/04/2014
  2498                              <1> 	; 04/12/2013
  2499                              <1> 	;
  2500                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2501                              <1> 	;
  2502                              <1> 	; SCROLL UP
  2503                              <1> 	;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  2504                              <1> 	;	ON THE SCREEN
  2505                              <1> 	; INPUT
  2506                              <1> 	;	(AH) = CURRENT CRT MODE
  2507                              <1> 	;	(AL) = NUMBER OF ROWS TO SCROLL
  2508                              <1> 	;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  2509                              <1> 	;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  2510                              <1> 	;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  2511                              <1> 	;	(DS) = DATA SEGMENT
  2512                              <1> 	;	(ES) = REGEN BUFFER SEGMENT
  2513                              <1> 	; OUTPUT
  2514                              <1> 	;	NONE -- THE REGEN BUFFER IS MODIFIED
  2515                              <1> 	;
  2516                              <1> 	;	bh = 0  (02/09/2014)
  2517                              <1> 	;
  2518                              <1> 	; ((ah = 3))
  2519                              <1> 	; cl = left upper column
  2520                              <1> 	; ch = left upper row
  2521                              <1> 	; dl = right lower column
  2522                              <1> 	; dh = right lower row
  2523                              <1> 	;
  2524                              <1> 	; al = line count 
  2525                              <1> 	; ah = attribute to be used on blanked line
  2526                              <1> 	; bl = video page number (0 to 7)
  2527                              <1> 	; 
  2528                              <1> 
  2529                              <1> 	; 02/02/2022 'scroll_up' code
  2530                              <1> 	; ------------------------------------------------------
  2531                              <1> 	; (ref: Retro UNIX 8086 v1 'scroll_up' code in 'u9.asm')
  2532                              <1> 
  2533                              <1> 	; INPUT:
  2534                              <1> 	;		
  2535                              <1> 	; al = line count 
  2536                              <1> 	;	(0 or 1) .. 0 -> clear video page
  2537                              <1> 	; ah = attribute to be used on blanked line
  2538                              <1> 	; bl = video page number (0 to 7)
  2539                              <1> 
  2540                              <1> 	;cli
  2541 0000142A 31C9                <1> 	xor	ecx, ecx
  2542 0000142C 88C1                <1> 	mov	cl, al ; line count (cl)
  2543 0000142E BE00800B00          <1> 	mov	esi, 0B8000h
  2544 00001433 3A1D[36670000]      <1> 	cmp	bl, [active_page]
  2545 00001439 7411                <1> 	je	short n1
  2546 0000143B 20DB                <1> 	and	bl, bl
  2547 0000143D 7422                <1> 	jz	short n3
  2548 0000143F 88DD                <1> 	mov	ch, bl ; video page number
  2549                              <1> n0:
  2550 00001441 6681C6A00F          <1> 	add	si, 25*80*2
  2551 00001446 FECD                <1> 	dec	ch
  2552 00001448 75F7                <1> 	jnz	short n0
  2553 0000144A EB15                <1> 	jmp	short n3
  2554                              <1> n1:
  2555 0000144C 660335[24670000]    <1> 	add	si, [CRT_START]
  2556                              <1> 	;
  2557 00001453 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here
  2558                              <1> n2:			 ; wait_display_enable
  2559 00001457 EC                  <1> 	in	al, dx	 ; get port
  2560 00001458 A808                <1> 	test	al, RVRT ; wait for vertical retrace
  2561 0000145A 74FB                <1> 	jz	short n2 ; wait_display_enable
  2562 0000145C B025                <1> 	mov	al, 25h
  2563 0000145E B2D8                <1> 	mov	dl, 0D8h ; address control port
  2564 00001460 EE                  <1> 	out	dx, al	 ; turn off video during vertical retrace
  2565                              <1> n3:
  2566                              <1> 	; cl = line count
  2567                              <1> 	; ah = attribute/color
  2568 00001461 89F7                <1> 	mov	edi, esi
  2569 00001463 20C9                <1> 	and	cl, cl
  2570 00001465 741F                <1> 	jz	short n6
  2571 00001467 6681C6A000          <1> 	add	si, 80*2 ; + 160 bytes
  2572 0000146C 66B98007            <1> 	mov	cx, 24*80 ; 24 rows/lines
  2573 00001470 F366A5              <1> 	rep	movsw
  2574 00001473 B150                <1> 	mov	cl, 80 ; 1 row (will be cleared)
  2575                              <1> n4:
  2576                              <1> 	; ah = character attribute/cocor
  2577 00001475 B020                <1> 	mov	al, 20h ; fill with blanks
  2578 00001477 F366AB              <1> 	rep	stosw
  2579                              <1> 
  2580 0000147A 3A1D[36670000]      <1> 	cmp	bl, [active_page]
  2581 00001480 7503                <1> 	jne	short n5
  2582                              <1> 
  2583                              <1> 	;mov	al, [crt_mode_set] ; get the value of mode set
  2584 00001482 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3
  2585                              <1> 	;mov	dx, 03D8h ; always set color card port
  2586 00001484 EE                  <1> 	out	dx, al
  2587                              <1> n5:
  2588 00001485 C3                  <1> 	retn
  2589                              <1> n6:
  2590                              <1> 	; clear video page
  2591 00001486 66B9D007            <1> 	mov	cx, 25*80 ; 25 rows/lines
  2592 0000148A EBE9                <1> 	jmp	short n4
  2593                              <1> 
  2594                              <1> 	; 23/02/2022
  2595                              <1> %if 0	; 16/01/2016 'scroll_up' code
  2596                              <1> 	; ------------------------------------------------------
  2597                              <1> 
  2598                              <1> 	; Test	Line Count
  2599                              <1> 	or	al, al
  2600                              <1> 	jz	short al_set
  2601                              <1> 	mov	bh, dh	; subtract lower row from upper row
  2602                              <1> 	sub	bh, ch
  2603                              <1> 	inc	bh	; adjust difference by 1
  2604                              <1> 	cmp	bh, al 	; line count = amount of rows in window?
  2605                              <1> 	jne	short al_set ; if not the we're all set
  2606                              <1> 	xor	al, al	; otherwise set al to zero
  2607                              <1> al_set:
  2608                              <1> 	xor	bh, bh	; 0
  2609                              <1> 	;push	ax
  2610                              <1> 	push	eax ; 23/02/2022
  2611                              <1> 	;mov 	esi, [crt_base]
  2612                              <1>         mov     esi, 0B8000h  
  2613                              <1>         cmp     bl, [active_page]
  2614                              <1> 	jne	short n0
  2615                              <1> 	;
  2616                              <1>         mov     ax, [CRT_START]
  2617                              <1>         add     si, ax
  2618                              <1>         jmp     short n1
  2619                              <1> n0:
  2620                              <1>         and     bl, bl
  2621                              <1> 	jz	short n1
  2622                              <1> 	mov	al, bl
  2623                              <1> n0x:
  2624                              <1>         ;add    si, [CRT_LEN]
  2625                              <1>         ;add    esi, 80*25*2 
  2626                              <1>         add     si, 80*25*2
  2627                              <1>         dec	al
  2628                              <1> 	jnz	short n0x
  2629                              <1> n1:	
  2630                              <1>         ; Scroll position
  2631                              <1> 	;push	dx ; 23/02/2022
  2632                              <1> 	mov	dx, cx	; now, upper left position in DX
  2633                              <1> 	call	position
  2634                              <1> 	add	esi, eax
  2635                              <1> 	mov	edi, esi
  2636                              <1> 	;pop	dx	; lower right position in DX
  2637                              <1> 	sub	dx, cx
  2638                              <1> 	inc	dh	; dh = #rows 
  2639                              <1> 	inc	dl	; dl = #cols in block
  2640                              <1> 	;pop	ax	; al = line count, ah = attribute
  2641                              <1> 	pop	eax ; 23/02/2022
  2642                              <1> 	xor	ecx, ecx
  2643                              <1> 	mov	cx, ax
  2644                              <1> 	;mov	ah, [CRT_COLS]
  2645                              <1> 	mov	ah, 80
  2646                              <1> 	mul	ah	; determine offset to from address
  2647                              <1> 	add	ax, ax  ; *2 for attribute byte
  2648                              <1> 	;
  2649                              <1> 	;push	ax	; offset 
  2650                              <1> 	;push	dx
  2651                              <1> 	; 23/02/2022
  2652                              <1> 	push	eax
  2653                              <1> 	push	edx
  2654                              <1> 	;
  2655                              <1> 	; 04/04/2014
  2656                              <1> 	mov	dx, 3DAh ; guaranteed to be color card here
  2657                              <1> n8:                      ; wait_display_enable
  2658                              <1>         in      al, dx   ; get port
  2659                              <1> 	test	al, RVRT ; wait for vertical retrace
  2660                              <1> 	jz	short n8 ; wait_display_enable
  2661                              <1> 	mov	al, 25h
  2662                              <1> 	mov	dl, 0D8h ; address control port
  2663                              <1> 	out	dx, al	; turn off video during vertical retrace
  2664                              <1> 	;pop	dx	; #rows, #cols
  2665                              <1>        	;pop	ax	; offset
  2666                              <1> 	; 23/02/2022
  2667                              <1> 	pop	edx
  2668                              <1> 	pop	eax
  2669                              <1> 	xchg	ax, cx	; 
  2670                              <1> 	; ecx = offset, al = line count, ah = attribute
  2671                              <1> ;n9:
  2672                              <1> 	or	al, al
  2673                              <1>         jz      short n3 
  2674                              <1>         add     esi, ecx ; from address for scroll
  2675                              <1> 	mov	bh, dh  ; #rows in block
  2676                              <1> 	sub	bh, al	; #rows to be moved
  2677                              <1> n2:
  2678                              <1> 	; Move rows
  2679                              <1> 	mov	cl, dl	; get # of cols to move
  2680                              <1> 	push	esi
  2681                              <1> 	push	edi	; save start address
  2682                              <1> n10:
  2683                              <1> 	movsw		; move that line on screen
  2684                              <1> 	dec	cl
  2685                              <1>         jnz     short n10
  2686                              <1> 	pop	edi
  2687                              <1> 	pop	esi	; recover addresses
  2688                              <1>         ;mov    cl, [CRT_COLS] 
  2689                              <1> 	;add	cl, cl
  2690                              <1>         ;mov    ecx, 80*2
  2691                              <1>         mov     cx, 80*2
  2692                              <1>         add     esi, ecx  ; next line
  2693                              <1>         add     edi, ecx
  2694                              <1> 	dec	bh	 ; count of lines to move
  2695                              <1> 	jnz	short n2 ; row loop
  2696                              <1> 	; bh = 0
  2697                              <1> 	mov	dh, al	 ; #rows	
  2698                              <1> n3:
  2699                              <1> 	; attribute in ah
  2700                              <1> 	mov	al, ' '	 ; fill with blanks
  2701                              <1> n3x:
  2702                              <1> 	; Clear rows
  2703                              <1>                 ; dh =  #rows
  2704                              <1>         mov	cl, dl	; get # of cols to clear
  2705                              <1>         push    edi     ; save address
  2706                              <1> n11:
  2707                              <1>         stosw           ; store fill character
  2708                              <1> 	dec	cl
  2709                              <1>         jnz     short n11
  2710                              <1>         pop     edi     ; recover address
  2711                              <1> 	;mov	cl, [CRT_COLS]
  2712                              <1> 	;add	cl, cl
  2713                              <1>         ;mov    ecx, 80*2
  2714                              <1>         mov	cl, 80*2
  2715                              <1>         add     edi, ecx
  2716                              <1> 	dec	dh
  2717                              <1> 	jnz	short n3x ; 16/01/2016
  2718                              <1> 	;
  2719                              <1> 	cmp	bl, [active_page]
  2720                              <1> 	jne	short n6
  2721                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  2722                              <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3
  2723                              <1> 	mov	dx, 03D8h ; always set color card port
  2724                              <1> 	out	dx, al
  2725                              <1> n6:
  2726                              <1> 	retn
  2727                              <1> 
  2728                              <1> %endif
  2729                              <1> 
  2730                              <1> write_c_current:
  2731                              <1> 	; 02/02/2022
  2732                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2733                              <1> 	; 18/01/2014
  2734                              <1> 	; 04/12/2013
  2735                              <1> 	;
  2736                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2737                              <1> 	;
  2738                              <1> 	; WRITE_C_CURRENT
  2739                              <1> 	;	THIS ROUTINE WRITES THE CHARACTER AT
  2740                              <1> 	;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
  2741                              <1> 	; INPUT	
  2742                              <1> 	;	(AH) = CURRENT CRT MODE
  2743                              <1> 	;	(BH) = DISPLAY PAGE
  2744                              <1> 	;	(CX) = COUNT OF CHARACTERS TO WRITE
  2745                              <1> 	;	(AL) = CHAR TO WRITE
  2746                              <1> 	;	(DS) = DATA SEGMENT
  2747                              <1> 	;	(ES) = REGEN SEGMENT
  2748                              <1> 	; OUTPUT
  2749                              <1> 	;	DISPLAY REGEN BUFFER UPDATED
  2750                              <1> 
  2751 0000148C FA                  <1> 	cli		
  2752                              <1> 	; bl = video page
  2753                              <1> 	; al = character
  2754                              <1> 	; ah = color/attribute
  2755                              <1> 	;push	dx
  2756                              <1> 	;push	ax	; save character & attribute/color
  2757                              <1> 	; 02/02/2022
  2758 0000148D 52                  <1> 	push	edx
  2759 0000148E 50                  <1> 	push	eax
  2760 0000148F E86CFFFFFF          <1> 	call 	find_position  ; get regen location and port address
  2761                              <1> 	; esi = regen location
  2762                              <1> 	; dx = status port
  2763                              <1> 	;
  2764                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  2765                              <1> 	;
  2766                              <1> p41:			; wait for horizontal retrace is low or vertical
  2767 00001494 FB                  <1> 	sti		; enable interrupts first
  2768 00001495 3A1D[36670000]      <1>         cmp     bl, [active_page]
  2769 0000149B 7510                <1> 	jne	short p44 
  2770 0000149D FA                  <1> 	cli 		; block interrupts for single loop
  2771 0000149E EC                  <1> 	in	al, dx	; get status from the adapter
  2772 0000149F A808                <1> 	test	al, RVRT ; check for vertical retrace first
  2773 000014A1 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  2774 000014A3 A801                <1> 	test	al, RHRZ  ; is horizontal retrace low
  2775 000014A5 75ED                <1> 	jnz	short p41 ; wait until it is
  2776                              <1> p42:			; wait for either retrace high
  2777 000014A7 EC                  <1> 	in	al, dx	; get status again
  2778 000014A8 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  2779 000014AA 74FB                <1> 	jz	short p42 ; wait until either retrace active
  2780                              <1> p43:	
  2781 000014AC FB                  <1> 	sti
  2782                              <1> p44:
  2783                              <1> 	;pop	ax	; restore the character (al) & attribute (ah)
  2784                              <1> 	; 02/02/2022
  2785 000014AD 58                  <1> 	pop	eax
  2786 000014AE 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  2787                              <1> 			; Retro UNIX 386 v1 feature only!
  2788 000014B4 668906              <1> 	mov	[esi], ax
  2789                              <1> 	;pop	dx
  2790                              <1> 	; 02/02/2022
  2791 000014B7 5A                  <1> 	pop	edx
  2792 000014B8 C3                  <1> 	retn
  2793                              <1> 
  2794                              <1> %if 0	; 02/02/2022
  2795                              <1> 
  2796                              <1> set_mode:
  2797                              <1> 	; 02/02/2022
  2798                              <1> 	; 16/01/2016
  2799                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  2800                              <1> 	;
  2801                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2802                              <1> 
  2803                              <1> ;------------------------------------------------------
  2804                              <1> ; SET MODE					      :
  2805                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  2806                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  2807                              <1> ; INPUT						      :
  2808                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  2809                              <1> ; OUTPUT					      :
  2810                              <1> ;	NONE					      :
  2811                              <1> ;------------------------------------------------------
  2812                              <1> 
  2813                              <1> 	push	edi ; 16/01/2016
  2814                              <1> 	push	ebx
  2815                              <1> 	push	edx
  2816                              <1> 	push	ecx ; 16/01/2016
  2817                              <1>         push    eax
  2818                              <1> 
  2819                              <1> 	;mov	dx, 03D4h 	; address or color card
  2820                              <1> 	mov	al, 3
  2821                              <1> ;M8:
  2822                              <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  2823                              <1> 	mov	al, 29h
  2824                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
  2825                              <1> 	and	al, 037h	; video off, save high resolution bit	
  2826                              <1> 	;push	dx  		; save port value
  2827                              <1> 	;add	dx, 4		; point to control register
  2828                              <1> 	mov	dx, 3D8h
  2829                              <1> 	out	dx, al		; reset video to off to suppress rolling
  2830                              <1> 	;pop	dx
  2831                              <1> ;M9:
  2832                              <1> 	mov	ebx, video_params ; initialization table
  2833                              <1> 	;mov	ax, [ebx+10]      ; get the cursor mode from the table	
  2834                              <1> 	;xchg 	ah, al
  2835                              <1> 	;mov	[CURSOR_MODE], ax ; save cursor mode
  2836                              <1> 	xor	ah, ah		  ; ah is register number during loop 
  2837                              <1> 	
  2838                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
  2839                              <1> 	; 02/02/2022
  2840                              <1> 	; dx = 3D8h
  2841                              <1> 	xor	ecx, ecx
  2842                              <1> 	mov	cl, 16
  2843                              <1> 	;mov	ecx, 16 ; 16/01/2016
  2844                              <1> M10:			;  initialization loop
  2845                              <1> 	mov	al, ah 	; get 6845 register number
  2846                              <1> 	out	dx, al
  2847                              <1> 	;inc	dx      ; point to data port
  2848                              <1> 	; 02/02/2022
  2849                              <1> 	inc	dl ; 3D9h
  2850                              <1> 	inc	ah	; next register value
  2851                              <1> 	mov	al, [ebx] ; get table value
  2852                              <1> 	out	dx, al	; out to chip
  2853                              <1> 	inc	ebx	; next in table
  2854                              <1> 	;dec	dx	; back to pointer register
  2855                              <1> 	; 02/02/2022
  2856                              <1> 	dec	dl ; 3D8h
  2857                              <1> 	loop	M10	; do the whole table
  2858                              <1> 	
  2859                              <1> ;-----	FILL REGEN AREA WITH BLANK
  2860                              <1> 	;xor	ax, ax  
  2861                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
  2862                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
  2863                              <1> 	;mov	ecx, 8192 ; number of words in color card
  2864                              <1> 	; black background, light gray characeter color, space character
  2865                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
  2866                              <1> ;M13:			  ; clear buffer
  2867                              <1> 	;add	edi, 0B8000h ; [crt_base]
  2868                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  2869                              <1> 
  2870                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
  2871                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
  2872                              <1> 			 ; prepare to output to video enable port
  2873                              <1> 	;;add	dx, 4	 ; point to the mode control gerister
  2874                              <1> 	; 02/02/2022
  2875                              <1> 	;mov	dx, 3D8h
  2876                              <1> 	; 
  2877                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
  2878                              <1> 	mov	al, 29h
  2879                              <1> 	out	dx, al	 ; set video enable port
  2880                              <1> 
  2881                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
  2882                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
  2883                              <1> 	;
  2884                              <1> 	;mov byte [CRT_COLS], 80h ; initialize number of columns count
  2885                              <1> 	;
  2886                              <1> ;-----	SET CURSOR POSITIONS
  2887                              <1> 	;push	edi
  2888                              <1> 	;mov	word [CRT_LEN], 80*25*2
  2889                              <1> 	mov	edi, cursor_posn
  2890                              <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
  2891                              <1> 	xor	eax, eax
  2892                              <1> 	rep 	stosd	; fill with zeroes
  2893                              <1> 	;pop	edi
  2894                              <1> 
  2895                              <1> ;-----	SET UP OVERSCAN REGISTER
  2896                              <1> 	inc	dx	; set overscan port to a default
  2897                              <1> 	mov	al, 30h	; 30H valuye for all modes except 640X200 bw
  2898                              <1> ;M14:
  2899                              <1> 	out	dx, al	; output the correct value to 3D9 port
  2900                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
  2901                              <1> 
  2902                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  2903                              <1> 	;
  2904                              <1> 	pop	eax
  2905                              <1> 	pop	ecx ; 16/01/2016
  2906                              <1> 	pop	edx
  2907                              <1> 	pop	ebx
  2908                              <1> 	pop	edi ; 16/01/2016
  2909                              <1> 	retn
  2910                              <1> 
  2911                              <1> %endif
  2912                              <1> 	
  2913                              <1> tty_sw:
  2914                              <1> 	; 02/02/2022
  2915                              <1> 	; 30/06/2015
  2916                              <1> 	; 27/06/2015 
  2917                              <1> 	; 07/09/2014
  2918                              <1> 	; 02/09/2014 (Retro UNIX 386 v1 - beginning)
  2919                              <1> 	;
  2920                              <1> 	; (Modified registers : EAX)
  2921                              <1> 	;
  2922                              <1>         ;mov     byte [u.quant], 0  ; 04/03/2014
  2923                              <1> 	;
  2924                              <1> ;act_disp_page:
  2925                              <1> 	; 30/06/2015
  2926                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  2927                              <1> 	; 10/12/2013
  2928                              <1> 	; 04/12/2013
  2929                              <1> 	;
  2930                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2931                              <1> 	;
  2932                              <1> 	; ACT_DISP_PAGE
  2933                              <1> 	;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  2934                              <1> 	;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  2935                              <1> 	; INPUT
  2936                              <1> 	;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  2937                              <1> 	; OUTPUT
  2938                              <1> 	;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  2939                              <1> 
  2940                              <1> 	;cli
  2941                              <1> 
  2942 000014B9 53                  <1> 	push	ebx
  2943                              <1> 	;push	cx
  2944                              <1> 	;push	dx
  2945                              <1> 	; 02/02/2022
  2946 000014BA 51                  <1> 	push	ecx
  2947 000014BB 52                  <1> 	push	edx
  2948                              <1> 	;
  2949 000014BC A2[36670000]        <1> 	mov	[active_page], al ; save active page value ; [ptty]
  2950                              <1> 	;;mov	cx, [CRT_LEN] ; get saved length of regen buffer
  2951                              <1> 	;mov	cx, 25*80*2
  2952                              <1> 	; 02/02/2022
  2953 000014C1 B9A00F0000          <1> 	mov	ecx, 25*80*2
  2954                              <1> 	; 27/06/2015
  2955 000014C6 0FB6D8              <1> 	movzx	ebx, al
  2956                              <1> 	; 02/02/2022
  2957 000014C9 89D8                <1> 	mov	eax, ebx
  2958                              <1> 	;
  2959                              <1> 	;cbw	; 07/09/2014 (ah=0)
  2960                              <1> 	;mul 	cx	; display page times regen length
  2961                              <1> 	; 02/02/2022
  2962 000014CB F7E1                <1> 	mul	ecx	
  2963                              <1> 	; 10/12/2013
  2964 000014CD 66A3[24670000]      <1> 	mov	[CRT_START], ax ; save start address for later
  2965                              <1> 	;mov	cx, ax	; start address to cx
  2966                              <1> 	; 02/02/2022
  2967 000014D3 89C1                <1> 	mov	ecx, eax
  2968                              <1> 	;;sar	cx, 1
  2969                              <1> 	;shr	cx, 1	; divide by 2 for 6845 handling
  2970                              <1> 	; 02/02/2022
  2971 000014D5 D1E9                <1> 	shr	ecx, 1
  2972 000014D7 B40C                <1> 	mov	ah, 12	; 6845 register for start address
  2973 000014D9 E8EFFEFFFF          <1> 	call	m16
  2974                              <1> 	;sal	bx, 1
  2975                              <1> 	; 01/09/2014
  2976 000014DE D0E3                <1> 	shl	bl, 1	; * 2 for word offset
  2977 000014E0 81C3[26670000]      <1> 	add	ebx, cursor_posn
  2978 000014E6 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  2979 000014E9 E8CDFEFFFF          <1> 	call	m18
  2980                              <1> 	;
  2981                              <1> 	;pop	dx
  2982                              <1> 	;pop	cx
  2983                              <1> 	; 02/02/2022
  2984 000014EE 5A                  <1> 	pop	edx
  2985 000014EF 59                  <1> 	pop	ecx
  2986 000014F0 5B                  <1> 	pop	ebx
  2987                              <1> 	;
  2988                              <1> 	;sti
  2989                              <1> 	;
  2990 000014F1 C3                  <1> 	retn
  2991                              <1> 
  2992                              <1> ; %include 'vidata.inc' ; VIDEO DATA ; 11/03/2015
  2993                              <1> 
  2994                              <1> ; /// End Of VIDEO FUNCTIONS ///
  1869                                  
  1870                                  setup_rtc_int:
  1871                                  ; source: http://wiki.osdev.org/RTC
  1872 000014F2 FA                      	cli		; disable interrupts
  1873                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  1874                                  	; in order to change this ...
  1875                                  	; frequency = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  1876                                  	; (rate must be above 2 and not over 15)
  1877                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  1878 000014F3 B08A                    	mov	al, 8Ah 
  1879 000014F5 E670                    	out	70h, al ; set index to register A, disable NMI
  1880 000014F7 90                      	nop
  1881 000014F8 E471                    	in	al, 71h ; get initial value of register A
  1882 000014FA 88C4                    	mov 	ah, al
  1883 000014FC 80E4F0                  	and	ah, 0F0h
  1884 000014FF B08A                    	mov	al, 8Ah 
  1885 00001501 E670                    	out	70h, al ; reset index to register A
  1886 00001503 88E0                    	mov	al, ah
  1887 00001505 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  1888 00001507 E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  1889                                  	; enable RTC interrupt
  1890 00001509 B08B                    	mov	al, 8Bh ;
  1891 0000150B E670                    	out	70h, al ; select register B and disable NMI
  1892 0000150D 90                      	nop
  1893 0000150E E471                    	in	al, 71h ; read the current value of register B
  1894 00001510 88C4                    	mov	ah, al  ;
  1895 00001512 B08B                    	mov 	al, 8Bh ;
  1896 00001514 E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  1897 00001516 88E0                    	mov	al, ah  ;
  1898 00001518 0C40                    	or	al, 40h ;
  1899 0000151A E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  1900 0000151C FB                      	sti
  1901 0000151D C3                      	retn
  1902                                  
  1903                                  ; Write memory information
  1904                                  ; Temporary Code
  1905                                  ; 06/11/2014
  1906                                  ; 14/08/2015 
  1907                                  memory_info:	
  1908 0000151E A1[0C670000]            	mov	eax, [memory_size] ; in pages
  1909 00001523 50                      	push	eax
  1910 00001524 C1E00C                  	shl	eax, 12		   ; in bytes
  1911 00001527 BB0A000000              	mov	ebx, 10
  1912 0000152C 89D9                    	mov	ecx, ebx	   ; 10
  1913 0000152E BE[75630000]            	mov	esi, mem_total_b_str	
  1914 00001533 E8AE000000              	call	bintdstr
  1915 00001538 58                      	pop	eax
  1916 00001539 B107                    	mov	cl, 7
  1917 0000153B BE[99630000]            	mov	esi, mem_total_p_str
  1918 00001540 E8A1000000              	call	bintdstr	
  1919                                  	; 14/08/2015
  1920 00001545 E8B9000000              	call	calc_free_mem
  1921                                  	; edx = calculated free pages
  1922                                  	; ecx = 0
  1923 0000154A A1[10670000]            	mov 	eax, [free_pages]
  1924 0000154F 39D0                    	cmp	eax, edx ; calculated free mem value 
  1925                                  		; and initial free mem value are same or not?
  1926 00001551 751D                    	jne 	short pmim ; print mem info with '?' if not
  1927 00001553 52                      	push 	edx ; free memory in pages	
  1928                                  	;mov 	eax, edx
  1929 00001554 C1E00C                  	shl	eax, 12 ; convert page count
  1930                                  			; to byte count
  1931 00001557 B10A                    	mov	cl, 10
  1932 00001559 BE[B9630000]            	mov	esi, free_mem_b_str
  1933 0000155E E883000000              	call	bintdstr
  1934 00001563 58                      	pop	eax
  1935 00001564 B107                    	mov	cl, 7
  1936 00001566 BE[DD630000]            	mov	esi, free_mem_p_str
  1937 0000156B E876000000              	call	bintdstr
  1938                                  pmim:
  1939 00001570 BE[63630000]            	mov	esi, msg_memory_info
  1940                                  pmim_nb:	
  1941 00001575 AC                      	lodsb
  1942 00001576 08C0                    	or	al, al
  1943 00001578 740D                    	jz	short pmim_ok
  1944 0000157A 56                      	push	esi
  1945 0000157B 31DB                    	xor	ebx, ebx ; 0
  1946                                  			; Video page 0 (bl=0)
  1947 0000157D B407                    	mov	ah, 07h ; Black background, 
  1948                                  			; light gray forecolor
  1949 0000157F E816FDFFFF              	call	write_tty
  1950 00001584 5E                      	pop	esi
  1951 00001585 EBEE                    	jmp	short pmim_nb
  1952                                  pmim_ok:
  1953 00001587 C3                      	retn
  1954                                  
  1955                                  ; Convert binary number to hexadecimal string
  1956                                  ; 10/05/2015  
  1957                                  ; dsectpm.s (28/02/2015)
  1958                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  1959                                  ; 01/12/2014
  1960                                  ; 25/11/2014
  1961                                  ;
  1962                                  bytetohex:
  1963                                  	; INPUT ->
  1964                                  	; 	AL = byte (binary number)
  1965                                  	; OUTPUT ->
  1966                                  	;	AX = hexadecimal string
  1967                                  	;
  1968 00001588 53                      	push	ebx
  1969 00001589 31DB                    	xor	ebx, ebx
  1970 0000158B 88C3                    	mov	bl, al
  1971 0000158D C0EB04                  	shr	bl, 4
  1972 00001590 8A9B[D6150000]          	mov	bl, [ebx+hexchrs]
  1973 00001596 86D8                    	xchg	bl, al
  1974 00001598 80E30F                  	and	bl, 0Fh
  1975 0000159B 8AA3[D6150000]          	mov	ah, [ebx+hexchrs]
  1976 000015A1 5B                      	pop	ebx	
  1977 000015A2 C3                      	retn
  1978                                  
  1979                                  wordtohex:
  1980                                  	; INPUT ->
  1981                                  	; 	AX = word (binary number)
  1982                                  	; OUTPUT ->
  1983                                  	;	EAX = hexadecimal string
  1984                                  	;
  1985 000015A3 53                      	push	ebx
  1986 000015A4 31DB                    	xor	ebx, ebx
  1987 000015A6 86E0                    	xchg	ah, al
  1988 000015A8 6650                    	push	ax
  1989 000015AA 88E3                    	mov	bl, ah
  1990 000015AC C0EB04                  	shr	bl, 4
  1991 000015AF 8A83[D6150000]          	mov	al, [ebx+hexchrs]
  1992 000015B5 88E3                    	mov	bl, ah
  1993 000015B7 80E30F                  	and	bl, 0Fh
  1994 000015BA 8AA3[D6150000]          	mov	ah, [ebx+hexchrs]
  1995 000015C0 C1E010                  	shl	eax, 16
  1996 000015C3 6658                    	pop	ax
  1997 000015C5 5B                      	pop	ebx
  1998 000015C6 EBC0                    	jmp	short bytetohex
  1999                                  	;mov	bl, al
  2000                                  	;shr	bl, 4
  2001                                  	;mov	bl, [ebx+hexchrs]
  2002                                  	;xchg	bl, al	 	
  2003                                  	;and	bl, 0Fh
  2004                                  	;mov	ah, [ebx+hexchrs]
  2005                                  	;pop	ebx	
  2006                                  	;retn
  2007                                  
  2008                                  dwordtohex:
  2009                                  	; INPUT ->
  2010                                  	; 	EAX = dword (binary number)
  2011                                  	; OUTPUT ->
  2012                                  	;	EDX:EAX = hexadecimal string
  2013                                  	;
  2014 000015C8 50                      	push	eax
  2015 000015C9 C1E810                  	shr	eax, 16
  2016 000015CC E8D2FFFFFF              	call	wordtohex
  2017 000015D1 89C2                    	mov	edx, eax
  2018 000015D3 58                      	pop	eax
  2019                                  	;call	wordtohex
  2020                                  	;retn
  2021                                  	; 02/01/2022
  2022 000015D4 EBCD                    	jmp	short wordtohex
  2023                                  
  2024                                  ; 10/05/2015
  2025                                  hex_digits:
  2026                                  hexchrs:
  2027 000015D6 303132333435363738-     	db '0123456789ABCDEF'
  2027 000015DF 39414243444546     
  2028                                  
  2029                                  ; Convert binary number to decimal/numeric string
  2030                                  ; 06/11/2014
  2031                                  ; Temporary Code
  2032                                  ;
  2033                                  
  2034                                  bintdstr:
  2035                                  	; EAX = binary number
  2036                                  	; ESI = decimal/numeric string address
  2037                                  	; EBX = divisor (10)
  2038                                  	; ECX = string length (<=10)
  2039 000015E6 01CE                    	add	esi, ecx
  2040                                  btdstr0:
  2041 000015E8 4E                      	dec	esi
  2042 000015E9 31D2                    	xor	edx, edx
  2043 000015EB F7F3                    	div	ebx
  2044 000015ED 80C230                  	add	dl, 30h
  2045 000015F0 8816                    	mov	[esi], dl
  2046 000015F2 FEC9                    	dec	cl
  2047 000015F4 740C                    	jz	short btdstr2 ; 02/01/2022 (short jump)
  2048 000015F6 09C0                    	or	eax, eax
  2049 000015F8 75EE                    	jnz	short btdstr0
  2050                                  btdstr1:
  2051 000015FA 4E                      	dec	esi
  2052 000015FB C60620                          mov     byte [esi], 20h ; blank space
  2053 000015FE FEC9                    	dec	cl
  2054 00001600 75F8                    	jnz	short btdstr1
  2055                                  btdstr2:
  2056 00001602 C3                      	retn
  2057                                  
  2058                                  ; Calculate free memory pages on M.A.T.
  2059                                  ; 06/11/2014
  2060                                  ; Temporary Code
  2061                                  ;
  2062                                  
  2063                                  calc_free_mem:
  2064 00001603 31D2                    	xor	edx, edx
  2065                                  	;xor	ecx, ecx
  2066                                  	;mov	cx, [mat_size] ; in pages
  2067                                  	; 02/01/2022
  2068 00001605 8B0D[20670000]          	mov	ecx, [mat_size] ; in pages
  2069 0000160B C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  2070 0000160E BE00001000              	mov	esi, MEM_ALLOC_TBL
  2071                                  cfm0:
  2072 00001613 AD                      	lodsd
  2073 00001614 51                      	push	ecx
  2074 00001615 B920000000              	mov	ecx, 32
  2075                                  cfm1:
  2076 0000161A D1E8                    	shr	eax, 1
  2077 0000161C 7301                    	jnc	short cfm2
  2078 0000161E 42                      	inc	edx
  2079                                  cfm2:
  2080 0000161F E2F9                    	loop	cfm1
  2081 00001621 59                      	pop	ecx
  2082 00001622 E2EF                    	loop	cfm0
  2083 00001624 C3                      	retn
  2084                                  
  2085                                  %include 'diskio.s'  ; 07/03/2015
  2086                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2087                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2088                              <1> ; ****************************************************************************
  2089                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
  2090                              <1> 
  2091                              <1> ; Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2092                              <1> ; Last Modification: 18/07/2022
  2093                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
  2094                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
  2095                              <1> ;
  2096                              <1> ; ****************************************************************************
  2097                              <1> ; Ref: Retro UNIX 386 v1.1 Kernel (v0.2.1.5) - DISKIO.INC
  2098                              <1> 
  2099                              <1> ; ///////// DISK I/O SYSTEM ///////////////
  2100                              <1> 
  2101                              <1> ; 11/07/2022
  2102                              <1> ;; 06/02/2015
  2103                              <1> ;diskette_io:
  2104                              <1> ;	pushfd
  2105                              <1> ;	push 	cs
  2106                              <1> ;	call 	DISKETTE_IO_1
  2107                              <1> ;	retn
  2108                              <1> 	
  2109                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
  2110                              <1> ;//////////////////////////////////////////////////////
  2111                              <1> 
  2112                              <1> ; 11/07/2022 - (direct call instead of int 13h simulation)
  2113                              <1> ;		Function in AL
  2114                              <1> ;			0 = reset
  2115                              <1> ;			1 = read
  2116                              <1> ;			2 = write
  2117                              <1> ;		Disk drive number in DL
  2118                              <1> ;			0 & 1 = floppy disks	
  2119                              <1> ;			80h .. 83h = hard disks
  2120                              <1> ;		Sector address (LBA) in ECX
  2121                              <1> ;		Buffer address in EBX
  2122                              <1> ;		R/W sector count is (always) 1
  2123                              <1> ;
  2124                              <1> ;		Return:
  2125                              <1> ;			Status in AH (>0 = error code)
  2126                              <1> ;			if CF = 1 -> error code in AH
  2127                              <1> ;			if CF = 0 -> successful
  2128                              <1> ;			AL = undefined
  2129                              <1> ;
  2130                              <1> ;		Modified registers: (only) EAX
  2131                              <1> 
  2132                              <1> ; 10/07/2022
  2133                              <1> ; 08/07/2022 - (diskio code has been simplified/shortened 
  2134                              <1> ;		by removing unused IBM PC-AT disk functions)
  2135                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  2136                              <1> ; 20/02/2015
  2137                              <1> ; 06/02/2015 (unix386.s)
  2138                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
  2139                              <1> ;
  2140                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
  2141                              <1> ;
  2142                              <1> ; ADISK.EQU
  2143                              <1> 
  2144                              <1> ;----- Wait control constants 
  2145                              <1> 
  2146                              <1> ;amount of time to wait while RESET is active.
  2147                              <1> 
  2148                              <1> WAITCPU_RESET_ON   EQU	21		;Reset on must last at least 14us
  2149                              <1> 					;at 250 KBS xfer rate.
  2150                              <1> 					;see INTEL MCS, 1985, pg. 5-456
  2151                              <1> 
  2152                              <1> WAITCPU_FOR_STATUS EQU	100		;allow 30 microseconds for
  2153                              <1> 					;status register to become valid
  2154                              <1> 					;before re-reading.
  2155                              <1> 
  2156                              <1> ;After sending a byte to NEC, status register may remain
  2157                              <1> ;incorrectly set for 24 us.
  2158                              <1> 
  2159                              <1> WAITCPU_RQM_LOW	   EQU	24		;number of loops to check for
  2160                              <1> 					;RQM low.
  2161                              <1> 
  2162                              <1> ; COMMON.MAC
  2163                              <1> ;
  2164                              <1> ;	Timing macros
  2165                              <1> ;
  2166                              <1> 
  2167                              <1> %macro 		SIODELAY 0 		; SHORT IODELAY
  2168                              <1> 		jmp short $+2
  2169                              <1> %endmacro		
  2170                              <1> 
  2171                              <1> %macro		IODELAY  0		; NORMAL IODELAY
  2172                              <1> 		jmp short $+2
  2173                              <1> 		jmp short $+2
  2174                              <1> %endmacro
  2175                              <1> 
  2176                              <1> %macro		NEWIODELAY 0
  2177                              <1> 		out 0EBh,al
  2178                              <1> %endmacro 
  2179                              <1> 
  2180                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  2181                              <1> ;;; WAIT_FOR_MEM
  2182                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
  2183                              <1> ;WAIT_FDU_INT_HI	equ	1
  2184                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
  2185                              <1> ;;; WAIT_FOR_PORT
  2186                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
  2187                              <1> ;WAIT_FDU_SEND_HI	equ	0
  2188                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
  2189                              <1> ;Time to wait while waiting for each byte of NEC results = .5
  2190                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  2191                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
  2192                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
  2193                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
  2194                              <1> ;;; WAIT_REFRESH
  2195                              <1> ;amount of time to wait for head settle, per unit in parameter
  2196                              <1> ;table = 1 ms.
  2197                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
  2198                              <1> 
  2199                              <1> 
  2200                              <1> ; //////////////// DISKETTE I/O ////////////////
  2201                              <1> 
  2202                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
  2203                              <1> 
  2204                              <1> ;----------------------------------------
  2205                              <1> ;	EQUATES USED BY POST AND BIOS	:
  2206                              <1> ;----------------------------------------
  2207                              <1> 
  2208                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  2209                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  2210                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  2211                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
  2212                              <1> 
  2213                              <1> ;----------------------------------------
  2214                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
  2215                              <1> ;-------------------------------------------------------------------------------
  2216                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
  2217                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
  2218                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
  2219                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
  2220                              <1> 
  2221                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
  2222                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
  2223                              <1> ;		EQU	011H		; - RESERVED			      ;C
  2224                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
  2225                              <1> ;		EQU	013H		; - RESERVED			      ;E
  2226                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
  2227                              <1> 
  2228                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
  2229                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
  2230                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
  2231                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
  2232                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
  2233                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
  2234                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
  2235                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
  2236                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
  2237                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
  2238                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
  2239                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
  2240                              <1> 
  2241                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
  2242                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
  2243                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
  2244                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
  2245                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
  2246                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
  2247                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
  2248                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
  2249                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
  2250                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
  2251                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
  2252                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
  2253                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
  2254                              <1> 
  2255                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
  2256                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
  2257                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
  2258                              <1> 
  2259                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
  2260                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
  2261                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
  2262                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
  2263                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
  2264                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
  2265                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
  2266                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
  2267                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
  2268                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
  2269                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
  2270                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
  2271                              <1> 
  2272                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
  2273                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
  2274                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
  2275                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
  2276                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
  2277                              <1> 
  2278                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
  2279                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
  2280                              <1> ;INTA00		EQU	020H		; 8259 PORT
  2281                              <1> INTA01		EQU	021H		; 8259 PORT
  2282                              <1> INTB00		EQU	0A0H		; 2ND 8259
  2283                              <1> INTB01		EQU	0A1H		;
  2284                              <1> 
  2285                              <1> ;-------------------------------------------------------------------------------
  2286                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
  2287                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
  2288                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
  2289                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
  2290                              <1> ;-------------------------------------------------------------------------------
  2291                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
  2292                              <1> 
  2293                              <1> ;-------------------------------------------------------------------------------
  2294                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
  2295                              <1> 
  2296                              <1> ; 10/07/2022
  2297                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2298                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
  2299                              <1> ; (unix386.s <-- dsectrm2.s)
  2300                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
  2301                              <1> 
  2302                              <1> ; 10/12/2014
  2303                              <1> ;
  2304                              <1> ;int40h:
  2305                              <1> ;	pushf
  2306                              <1> ;	push 	cs
  2307                              <1> ;	;cli
  2308                              <1> ;	call 	DISKETTE_IO_1
  2309                              <1> ;	retn
  2310                              <1> 
  2311                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
  2312                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  2313                              <1> ;
  2314                              <1> 
  2315                              <1> ;-- Retro UNIX 386 v1.1 (Kernel v0.2.1.5) ---08/07/2022-------------------------
  2316                              <1> ; DISKETTE I/O
  2317                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
  2318                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
  2319                              <1> ; INPUT
  2320                              <1> ;	(AH)= 00H RESET DISKETTE SYSTEM
  2321                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
  2322                              <1> ;		ON ALL DRIVES
  2323                              <1> ;------------------------------------------------------------------------------- 
  2324                              <1> ;	(AH)= 01H  READ THE DESIRED SECTORS INTO MEMORY
  2325                              <1> ;-------------------------------------------------------------------------------
  2326                              <1> ;	(AH)= 02H  WRITE THE DESIRED SECTORS FROM MEMORY
  2327                              <1> ;-------------------------------------------------------------------------------
  2328                              <1> ;
  2329                              <1> ;	REGISTERS FOR READ/WRITE
  2330                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  2331                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
  2332                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
  2333                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
  2334                              <1> ;		320/360	320/360	    0-39
  2335                              <1> ;		320/360	1.2M	    0-39
  2336                              <1> ;		1.2M	1.2M	    0-79
  2337                              <1> ;		720K	720K	    0-79
  2338                              <1> ;		1.44M	1.44M	    0-79	
  2339                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED)
  2340                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
  2341                              <1> ;		320/360	320/360	     1-8/9
  2342                              <1> ;		320/360	1.2M	     1-8/9
  2343                              <1> ;		1.2M	1.2M	     1-15
  2344                              <1> ;		720K	720K	     1-9
  2345                              <1> ;		1.44M	1.44M	     1-18		
  2346                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
  2347                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
  2348                              <1> ;		320/360	320/360	        8/9
  2349                              <1> ;		320/360	1.2M	        8/9
  2350                              <1> ;		1.2M	1.2M		15
  2351                              <1> ;		720K	720K		9
  2352                              <1> ;		1.44M	1.44M		18
  2353                              <1> ;
  2354                              <1> ;	(EBX) - ADDRESS OF BUFFER
  2355                              <1> ;
  2356                              <1> ;-------------------------------------------------------------------------------
  2357                              <1> ; OUTPUT FOR ALL FUNCTIONS
  2358                              <1> ;	AH = STATUS OF OPERATION
  2359                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
  2360                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
  2361                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)
  2362                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
  2363                              <1> ;	FOR READ/WRITE/VERIFY
  2364                              <1> ;		DS,BX,DX,CX PRESERVED
  2365                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
  2366                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
  2367                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
  2368                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
  2369                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
  2370                              <1> ;-------------------------------------------------------------------------------
  2371                              <1> ;
  2372                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
  2373                              <1> ;
  2374                              <1> ;   -----------------------------------------------------------------
  2375                              <1> ;   |       |       |       |       |       |       |       |       |
  2376                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
  2377                              <1> ;   |       |       |       |       |       |       |       |       |
  2378                              <1> ;   -----------------------------------------------------------------
  2379                              <1> ;	|	|	|	|	|	|	|	|
  2380                              <1> ;	|	|	|	|	|	-----------------
  2381                              <1> ;	|	|	|	|	|		|
  2382                              <1> ;	|	|	|	|    RESERVED		|
  2383                              <1> ;	|	|	|	|		  PRESENT STATE
  2384                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
  2385                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
  2386                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
  2387                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
  2388                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
  2389                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
  2390                              <1> ;	|	|	|	|	110: RESERVED
  2391                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
  2392                              <1> ;	|	|	|	|
  2393                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
  2394                              <1> ;	|	|	|
  2395                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED
  2396                              <1> ;	|	|					 (360K IN 1.2M DRIVE)
  2397                              <1> ;	|	|
  2398                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
  2399                              <1> ;
  2400                              <1> ;						00: 500 KBS
  2401                              <1> ;						01: 300 KBS
  2402                              <1> ;						10: 250 KBS
  2403                              <1> ;						11: RESERVED
  2404                              <1> ;
  2405                              <1> ;
  2406                              <1> 
  2407                              <1> struc MD
  2408 00000000 ??                  <1> 	.SPEC1:	  resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2409 00000001 ??                  <1> 	.SPEC2:	  resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2410 00000002 ??                  <1> 	.OFF_TIM: resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2411 00000003 ??                  <1> 	.BYT_SEC: resb	1	; 512 BYTES/SECTOR
  2412 00000004 ??                  <1> 	.SEC_TRK: resb	1	; EOT (LAST SECTOR ON TRACK)
  2413 00000005 ??                  <1> 	.GAP:	  resb	1	; GAP LENGTH
  2414 00000006 ??                  <1> 	.DTL:	  resb	1	; DTL
  2415 00000007 ??                  <1> 	.GAP3:	  resb	1	; GAP LENGTH FOR FORMAT
  2416 00000008 ??                  <1> 	.FIL_BYT: resb	1	; FILL BYTE FOR FORMAT
  2417 00000009 ??                  <1> 	.HD_TIM:  resb	1	; HEAD SETTLE TIME (MILLISECONDS)
  2418 0000000A ??                  <1> 	.STR_TIM: resb	1	; MOTOR START TIME (1/8 SECONDS)
  2419 0000000B ??                  <1> 	.MAX_TRK: resb	1	; MAX. TRACK NUMBER
  2420 0000000C ??                  <1> 	.RATE:	  resb	1	; DATA TRANSFER RATE
  2421                              <1> endstruc
  2422                              <1> 
  2423                              <1> BIT7OFF	EQU	7FH
  2424                              <1> BIT7ON	EQU	80H
  2425                              <1> 
  2426                              <1> ; 11/07/2022 - (direct call instead of int 13h simulation)
  2427                              <1> ;		Function in AL
  2428                              <1> ;			0 = reset
  2429                              <1> ;			1 = read
  2430                              <1> ;			2 = write
  2431                              <1> ;		Disk drive number in DL
  2432                              <1> ;			0 & 1 = floppy disks	
  2433                              <1> ;			80h .. 83h = hard disks
  2434                              <1> ;		Sector address (LBA) in ECX
  2435                              <1> ;		Buffer address in EBX
  2436                              <1> ;		R/W sector count is (always) 1
  2437                              <1> ;
  2438                              <1> ;		Return:
  2439                              <1> ;			Status in AH (>0 = error code)
  2440                              <1> ;			if CF = 1 -> error code in AH
  2441                              <1> ;			if CF = 0 -> successful
  2442                              <1> ;			AL = undefined
  2443                              <1> ;
  2444                              <1> ;		Modified registers: (only) EAX
  2445                              <1> 
  2446                              <1> ; 11/07/2022
  2447                              <1> ;;int13h: ; 16/02/2015
  2448                              <1> ;; 16/02/2015 - 21/02/2015
  2449                              <1> ;int40h:
  2450                              <1> ;	pushfd
  2451                              <1> ;	push 	cs
  2452                              <1> ;	call 	DISKETTE_IO_1
  2453                              <1> ;	retn	
  2454                              <1> 
  2455                              <1> DISKETTE_IO_1:
  2456                              <1> 
  2457                              <1> 	;sti				; INTERRUPTS BACK ON
  2458                              <1> 	; 11/07/2022
  2459                              <1> 	; save registers
  2460 00001625 55                  <1> 	push	ebp			; ANY
  2461                              <1> 
  2462                              <1> 	; 11/07/2022
  2463                              <1> 	;push	edi			; ANY
  2464                              <1> 	;push	edx			; DRIVE NUMBER (DL)
  2465                              <1> 	;push	ebx			; BUFFER ADDRESS
  2466                              <1> 	;push	ecx			; SECTOR ADDRESS (LBA)
  2467                              <1> 	;push	esi			; ANY
  2468                              <1> 
  2469                              <1> 	; 11/07/2022
  2470 00001626 89DD                <1> 	mov	ebp, ebx ; buffer address
  2471 00001628 C605[8C670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; RESET DISKETTE STATUS
  2472 0000162F 0FB6FA              <1> 	movzx	edi, dl ; drive number (0 or 1)
  2473                              <1> 	
  2474 00001632 08C0                <1> 	or	al, al			; RESET ?
  2475 00001634 7507                <1> 	jnz	short DISKETTE_RW_1	; NO
  2476                              <1> 
  2477 00001636 E84D010000          <1> 	call	DSK_RESET
  2478                              <1> 
  2479 0000163B EB37                <1> 	jmp	short DISKETTE_RW_2	
  2480                              <1> 
  2481                              <1> DISKETTE_RW_1:
  2482                              <1> 	; 12/07/2022
  2483                              <1> 	; 11/07/2022
  2484                              <1> 	; ecx = sector address (LBA, < 2880)
  2485                              <1> 	; ebp = buffer address
  2486                              <1> 	; edi = drive number (0 or 1)
  2487                              <1> 	;  al = function (read = 1 or write = 2)
  2488                              <1> 
  2489 0000163D 88C2                <1> 	mov	dl, al ; *
  2490                              <1> convert_to_chs:
  2491                              <1> 	;;;
  2492 0000163F B004                <1> 	mov	al, 4 ; MD.SEC_TRK ; sector per track (drv.spt)
  2493 00001641 E8D9050000          <1> 	call	GET_PARM
  2494                              <1> 	; 12/07/2022
  2495 00001646 88E6                <1> 	mov	dh, ah ; spt
  2496 00001648 89C8                <1> 	mov	eax, ecx ; sector address (LBA) 
  2497 0000164A F6F6                <1> 	div	dh  ; AX/DH
  2498 0000164C 88E1                <1> 	mov	cl, ah ; sector number - 1
  2499 0000164E FEC1                <1> 	inc	cl  ; sector number (1 based)
  2500 00001650 28ED                <1> 	sub	ch, ch ; head = 0 
  2501                              <1> 	; heads = 2
  2502 00001652 D0E8                <1> 	shr	al, 1 ; al = al/2
  2503 00001654 80D500              <1> 	adc	ch, 0 ; head = 1 or head = 0
  2504 00001657 C1E110              <1> 	shl	ecx, 16
  2505 0000165A 88C1                <1> 	mov	cl, al ; track (cylinder)
  2506 0000165C 88D5                <1> 	mov	ch, dl ; function number 
  2507 0000165E 89CE                <1> 	mov	esi, ecx ; byte 0 = track, byte 1 = function
  2508                              <1> 			 ; byte 2 = sector, byte 3 = head
  2509 00001660 C1C610              <1> 	rol	esi, 16
  2510                              <1> 			 ; byte 0 = sector, byte 1 = head
  2511                              <1> 			 ; byte 2 = track, byte 3 = function		
  2512                              <1> 	;;; 
  2513 00001663 80FA02              <1> 	cmp	dl, 2 ; *
  2514 00001666 7407                <1> 	je	short DISKETTE_W
  2515                              <1> DISKETTE_R:	
  2516                              <1> 	; dl = 1 ; *
  2517 00001668 E809000000          <1> 	call	DSK_READ
  2518 0000166D EB05                <1> 	jmp	short DISKETTE_RW_2
  2519                              <1> DISKETTE_W:
  2520 0000166F E80F000000          <1> 	call	DSK_WRITE
  2521                              <1> DISKETTE_RW_2:
  2522                              <1> 	; 11/07/2022
  2523                              <1> 	; Restore registers
  2524                              <1> 	;pop	esi
  2525                              <1> 	;pop	ecx
  2526                              <1> 	;pop	ebx
  2527                              <1> 	;pop	edx
  2528                              <1> 	;pop	edi
  2529                              <1> 
  2530                              <1> 	; 11/07/2022
  2531 00001674 5D                  <1> 	pop	ebp
  2532 00001675 C3                  <1> 	retn
  2533                              <1> 
  2534                              <1> ;-------------------------------------------------------------------------------
  2535                              <1> ; DISK_READ	(AH = 01H)  ; Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2536                              <1> ;	DISKETTE READ.
  2537                              <1> ;
  2538                              <1> ; ON ENTRY:	EDI	: DRIVE #
  2539                              <1> ;		SI-HI	: HEAD #
  2540                              <1> ;		SI-LOW	: # OF SECTORS
  2541                              <1> ;		ES	: BUFFER SEGMENT
  2542                              <1> ;		[BP]	: SECTOR #
  2543                              <1> ;		[BP+1]	: TRACK #
  2544                              <1> ;		[BP+2]	: BUFFER OFFSET
  2545                              <1> ;
  2546                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2547                              <1> ;-------------------------------------------------------------------------------
  2548                              <1> 
  2549                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2550                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  2551                              <1> 
  2552                              <1> DSK_READ:
  2553 00001676 8025[8A670000]7F    <1> 	and	byte [MOTOR_STATUS], 01111111b ; INDICATE A READ OPERATION
  2554 0000167D 66B846E6            <1> 	mov	ax, 0E646h		; AX = NEC COMMAND, DMA COMMAND
  2555                              <1> 	;call	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  2556                              <1> 	;retn
  2557 00001681 EB0B                <1> 	jmp	short RD_WR_VF
  2558                              <1> 
  2559                              <1> ;-------------------------------------------------------------------------------
  2560                              <1> ; DISK_WRITE	(AH = 02H)
  2561                              <1> ;	DISKETTE WRITE.
  2562                              <1> ;
  2563                              <1> ; ON ENTRY:	EDI	: DRIVE #
  2564                              <1> ;		SI-HI	: HEAD #
  2565                              <1> ;		SI-LOW	: # OF SECTORS
  2566                              <1> ;		ES	: BUFFER SEGMENT
  2567                              <1> ;		[BP]	: SECTOR #
  2568                              <1> ;		[BP+1]	: TRACK #
  2569                              <1> ;		[BP+2]	: BUFFER OFFSET
  2570                              <1> ;
  2571                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2572                              <1> ;-------------------------------------------------------------------------------
  2573                              <1> 
  2574                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2575                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  2576                              <1> 
  2577                              <1> DSK_WRITE:
  2578 00001683 66B84AC5            <1> 	mov	ax, 0C54Ah		; AX = NEC COMMAND, DMA COMMAND
  2579 00001687 800D[8A670000]80    <1>         or	byte [MOTOR_STATUS], 10000000b ; INDICATE WRITE OPERATION
  2580                              <1> 	;;call	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  2581                              <1> 	;;retn
  2582                              <1> 	;jmp	short RD_WR_VF
  2583                              <1> 
  2584                              <1> ;-------------------------------------------------------------------------------
  2585                              <1> ; RD_WR_VF
  2586                              <1> ;	COMMON READ, WRITE
  2587                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  2588                              <1> ;
  2589                              <1> ; ON ENTRY:	AH = READ/WRITE NEC PARAMETER
  2590                              <1> ;		AL = READ/WRITE DMA PARAMETER
  2591                              <1> ;
  2592                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2593                              <1> ;-------------------------------------------------------------------------------
  2594                              <1> 
  2595                              <1> RD_WR_VF:
  2596                              <1> 	; 18/07/2022
  2597                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2598 0000168E 50                  <1> 	push	eax ; 24/12/2021	; SAVE DMA, NEC PARAMETERS
  2599 0000168F E8C9010000          <1> 	call	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  2600 00001694 E82B020000          <1> 	call	SETUP_STATE		; INITIALIZE START AND END RATE
  2601 00001699 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE READ/WRITE PARAMETER
  2602                              <1> DO_AGAIN:
  2603 0000169A 50                  <1> 	push	eax ; 24/12/2021	; SAVE READ/WRITE PARAMETER
  2604 0000169B E865020000          <1> 	call	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  2605 000016A0 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE READ/WRITE PARAMETER
  2606                              <1> 	; 24/12/2021
  2607 000016A1 7305                <1> 	jnc	short RWV
  2608 000016A3 E9B6000000          <1> 	jmp	RWV_END			; MEDIA CHANGE ERROR OR TIME-OUT
  2609                              <1> RWV:
  2610 000016A8 50                  <1> 	push	eax ; 24/12/2021	; SAVE READ/WRITE/VERIFY PARAMETER
  2611 000016A9 8AB7[97670000]      <1> 	mov	dh, [DSK_STATE+edi]	; GET RATE STATE OF THIS DRIVE
  2612 000016AF 80E6C0              <1> 	and	dh, RATE_MSK		; KEEP ONLY RATE
  2613 000016B2 E85F050000          <1> 	call	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  2614                              <1> 	; 20/02/2015
  2615 000016B7 7445                <1> 	jz	short RWV_ASSUME	; ERROR IN CMOS
  2616 000016B9 3C01                <1> 	cmp	al, 1			; 40 TRACK DRIVE?
  2617 000016BB 750D                <1> 	jne	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  2618 000016BD F687[97670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  2619 000016C4 740F                <1> 	jz	short RWV_2		; YES, CMOS IS CORRECT
  2620                              <1> 	;mov	al, 2			; CHANGE TO 1.2M
  2621                              <1> 	; 12/07/2022
  2622 000016C6 FEC0                <1> 	inc	al  ; al = 2
  2623 000016C8 EB0B                <1> 	jmp	short RWV_2
  2624                              <1> RWV_1:
  2625                              <1> 	; 12/07/2022
  2626                              <1> 	;jb	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  2627 000016CA F687[97670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; IS IT REALLY 40 TRACK?
  2628 000016D1 7502                <1> 	jnz	short RWV_2		; NO, 80 TRACK
  2629 000016D3 B001                <1> 	mov	al, 1			; IT IS 40 TRACK, FIX CMOS VALUE
  2630                              <1> 	; 12/07/2022
  2631                              <1> 	;jmp	short RWV_3
  2632                              <1> RWV_2:
  2633                              <1> 	; 12/07/2022
  2634                              <1> 	;or	al, al			; TEST FOR NO DRIVE
  2635                              <1> 	;jz	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  2636                              <1> RWV_3:
  2637                              <1> 	; 12/07/2022
  2638                              <1> 	;mov	dl, al	; 11/07/2022
  2639 000016D5 E81F010000          <1> 	call	DR_TYPE_CHECK		; RTN EBX = MEDIA/DRIVE PARAM TBL.
  2640 000016DA 7222                <1> 	jc	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  2641                              <1> 
  2642                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  2643                              <1> 
  2644 000016DC 57                  <1> 	push	edi			; SAVE DRIVE #
  2645                              <1> 	;xor	ebx, ebx		; EBX = INDEX TO DR_TYPE TABLE
  2646 000016DD BB[AC610000]        <1> 	mov	ebx, DR_TYPE
  2647                              <1> 	;mov	ecx, DR_CNT		; ECX = LOOP COUNT
  2648 000016E2 B106                <1> 	mov	cl, DR_CNT
  2649                              <1> RWV_DR_SEARCH:
  2650                              <1> 	;mov	ah, [DR_TYPE+ebx]	; GET DRIVE TYPE
  2651 000016E4 8A23                <1> 	mov	ah, [ebx]
  2652 000016E6 80E47F              <1> 	and	ah, BIT7OFF		; MASK OUT MSB
  2653 000016E9 38E0                <1> 	cmp	al, ah			; DRIVE TYPE MATCH?
  2654                              <1> 	; 12/07/2022
  2655                              <1> 	;cmp	dl, ah ; 11/07/2022
  2656 000016EB 7509                <1> 	jne	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  2657                              <1> RWV_DR_FND:
  2658                              <1> 	;mov	edi, [DR_TYPE+ebx+1] 	; EDI = MEDIA/DRIVE PARAMETER TABLE
  2659 000016ED 43                  <1> 	inc	ebx
  2660 000016EE 8B3B                <1> 	mov	edi, [ebx]
  2661 000016F0 4B                  <1> 	dec	ebx
  2662                              <1> RWV_MD_SEARH:
  2663 000016F1 3A770C              <1>         cmp	dh, [edi+MD.RATE]       ; MATCH?
  2664 000016F4 741D                <1> 	je	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  2665                              <1> RWV_NXT_MD:
  2666 000016F6 83C305              <1> 	add	ebx, 5			; CHECK NEXT DRIVE TYPE
  2667                              <1> 	;loop	RWV_DR_SEARCH
  2668 000016F9 FEC9                <1> 	dec	cl
  2669 000016FB 75E7                <1> 	jnz	short RWV_DR_SEARCH 
  2670 000016FD 5F                  <1> 	pop	edi			; RESTORE DRIVE #
  2671                              <1> 
  2672                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  2673                              <1> 
  2674                              <1> RWV_ASSUME:
  2675 000016FE BB[CA610000]        <1> 	mov	ebx, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  2676 00001703 F687[97670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; TEST FOR 80 TRACK
  2677 0000170A 740A                <1> 	jz	short RWV_MD_FND1	; MUST BE 40 TRACK
  2678 0000170C BB[E4610000]        <1> 	mov	ebx, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  2679 00001711 EB03                <1> 	jmp	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  2680                              <1> 
  2681                              <1> ;-----	EBX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  2682                              <1> 	 			
  2683                              <1> RWV_MD_FND:
  2684 00001713 89FB                <1> 	mov	ebx, edi		; EBX = MEDIA/DRIVE PARAMETER TABLE
  2685 00001715 5F                  <1> 	pop	edi			; RESTORE DRIVE #
  2686                              <1> 	
  2687                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  2688                              <1> 
  2689                              <1> RWV_MD_FND1:
  2690 00001716 E824010000          <1> 	call	SEND_SPEC_MD
  2691 0000171B E851020000          <1> 	call	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  2692 00001720 7405                <1> 	jz	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  2693 00001722 E82C020000          <1> 	call	SEND_RATE		; SEND DATA RATE TO NEC
  2694                              <1> RWV_DBL:
  2695 00001727 53                  <1> 	push	ebx			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  2696 00001728 E847040000          <1> 	call	SETUP_DBL		; CHECK FOR DOUBLE STEP
  2697 0000172D 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2698 0000172E 7221                <1> 	jc	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  2699                              <1> 	;pop	eax ; 24/12/2021	; RESTORE NEC COMMAND
  2700                              <1> 	;push	eax ; 24/12/2021	; SAVE NEC COMMAND
  2701                              <1> 	; 08/07/2022
  2702 00001730 8B0424              <1> 	mov	eax, [esp]
  2703                              <1> 	; 18/07/2022
  2704                              <1> 	;push	ebx			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  2705 00001733 E84C020000          <1> 	call	DMA_SETUP		; SET UP THE DMA
  2706                              <1> 	;pop	ebx
  2707 00001738 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE NEC COMMAND
  2708 00001739 722D                <1> 	jc	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  2709 0000173B 50                  <1> 	push	eax ; 24/12/2021	; SAVE NEC COMMAND
  2710 0000173C 53                  <1> 	push	ebx			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  2711 0000173D E88C020000          <1> 	call	NEC_INIT		; INITIALIZE NEC
  2712 00001742 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2713 00001743 720C                <1> 	jc	short CHK_RET		; ERROR - EXIT
  2714 00001745 E8B5020000          <1> 	call	RWV_COM			; OP CODE COMMON TO READ/WRITE
  2715 0000174A 7205                <1> 	jc	short CHK_RET		; ERROR - EXIT
  2716 0000174C E8FC020000          <1> 	call	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  2717                              <1> CHK_RET:
  2718 00001751 E89B030000          <1> 	call	RETRY			; CHECK FOR, SETUP RETRY
  2719 00001756 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE READ/WRITE PARAMETER
  2720 00001757 7305                <1> 	jnc	short RWV_END		; CY = 0 NO RETRY
  2721 00001759 E93CFFFFFF          <1>         jmp	DO_AGAIN                ; CY = 1 MEANS RETRY
  2722                              <1> RWV_END:
  2723 0000175E E846030000          <1> 	call	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  2724 00001763 E8D7030000          <1> 	call	NUM_TRANS		; AL = NUMBER TRANSFERRED
  2725                              <1> RWV_BAC:
  2726                              <1> 	; 08/07/2022			; BAD DMA ERROR ENTRY
  2727                              <1> 	;push	eax ; 24/12/2021	; SAVE NUMBER TRANSFERRED
  2728                              <1> 	;CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  2729                              <1> 	;pop	eax ; 24/12/2021	; RESTORE NUMBER TRANSFERRED
  2730                              <1> 	;;call	SETUP_END		; VARIOUS CLEANUPS
  2731                              <1> 	;;retn
  2732                              <1> 	;jmp	SETUP_END
  2733                              <1> 
  2734                              <1> ;-------------------------------------------------------------------------------
  2735                              <1> ; SETUP_END
  2736                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  2737                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  2738                              <1> ;
  2739                              <1> ; ON EXIT:
  2740                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2741                              <1> ;-------------------------------------------------------------------------------
  2742                              <1> SETUP_END:
  2743                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5) 
  2744                              <1> 	;mov	dl, 2			; GET THE MOTOR WAIT PARAMETER
  2745                              <1> 	;push	ax			; SAVE NUMBER TRANSFERRED
  2746 00001768 50                  <1> 	push	eax ; 24/12/2021
  2747 00001769 B002                <1> 	mov	al, 2 ; 08/07/2022
  2748 0000176B E8AF040000          <1> 	call	GET_PARM
  2749 00001770 8825[8B670000]      <1> 	mov	[MOTOR_COUNT], ah	; STORE UPON RETURN
  2750                              <1> 	;pop	ax			; RESTORE NUMBER TRANSFERRED
  2751 00001776 58                  <1> 	pop	eax ; 24/12/2021
  2752 00001777 8A25[8C670000]      <1> 	mov	ah, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  2753 0000177D 08E4                <1> 	or	ah, ah			; CHECK FOR ERROR
  2754 0000177F 7406                <1> 	jz	short NUN_ERR		; NO ERROR
  2755 00001781 30C0                <1> 	xor 	al, al			; CLEAR NUMBER RETURNED
  2756                              <1> ;NUN_ERR: 
  2757 00001783 80FC01              <1> 	cmp	ah, 1			; SET THE CARRY FLAG TO INDICATE
  2758 00001786 F5                  <1> 	cmc				; SUCCESS OR FAILURE
  2759                              <1> NUN_ERR:
  2760 00001787 C3                  <1> 	retn
  2761                              <1> 
  2762                              <1> ; 17/07/2022
  2763                              <1> ;-------------------------------------------------------------------------------
  2764                              <1> ; DISK_RESET	(AH = 00H)	
  2765                              <1> ;		RESET THE DISKETTE SYSTEM.
  2766                              <1> ;
  2767                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2768                              <1> ;-------------------------------------------------------------------------------
  2769                              <1> DSK_RESET:
  2770                              <1> 	; 17/07/2022
  2771                              <1> 	; 12/07/2022
  2772                              <1> 	; 11/07/2022
  2773                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2774 00001788 66BAF203            <1> 	mov	dx, 03F2h		; ADAPTER CONTROL PORT
  2775 0000178C FA                  <1> 	cli				; NO INTERRUPTS
  2776 0000178D A0[8A670000]        <1> 	mov	al, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2777 00001792 243F                <1> 	and	al, 00111111b		; KEEP SELECTED AND MOTOR ON BITS
  2778 00001794 C0C004              <1> 	rol	al, 4			; MOTOR VALUE TO HIGH NIBBLE
  2779                              <1> 					; DRIVE SELECT TO LOW NIBBLE
  2780 00001797 0C08                <1> 	or	al, 00001000b		; TURN ON INTERRUPT ENABLE
  2781 00001799 EE                  <1> 	out	dx, al			; RESET THE ADAPTER
  2782 0000179A C605[89670000]00    <1> 	mov	byte [SEEK_STATUS], 0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  2783                              <1> 	;JMP	$+2			; WAIT FOR I/O
  2784                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
  2785                              <1> 					;      PULSE WIDTH)
  2786                              <1> 	; 19/12/2014
  2787                              <1> 	NEWIODELAY
  2177 000017A1 E6EB                <2>  out 0EBh,al
  2788                              <1> 
  2789                              <1> 	; 17/12/2014 
  2790                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
  2791 000017A3 B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
  2792                              <1> wdw1:
  2793                              <1> 	NEWIODELAY   ; 27/02/2015
  2177 000017A8 E6EB                <2>  out 0EBh,al
  2794 000017AA E2FC                <1> 	loop	wdw1
  2795                              <1> 	;
  2796 000017AC 0C04                <1> 	or	al, 00000100b		; TURN OFF RESET BIT
  2797 000017AE EE                  <1> 	out	dx, al			; RESET THE ADAPTER
  2798                              <1> 	; 16/12/2014
  2799                              <1> 	IODELAY
  2172 000017AF EB00                <2>  jmp short $+2
  2173 000017B1 EB00                <2>  jmp short $+2
  2800                              <1> 	;
  2801                              <1> 	;sti				; ENABLE THE INTERRUPTS
  2802 000017B3 E862060000          <1> 	call	WAIT_INT		; WAIT FOR THE INTERRUPT
  2803 000017B8 7236                <1> 	jc	short DR_ERR		; IF ERROR, RETURN IT
  2804                              <1> 	;mov	cx, 11000000b		; CL = EXPECTED @NEC_STATUS
  2805                              <1> 	; 12/07/2022
  2806                              <1> 	;xor	ecx, ecx
  2807                              <1> 	; 17/07/2022
  2808                              <1> 	;xor	ch, ch
  2809 000017BA B1C0                <1> 	mov	cl, 11000000b
  2810                              <1> NXT_DRV:
  2811                              <1> 	; 24/12/2021
  2812 000017BC 51                  <1> 	push	ecx			; SAVE FOR CALL
  2813 000017BD B8[EF170000]        <1> 	mov	eax, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
  2814 000017C2 50                  <1> 	push	eax			;
  2815 000017C3 B408                <1> 	mov	ah, 08h			; SENSE INTERRUPT STATUS COMMAND
  2816 000017C5 E846050000          <1> 	call	NEC_OUTPUT
  2817 000017CA 58                  <1> 	pop	eax			; THROW AWAY ERROR RETURN
  2818 000017CB E879060000          <1> 	call	RESULTS			; READ IN THE RESULTS
  2819                              <1> 	; 24/12/2021
  2820 000017D0 59                  <1> 	pop	ecx			; RESTORE AFTER CALL
  2821 000017D1 721D                <1> 	jc	short DR_ERR		; ERROR RETURN
  2822 000017D3 3A0D[8D670000]      <1> 	cmp	cl, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
  2823 000017D9 7515                <1> 	jnz	short DR_ERR		; EVERYTHING OK
  2824 000017DB FEC1                <1> 	inc	cl			; NEXT EXPECTED @NEC_STATUS
  2825 000017DD 80F9C3              <1> 	cmp	cl, 11000011b		; ALL POSSIBLE DRIVES CLEARED
  2826 000017E0 76DA                <1> 	jbe	short NXT_DRV		; FALL THRU IF 11000100B OR >
  2827                              <1> 	;
  2828 000017E2 E82F000000          <1> 	call	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  2829                              <1> RESBAC:
  2830 000017E7 E87CFFFFFF          <1> 	call	SETUP_END		; VARIOUS CLEANUPS
  2831                              <1> 	
  2832                              <1> 	; 11/07/2022
  2833                              <1> 	; CF = 1 -> error (error code in AH)
  2834                              <1> 	; CF = 0 -> OK
  2835                              <1> 	
  2836                              <1> 	;; 24/12/2021
  2837                              <1> 	;mov	ebx, esi		; GET SAVED AL TO BL
  2838                              <1> 	;; 11/07/2022
  2839                              <1> 	;; byte 0 = sector, byte 1 = head, byte 2 = track, byte 3 = function 
  2840                              <1> 	;rol	ebx, 8
  2841                              <1> 	; bl = function (reset = 0)
  2842                              <1> 	;
  2843                              <1> 	;mov	al, bl			; PUT BACK FOR RETURN
  2844                              <1> 	
  2845                              <1> 	; 11/07/2022  
  2846 000017EC B000                <1> 	mov	al, 0	; (reset function = 0)
  2847                              <1> 
  2848 000017EE C3                  <1> 	retn
  2849                              <1> 
  2850                              <1> DR_POP_ERR:
  2851                              <1> 	; 24/12/2021
  2852 000017EF 59                  <1> 	pop	ecx			; CLEAR STACK
  2853                              <1> DR_ERR:
  2854 000017F0 800D[8C670000]20    <1> 	or	byte [DSKETTE_STATUS], BAD_NEC ; SET ERROR CODE
  2855 000017F7 EBEE                <1> 	jmp	short RESBAC		; RETURN FROM RESET
  2856                              <1> 
  2857                              <1> ;-------------------------------------------------------------------------------
  2858                              <1> ; FNC_ERR
  2859                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
  2860                              <1> ;	SET BAD COMMAND IN STATUS.
  2861                              <1> ;
  2862                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2863                              <1> ;-------------------------------------------------------------------------------
  2864                              <1> 
  2865                              <1> 	; 11/07/2022 - not needed (because diskio is used by kernel only)
  2866                              <1> 	
  2867                              <1> ;FNC_ERR:				; INVALID FUNCTION REQUEST
  2868                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2869                              <1> ;	; 24/12/2021
  2870                              <1> ;	mov	eax, esi		; RESTORE AL
  2871                              <1> ;	mov	ah, BAD_CMD		; SET BAD COMMAND ERROR
  2872                              <1> ;	mov	[DSKETTE_STATUS], ah	; STORE IN DATA AREA
  2873                              <1> ;	stc				; SET CARRY INDICATING ERROR
  2874                              <1> ;	retn
  2875                              <1> 
  2876                              <1> ;----------------------------------------------------------------
  2877                              <1> ; DR_TYPE_CHECK							:
  2878                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  2879                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  2880                              <1> ; ON ENTRY:							:
  2881                              <1> ;	AL = DRIVE TYPE						:
  2882                              <1> ; ON EXIT:							:
  2883                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  2884                              <1> ;	     EBX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE	:
  2885                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  2886                              <1> ; REGISTERS ALTERED: EBX, AH ; 11/07/2022 			:
  2887                              <1> ;----------------------------------------------------------------
  2888                              <1> DR_TYPE_CHECK:
  2889                              <1> 	; 12/07/2022
  2890                              <1> 	; 11/07/2022
  2891                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2892                              <1> 	; 24/12/2021
  2893                              <1> 	;push	eax ; 11/07/2022
  2894                              <1> 	;push	ecx ; 08/07/2022
  2895                              <1> 	;xor	ebx,ebx			; EBX = INDEX TO DR_TYPE TABLE
  2896 000017F9 BB[AC610000]        <1> 	mov	ebx, DR_TYPE
  2897                              <1> 	;;mov	ecx, DR_CNT		; ECX = LOOP COUNT
  2898                              <1> 	;mov	cl, DR_CNT
  2899 000017FE B406                <1> 	mov	ah, DR_CNT ; 11/07/2022
  2900                              <1> TYPE_CHK:	
  2901                              <1> 	;;mov	ah, [DR_TYPE+ebx]	; GET DRIVE TYPE
  2902                              <1> 	;mov	ah, [ebx]
  2903                              <1> 	;cmp	al, ah			; DRIVE TYPE MATCH?
  2904 00001800 3A03                <1> 	cmp	al, [ebx] ; 11/07/2022
  2905 00001802 740E                <1> 	je	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  2906                              <1> 	; 16/02/2015 (32 bit address modification)
  2907 00001804 83C305              <1> 	add	ebx, 5			; CHECK NEXT DRIVE TYPE
  2908                              <1> 	;loop	TYPE_CHK
  2909                              <1> 	;dec	cl
  2910 00001807 FECC                <1> 	dec	ah ; 11/07/2022
  2911 00001809 75F5                <1> 	jnz	short TYPE_CHK
  2912                              <1> 	;
  2913 0000180B BB[0B620000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  2914                              <1> 					; Default for GET_PARM (11/12/2014)
  2915                              <1> 	;
  2916 00001810 F9                  <1> 	stc				; DRIVE TYPE NOT FOUND IN TABLE
  2917                              <1> 	;jmp	short TYPE_RTN
  2918                              <1> 	; 12/07/2022
  2919 00001811 C3                  <1> 	retn
  2920                              <1> DR_TYPE_VALID:
  2921                              <1> 	;mov	ebx, [DR_TYPE+ebx+1] 	; EBX = MEDIA TABLE
  2922 00001812 43                  <1> 	inc	ebx
  2923 00001813 8B1B                <1> 	mov	ebx, [ebx]
  2924                              <1> TYPE_RTN:
  2925                              <1> 	;pop	ecx ; 08/07/2022
  2926                              <1> 	; 24/12/2021
  2927                              <1> 	;pop	eax ; 11/07/2022
  2928 00001815 C3                  <1> 	retn
  2929                              <1> 		
  2930                              <1> ;----------------------------------------------------------------
  2931                              <1> ; SEND_SPEC							:
  2932                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  2933                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  2934                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  2935                              <1> ; ON EXIT:	NONE						:
  2936                              <1> ; REGISTERS ALTERED: ECX, EDX					:
  2937                              <1> ;----------------------------------------------------------------
  2938                              <1> SEND_SPEC:
  2939                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2940 00001816 50                  <1> 	push	eax			; SAVE EAX
  2941 00001817 B8[3D180000]        <1> 	mov	eax, SPECBAC		; LOAD ERROR ADDRESS
  2942 0000181C 50                  <1> 	push	eax			; PUSH NEC_OUT ERROR RETURN
  2943 0000181D B403                <1> 	mov	ah, 03h			; SPECIFY COMMAND
  2944 0000181F E8EC040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  2945                              <1> 	;sub	dl, dl			; FIRST SPECIFY BYTE
  2946 00001824 28C0                <1> 	sub	al, al ; 08/07/2022
  2947 00001826 E8F4030000          <1> 	call	GET_PARM		; GET PARAMETER TO AH
  2948 0000182B E8E0040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  2949                              <1> 	;mov	dl, 1			; SECOND SPECIFY BYTE
  2950 00001830 B001                <1> 	mov	al, 1 ; 08/07/2022
  2951 00001832 E8E8030000          <1> 	call	GET_PARM		; GET PARAMETER TO AH
  2952 00001837 E8D4040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  2953 0000183C 58                  <1> 	pop	eax			; POP ERROR RETURN
  2954                              <1> SPECBAC:
  2955 0000183D 58                  <1> 	pop	eax			; RESTORE ORIGINAL EAX VALUE
  2956 0000183E C3                  <1> 	retn
  2957                              <1> 
  2958                              <1> ;----------------------------------------------------------------
  2959                              <1> ; SEND_SPEC_MD							:
  2960                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  2961                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (EBX)	:
  2962                              <1> ; ON ENTRY:	EBX = MEDIA/DRIVE PARAMETER TABLE		:
  2963                              <1> ; ON EXIT:	NONE						:
  2964                              <1> ; REGISTERS ALTERED: EAX ; 11/07/2022				:
  2965                              <1> ;----------------------------------------------------------------
  2966                              <1> SEND_SPEC_MD:
  2967                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2968                              <1> 	;push	eax ; 11/07/2022	; SAVE RATE DATA
  2969 0000183F B8[5C180000]        <1> 	mov	eax, SPEC_ESBAC		; LOAD ERROR ADDRESS
  2970 00001844 50                  <1> 	push	eax			; PUSH NEC_OUT ERROR RETURN
  2971 00001845 B403                <1> 	mov	ah, 03h			; SPECIFY COMMAND
  2972 00001847 E8C4040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  2973 0000184C 8A23                <1>         mov	ah, [ebx+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  2974 0000184E E8BD040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  2975 00001853 8A6301              <1>         mov	ah, [ebx+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  2976 00001856 E8B5040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  2977 0000185B 58                  <1> 	pop	eax			; POP ERROR RETURN
  2978                              <1> SPEC_ESBAC:
  2979                              <1> 	;pop	eax ; 11/07/2022	; RESTORE ORIGINAL EAX VALUE
  2980 0000185C C3                  <1> 	retn
  2981                              <1> 
  2982                              <1> ;-------------------------------------------------------------------------------
  2983                              <1> ; XLAT_NEW  
  2984                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  2985                              <1> ;	MODE TO NEW ARCHITECTURE.
  2986                              <1> ;
  2987                              <1> ; ON ENTRY:	EDI = DRIVE #
  2988                              <1> ;-------------------------------------------------------------------------------
  2989                              <1> XLAT_NEW:
  2990                              <1> 	; 11/07/2022
  2991                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2992                              <1> 	;cmp	edi, 1				; VALID DRIVE
  2993                              <1> 	;ja	short XN_OUT			; IF INVALID BACK
  2994                              <1> 	;
  2995 0000185D 80BF[97670000]00    <1> 	cmp	byte [DSK_STATE+edi], 0		; NO DRIVE ?
  2996 00001864 7401                <1> 	jz	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  2997                              <1> 	;
  2998                              <1> 	;mov	al, [HF_CNTRL]			; DRIVE INFORMATION
  2999                              <1> 	;mov	ecx, edi			; ECX = DRIVE NUMBER
  3000                              <1> 	;or	cl, cl
  3001                              <1> 	;jz	short XN_0  ; 08/07/2022
  3002                              <1> 	;shl	cl, 2				; CL = SHIFT COUNT, A=0, B=4
  3003                              <1> 	;;mov	al, [HF_CNTRL]			; DRIVE INFORMATION
  3004                              <1> 	;ror	al, cl				; TO LOW NIBBLE
  3005                              <1> ;XN_0:	
  3006                              <1> 	;and	al, DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  3007                              <1>         ;and	byte [DSK_STATE+edi], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  3008                              <1> 	;or	[DSK_STATE+edi], al		; UPDATE DRIVE STATE
  3009                              <1> XN_OUT:
  3010 00001866 C3                  <1> 	retn
  3011                              <1> DO_DET:
  3012                              <1> 	;;call	DRIVE_DET			; TRY TO DETERMINE
  3013                              <1> 	;;retn
  3014                              <1> 	;jmp	DRIVE_DET
  3015                              <1> 
  3016                              <1> ;-------------------------------------------------------------------------------
  3017                              <1> ; DRIVE_DET
  3018                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  3019                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  3020                              <1> ; ON ENTRY:	EDI = DRIVE #
  3021                              <1> ;-------------------------------------------------------------------------------
  3022                              <1> DRIVE_DET:
  3023                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3024 00001867 E8EE030000          <1> 	call	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  3025 0000186C E857050000          <1> 	call	RECAL			; RECALIBRATE DRIVE
  3026 00001871 724E                <1> 	jc	short DD_BAC		; ASSUME NO DRIVE PRESENT
  3027 00001873 B530                <1> 	mov	ch, TRK_SLAP		; SEEK TO TRACK 48
  3028 00001875 E8CF040000          <1> 	call	SEEK
  3029 0000187A 7245                <1> 	jc	short DD_BAC		; ERROR NO DRIVE
  3030 0000187C B50B                <1> 	mov	ch, QUIET_SEEK+1	; SEEK TO TRACK 10
  3031                              <1> SK_GIN:
  3032 0000187E FECD                <1> 	dec	ch			; DECREMENT TO NEXT TRACK
  3033                              <1> 	;push	cx		
  3034                              <1> 	; 24/12/2021
  3035 00001880 51                  <1> 	push	ecx			; SAVE TRACK
  3036 00001881 E8C3040000          <1> 	call	SEEK
  3037 00001886 723A                <1> 	jc	short POP_BAC		; POP AND RETURN
  3038 00001888 B8[C2180000]        <1> 	mov	eax, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  3039 0000188D 50                  <1> 	push	eax
  3040 0000188E B404                <1> 	mov	ah, SENSE_DRV_ST	; SENSE DRIVE STATUS COMMAND BYTE
  3041 00001890 E87B040000          <1> 	call	NEC_OUTPUT		; OUTPUT TO NEC
  3042                              <1> 	; 08/07/2022
  3043 00001895 89F8                <1> 	mov	eax, edi		; AL = DRIVE
  3044 00001897 88C4                <1> 	mov	ah, al			; AH = DRIVE
  3045 00001899 E872040000          <1> 	call	NEC_OUTPUT		; OUTPUT TO NEC
  3046 0000189E E8A6050000          <1> 	call	RESULTS			; GO GET STATUS
  3047 000018A3 58                  <1> 	pop	eax			; THROW AWAY ERROR ADDRESS
  3048                              <1> 	;pop	cx			; RESTORE TRACK
  3049                              <1> 	; 24/12/2021
  3050 000018A4 59                  <1> 	pop	ecx
  3051 000018A5 F605[8D670000]10    <1> 	test	byte [NEC_STATUS], HOME	; TRACK 0 ?
  3052 000018AC 74D0                <1> 	jz	short SK_GIN		; GO TILL TRACK 0
  3053 000018AE 08ED                <1> 	or	ch, ch			; IS HOME AT TRACK 0
  3054 000018B0 7408                <1> 	jz	short IS_80		; MUST BE 80 TRACK DRIVE
  3055                              <1> 
  3056                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  3057                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  3058                              <1> 
  3059 000018B2 808F[97670000]94    <1> 	or	byte [DSK_STATE+edi], DRV_DET+MED_DET+RATE_250
  3060 000018B9 C3                  <1> 	retn				; ALL INFORMATION SET
  3061                              <1> IS_80:
  3062 000018BA 808F[97670000]01    <1> 	or	byte [DSK_STATE+edi], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  3063                              <1> DD_BAC:
  3064 000018C1 C3                  <1> 	retn
  3065                              <1> POP_BAC:
  3066                              <1> 	;pop	cx			; THROW AWAY
  3067                              <1> 	; 24/12/2021
  3068 000018C2 59                  <1> 	pop	ecx
  3069 000018C3 C3                  <1> 	retn
  3070                              <1> 
  3071                              <1> ;-------------------------------------------------------------------------------
  3072                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  3073                              <1> ;-------------------------------------------------------------------------------
  3074                              <1> SETUP_STATE:
  3075                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3076 000018C4 F687[97670000]10    <1> 	test	byte [DSK_STATE+edi], MED_DET ; MEDIA DETERMINED ?
  3077 000018CB 7537                <1> 	jnz	short J1C		; NO STATES IF DETERMINED
  3078 000018CD 66B84000            <1>        	mov	ax, (RATE_500*256)+RATE_300 ; AH = START RATE, AL = END RATE
  3079 000018D1 F687[97670000]04    <1> 	test	byte [DSK_STATE+edi], DRV_DET ; DRIVE ?
  3080 000018D8 740D                <1> 	jz	short AX_SET		; DO NOT KNOW DRIVE
  3081 000018DA F687[97670000]02    <1> 	test	byte [DSK_STATE+edi], FMT_CAPA ; MULTI-RATE?
  3082 000018E1 7504                <1> 	jnz	short AX_SET		; JUMP IF YES
  3083 000018E3 66B88080            <1>         mov	ax, RATE_250*257	; START A END RATE 250 FOR 360 DRIVE
  3084                              <1> AX_SET:	
  3085 000018E7 80A7[97670000]1F    <1> 	and	byte [DSK_STATE+edi], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  3086 000018EE 08A7[97670000]      <1> 	or	[DSK_STATE+edi], ah	; RATE FIRST TO TRY
  3087 000018F4 8025[94670000]F3    <1> 	and	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  3088 000018FB C0C804              <1> 	ror	al, 4			; TO OPERATION LAST RATE LOCATION
  3089 000018FE 0805[94670000]      <1> 	or	[LASTRATE], al		; LAST RATE
  3090                              <1> J1C:	
  3091 00001904 C3                  <1> 	retn
  3092                              <1> 
  3093                              <1> ;-------------------------------------------------------------------------------
  3094                              <1> ; MED_CHANGE	
  3095                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  3096                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  3097                              <1> ;
  3098                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  3099                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  3100                              <1> ;-------------------------------------------------------------------------------
  3101                              <1> MED_CHANGE:
  3102                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3103 00001905 E897050000          <1> 	call	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  3104 0000190A 7446                <1> 	jz	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  3105 0000190C 80A7[97670000]EF    <1> 	and	byte [DSK_STATE+edi], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  3106                              <1> 
  3107                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  3108                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  3109                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  3110                              <1> 
  3111 00001913 89F9                <1> 	mov	ecx, edi		; CL = DRIVE #
  3112 00001915 B001                <1> 	mov	al, 1			; MOTOR ON BIT MASK
  3113 00001917 D2E0                <1> 	shl	al, cl			; TO APPROPRIATE POSITION
  3114 00001919 F6D0                <1> 	not	al			; KEEP ALL BUT MOTOR ON
  3115 0000191B FA                  <1> 	cli				; NO INTERRUPTS
  3116 0000191C 2005[8A670000]      <1> 	and	[MOTOR_STATUS], al	; TURN MOTOR OFF INDICATOR
  3117 00001922 FB                  <1> 	sti				; INTERRUPTS ENABLED
  3118 00001923 E832030000          <1> 	call	MOTOR_ON		; TURN MOTOR ON
  3119                              <1> 
  3120                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  3121                              <1> 
  3122 00001928 E85BFEFFFF          <1> 	call	DSK_RESET		; RESET NEC
  3123 0000192D B501                <1> 	mov	ch, 1			; MOVE TO CYLINDER 1
  3124 0000192F E815040000          <1> 	call	SEEK			; ISSUE SEEK
  3125 00001934 30ED                <1> 	xor	ch, ch			; MOVE TO CYLINDER 0
  3126 00001936 E80E040000          <1> 	call	SEEK			; ISSUE SEEK
  3127 0000193B C605[8C670000]06    <1> 	mov	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  3128                              <1> OK1:
  3129 00001942 E85A050000          <1> 	call	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  3130 00001947 7407                <1> 	jz	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  3131                              <1> OK4:
  3132 00001949 C605[8C670000]80    <1> 	mov	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  3133                              <1> OK2:		
  3134 00001950 F9                  <1> 	stc				; MEDIA CHANGED, SET CY
  3135 00001951 C3                  <1> 	retn
  3136                              <1> MC_OUT:
  3137                              <1> 	;clc	; 08/07/2022		; NO MEDIA CHANGED, CLEAR CY
  3138 00001952 C3                  <1> 	retn
  3139                              <1> 
  3140                              <1> ;-------------------------------------------------------------------------------
  3141                              <1> ; SEND_RATE
  3142                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  3143                              <1> ; ON ENTRY:	EDI = DRIVE #
  3144                              <1> ; ON EXIT:	NONE
  3145                              <1> ; REGISTERS ALTERED: EDX, EAX ; 11/07/2022
  3146                              <1> ;-------------------------------------------------------------------------------
  3147                              <1> SEND_RATE:
  3148                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3149                              <1> 	;push	ax			; SAVE REG.
  3150                              <1> 	; 24/12/2021
  3151                              <1> 	;push	eax ; 11/07/2022
  3152 00001953 8025[94670000]3F    <1> 	and	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  3153 0000195A 8A87[97670000]      <1> 	mov	al, [DSK_STATE+edi]	; GET RATE STATE OF THIS DRIVE
  3154 00001960 24C0                <1> 	and	al, SEND_MSK		; KEEP ONLY RATE BITS
  3155 00001962 0805[94670000]      <1> 	or	[LASTRATE], al		; SAVE NEW RATE FOR NEXT CHECK
  3156 00001968 C0C002              <1> 	rol	al, 2			; MOVE TO BIT OUTPUT POSITIONS
  3157 0000196B 66BAF703            <1> 	mov	dx, 03F7h		; OUTPUT NEW DATA RATE
  3158 0000196F EE                  <1> 	out	dx, al
  3159                              <1> 	;pop	ax			; RESTORE REG.
  3160                              <1> 	; 24/12/2021
  3161                              <1> 	;pop	eax ; 11/07/2022
  3162 00001970 C3                  <1> 	retn
  3163                              <1> 
  3164                              <1> ;-------------------------------------------------------------------------------
  3165                              <1> ; CHK_LASTRATE
  3166                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  3167                              <1> ; ON ENTRY:
  3168                              <1> ;	EDI = DRIVE #
  3169                              <1> ; ON EXIT:
  3170                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  3171                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  3172                              <1> ; REGISTERS ALTERED: EAX ; 11/07/2022
  3173                              <1> ;-------------------------------------------------------------------------------
  3174                              <1> CHK_LASTRATE:
  3175                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3176                              <1> 	;push	ax			; SAVE REG.
  3177                              <1> 	; 24/12/2021
  3178                              <1> 	;push	eax ; 11/07/2022
  3179 00001971 8A25[94670000]      <1> 	mov	ah, [LASTRATE] ; 08/07/2022 (BugFix) 
  3180                              <1> 					; GET LAST DATA RATE SELECTED
  3181 00001977 8A87[97670000]      <1> 	mov	al, [DSK_STATE+edi]	; GET RATE STATE OF THIS DRIVE
  3182 0000197D 6625C0C0            <1>        	and	ax, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  3183 00001981 38E0                <1> 	cmp	al, ah			; COMPARE TO PREVIOUSLY TRIED
  3184                              <1> 					; ZF = 1 RATE IS THE SAME
  3185                              <1> 	;pop	ax			; RESTORE REG.
  3186                              <1> 	; 24/12/2021
  3187                              <1> 	;pop	eax ; 11/07/2022
  3188 00001983 C3                  <1> 	retn
  3189                              <1> 
  3190                              <1> ;-------------------------------------------------------------------------------
  3191                              <1> ; DMA_SETUP
  3192                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  3193                              <1> ;
  3194                              <1> ; ON ENTRY:	AL = DMA COMMAND
  3195                              <1> ;
  3196                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  3197                              <1> ;-------------------------------------------------------------------------------
  3198                              <1> 
  3199                              <1> ; SI = Head #, # of Sectors or DASD Type
  3200                              <1> 
  3201                              <1> ; 22/08/2015
  3202                              <1> ; 08/02/2015 - Protected Mode Modification
  3203                              <1> ; 06/02/2015 - 07/02/2015
  3204                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  3205                              <1> ; (DMA Addres = Physical Address)
  3206                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  3207                              <1> ;
  3208                              <1> ; 04/02/2016 (clc)
  3209                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  3210                              <1> ; 16/12/2014 (IODELAY)
  3211                              <1> 
  3212                              <1> DMA_SETUP:
  3213                              <1> 	; 18/07/2022
  3214                              <1> 	; 11/07/2022
  3215                              <1> 	;	ebp = buffer address
  3216                              <1> 	
  3217                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3218                              <1> 	;; 20/02/2015
  3219                              <1> 	;mov	edx, [ebp+4] ; 11/07/2022 ; Buffer address
  3220                              <1> 	; 08/07/2022 - not needed for Retro UNIX 386 v1.1
  3221                              <1> 	;test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  3222                              <1> 	;jnz	short dma_bnd_err_stc
  3223                              <1> 
  3224                              <1> 	; al = dma command
  3225                              <1> 	
  3226                              <1> ;	; 18/07/2022
  3227                              <1> ;	;	(512 bytes/sector only!) 
  3228                              <1> ;	; 24/12/2021
  3229                              <1> ;	push	eax			; DMA command
  3230                              <1> ;	;push	edx ; 11/07/2022	; *
  3231                              <1> ;	;mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  3232                              <1> ;	mov	al, 3 ; 08/07/2022
  3233                              <1> ;	call	GET_PARM		; 
  3234                              <1> ;	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  3235                              <1> ;	;mov	ax, si			; Sector count
  3236                              <1> ;	;mov	ah, al			; AH = # OF SECTORS
  3237                              <1> ;	;sub	al, al			; AL = 0, AX = # SECTORS * 256
  3238                              <1> ;	;shr	ax, 1			; AX = # SECTORS * 128
  3239                              <1> ;	;shl	ax, cl			; SHIFT BY PARAMETER VALUE
  3240                              <1> ;	; 08/07/2022
  3241                              <1> ;	; 24/12/2021
  3242                              <1> ;	;mov	edx, esi
  3243                              <1> ;	sub	eax, eax
  3244                              <1> ;	;mov	ah, dl
  3245                              <1> ;	;shr	eax, 1
  3246                              <1> ;	mov	al, 128
  3247                              <1> ;	shl	eax, cl
  3248                              <1> ;	;
  3249                              <1> ;	dec	eax			; -1 FOR DMA VALUE
  3250                              <1> ;	mov	ecx, eax
  3251                              <1> ;	;pop	edx ; 11/07/2022	; *
  3252                              <1> ;	; 24/12/2021
  3253                              <1> ;	pop	eax
  3254                              <1> 
  3255                              <1> 	; 18/07/2022
  3256                              <1> 	;mov	cx, 511
  3257                              <1> 
  3258                              <1> 	; 08/07/2022
  3259                              <1> 	;cmp	al, 42h
  3260                              <1>         ;jne	short NOT_VERF
  3261                              <1> 	;mov	edx, 0FF0000h
  3262                              <1> 	;jmp	short J33
  3263                              <1> ;NOT_VERF:
  3264                              <1> 	; 11/07/2022
  3265 00001984 89EA                <1> 	mov	edx, ebp
  3266                              <1> 	;
  3267                              <1> 	;add	dx, cx			; check for (64K) overflow
  3268                              <1> 	; 18/07/2022
  3269                              <1> 	; (512 bytes/sector)
  3270 00001986 6681C2FF01          <1> 	add	dx, 511
  3271 0000198B 7239                <1> 	jc	short dma_bnd_err
  3272                              <1> 	;
  3273                              <1> 	;sub	dx, cx ; 11/07/2022	; Restore start address
  3274                              <1> J33:
  3275                              <1> 	; 08/07/2022
  3276 0000198D FA                  <1> 	cli				; DISABLE INTERRUPTS DURING DMA SET-UP
  3277 0000198E E60C                <1> 	out	DMA+12, al		; SET THE FIRST/LAST F/F
  3278                              <1> 	IODELAY				; WAIT FOR I/O
  2172 00001990 EB00                <2>  jmp short $+2
  2173 00001992 EB00                <2>  jmp short $+2
  3279 00001994 E60B                <1> 	out	DMA+11, al		; OUTPUT THE MODE BYTE
  3280                              <1> 	;mov	eax, edx		; Buffer address
  3281                              <1> 	; 11/07/2022
  3282 00001996 89E8                <1> 	mov	eax, ebp ; buffer address
  3283 00001998 E604                <1> 	out	DMA+4, al		; OUTPUT LOW ADDRESS
  3284                              <1> 	IODELAY				; WAIT FOR I/O
  2172 0000199A EB00                <2>  jmp short $+2
  2173 0000199C EB00                <2>  jmp short $+2
  3285 0000199E 88E0                <1> 	mov	al, ah
  3286 000019A0 E604                <1> 	out	DMA+4, al		; OUTPUT HIGH ADDRESS
  3287 000019A2 C1E810              <1> 	shr	eax, 16
  3288                              <1> 	IODELAY				; I/O WAIT STATE
  2172 000019A5 EB00                <2>  jmp short $+2
  2173 000019A7 EB00                <2>  jmp short $+2
  3289 000019A9 E681                <1> 	out	081h, al		; OUTPUT highest BITS TO PAGE REGISTER
  3290                              <1> 	IODELAY
  2172 000019AB EB00                <2>  jmp short $+2
  2173 000019AD EB00                <2>  jmp short $+2
  3291                              <1> 	;;mov	ax, cx			; Byte count - 1
  3292                              <1> 	;mov	al, cl
  3293                              <1> 	; 18/07/2022
  3294                              <1> 	; (Byte count - 1 = 511)
  3295 000019AF B0FF                <1> 	mov	al, 0FFh ; 511-256
  3296 000019B1 E605                <1> 	out	DMA+5, al		; LOW BYTE OF COUNT
  3297                              <1> 	IODELAY				; WAIT FOR I/O
  2172 000019B3 EB00                <2>  jmp short $+2
  2173 000019B5 EB00                <2>  jmp short $+2
  3298                              <1> 	;;mov	al, ah
  3299                              <1> 	;mov	al, ch
  3300                              <1> 	; 18/07/2022
  3301 000019B7 B001                <1> 	mov	al, 1 ; 256
  3302 000019B9 E605                <1> 	out	DMA+5, al		; HIGH BYTE OF COUNT
  3303                              <1> 	IODELAY
  2172 000019BB EB00                <2>  jmp short $+2
  2173 000019BD EB00                <2>  jmp short $+2
  3304 000019BF FB                  <1> 	sti				; RE-ENABLE INTERRUPTS
  3305 000019C0 B002                <1> 	mov	al, 2			; MODE FOR 8237
  3306 000019C2 E60A                <1> 	out	DMA+10, al		; INITIALIZE THE DISKETTE CHANNEL
  3307                              <1> 	
  3308 000019C4 F8                  <1> 	clc	; 04/02/2016
  3309                              <1> 	
  3310 000019C5 C3                  <1> 	retn
  3311                              <1> 
  3312                              <1> 	; 18/07/2022
  3313                              <1> ;dma_bnd_err_stc:
  3314                              <1> ;	stc
  3315                              <1> 
  3316                              <1> dma_bnd_err:
  3317 000019C6 C605[8C670000]09    <1> 	mov	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  3318 000019CD C3                  <1> 	retn				; CY SET BY ABOVE IF ERROR
  3319                              <1> 
  3320                              <1> ;-------------------------------------------------------------------------------
  3321                              <1> ; NEC_INIT	
  3322                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  3323                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  3324                              <1> ;
  3325                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  3326                              <1> ;
  3327                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  3328                              <1> ;-------------------------------------------------------------------------------
  3329                              <1> NEC_INIT:
  3330                              <1> 	; 11/07/2022
  3331                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3332                              <1> 	;push	ax			; SAVE NEC COMMAND
  3333                              <1> 	; 24/12/2021
  3334 000019CE 50                  <1> 	push	eax
  3335 000019CF E886020000          <1> 	call	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  3336                              <1> 
  3337                              <1> ;-----	DO THE SEEK OPERATION
  3338                              <1> 
  3339                              <1> 	;mov	ch, [ebp+1]		; CH = TRACK #
  3340                              <1> 	; 11/07/2022
  3341 000019D4 89F1                <1> 	mov	ecx, esi ; byte 2 = track, byte = 1 head, byte 0 = sector
  3342 000019D6 C1E908              <1> 	shr	ecx, 8
  3343                              <1> 	; ch = track #	
  3344                              <1> 
  3345 000019D9 E86B030000          <1> 	call	SEEK			; MOVE TO CORRECT TRACK
  3346                              <1> 	;pop	ax			; RECOVER COMMAND
  3347                              <1> 	; 24/12/2021
  3348 000019DE 58                  <1> 	pop	eax
  3349 000019DF 721D                <1> 	jc	short ER_1		; ERROR ON SEEK
  3350 000019E1 BB[FE190000]        <1> 	mov	ebx, ER_1		; LOAD ERROR ADDRESS
  3351 000019E6 53                  <1> 	push	ebx			; PUSH NEC_OUT ERROR RETURN
  3352                              <1> 
  3353                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  3354                              <1> 
  3355 000019E7 E824030000          <1> 	call	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  3356 000019EC 89F0                <1> 	mov	eax, esi		; AH = HEAD #
  3357 000019EE 89FB                <1> 	mov	ebx, edi		; BL = DRIVE #
  3358 000019F0 C0E402              <1> 	sal	ah, 2			; MOVE IT TO BIT 2
  3359 000019F3 80E404              <1> 	and	ah, 00000100b		; ISOLATE THAT BIT
  3360 000019F6 08DC                <1> 	or	ah, bl			; OR IN THE DRIVE NUMBER
  3361 000019F8 E813030000          <1> 	call	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  3362 000019FD 5B                  <1> 	pop	ebx			; THROW AWAY ERROR RETURN
  3363                              <1> ER_1:
  3364 000019FE C3                  <1> 	retn
  3365                              <1> 
  3366                              <1> ;-------------------------------------------------------------------------------
  3367                              <1> ; RWV_COM
  3368                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  3369                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  3370                              <1> ;
  3371                              <1> ; ON ENTRY:	EBX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  3372                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  3373                              <1> ;-------------------------------------------------------------------------------
  3374                              <1> RWV_COM:
  3375                              <1> 	; 11/07/2022
  3376                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3377 000019FF B8[4C1A0000]        <1> 	mov	eax, ER_2		; LOAD ERROR ADDRESS
  3378 00001A04 50                  <1> 	push	eax			; PUSH NEC_OUT ERROR RETURN
  3379                              <1> 	;mov	ah, [ebp+1]		; OUTPUT TRACK #
  3380                              <1> 	; 11/07/2022
  3381 00001A05 89F0                <1> 	mov	eax, esi ; byte 0 = sector, byte 1 = head, byte 2 = track
  3382 00001A07 C1E808              <1> 	shr	eax, 8
  3383                              <1> 	; ah = track # 
  3384 00001A0A E801030000          <1> 	call	NEC_OUTPUT
  3385 00001A0F 89F0                <1> 	mov	eax, esi		; OUTPUT HEAD #
  3386                              <1> 	; ah = head #
  3387 00001A11 E8FA020000          <1> 	call	NEC_OUTPUT
  3388                              <1>         ;mov	ah, [ebp]		; OUTPUT SECTOR #
  3389 00001A16 89F0                <1> 	mov	eax, esi
  3390 00001A18 88C4                <1> 	mov	ah, al
  3391                              <1>  	; ah = sector #
  3392 00001A1A E8F1020000          <1> 	CALL	NEC_OUTPUT
  3393                              <1> 	;mov	dl, 3			; BYTES/SECTOR PARAMETER FROM BLOCK
  3394 00001A1F B003                <1> 	mov	al, 3 ; 08/07/2022
  3395 00001A21 E8F9010000          <1> 	call	GET_PARM 		; .. TO THE NEC
  3396 00001A26 E8E5020000          <1> 	call	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  3397                              <1> 	;mov	dl, 4			; EOT PARAMETER FROM BLOCK
  3398 00001A2B B004                <1> 	mov	al, 4 ; 08/07/2022
  3399 00001A2D E8ED010000          <1> 	call	GET_PARM 		; .. TO THE NEC
  3400 00001A32 E8D9020000          <1> 	call	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  3401 00001A37 8A6305              <1>         mov	ah, [ebx+MD.GAP]	; GET GAP LENGTH
  3402                              <1> _R15:
  3403 00001A3A E8D1020000          <1> 	call	NEC_OUTPUT
  3404                              <1> 	;mov	dl, 6			; DTL PARAMETER PROM BLOCK
  3405 00001A3F B006                <1> 	mov	al, 6 ; 08/07/2022
  3406 00001A41 E8D9010000          <1> 	call	GET_PARM		; .. TO THE NEC
  3407 00001A46 E8C5020000          <1> 	call	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  3408 00001A4B 58                  <1> 	pop	eax			; THROW AWAY ERROR EXIT
  3409                              <1> ER_2:
  3410 00001A4C C3                  <1> 	retn
  3411                              <1> 
  3412                              <1> ;-------------------------------------------------------------------------------
  3413                              <1> ; NEC_TERM
  3414                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  3415                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  3416                              <1> ;
  3417                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  3418                              <1> ;-------------------------------------------------------------------------------
  3419                              <1> 
  3420                              <1> NEC_TERM:
  3421                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3422                              <1> 
  3423                              <1> ;-----	LET THE OPERATION HAPPEN
  3424                              <1> 
  3425 00001A4D 56                  <1> 	push	esi			; SAVE HEAD #, # OF SECTORS
  3426 00001A4E E8C7030000          <1> 	call	WAIT_INT		; WAIT FOR THE INTERRUPT
  3427 00001A53 9C                  <1> 	pushfd	; 24/12/2021
  3428 00001A54 E8F0030000          <1> 	call	RESULTS			; GET THE NEC STATUS
  3429 00001A59 724B                <1> 	jc	short SET_END_POP
  3430 00001A5B 9D                  <1> 	popfd	; 24/12/2021
  3431 00001A5C 723E                <1> 	jc	short SET_END		; LOOK FOR ERROR
  3432                              <1> 
  3433                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  3434                              <1> 
  3435 00001A5E FC                  <1> 	cld				; SET THE CORRECT DIRECTION
  3436 00001A5F BE[8D670000]        <1> 	mov	esi, NEC_STATUS		; POINT TO STATUS FIELD
  3437 00001A64 AC                  <1> 	lodsb				; GET ST0
  3438 00001A65 24C0                <1> 	and	al, 11000000b		; TEST FOR NORMAL TERMINATION
  3439 00001A67 7433                <1> 	jz	short SET_END
  3440 00001A69 3C40                <1> 	cmp	al, 01000000b		; TEST FOR ABNORMAL TERMINATION
  3441 00001A6B 7527                <1> 	jnz	short J18		; NOT ABNORMAL, BAD NEC
  3442                              <1> 
  3443                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  3444                              <1> 
  3445 00001A6D AC                  <1> 	lodsb				; GET ST1
  3446 00001A6E D0E0                <1> 	sal	al, 1			; TEST FOR EDT FOUND
  3447 00001A70 B404                <1> 	mov	ah, RECORD_NOT_FND
  3448 00001A72 7222                <1> 	jc	short J19
  3449 00001A74 C0E002              <1> 	sal	al, 2
  3450 00001A77 B410                <1> 	mov	ah, BAD_CRC
  3451 00001A79 721B                <1> 	jc	short J19
  3452 00001A7B D0E0                <1> 	sal	al, 1			; TEST FOR DMA OVERRUN
  3453 00001A7D B408                <1> 	mov	ah, BAD_DMA
  3454 00001A7F 7215                <1> 	jc	short J19
  3455 00001A81 C0E002              <1> 	sal	al, 2			; TEST FOR RECORD NOT FOUND
  3456 00001A84 B404                <1> 	mov	ah, RECORD_NOT_FND
  3457 00001A86 720E                <1> 	jc	short J19
  3458 00001A88 D0E0                <1> 	sal	al, 1
  3459 00001A8A B403                <1> 	mov	ah, WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  3460 00001A8C 7208                <1> 	jc	short J19
  3461 00001A8E D0E0                <1> 	sal	al, 1			; TEST MISSING ADDRESS MARK
  3462 00001A90 B402                <1> 	mov	ah, BAD_ADDR_MARK
  3463 00001A92 7202                <1> 	jc	short J19
  3464                              <1> 
  3465                              <1> ;----- 	NEC MUST HAVE FAILED
  3466                              <1> J18:
  3467 00001A94 B420                <1> 	mov	ah, BAD_NEC
  3468                              <1> J19:
  3469 00001A96 0825[8C670000]      <1> 	or	[DSKETTE_STATUS], ah
  3470                              <1> SET_END:
  3471 00001A9C 803D[8C670000]01    <1> 	cmp	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  3472 00001AA3 F5                  <1> 	cmc
  3473 00001AA4 5E                  <1> 	pop	esi
  3474 00001AA5 C3                  <1> 	retn				; RESTORE HEAD #, # OF SECTORS
  3475                              <1> 
  3476                              <1> SET_END_POP:
  3477 00001AA6 9D                  <1> 	popfd	; 24/12/2021
  3478 00001AA7 EBF3                <1> 	jmp	short SET_END
  3479                              <1> 
  3480                              <1> ;-------------------------------------------------------------------------------
  3481                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  3482                              <1> ;-------------------------------------------------------------------------------
  3483                              <1> DSTATE:
  3484                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3485 00001AA9 803D[8C670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; CHECK FOR ERROR
  3486 00001AB0 753E                <1> 	jne	short SETBAC		; IF ERROR JUMP
  3487 00001AB2 808F[97670000]10    <1> 	or	byte [DSK_STATE+edi], MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  3488 00001AB9 F687[97670000]04    <1> 	test	byte [DSK_STATE+edi], DRV_DET ; DRIVE DETERMINED ?
  3489 00001AC0 752E                <1> 	jnz	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  3490 00001AC2 8A87[97670000]      <1> 	mov	al, [DSK_STATE+edi]	; LOAD STATE
  3491 00001AC8 24C0                <1> 	and	al, RATE_MSK		; KEEP ONLY RATE
  3492 00001ACA 3C80                <1> 	cmp	al, RATE_250		; RATE 250 ?
  3493 00001ACC 751B                <1> 	jne	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  3494                              <1> 
  3495                              <1> ;----- 	CHECK IF IT IS 1.44M
  3496                              <1> 
  3497 00001ACE E843010000          <1> 	call	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  3498                              <1> 	;;20/02/2015
  3499                              <1> 	;;jc	short M_12		; CMOS BAD
  3500 00001AD3 7414                <1> 	jz	short M_12 ;; 20/02/2015
  3501 00001AD5 3C04                <1> 	cmp	al, 4			; 1.44MB DRIVE ?
  3502 00001AD7 7410                <1> 	je	short M_12		; YES
  3503                              <1> M_720:
  3504 00001AD9 80A7[97670000]FD    <1> 	and	byte [DSK_STATE+edi], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  3505 00001AE0 808F[97670000]04    <1> 	or	byte [DSK_STATE+edi], DRV_DET  ; MARK DRIVE DETERMINED
  3506 00001AE7 EB07                <1> 	jmp	short SETBAC		; BACK
  3507                              <1> M_12:	
  3508 00001AE9 808F[97670000]06    <1> 	or	byte [DSK_STATE+edi], DRV_DET+FMT_CAPA 
  3509                              <1> 					; TURN ON DETERMINED & FMT CAPA
  3510                              <1> SETBAC:
  3511 00001AF0 C3                  <1> 	retn
  3512                              <1> 
  3513                              <1> ;-------------------------------------------------------------------------------
  3514                              <1> ; RETRY	
  3515                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  3516                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  3517                              <1> ;
  3518                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  3519                              <1> ;-------------------------------------------------------------------------------
  3520                              <1> RETRY:
  3521                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3522 00001AF1 803D[8C670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; GET STATUS OF OPERATION
  3523 00001AF8 7444                <1> 	je	short NO_RETRY		; SUCCESSFUL OPERATION
  3524 00001AFA 803D[8C670000]80    <1> 	cmp	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT NO RETRY
  3525 00001B01 743B                <1> 	je	short NO_RETRY
  3526 00001B03 8AA7[97670000]      <1> 	mov	ah, [DSK_STATE+edi]	; GET MEDIA STATE OF DRIVE
  3527 00001B09 F6C410              <1> 	test	ah, MED_DET		; ESTABLISHED/DETERMINED ?
  3528 00001B0C 7530                <1> 	jnz	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  3529 00001B0E 80E4C0              <1> 	and	ah, RATE_MSK		; ISOLATE RATE
  3530 00001B11 8A2D[94670000]      <1> 	mov	ch, [LASTRATE]		; GET START OPERATION STATE
  3531 00001B17 C0C504              <1> 	rol	ch, 4			; TO CORRESPONDING BITS
  3532 00001B1A 80E5C0              <1> 	and	ch, RATE_MSK		; ISOLATE RATE BITS
  3533 00001B1D 38E5                <1> 	cmp	ch, ah			; ALL RATES TRIED
  3534 00001B1F 741D                <1> 	je	short NO_RETRY		; IF YES, THEN TRUE ERROR
  3535                              <1> 
  3536                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  3537                              <1> ;	 00000000B (500) -> 10000000B	(250)
  3538                              <1> ;	 10000000B (250) -> 01000000B	(300)
  3539                              <1> ;	 01000000B (300) -> 00000000B	(500)
  3540                              <1> 
  3541 00001B21 80FC01              <1> 	cmp	ah, RATE_500+1		; SET CY FOR RATE 500
  3542 00001B24 D0DC                <1> 	rcr	ah, 1			; TO NEXT STATE
  3543 00001B26 80E4C0              <1> 	and	ah, RATE_MSK		; KEEP ONLY RATE BITS
  3544 00001B29 80A7[97670000]1F    <1> 	and	byte [DSK_STATE+edi], ~(RATE_MSK+DBL_STEP)
  3545                              <1> 					; RATE, DBL STEP OFF
  3546 00001B30 08A7[97670000]      <1> 	or	[DSK_STATE+edi], ah	; TURN ON NEW RATE
  3547 00001B36 C605[8C670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; RESET STATUS FOR RETRY
  3548 00001B3D F9                  <1> 	stc				; SET CARRY FOR RETRY
  3549                              <1> NO_RETRY:	; 08/07/2022
  3550 00001B3E C3                  <1> 	retn				; RETRY RETURN
  3551                              <1> 
  3552                              <1> ;NO_RETRY:
  3553                              <1> 	;clc				; CLEAR CARRY NO RETRY
  3554                              <1> 	;RETn				; NO RETRY RETURN
  3555                              <1> 
  3556                              <1> ;-------------------------------------------------------------------------------
  3557                              <1> ; NUM_TRANS
  3558                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  3559                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  3560                              <1> ;
  3561                              <1> ; ON ENTRY:	[BP+1] = TRACK
  3562                              <1> ;		SI-HI  = HEAD
  3563                              <1> ;		[BP]   = START SECTOR
  3564                              <1> ;
  3565                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  3566                              <1> ;-------------------------------------------------------------------------------
  3567                              <1> NUM_TRANS:
  3568                              <1> 	; 11/07/2022
  3569                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3570 00001B3F 30C0                <1> 	xor	al, al			; CLEAR FOR ERROR
  3571 00001B41 803D[8C670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; CHECK FOR ERROR
  3572                              <1> 	; 24/12/2021
  3573 00001B48 7529                <1> 	jne	short NT_OUT		; IF ERROR 0 TRANSFERRED
  3574                              <1> 	;mov	dl, 4			; SECTORS/TRACK OFFSET TO DL
  3575 00001B4A B004                <1> 	mov	al, 4 ; 08/07/2022
  3576 00001B4C E8CE000000          <1> 	call	GET_PARM		; AH = SECTORS/TRACK
  3577                              <1> 	;mov	bl, [NEC_STATUS+5]	; GET ENDING SECTOR
  3578 00001B51 A0[92670000]        <1> 	mov	al, [NEC_STATUS+5]
  3579 00001B56 89F1                <1> 	mov	ecx, esi		; CH = HEAD # STARTED
  3580 00001B58 88CB                <1> 	mov	bl, cl ; 11/07/2022 ; sector #
  3581 00001B5A 3A2D[91670000]      <1> 	cmp	ch, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  3582 00001B60 750D                <1> 	jne	short DIF_HD		; IF ON SAME HEAD, THEN NO ADJUST
  3583                              <1> 	; 11/07/2022
  3584                              <1> 	;mov	ch, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  3585                              <1> 	;cmp	ch, [ebp+1]		; IS IT ASKED FOR TRACK
  3586                              <1> 	;jz	short SAME_TR		; IF SAME TRACK NO INCREASE
  3587 00001B62 C1E908              <1> 	shr	ecx, 8 ; byte 3 = track # --> byte 2
  3588 00001B65 3A2D[90670000]      <1> 	cmp	ch, [NEC_STATUS+3]
  3589 00001B6B 7404                <1> 	je	short SAME_TRK		
  3590                              <1> 	; 11/07/2022
  3591                              <1> 	;add	bl, ah			; ADD SECTORS/TRACK
  3592 00001B6D 00E0                <1> 	add	al, ah
  3593                              <1> DIF_HD:
  3594                              <1> 	;add	bl, ah			; ADD SECTORS/TRACK
  3595 00001B6F 00E0                <1> 	add	al, ah
  3596                              <1> SAME_TRK:
  3597                              <1> 	;sub	bl, [ebp]		; SUBTRACT START FROM END
  3598                              <1> 	;mov	al, bl			; TO AL
  3599 00001B71 28D8                <1> 	sub	al, bl
  3600                              <1> NT_OUT:
  3601 00001B73 C3                  <1> 	retn
  3602                              <1> 
  3603                              <1> ;-------------------------------------------------------------------------------
  3604                              <1> ; SETUP_DBL
  3605                              <1> ;	CHECK DOUBLE STEP.
  3606                              <1> ;
  3607                              <1> ; ON ENTRY :	EDI = DRIVE #
  3608                              <1> ;
  3609                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  3610                              <1> ;-------------------------------------------------------------------------------
  3611                              <1> SETUP_DBL:
  3612                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3613 00001B74 8AA7[97670000]      <1> 	mov	ah, [DSK_STATE+edi]	; ACCESS STATE
  3614 00001B7A F6C410              <1> 	test	ah, MED_DET		; ESTABLISHED STATE ?
  3615 00001B7D 7578                <1> 	jnz	short NO_DBL		; IF ESTABLISHED THEN DOUBLE DONE
  3616                              <1> 
  3617                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  3618                              <1> 
  3619 00001B7F C605[89670000]00    <1> 	mov	byte [SEEK_STATUS], 0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  3620 00001B86 E8CF000000          <1> 	call	MOTOR_ON		; ENSURE MOTOR STAY ON
  3621 00001B8B B500                <1> 	mov	ch, 0			; LOAD TRACK 0
  3622 00001B8D E8B7010000          <1> 	call	SEEK			; SEEK TO TRACK 0
  3623 00001B92 E862000000          <1> 	call	READ_ID			; READ ID FUNCTION
  3624 00001B97 7243                <1> 	jc	short SD_ERR		; IF ERROR NO TRACK 0
  3625                              <1> 
  3626                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  3627                              <1> 
  3628 00001B99 66B95004            <1> 	mov	cx, 0450h 		; START, MAX TRACKS
  3629 00001B9D F687[97670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  3630 00001BA4 7402                <1> 	jz	short CNT_OK		; IF NOT COUNT IS SETUP
  3631 00001BA6 B1A0                <1> 	mov	cl, 0A0h		; MAXIMUM TRACK 1.2 MB
  3632                              <1> 
  3633                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  3634                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  3635                              <1> ;	THEN SET DOUBLE STEP ON.
  3636                              <1> 
  3637                              <1> CNT_OK:
  3638 00001BA8 C605[8B670000]FF    <1>        	mov	byte [MOTOR_COUNT], 0FFh ; ENSURE MOTOR STAYS ON FOR OPERATION 
  3639                              <1> 	; 24/12/2021
  3640 00001BAF 51                  <1> 	push	ecx			; SAVE TRACK, COUNT
  3641 00001BB0 C605[8C670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS, EXPECT ERRORS
  3642 00001BB7 31C0                <1> 	xor	eax, eax		; CLEAR EAX
  3643 00001BB9 D0ED                <1> 	shr	ch, 1			; HALVE TRACK, CY = HEAD
  3644 00001BBB C0D003              <1> 	rcl	al, 3			; AX = HEAD IN CORRECT BIT
  3645                              <1> 	; 24/12/2021
  3646 00001BBE 50                  <1> 	push	eax			; SAVE HEAD
  3647 00001BBF E885010000          <1> 	call	SEEK			; SEEK TO TRACK
  3648                              <1> 	; 24/12/2021
  3649 00001BC4 58                  <1> 	pop	eax			; RESTORE HEAD
  3650 00001BC5 09C7                <1> 	or	edi, eax		; DI = HEAD OR'ED DRIVE
  3651 00001BC7 E82D000000          <1> 	call	READ_ID			; READ ID HEAD 0
  3652 00001BCC 9C                  <1> 	pushf				; SAVE RETURN FROM READ_ID
  3653 00001BCD 6681E7FB00          <1> 	and	di, 11111011b		; TURN OFF HEAD 1 BIT
  3654 00001BD2 9D                  <1> 	popf				; RESTORE ERROR RETURN
  3655                              <1> 	; 24/12/2021
  3656 00001BD3 59                  <1> 	pop	ecx			; RESTORE COUNT
  3657 00001BD4 7308                <1> 	jnc	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  3658 00001BD6 FEC5                <1> 	inc	ch			; INC FOR NEXT TRACK
  3659 00001BD8 38CD                <1> 	cmp	ch, cl			; REACHED MAXIMUM YET
  3660 00001BDA 75CC                <1> 	jnz	short CNT_OK		; CONTINUE TILL ALL TRIED
  3661                              <1> 
  3662                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  3663                              <1> 
  3664                              <1> SD_ERR:	
  3665 00001BDC F9                  <1> 	stc				; SET CARRY FOR ERROR
  3666 00001BDD C3                  <1> 	retn				; SETUP_DBL ERROR EXIT
  3667                              <1> 
  3668                              <1> DO_CHK:
  3669 00001BDE 8A0D[90670000]      <1> 	mov	cl, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  3670 00001BE4 888F[99670000]      <1> 	mov	[DSK_TRK+edi], cl	; STORE TRACK NUMBER
  3671 00001BEA D0ED                <1> 	shr	ch, 1			; HALVE TRACK
  3672 00001BEC 38CD                <1> 	cmp	ch, cl			; IS IT THE SAME AS ASKED FOR TRACK
  3673 00001BEE 7407                <1> 	jz	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  3674 00001BF0 808F[97670000]20    <1> 	or	byte [DSK_STATE+edi], DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  3675                              <1> NO_DBL:
  3676 00001BF7 F8                  <1> 	clc				; CLEAR ERROR FLAG
  3677 00001BF8 C3                  <1> 	retn
  3678                              <1> 
  3679                              <1> ;-------------------------------------------------------------------------------
  3680                              <1> ; READ_ID
  3681                              <1> ;	READ ID FUNCTION.
  3682                              <1> ;
  3683                              <1> ; ON ENTRY:	EDI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  3684                              <1> ;
  3685                              <1> ; ON EXIT: 	EDI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  3686                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  3687                              <1> ;-------------------------------------------------------------------------------
  3688                              <1> READ_ID:
  3689                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3690 00001BF9 B8[151C0000]        <1> 	mov	eax, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  3691 00001BFE 50                  <1> 	push	eax
  3692 00001BFF B44A                <1> 	mov	ah, 4Ah			; READ ID COMMAND
  3693 00001C01 E80A010000          <1> 	call	NEC_OUTPUT		; TO CONTROLLER
  3694 00001C06 89F8                <1> 	mov	eax, edi		; DRIVE # TO AH, HEAD 0
  3695 00001C08 88C4                <1> 	mov	ah, al
  3696 00001C0A E801010000          <1> 	call	NEC_OUTPUT		; TO CONTROLLER
  3697 00001C0F E839FEFFFF          <1> 	call	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  3698 00001C14 58                  <1> 	pop	eax			; THROW AWAY ERROR ADDRESS
  3699                              <1> ER_3:
  3700 00001C15 C3                  <1> 	retn
  3701                              <1> 
  3702                              <1> ;-------------------------------------------------------------------------------
  3703                              <1> ; CMOS_TYPE
  3704                              <1> ;	RETURNS CMOS DISKETTE TYPE
  3705                              <1> ;
  3706                              <1> ; ON ENTRY:	EDI = DRIVE #
  3707                              <1> ;
  3708                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  3709                              <1> ;-------------------------------------------------------------------------------
  3710                              <1> 
  3711                              <1> CMOS_TYPE: ; 11/12/2014
  3712                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3713 00001C16 8A87[2C620000]      <1> 	mov	al, [edi+fd0_type] ; diskette type
  3714 00001C1C 20C0                <1> 	and 	al, al ; 18/12/2014
  3715 00001C1E C3                  <1> 	retn
  3716                              <1> 
  3717                              <1> ;-------------------------------------------------------------------------------
  3718                              <1> ; GET_PARM
  3719                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  3720                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  3721                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  3722                              <1> ;	THE PARAMETER IN DL.
  3723                              <1> ;
  3724                              <1> ; ON ENTRY:	AL = INDEX OF BYTE TO BE FETCHED ; 08/07/2022
  3725                              <1> ;
  3726                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  3727                              <1> ;		AL DESTROYED
  3728                              <1> ;-------------------------------------------------------------------------------
  3729                              <1> GET_PARM:
  3730                              <1> 	; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3731                              <1> 	;	 ENTRY:
  3732                              <1> 	;	     AL = INDEX
  3733                              <1> 	;	    EDI = DRIVE #
  3734                              <1> 	; 	 RETURN:
  3735                              <1> 	;	     AH = REQUESTED PARAMETER
  3736                              <1> 	;	     AL DESTROYED
  3737                              <1> 	
  3738                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3739                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  3740                              <1> 	;push	esi ; 11/07/2022
  3741 00001C1F 53                  <1> 	push	ebx			; SAVE EBX	
  3742 00001C20 0FB6D8              <1> 	movzx	ebx, al			; EBX = INDEX
  3743                              <1>    	; 17/12/2014
  3744                              <1> 	;mov	ax, [cfd] ; current (AL) and previous fd (AH)
  3745                              <1> 	; 11/07/2022
  3746                              <1> 	;cmp	al, ah
  3747                              <1> 	;je	short gpndc
  3748                              <1> 
  3749                              <1> 	; 11/07/2022
  3750 00001C23 89F8                <1> 	mov	eax, edi
  3751 00001C25 3A05[21620000]      <1> 	cmp	al, [pfd] ; is same with previous drive # ?
  3752 00001C2B 7423                <1> 	je	short gpndc	
  3753                              <1> 
  3754 00001C2D A2[21620000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  3755                              <1> 
  3756 00001C32 53                  <1> 	push	ebx ; 08/02/2015
  3757                              <1> 	
  3758                              <1> 	;mov	bl, al 
  3759                              <1> 	; 11/12/2014
  3760                              <1> 	;mov	al, [ebx+fd0_type]	; Drive type (0,1,2,3,4)
  3761                              <1> 	; 11/07/2022
  3762 00001C33 8A87[2C620000]      <1> 	mov	al, [edi+fd0_type]	; Drive type (0,1,2,3,4)	
  3763                              <1> 	; 18/12/2014
  3764 00001C39 20C0                <1> 	and	al, al
  3765 00001C3B 7507                <1> 	jnz	short gpdtc
  3766 00001C3D BB[0B620000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  3767 00001C42 EB05                <1>         jmp     short gpdpu
  3768                              <1> gpdtc:	
  3769 00001C44 E8B0FBFFFF          <1> 	call	DR_TYPE_CHECK
  3770                              <1> 	; cf = 1 -> EBX points to 1.44MB fd parameter table (default)
  3771                              <1> gpdpu:
  3772 00001C49 891D[A8610000]      <1> 	mov	[DISK_POINTER], ebx
  3773 00001C4F 5B                  <1> 	pop	ebx
  3774                              <1> gpndc:
  3775                              <1> 	;mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  3776                              <1> 	;mov	ah, [esi+ebx]		; GET THE WORD
  3777                              <1> 	; 11/07/2022
  3778 00001C50 031D[A8610000]      <1> 	add	ebx, [DISK_POINTER]
  3779 00001C56 8A23                <1> 	mov	ah, [ebx] 
  3780 00001C58 5B                  <1> 	pop	ebx			; RESTORE EBX
  3781                              <1> 	;pop	esi ; 11/07/2022
  3782 00001C59 C3                  <1> 	retn
  3783                              <1> 
  3784                              <1> ;-------------------------------------------------------------------------------
  3785                              <1> ; MOTOR_ON
  3786                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  3787                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  3788                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  3789                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  3790                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  3791                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  3792                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  3793                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  3794                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  3795                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  3796                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  3797                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  3798                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  3799                              <1> ;
  3800                              <1> ; ON ENTRY:	EDI = DRIVE #
  3801                              <1> ; ON EXIT:	EAX, ECX, EDX DESTROYED
  3802                              <1> ;-------------------------------------------------------------------------------
  3803                              <1> MOTOR_ON:
  3804                              <1> 	; 12/07/2022
  3805                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3806 00001C5A 53                  <1> 	push	ebx			; SAVE REG.
  3807 00001C5B E820000000          <1> 	call	TURN_ON			; TURN ON MOTOR
  3808 00001C60 721C                <1> 	jc	short MOT_IS_ON		; IF CY=1 NO WAIT
  3809                              <1> 	;call	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  3810                              <1> 	; 08/07/2022
  3811                              <1> 	;call	XLAT_NEW ; 12/07/2022	; TRANSLATE STATE TO PRESENT ARCH,
  3812                              <1> 	;call	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  3813                              <1> 	;jc	short MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  3814                              <1> M_WAIT:
  3815                              <1> 	;mov	dl,10			; GET THE MOTOR WAIT PARAMETER
  3816 00001C62 B00A                <1> 	mov	al, 10 ; 08/07/2022
  3817 00001C64 E8B6FFFFFF          <1> 	call	GET_PARM
  3818                              <1> 	; 08/07/2022			; AH = MOTOR WAIT PARAMETER
  3819 00001C69 80FC08              <1> 	cmp	ah, 8			; SEE IF AT LEAST A SECOND IS SPECIFIED			
  3820                              <1> 	;jae	short GP2		; IF YES, CONTINUE
  3821 00001C6C 7302                <1> 	jae	short J13
  3822 00001C6E B408                <1> 	mov	ah, 8			; ONE SECOND WAIT FOR MOTOR START UP
  3823                              <1> 
  3824                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  3825                              <1> GP2:	
  3826                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  3827                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  3828 00001C70 B95E200000          <1> 	mov	ecx, 8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  3829 00001C75 E817F7FFFF          <1> 	call	WAITF			; GO TO FIXED WAIT ROUTINE
  3830                              <1> 	;dec	al			; DECREMENT TIME VALUE
  3831 00001C7A FECC                <1> 	dec	ah
  3832 00001C7C 75F2                <1> 	jnz	short J13		; ARE WE DONE YET
  3833                              <1> MOT_IS_ON:
  3834 00001C7E 5B                  <1> 	pop	ebx			; RESTORE REG.
  3835 00001C7F C3                  <1> 	retn
  3836                              <1> 
  3837                              <1> ;-------------------------------------------------------------------------------
  3838                              <1> ; TURN_ON
  3839                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  3840                              <1> ;
  3841                              <1> ; ON ENTRY:	EDI = DRIVE #
  3842                              <1> ;
  3843                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  3844                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  3845                              <1> ;		EAX, EBX, ECX, EDX DESTROYED
  3846                              <1> ;-------------------------------------------------------------------------------
  3847                              <1> TURN_ON:
  3848                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3849 00001C80 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  3850 00001C82 88D9                <1> 	mov	cl, bl			; CL = DRIVE #
  3851 00001C84 C0C304              <1> 	rol	bl, 4			; BL = DRIVE SELECT
  3852 00001C87 FA                  <1> 	cli				; NO INTERRUPTS WHILE DETERMINING STATUS
  3853 00001C88 C605[8B670000]FF    <1> 	mov	byte [MOTOR_COUNT], 0FFh ; ENSURE MOTOR STAYS ON FOR OPERATION
  3854 00001C8F A0[8A670000]        <1> 	mov	al, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  3855 00001C94 2430                <1> 	and	al, 00110000b		; KEEP ONLY DRIVE SELECT BITS
  3856 00001C96 B401                <1> 	mov	ah, 1			; MASK FOR DETERMINING MOTOR BIT
  3857 00001C98 D2E4                <1> 	shl	ah, cl			; AH = MOTOR ON, A=00000001, B=00000010
  3858                              <1> 
  3859                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  3860                              <1> ;  BL = DRIVE SELECT DESIRED
  3861                              <1> ;  AH = MOTOR ON MASK DESIRED
  3862                              <1> 
  3863 00001C9A 38D8                <1> 	cmp	al, bl			; REQUESTED DRIVE ALREADY SELECTED ?
  3864 00001C9C 7508                <1> 	jne	short TURN_IT_ON	; IF NOT SELECTED JUMP
  3865 00001C9E 8425[8A670000]      <1> 	test	ah, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  3866 00001CA4 7535                <1> 	jnz	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  3867                              <1> 
  3868                              <1> TURN_IT_ON:
  3869 00001CA6 08DC                <1> 	or	ah, bl			; AH = DRIVE SELECT AND MOTOR ON
  3870 00001CA8 8A3D[8A670000]      <1> 	mov	bh, [MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  3871 00001CAE 80E70F              <1> 	and	bh, 00001111b		; KEEP ONLY MOTOR BITS
  3872 00001CB1 8025[8A670000]CF    <1> 	and	byte [MOTOR_STATUS], 11001111b ; CLEAR OUT DRIVE SELECT
  3873 00001CB8 0825[8A670000]      <1> 	or	[MOTOR_STATUS], ah	; OR IN DRIVE SELECTED AND MOTOR ON
  3874 00001CBE A0[8A670000]        <1> 	mov	al, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  3875 00001CC3 88C3                <1> 	mov	bl, al			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  3876 00001CC5 80E30F              <1> 	and	bl, 00001111b		; KEEP ONLY MOTOR BITS
  3877 00001CC8 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3878 00001CC9 243F                <1> 	and	al, 00111111b		; STRIP AWAY UNWANTED BITS
  3879 00001CCB C0C004              <1> 	rol	al, 4			; PUT BITS IN DESIRED POSITIONS
  3880 00001CCE 0C0C                <1> 	or	al, 00001100b		; NO RESET, ENABLE DMA/INTERRUPT
  3881 00001CD0 66BAF203            <1> 	mov	dx, 03F2h		; SELECT DRIVE AND TURN ON MOTOR
  3882 00001CD4 EE                  <1> 	out	dx, al
  3883 00001CD5 38FB                <1> 	cmp	bl, bh			; NEW MOTOR TURNED ON ?
  3884                              <1> 	;je	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  3885 00001CD7 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  3886 00001CD9 F8                  <1> 	clc				; RESET CARRY MEANING WAIT
  3887 00001CDA C3                  <1> 	retn
  3888                              <1> 
  3889                              <1> NO_MOT_WAIT:
  3890 00001CDB FB                  <1> 	sti
  3891                              <1> no_mot_w1: ; 27/02/2015
  3892 00001CDC F9                  <1> 	stc				; SET NO WAIT REQUIRED
  3893                              <1> 	;sti				; INTERRUPTS BACK ON
  3894 00001CDD C3                  <1> 	retn
  3895                              <1> 
  3896                              <1> ;-------------------------------------------------------------------------------
  3897                              <1> ; HD_WAIT
  3898                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  3899                              <1> ;
  3900                              <1> ; ON ENTRY:	DI = DRIVE #
  3901                              <1> ;
  3902                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  3903                              <1> ;-------------------------------------------------------------------------------
  3904                              <1> HD_WAIT:
  3905                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3906                              <1> 	;mov	dl, 9			; GET HEAD SETTLE PARAMETER
  3907 00001CDE B009                <1> 	mov	al, 9	; 08/07/2022
  3908 00001CE0 E83AFFFFFF          <1> 	CALL	GET_PARM
  3909 00001CE5 08E4                <1> 	or	ah, ah	; 17/12/2014	; CHECK FOR ANY WAIT?
  3910 00001CE7 7519                <1> 	jnz	short DO_WAT		; IF THERE DO NOT ENFORCE
  3911 00001CE9 F605[8A670000]80    <1>         test	byte [MOTOR_STATUS], 10000000b ; SEE IF A WRITE OPERATION
  3912                              <1> 	;jz	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  3913                              <1> 	;or	ah, ah			; CHECK FOR ANY WAIT?
  3914                              <1> 	;jnz	short DO_WAT		; IF THERE DO NOT ENFORCE
  3915 00001CF0 741D                <1> 	jz	short HW_DONE
  3916 00001CF2 B40F                <1> 	mov	ah, HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  3917 00001CF4 8A87[97670000]      <1> 	mov	al, [DSK_STATE+edi]	; LOAD STATE
  3918 00001CFA 24C0                <1> 	and	al, RATE_MSK		; KEEP ONLY RATE
  3919 00001CFC 3C80                <1> 	cmp	al, RATE_250		; 1.2 M DRIVE ?
  3920 00001CFE 7502                <1> 	jnz	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  3921                              <1> ;GP3:
  3922 00001D00 B414                <1> 	mov	ah, HD320_SETTLE		; USE 320/360 HEAD SETTLE
  3923                              <1> ;	jmp	short DO_WAT
  3924                              <1> 
  3925                              <1> ;ISNT_WRITE:
  3926                              <1> ;	or	ah, ah			; CHECK FOR NO WAIT
  3927                              <1> ;	jz	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  3928                              <1> 
  3929                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  3930                              <1> DO_WAT:
  3931                              <1> ;	mov	al, ah			; AL = # MILLISECONDS
  3932                              <1> ;	;xor	ah, ah			; AX = # MILLISECONDS
  3933                              <1> J29:					; 	1 MILLISECOND LOOP
  3934                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  3935                              <1> 	;mov	ecx, 66			; COUNT AT 15.085737 US PER COUNT
  3936                              <1> 	; 08/07/2022
  3937 00001D02 29C9                <1> 	sub	ecx, ecx
  3938 00001D04 B142                <1> 	mov	cl, 66
  3939 00001D06 E886F6FFFF          <1> 	call	WAITF			; DELAY FOR 1 MILLISECOND
  3940                              <1> 	;dec	al			; DECREMENT THE COUNT
  3941 00001D0B FECC                <1> 	dec	ah
  3942 00001D0D 75F3                <1> 	jnz	short J29		; DO AL MILLISECOND # OF TIMES
  3943                              <1> HW_DONE:
  3944 00001D0F C3                  <1> 	retn
  3945                              <1> 
  3946                              <1> ;-------------------------------------------------------------------------------
  3947                              <1> ; NEC_OUTPUT
  3948                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  3949                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  3950                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  3951                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  3952                              <1> ; 
  3953                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  3954                              <1> ;
  3955                              <1> ; ON EXIT:	CY = 0  SUCCESS
  3956                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  3957                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  3958                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  3959                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  3960                              <1> ;
  3961                              <1> ;		EAX, ECX, EDX DESTROYED
  3962                              <1> ;-------------------------------------------------------------------------------
  3963                              <1> 
  3964                              <1> ; 09/12/2014 [Erdogan Tan] 
  3965                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  3966                              <1> ; Diskette Drive Controller Status Register (3F4h)
  3967                              <1> ;	This read only register facilitates the transfer of data between
  3968                              <1> ;	the system microprocessor and the controller.
  3969                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  3970                              <1> ;	  with the system micrprocessor.
  3971                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  3972                              <1> ;	  the transfer is to the controller.
  3973                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  3974                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  3975                              <1> ; Bit 3 - Reserved.
  3976                              <1> ; Bit 2 - Reserved.
  3977                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  3978                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 0 is in the seek mode.
  3979                              <1> 
  3980                              <1> ; Data Register (3F5h)
  3981                              <1> ; This read/write register passes data, commands and parameters, and provides
  3982                              <1> ; diskette status information.
  3983                              <1>   		
  3984                              <1> NEC_OUTPUT:
  3985                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3986                              <1> 	;push	ebx			; SAVE REG.
  3987 00001D10 BAF4030000          <1> 	mov	edx, 03F4h		; STATUS PORT
  3988                              <1> 	;xor	ecx, ecx		; COUNT FOR TIME OUT
  3989                              <1> 	; 16/12/2014
  3990                              <1> 	; waiting for (max.) 0.5 seconds
  3991                              <1>         ;;mov	byte [wait_count], 0 ;; 27/02/2015
  3992                              <1> 	;
  3993                              <1> 	; 17/12/2014
  3994                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  3995                              <1> 	;
  3996                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  3997                              <1> 	;		go on.
  3998                              <1> 	;INPUT:
  3999                              <1> 	;	AH=Mask for isolation bits.
  4000                              <1> 	;	AL=pattern to look for.
  4001                              <1> 	;	DX=Port to test for
  4002                              <1> 	;	ECX=Number of memory refresh periods to delay.
  4003                              <1> 	;	     (normally 30 microseconds per period.)
  4004                              <1> 	;
  4005                              <1> 	;WFP_SHORT:  
  4006                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  4007                              <1> 	;
  4008                              <1> 
  4009 00001D15 B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  4010                              <1> ;
  4011                              <1> ;WFPS_OUTER_LP:
  4012                              <1> ;	;
  4013                              <1> ;WFPS_CHECK_PORT:
  4014                              <1> J23:
  4015 00001D1A EC                  <1> 	in	al, dx			; GET STATUS
  4016 00001D1B 24C0                <1> 	and	al, 11000000b		; KEEP STATUS AND DIRECTION
  4017 00001D1D 3C80                <1> 	cmp	al, 10000000b		; STATUS 1 AND DIRECTION 0 ?
  4018 00001D1F 7418                <1> 	jz	short J27		; STATUS AND DIRECTION OK
  4019                              <1> WFPS_HI:
  4020 00001D21 E461                <1> 	in	al, PORT_B	; 061h	; SYS1	; wait for hi to lo
  4021 00001D23 A810                <1> 	test	al, 010h		; transition on memory
  4022 00001D25 75FA                <1> 	jnz	short WFPS_HI		; refresh.
  4023                              <1> WFPS_LO:
  4024 00001D27 E461                <1> 	in	al, PORT_B		; SYS1
  4025 00001D29 A810                <1> 	test	al, 010h
  4026 00001D2B 74FA                <1> 	jz	short WFPS_LO
  4027                              <1> 	;loop	short WFPS_CHECK_PORT
  4028 00001D2D E2EB                <1> 	loop	J23	; 27/02/2015	; REPEAT TILL DELAY FINISHED
  4029                              <1> 
  4030                              <1> 	; fail
  4031                              <1> 
  4032                              <1> ;WFPS_TIMEOUT:
  4033                              <1> 
  4034                              <1> ;-----	FALL THRU TO ERROR RETURN
  4035                              <1> 
  4036 00001D2F 800D[8C670000]80    <1> 	or	byte [DSKETTE_STATUS], TIME_OUT
  4037                              <1> 	;pop	ebx			; RESTORE REG.
  4038 00001D36 58                  <1> 	pop	eax ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  4039 00001D37 F9                  <1> 	stc				; INDICATE ERROR TO CALLER
  4040 00001D38 C3                  <1> 	retn
  4041                              <1> 
  4042                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  4043                              <1> 
  4044                              <1> J27:	
  4045 00001D39 88E0                <1> 	mov	al, ah			; GET BYTE TO OUTPUT
  4046 00001D3B 42                  <1> 	inc	edx			; DATA PORT = STATUS PORT + 1
  4047 00001D3C EE                  <1> 	out	dx, al			; OUTPUT THE BYTE
  4048                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  4049                              <1> 	; 27/02/2015
  4050 00001D3D 9C                  <1> 	pushfd	; 24/12/2021		; SAVE FLAGS
  4051                              <1> 	;mov	ecx, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  4052 00001D3E 29C9                <1> 	sub	ecx, ecx
  4053 00001D40 B103                <1> 	mov	cl, 3 ; 24/12/2021
  4054 00001D42 E84AF6FFFF          <1> 	call 	WAITF			; NEC FLAGS UPDATE CYCLE
  4055 00001D47 9D                  <1> 	popfd	; 24/12/2021		; RESTORE FLAGS FOR EXIT
  4056                              <1> 	;pop	ebx			; RESTORE REG
  4057 00001D48 C3                  <1> 	retn				; CY = 0 FROM TEST INSTRUCTION
  4058                              <1> 
  4059                              <1> ;-------------------------------------------------------------------------------
  4060                              <1> ; SEEK
  4061                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  4062                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  4063                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  4064                              <1> ;
  4065                              <1> ; ON ENTRY:	EDI = DRIVE #
  4066                              <1> ;		CH = TRACK #
  4067                              <1> ;
  4068                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  4069                              <1> ;		EAX, EBX, ECX, EDX DESTROYED
  4070                              <1> ;-------------------------------------------------------------------------------
  4071                              <1> SEEK:
  4072                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4073 00001D49 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  4074 00001D4B B001                <1> 	mov	al, 1			; ESTABLISH MASK FOR RECALIBRATE TEST
  4075 00001D4D 86CB                <1> 	xchg	cl, bl			; SET DRIVE VALUE INTO CL
  4076 00001D4F D2C0                <1> 	rol	al, cl			; SHIFT MASK BY THE DRIVE VALUE
  4077 00001D51 86CB                <1> 	xchg	cl, bl			; RECOVER DRIVE VALUE
  4078 00001D53 8405[89670000]      <1> 	test	al, [SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  4079 00001D59 7526                <1> 	jnz	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  4080                              <1> 
  4081 00001D5B 0805[89670000]      <1> 	or	[SEEK_STATUS], al	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  4082 00001D61 E862000000          <1> 	call	RECAL			; RECALIBRATE DRIVE
  4083 00001D66 730E                <1> 	jnc	short AFT_RECAL		; RECALIBRATE DONE
  4084                              <1> 
  4085                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  4086                              <1> 
  4087 00001D68 C605[8C670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; CLEAR OUT INVALID STATUS
  4088 00001D6F E854000000          <1> 	call	RECAL			; RECALIBRATE DRIVE
  4089 00001D74 7251                <1> 	jc	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  4090                              <1> 
  4091                              <1> AFT_RECAL:
  4092 00001D76 C687[99670000]00    <1> 	mov	byte [DSK_TRK+edi], 0	; SAVE NEW CYLINDER AS PRESENT POSITION
  4093 00001D7D 08ED                <1> 	or	ch, ch			; CHECK FOR SEEK TO TRACK 0
  4094 00001D7F 743F                <1> 	jz	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  4095                              <1> 
  4096                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  4097                              <1> 
  4098 00001D81 F687[97670000]20    <1> J28A:	test	byte [DSK_STATE+edi], DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  4099 00001D88 7402                <1> 	jz	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  4100 00001D8A D0E5                <1> 	shl	ch, 1			; DOUBLE NUMBER OF STEP TO TAKE
  4101                              <1> 
  4102 00001D8C 3AAF[99670000]      <1> _R7:	cmp	ch, [DSK_TRK+edi]	; SEE IF ALREADY AT THE DESIRED TRACK
  4103 00001D92 7433                <1> 	je	short RB		; IF YES, DO NOT NEED TO SEEK
  4104                              <1> 
  4105 00001D94 BA[C71D0000]        <1> 	mov	edx, NEC_ERR		; LOAD RETURN ADDRESS
  4106 00001D99 52                  <1> 	push	edx ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  4107 00001D9A 88AF[99670000]      <1> 	mov	[DSK_TRK+edi], ch	; SAVE NEW CYLINDER AS PRESENT POSITION
  4108 00001DA0 B40F                <1> 	mov	ah, 0Fh			; SEEK COMMAND TO NEC
  4109 00001DA2 E869FFFFFF          <1> 	call	NEC_OUTPUT
  4110 00001DA7 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  4111 00001DA9 88DC                <1> 	mov	ah, bl			; OUTPUT DRIVE NUMBER
  4112 00001DAB E860FFFFFF          <1> 	call	NEC_OUTPUT
  4113 00001DB0 8AA7[99670000]      <1> 	mov	ah, [DSK_TRK+edi]	; GET CYLINDER NUMBER
  4114 00001DB6 E855FFFFFF          <1> 	call	NEC_OUTPUT
  4115 00001DBB E827000000          <1> 	call	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  4116                              <1> 
  4117                              <1> ;-----	WAIT FOR HEAD SETTLE
  4118                              <1> 
  4119                              <1> DO_WAIT:
  4120 00001DC0 9C                  <1> 	pushfd	; 24/12/2021		; SAVE STATUS
  4121 00001DC1 E818FFFFFF          <1> 	call	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  4122 00001DC6 9D                  <1> 	popfd	; 24/12/2021		; RESTORE STATUS
  4123                              <1> RB:
  4124                              <1> NEC_ERR:
  4125                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  4126                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  4127 00001DC7 C3                  <1> 	retn				; RETURN TO CALLER
  4128                              <1> 
  4129                              <1> ;-------------------------------------------------------------------------------
  4130                              <1> ; RECAL
  4131                              <1> ;	RECALIBRATE DRIVE
  4132                              <1> ;
  4133                              <1> ; ON ENTRY:	EDI = DRIVE #
  4134                              <1> ;
  4135                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  4136                              <1> ;-------------------------------------------------------------------------------
  4137                              <1> RECAL:
  4138                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4139                              <1> 	;push	cx
  4140                              <1> 	; 24/12/2021
  4141 00001DC8 51                  <1> 	push	ecx
  4142 00001DC9 B8[E51D0000]        <1> 	mov	eax, RC_BACK		; LOAD NEC_OUTPUT ERROR
  4143 00001DCE 50                  <1> 	push	eax
  4144 00001DCF B407                <1> 	mov	ah, 07h			; RECALIBRATE COMMAND
  4145 00001DD1 E83AFFFFFF          <1> 	call	NEC_OUTPUT
  4146 00001DD6 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  4147 00001DD8 88DC                <1> 	mov	ah, bl
  4148 00001DDA E831FFFFFF          <1> 	call	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  4149 00001DDF E803000000          <1> 	call	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  4150 00001DE4 58                  <1> 	pop	eax			; THROW AWAY ERROR
  4151                              <1> RC_BACK:
  4152                              <1> 	;pop	cx
  4153                              <1> 	; 24/12/2021
  4154 00001DE5 59                  <1> 	pop	ecx
  4155 00001DE6 C3                  <1> 	RETn
  4156                              <1> 
  4157                              <1> ;-------------------------------------------------------------------------------
  4158                              <1> ; CHK_STAT_2
  4159                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  4160                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  4161                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  4162                              <1> ;
  4163                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  4164                              <1> ;-------------------------------------------------------------------------------
  4165                              <1> CHK_STAT_2:
  4166                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4167 00001DE7 B8[0F1E0000]        <1>         mov	eax, CS_BACK		; LOAD NEC_OUTPUT ERROR ADDRESS
  4168 00001DEC 50                  <1> 	push	eax
  4169 00001DED E828000000          <1> 	call	WAIT_INT		; WAIT FOR THE INTERRUPT
  4170 00001DF2 721A                <1> 	jc	short J34		; IF ERROR, RETURN IT
  4171 00001DF4 B408                <1> 	mov	ah, 08h			; SENSE INTERRUPT STATUS COMMAND
  4172 00001DF6 E815FFFFFF          <1> 	call	NEC_OUTPUT
  4173 00001DFB E849000000          <1> 	call	RESULTS			; READ IN THE RESULTS
  4174 00001E00 720C                <1> 	jc	short J34
  4175 00001E02 A0[8D670000]        <1> 	mov	al, [NEC_STATUS]	; GET THE FIRST STATUS BYTE
  4176 00001E07 2460                <1> 	and	al, 01100000b		; ISOLATE THE BITS
  4177 00001E09 3C60                <1> 	cmp	al, 01100000b		; TEST FOR CORRECT VALUE
  4178 00001E0B 7403                <1> 	jz	short J35		; IF ERROR, GO MARK IT
  4179 00001E0D F8                  <1> 	clc				; GOOD RETURN
  4180                              <1> J34:
  4181 00001E0E 58                  <1> 	pop	eax			; THROW AWAY ERROR RETURN
  4182                              <1> CS_BACK:
  4183 00001E0F C3                  <1> 	retn
  4184                              <1> J35:
  4185 00001E10 800D[8C670000]40    <1> 	or	byte [DSKETTE_STATUS], BAD_SEEK
  4186 00001E17 F9                  <1> 	stc				; ERROR RETURN CODE
  4187 00001E18 EBF4                <1> 	jmp	short J34
  4188                              <1> 
  4189                              <1> ;-------------------------------------------------------------------------------
  4190                              <1> ; WAIT_INT
  4191                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  4192                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  4193                              <1> ;	IF THE DRIVE IS NOT READY.
  4194                              <1> ;
  4195                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  4196                              <1> ;-------------------------------------------------------------------------------
  4197                              <1> 
  4198                              <1> ; 17/12/2014
  4199                              <1> ; 2.5 seconds waiting !
  4200                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  4201                              <1> ; amount of time to wait for completion interrupt from NEC.
  4202                              <1> 
  4203                              <1> WAIT_INT:
  4204                              <1> 	; 12/07/2022
  4205                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4206 00001E1A FB                  <1> 	sti				; TURN ON INTERRUPTS, JUST IN CASE
  4207                              <1> 	; 12/07/2022
  4208                              <1> 	;clc				; CLEAR TIMEOUT INDICATOR
  4209                              <1>        ;mov	bl, 10			; CLEAR THE COUNTERS
  4210                              <1>        ;xor	cx, cx			; FOR 2 SECOND WAIT
  4211                              <1> 
  4212                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  4213                              <1> 	;
  4214                              <1> 	;WAIT_FOR_MEM:	
  4215                              <1> 	;	Waits for a bit at a specified memory location pointed
  4216                              <1> 	;	to by ES:[DI] to become set.
  4217                              <1> 	;INPUT:
  4218                              <1> 	;	AH=Mask to test with.
  4219                              <1> 	;	ES:[DI] = memory location to watch.
  4220                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  4221                              <1> 	;	     (normally 30 microseconds per period.)
  4222                              <1> 
  4223                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  4224                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  4225                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  4226                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  4227                              <1> 	; 27/02/2015
  4228 00001E1B B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  4229                              <1> WFMS_CHECK_MEM:
  4230 00001E20 F605[89670000]80    <1> 	test	byte [SEEK_STATUS], INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  4231 00001E27 7516                <1>         jnz     short J37
  4232                              <1> WFMS_HI:
  4233 00001E29 E461                <1> 	in	al, PORT_B  ; 061h	; SYS1, wait for lo to hi
  4234 00001E2B A810                <1> 	test	al, 010h		; transition on memory
  4235 00001E2D 75FA                <1> 	jnz	short WFMS_HI		; refresh.
  4236                              <1> WFMS_LO:
  4237 00001E2F E461                <1> 	in	al, PORT_B		; SYS1
  4238 00001E31 A810                <1> 	test	al, 010h
  4239 00001E33 74FA                <1> 	jz	short WFMS_LO
  4240 00001E35 E2E9                <1>         loop	WFMS_CHECK_MEM
  4241                              <1> ;WFMS_OUTER_LP:
  4242                              <1> ;;	or	bl, bl			; check outer counter
  4243                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  4244                              <1> ;	dec	bl
  4245                              <1> ;	jz	short J36A	
  4246                              <1> ;	jmp	short WFMS_CHECK_MEM
  4247                              <1> 
  4248                              <1> 	;17/12/2014
  4249                              <1> 	;16/12/2014
  4250                              <1> ;	mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  4251                              <1> ;J36:
  4252                              <1> ;	test	byte [SEEK_STATUS], INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  4253                              <1> ;	jnz	short J37
  4254                              <1> 	;16/12/2014
  4255                              <1> 	;loop	J36			; COUNT DOWN WHILE WAITING
  4256                              <1> 	;dec	bl			; SECOND LEVEL COUNTER
  4257                              <1> 	;jnz	short J36
  4258                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  4259                              <1> ;	jb	short J36
  4260                              <1> 
  4261                              <1> ;WFMS_TIMEOUT:
  4262                              <1> ;J36A:
  4263 00001E37 800D[8C670000]80    <1> 	or	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  4264 00001E3E F9                  <1> 	stc				; ERROR RETURN
  4265                              <1> J37:
  4266 00001E3F 9C                  <1> 	pushf				; SAVE CURRENT CARRY
  4267 00001E40 8025[89670000]7F    <1> 	and	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  4268 00001E47 9D                  <1> 	popf				; RECOVER CARRY
  4269 00001E48 C3                  <1> 	retn				; GOOD RETURN CODE
  4270                              <1> 
  4271                              <1> ;-------------------------------------------------------------------------------
  4272                              <1> ; RESULTS
  4273                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  4274                              <1> ;	FOLLOWING AN INTERRUPT.
  4275                              <1> ;
  4276                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  4277                              <1> ;		EAX, EBX, ECX, EDX DESTROYED
  4278                              <1> ;-------------------------------------------------------------------------------
  4279                              <1> RESULTS:
  4280                              <1> 	; 12/07/2022
  4281                              <1> 	; 11/07/2022
  4282                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4283 00001E49 57                  <1> 	push	edi
  4284 00001E4A BF[8D670000]        <1> 	mov	edi, NEC_STATUS		; POINTER TO DATA AREA
  4285 00001E4F B307                <1> 	mov	bl, 7			; MAX STATUS BYTES
  4286 00001E51 66BAF403            <1> 	mov	dx, 03F4h		; STATUS PORT
  4287                              <1> 
  4288                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  4289                              <1> 
  4290                              <1> _R10: 
  4291                              <1> 	; 16/12/2014
  4292                              <1> 	; wait for (max) 0.5 seconds
  4293                              <1> 	;mov	bh, 2			; HIGH ORDER COUNTER
  4294                              <1> 	;xor	cx, cx			; COUNTER
  4295                              <1> 
  4296                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  4297                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  4298                              <1> 	; 27/02/2015
  4299                              <1> 
  4300 00001E55 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  4301                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  4302                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  4303                              <1> 
  4304                              <1> WFPSR_OUTER_LP:
  4305                              <1> 	;
  4306                              <1> WFPSR_CHECK_PORT:
  4307                              <1> J39:					; WAIT FOR MASTER
  4308 00001E5A EC                  <1> 	in	al, dx			; GET STATUS
  4309 00001E5B 24C0                <1> 	and	al, 11000000b		; KEEP ONLY STATUS AND DIRECTION
  4310 00001E5D 3CC0                <1> 	cmp	al, 11000000b		; STATUS 1 AND DIRECTION 1 ?
  4311 00001E5F 7418                <1> 	jz	short J42		; STATUS AND DIRECTION OK
  4312                              <1> WFPSR_HI:
  4313 00001E61 E461                <1> 	in	al, PORT_B	;061h	; SYS1	; wait for hi to lo
  4314 00001E63 A810                <1> 	test	al, 010h		; transition on memory
  4315 00001E65 75FA                <1> 	jnz	short WFPSR_HI		; refresh.
  4316                              <1> WFPSR_LO:
  4317 00001E67 E461                <1> 	in	al, PORT_B		; SYS1
  4318 00001E69 A810                <1> 	test	al, 010h
  4319 00001E6B 74FA                <1> 	jz	short WFPSR_LO
  4320 00001E6D E2EB                <1>         loop	WFPSR_CHECK_PORT
  4321                              <1> 	
  4322                              <1> 	;; 27/02/2015
  4323                              <1> 	;;dec	bh
  4324                              <1> 	;;jnz	short WFPSR_OUTER_LP
  4325                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  4326                              <1> 
  4327                              <1> 	;;mov	byte [wait_count], 0
  4328                              <1> ;J39:					; WAIT FOR MASTER
  4329                              <1> ;	in	al, dx			; GET STATUS
  4330                              <1> ;	and	al, 11000000b		; KEEP ONLY STATUS AND DIRECTION
  4331                              <1> ;	cmp	al, 11000000b		; STATUS 1 AND DIRECTION 1 ?
  4332                              <1> ;	jz	short J42		; STATUS AND DIRECTION OK
  4333                              <1> 	;loop	J39			; LOOP TILL TIMEOUT
  4334                              <1> 	;dec	bh			; DECREMENT HIGH ORDER COUNTER
  4335                              <1> 	;jnz	short J39		; REPEAT TILL DELAY DONE
  4336                              <1> 	;
  4337                              <1> 	;;cmp	byte [wait_count], 10	; (10/18.2 seconds)
  4338                              <1> 	;;jb	short J39	
  4339                              <1> 
  4340                              <1> ;WFPSR_TIMEOUT:
  4341 00001E6F 800D[8C670000]80    <1> 	or	byte [DSKETTE_STATUS], TIME_OUT
  4342 00001E76 F9                  <1> 	stc				; SET ERROR RETURN
  4343 00001E77 EB26                <1> 	jmp	short POPRES		; POP REGISTERS AND RETURN
  4344                              <1> 
  4345                              <1> ;-----	READ IN THE STATUS
  4346                              <1> 
  4347                              <1> J42:
  4348 00001E79 EB00                <1> 	JMP	$+2			; I/O DELAY
  4349                              <1> 	;inc	dx			; POINT AT DATA PORT
  4350 00001E7B FEC2                <1> 	inc	dl
  4351 00001E7D EC                  <1> 	in	al, dx			; GET THE DATA
  4352                              <1> 	; 16/12/2014
  4353                              <1> 	NEWIODELAY
  2177 00001E7E E6EB                <2>  out 0EBh,al
  4354                              <1> 	
  4355                              <1> 	;mov	[edi], al		; STORE THE BYTE
  4356                              <1> 	;inc	edi			; INCREMENT THE POINTER
  4357                              <1> 	; 11/07/2022
  4358 00001E80 AA                  <1> 	stosb
  4359                              <1> 
  4360                              <1> 	; 16/12/2014
  4361                              <1> ;	push	cx
  4362                              <1> ;	mov	cx, 30
  4363                              <1> ;wdw2:
  4364                              <1> ;	NEWIODELAY
  4365                              <1> ;	loop	wdw2
  4366                              <1> ;	pop	cx
  4367                              <1> 
  4368                              <1> 	;mov	ecx,3			; MINIMUM 24 MICROSECONDS FOR NEC
  4369                              <1> 	; 12/07/2022
  4370 00001E81 29C9                <1> 	sub	ecx, ecx
  4371 00001E83 B103                <1> 	mov	cl, 3
  4372 00001E85 E807F5FFFF          <1> 	call	WAITF			; WAIT 30 TO 45 MICROSECONDS
  4373                              <1> 	;dec	dx			; POINT AT STATUS PORT
  4374 00001E8A FECA                <1> 	dec	dl
  4375 00001E8C EC                  <1> 	in	al, dx			; GET STATUS
  4376                              <1> 	; 16/12/2014
  4377                              <1> 	NEWIODELAY
  2177 00001E8D E6EB                <2>  out 0EBh,al
  4378                              <1> 	;
  4379 00001E8F A810                <1> 	test	al, 00010000b		; TEST FOR NEC STILL BUSY
  4380 00001E91 740C                <1> 	jz	short POPRES		; RESULTS DONE ?
  4381                              <1> 
  4382 00001E93 FECB                <1> 	dec	bl			; DECREMENT THE STATUS COUNTER
  4383 00001E95 75BE                <1>         jnz	short _R10              ; GO BACK FOR MORE
  4384 00001E97 800D[8C670000]20    <1> 	or	byte [DSKETTE_STATUS], BAD_NEC ; TOO MANY STATUS BYTES
  4385 00001E9E F9                  <1> 	stc				; SET ERROR FLAG
  4386                              <1> 
  4387                              <1> ;-----	RESULT OPERATION IS DONE
  4388                              <1> POPRES:
  4389 00001E9F 5F                  <1> 	pop	edi
  4390 00001EA0 C3                  <1> 	retn				; RETURN WITH CARRY SET
  4391                              <1> 
  4392                              <1> ;-------------------------------------------------------------------------------
  4393                              <1> ; READ_DSKCHNG
  4394                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  4395                              <1> ;
  4396                              <1> ; ON ENTRY:	EDI = DRIVE #
  4397                              <1> ;
  4398                              <1> ; ON EXIT:	EDI = DRIVE #
  4399                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  4400                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  4401                              <1> ;		EAX, ECX, EDX DESTROYED
  4402                              <1> ;-------------------------------------------------------------------------------
  4403                              <1> READ_DSKCHNG:
  4404                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4405 00001EA1 E8B4FDFFFF          <1> 	call	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  4406 00001EA6 66BAF703            <1> 	mov	dx, 03F7h		; ADDRESS DIGITAL INPUT REGISTER
  4407 00001EAA EC                  <1> 	in	al, dx			; INPUT DIGITAL INPUT REGISTER
  4408 00001EAB A880                <1> 	test	al, DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  4409 00001EAD C3                  <1> 	retn				; RETURN TO CALLER WITH ZERO FLAG SET
  4410                              <1> 
  4411                              <1> fdc_int:  
  4412                              <1> 	  ; 30/07/2015	
  4413                              <1> 	  ; 16/02/2015
  4414                              <1> ;int_0Eh: ; 11/12/2014
  4415                              <1> 
  4416                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL 6 ) ---------------------------------------
  4417                              <1> ; DISK_INT
  4418                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  4419                              <1> ;
  4420                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  4421                              <1> ;-------------------------------------------------------------------------------
  4422                              <1> DISK_INT_1:
  4423                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4424                              <1> 	;push	eax			; SAVE WORK REGISTER
  4425                              <1> 	; 24/12/2021
  4426 00001EAE 50                  <1> 	push	eax
  4427 00001EAF 1E                  <1> 	push	ds
  4428 00001EB0 66B81000            <1> 	mov	ax, KDATA
  4429 00001EB4 8ED8                <1> 	mov 	ds, ax
  4430 00001EB6 800D[89670000]80    <1>         or	byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  4431 00001EBD B020                <1> 	mov	al, EOI			; END OF INTERRUPT MARKER
  4432 00001EBF E620                <1> 	out	INTA00, al		; INTERRUPT CONTROL PORT
  4433 00001EC1 1F                  <1> 	pop	ds
  4434                              <1> 	;pop	ax			; RECOVER REGISTER
  4435                              <1> 	; 24/12/2021
  4436 00001EC2 58                  <1> 	pop	eax
  4437 00001EC3 CF                  <1> 	iretd				; RETURN FROM INTERRUPT
  4438                              <1> 
  4439                              <1> ;-------------------------------------------------------------------------------
  4440                              <1> ; DSKETTE_SETUP
  4441                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  4442                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  4443                              <1> ;-------------------------------------------------------------------------------
  4444                              <1> DSKETTE_SETUP:
  4445                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4446                              <1> 	;push	eax			; SAVE REGISTERS
  4447                              <1> 	;push	ebx
  4448                              <1> 	;push	ecx
  4449 00001EC4 52                  <1> 	push	edx
  4450                              <1> 	;push	edi
  4451                              <1> 	; 14/12/2014
  4452                              <1> 	;mov	dword [DISK_POINTER], MD_TBL6
  4453                              <1> 	;
  4454                              <1> 	;or	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  4455                              <1> 
  4456 00001EC5 31FF                <1> 	xor	edi, edi 		; INITIALIZE DRIVE POINTER
  4457 00001EC7 29C9                <1> 	sub	ecx, ecx
  4458 00001EC9 66890D[97670000]    <1> 	mov	[DSK_STATE], cx ; 0	; INITIALIZE STATES
  4459                              <1> 	; 08/07/2022
  4460                              <1> 	;and	byte [LASTRATE], ~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  4461 00001ED0 800D[94670000]C0    <1> 	or	byte [LASTRATE], SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  4462 00001ED7 880D[89670000]      <1> 	mov	[SEEK_STATUS], cl ; 0	; INDICATE RECALIBRATE NEEDED
  4463 00001EDD 880D[8B670000]      <1> 	mov	[MOTOR_COUNT], cl ; 0	; INITIALIZE MOTOR COUNT
  4464 00001EE3 880D[8A670000]      <1> 	mov	[MOTOR_STATUS], cl ; 0	; INITIALIZE DRIVES TO OFF STATE
  4465 00001EE9 880D[8C670000]      <1> 	mov	[DSKETTE_STATUS], cl ; 0 ; NO ERRORS
  4466                              <1> 	;
  4467                              <1> 	; 28/02/2015
  4468                              <1> 	;mov	word [cfd], 100h 
  4469 00001EEF E894F8FFFF          <1> 	call	DSK_RESET
  4470 00001EF4 5A                  <1> 	pop	edx
  4471 00001EF5 C3                  <1> 	retn
  4472                              <1> 
  4473                              <1> ;//////////////////////////////////////////////////////
  4474                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4475                              <1> ;
  4476                              <1> 
  4477                              <1> ; 12/07/2022
  4478                              <1> ;int13h: ; 21/02/2015
  4479                              <1> ;	pushfd
  4480                              <1> ;	push 	cs
  4481                              <1> ;	call 	DISK_IO
  4482                              <1> ;	retn
  4483                              <1> 
  4484                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  4485                              <1> ;/////////////////////////////////////////////////////////////////////
  4486                              <1> 
  4487                              <1> ; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4488                              <1> ; ((Direct call instead of int 13h simulation))
  4489                              <1> ;
  4490                              <1> ;		Function in AL
  4491                              <1> ;			0 = reset
  4492                              <1> ;			1 = read
  4493                              <1> ;			2 = write
  4494                              <1> ;		Disk drive number in DL
  4495                              <1> ;			0 & 1 = floppy disks	
  4496                              <1> ;			80h .. 83h = hard disks
  4497                              <1> ;		Sector address (LBA) in ECX
  4498                              <1> ;		Buffer address in EBX
  4499                              <1> ;		R/W sector count is (always) 1
  4500                              <1> ;
  4501                              <1> ;		Return:
  4502                              <1> ;			Status in AH (>0 = error code)
  4503                              <1> ;			if CF = 1 -> error code in AH
  4504                              <1> ;			if CF = 0 -> successful
  4505                              <1> ;			AL = undefined
  4506                              <1> ;
  4507                              <1> ;		Modified registers: (only) EAX
  4508                              <1> 
  4509                              <1> ; 10/07/2022
  4510                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4511                              <1> 
  4512                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  4513                              <1> ; 23/02/2015
  4514                              <1> ; 21/02/2015 (unix386.s)
  4515                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  4516                              <1> ;
  4517                              <1> ; Original Source Code:
  4518                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  4519                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  4520                              <1> ;
  4521                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  4522                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  4523                              <1> ;
  4524                              <1> 
  4525                              <1> ;The wait for controller to be not busy is 10 seconds.
  4526                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  4527                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  4528                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  4529                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  4530                              <1> 
  4531                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  4532                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  4533                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  4534                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  4535                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  4536                              <1> 
  4537                              <1> ;The wait for Data request on read and write longs is
  4538                              <1> ;2000 us. (?)
  4539                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  4540                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  4541                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  4542                              <1> 
  4543                              <1> ; Port 61h (PORT_B)
  4544                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  4545                              <1> 
  4546                              <1> ; 23/12/2014
  4547                              <1> %define CMD_BLOCK       ebp-8  ; 21/02/2015
  4548                              <1> 
  4549                              <1> 	; 11/07/2022
  4550                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4551                              <1> 
  4552                              <1> ;--- INT 13H -------------------------------------------------------------------
  4553                              <1> ;									       :
  4554                              <1> ; FIXED DISK I/O INTERFACE						       :
  4555                              <1> ;									       :
  4556                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  4557                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  4558                              <1> ;									       :
  4559                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  4560                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  4561                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  4562                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  4563                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  4564                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  4565                              <1> ;									       :
  4566                              <1> ;------------------------------------------------------------------------------:
  4567                              <1> ;									       :
  4568                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  4569                              <1> ;									       :
  4570                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  4571                              <1> ;	(AH)= 01H  READ THE DESIRED SECTORS INTO MEMORY                        :
  4572                              <1> ;	(AH)= 02H  WRITE THE DESIRED SECTORS FROM MEMORY                       :
  4573                              <1> ;									       :
  4574                              <1> ;------------------------------------------------------------------------------:
  4575                              <1> ;									       :
  4576                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  4577                              <1> ;									       :
  4578                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  4579                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  4580                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  4581                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  4582                              <1> ;									       :
  4583                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  4584                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  4585                              <1> ;				 (10 BITS TOTAL)			       :
  4586                              <1> ;									       :
  4587                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  4588                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  4589                              <1> ;									       :
  4590                              <1> ;		(EBX)   -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  4591                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  4592                              <1> ;									       :
  4593                              <1> ;------------------------------------------------------------------------------:
  4594                              <1> ; OUTPUT								       :
  4595                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  4596                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  4597                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  4598                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  4599                              <1> ;									       :
  4600                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  4601                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  4602                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  4603                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  4604                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  4605                              <1> ;		REWRITTEN.						       :
  4606                              <1> ;									       :
  4607                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  4608                              <1> ;	   INPUT:							       :
  4609                              <1> ;	     (DL) = DRIVE NUMBER					       :
  4610                              <1> ;	   OUTPUT:							       :
  4611                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  4612                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  4613                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  4614                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  4615                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  4616                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  4617                              <1> ;									       :
  4618                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  4619                              <1> ;	INFORMATION.							       :
  4620                              <1> ;									       :
  4621                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  4622                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  4623                              <1> ;									       :
  4624                              <1> ;-------------------------------------------------------------------------------
  4625                              <1> 
  4626                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  4627                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  4628                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  4629                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  4630                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  4631                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  4632                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  4633                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  4634                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  4635                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  4636                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  4637                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  4638                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  4639                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  4640                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  4641                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  4642                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  4643                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  4644                              <1> 
  4645                              <1> ;--------------------------------------------------------
  4646                              <1> ;							:
  4647                              <1> ; FIXED DISK PARAMETER TABLE				:
  4648                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  4649                              <1> ;							:
  4650                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  4651                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  4652                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  4653                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  4654                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  4655                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  4656                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  4657                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  4658                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  4659                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  4660                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  4661                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  4662                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  4663                              <1> ;							:
  4664                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  4665                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  4666                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  4667                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  4668                              <1> ;							:
  4669                              <1> ;--------------------------------------------------------
  4670                              <1> 
  4671                              <1> ;--------------------------------------------------------
  4672                              <1> ;							:
  4673                              <1> ; HARDWARE SPECIFIC VALUES				:
  4674                              <1> ;							:
  4675                              <1> ;  -  CONTROLLER I/O PORT				:
  4676                              <1> ;							:
  4677                              <1> ;     > WHEN READ FROM: 				:
  4678                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  4679                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  4680                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  4681                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  4682                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  4683                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  4684                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  4685                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  4686                              <1> ;							:
  4687                              <1> ;     > WHEN WRITTEN TO:				:
  4688                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  4689                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  4690                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  4691                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  4692                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  4693                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  4694                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  4695                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  4696                              <1> ;							:
  4697                              <1> ;--------------------------------------------------------
  4698                              <1> 
  4699                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  4700                              <1> ;HF1_PORT	equ	0170h	
  4701                              <1> ;HF_REG_PORT	EQU	03F6H
  4702                              <1> ;HF1_REG_PORT	equ	0376h
  4703                              <1> 
  4704                              <1> HDC1_BASEPORT	equ	1F0h
  4705                              <1> HDC2_BASEPORT	equ	170h		
  4706                              <1> 
  4707                              <1> align 2
  4708                              <1> 
  4709                              <1> ;-----		STATUS REGISTER
  4710                              <1> 
  4711                              <1> ST_ERROR	EQU	00000001B	;
  4712                              <1> ST_INDEX	EQU	00000010B	;
  4713                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  4714                              <1> ST_DRQ		EQU	00001000B	;
  4715                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  4716                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  4717                              <1> ST_READY	EQU	01000000B	;
  4718                              <1> ST_BUSY 	EQU	10000000B	;
  4719                              <1> 
  4720                              <1> ;-----		ERROR REGISTER
  4721                              <1> 
  4722                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  4723                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  4724                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  4725                              <1> ;		EQU	00001000B	; NOT USED
  4726                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  4727                              <1> ;		EQU	00100000B	; NOT USED
  4728                              <1> ERR_DATA_ECC	EQU	01000000B
  4729                              <1> ERR_BAD_BLOCK	EQU	10000000B
  4730                              <1> 
  4731                              <1> 
  4732                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  4733                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  4734                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  4735                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  4736                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  4737                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  4738                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  4739                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  4740                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  4741                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  4742                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  4743                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  4744                              <1> 
  4745                              <1> ;MAX_FILE	EQU	2
  4746                              <1> ;S_MAX_FILE	EQU	2
  4747                              <1> MAX_FILE	equ	4		; 22/12/2014
  4748                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  4749                              <1> 
  4750                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  4751                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  4752                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  4753                              <1> 
  4754                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  4755                              <1> 
  4756                              <1> ;-----		COMMAND BLOCK REFERENCE
  4757                              <1> 
  4758                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  4759                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  4760                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  4761                              <1> ; 19/12/2014
  4762                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  4763                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  4764                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  4765                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  4766                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  4767                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  4768                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  4769                              <1> 
  4770                              <1> align 2
  4771                              <1> 
  4772                              <1> ;----------------------------------------------------------------
  4773                              <1> ; FIXED DISK I/O SETUP						:
  4774                              <1> ;								:
  4775                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  4776                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  4777                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  4778                              <1> ;								:
  4779                              <1> ;----------------------------------------------------------------
  4780                              <1> 
  4781                              <1> 	; 12/07/2022
  4782                              <1> 	; 11/07/2022
  4783                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4784                              <1> 
  4785                              <1> DISK_SETUP:
  4786                              <1> 	;cli
  4787                              <1> 	;;mov	ax, ABS0 			; GET ABSOLUTE SEGMENT
  4788                              <1> 	;xor	ax, ax
  4789                              <1> 	;mov	ds, ax				; SET SEGMENT REGISTER
  4790                              <1> 	;mov	ax, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  4791                              <1> 	;mov	[DISK_VECTOR], ax		; INTO INT 40H
  4792                              <1> 	;mov	ax, [ORG_VECTOR+2]
  4793                              <1> 	;mov	[DISK_VECTOR+2], ax
  4794                              <1> 	;mov	word [ORG_VECTOR], DISK_IO	; FIXED DISK HANDLER
  4795                              <1> 	;mov	[ORG_VECTOR+2], cs
  4796                              <1> 	; 1st controller (primary master, slave) - IRQ 14
  4797                              <1> 	;;mov	word [HDISK_INT], HD_INT	; FIXED DISK INTERRUPT
  4798                              <1> 	;mov	word [HDISK_INT1], HD_INT	;
  4799                              <1> 	;;mov	[HDISK_INT+2], cs
  4800                              <1> 	;mov	[HDISK_INT1+2], cs
  4801                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  4802                              <1> 	;mov	word [HDISK_INT2], HD1_INT	;
  4803                              <1> 	;mov	[HDISK_INT2+2], cs
  4804                              <1> 	;
  4805                              <1> 	;;mov	word [HF_TBL_VEC], HD0_DPT	; PARM TABLE DRIVE 80
  4806                              <1> 	;;mov	word [HF_TBL_VEC+2], DPT_SEGM
  4807                              <1> 	;;mov	word [HF1_TBL_VEC], HD1_DPT	; PARM TABLE DRIVE 81
  4808                              <1> 	;;mov	word [HF1_TBL_VEC+2], DPT_SEGM
  4809                              <1> 	;push	cs
  4810                              <1> 	;pop	ds
  4811                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  4812                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  4813 00001EF6 C705[A0670000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  4813 00001EFE 0900                <1>
  4814                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  4815                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  4816 00001F00 C705[A4670000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  4816 00001F08 0900                <1>
  4817                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  4818                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  4819 00001F0A C705[A8670000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  4819 00001F12 0900                <1>
  4820                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  4821                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  4822 00001F14 C705[AC670000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  4822 00001F1C 0900                <1>
  4823                              <1> 	;
  4824                              <1> 	;;in	al, INTB01		; TURN ON SECOND INTERRUPT CHIP
  4825                              <1> 	;;;and	al, 0BFh
  4826                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  4827                              <1> 	;;;JMP	$+2
  4828                              <1> 	;;IODELAY
  4829                              <1> 	;;out	INTB01, al
  4830                              <1> 	;;IODELAY
  4831                              <1> 	;;in	al, INTA01		; LET INTERRUPTS PASS THRU TO
  4832                              <1> 	;;and	al, 0FBh 		; SECOND CHIP
  4833                              <1> 	;;;JMP	$+2
  4834                              <1> 	;;IODELAY
  4835                              <1> 	;;out	INTA01, al
  4836                              <1> 	;
  4837                              <1> 	;sti
  4838                              <1> 	;;push	ds			; MOVE ABS0 POINTER TO
  4839                              <1> 	;;pop	es			; EXTRA SEGMENT POINTER
  4840                              <1> 	;;;call	DDS			; ESTABLISH DATA SEGMENT
  4841                              <1> 	;;mov	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  4842                              <1> 	;;mov	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  4843                              <1> 	;;mov	byte [CONTROL_BYTE],0
  4844                              <1> 	;;mov	byte [PORT_OFF],0	; ZERO CARD OFFSET
  4845                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  4846                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  4847                              <1> 	;mov	si, hd0_type
  4848 00001F1E BE[2E620000]        <1> 	mov	esi, hd0_type
  4849                              <1> 	;;mov	cx, 4
  4850                              <1> 	;mov	ecx, 4
  4851                              <1> 	; 11/07/2022
  4852 00001F23 29C9                <1> 	sub	ecx, ecx
  4853 00001F25 B104                <1> 	mov	cl, 4
  4854                              <1> hde_l:
  4855 00001F27 AC                  <1> 	lodsb
  4856 00001F28 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  4857 00001F2A 7206                <1> 	jb	short _L4
  4858 00001F2C FE05[9C670000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  4859                              <1> _L4: ; 26/02/2015
  4860 00001F32 E2F3                <1> 	loop	hde_l	
  4861                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  4862                              <1> ;L4:
  4863                              <1> 	; 
  4864                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  4865                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  4866                              <1> 	;;mov 	cl, 3
  4867                              <1> 	;;
  4868                              <1> 	;;mov	dl, 80h			; CHECK THE CONTROLLER
  4869                              <1> ;;hdc_dl:
  4870                              <1> 	;;mov	ah, 14h			; USE CONTROLLER DIAGNOSTIC COMMAND
  4871                              <1> 	;;int	13h			; CALL BIOS WITH DIAGNOSTIC COMMAND
  4872                              <1> 	;;;jc	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  4873                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  4874                              <1> 	;;jnc	short hdc_reset0
  4875                              <1> 	;;loop	hdc_dl
  4876                              <1> 	;;; 27/12/2014
  4877                              <1> 	;;stc
  4878                              <1> 	;;retn
  4879                              <1> 	;
  4880                              <1> ;;hdc_reset0:
  4881                              <1> 	; 18/01/2015
  4882 00001F34 8A0D[9C670000]      <1> 	mov	cl, [HF_NUM]
  4883 00001F3A 20C9                <1> 	and	cl, cl
  4884 00001F3C 740D                <1> 	jz	short POD_DONE
  4885                              <1> 	;
  4886 00001F3E B27F                <1> 	mov	dl, 7Fh
  4887                              <1> hdc_reset1:
  4888 00001F40 FEC2                <1> 	inc	dl
  4889                              <1> 	;; 31/12/2015
  4890                              <1> 	;;push	dx
  4891                              <1> 	;;push	cx
  4892                              <1> 	;;push	ds
  4893                              <1> 	;;sub	ax, ax
  4894                              <1> 	;;mov	ds, ax
  4895                              <1> 	;;mov	ax, [TIMER_LOW]		; GET START TIMER COUNTS
  4896                              <1> 	;;pop	ds
  4897                              <1> 	;;mov	bx, ax
  4898                              <1> 	;;add	ax, 6*182		; 60 SECONDS* 18.2
  4899                              <1> 	;;mov	cx, ax
  4900                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  4901                              <1> 	;;
  4902                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  4903                              <1> 	;;call	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  4904                              <1> 	;;pop	cx
  4905                              <1> 	;;pop	dx
  4906                              <1> 	;;
  4907                              <1> 	; 18/01/2015
  4908                              <1> 	;mov	ah, 0Dh ; ALTERNATE RESET
  4909                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4910                              <1> 	;mov	ah, 5 ; ALTERNATE RESET
  4911                              <1> 	;;int	13h
  4912                              <1> 	;call	int13h
  4913                              <1> 	; 12/07/2022
  4914 00001F42 30C0                <1> 	xor	al, al  ; reset
  4915 00001F44 E803000000          <1> 	call	DISK_IO	
  4916                              <1> 	;
  4917 00001F49 E2F5                <1> 	loop	hdc_reset1
  4918                              <1> POD_DONE:
  4919 00001F4B C3                  <1> 	RETn
  4920                              <1> 
  4921                              <1> ;----------------------------------------
  4922                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  4923                              <1> ;----------------------------------------
  4924                              <1> 
  4925                              <1> ; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4926                              <1> ; ((Direct call instead of int 13h simulation))
  4927                              <1> ;
  4928                              <1> ;		Function in AL
  4929                              <1> ;			0 = reset
  4930                              <1> ;			1 = read
  4931                              <1> ;			2 = write
  4932                              <1> ;		Disk drive number in DL
  4933                              <1> ;			0 & 1 = floppy disks	
  4934                              <1> ;			80h .. 83h = hard disks
  4935                              <1> ;		Sector address (LBA) in ECX
  4936                              <1> ;		Buffer address in EBX
  4937                              <1> ;		R/W sector count is (always) 1
  4938                              <1> ;
  4939                              <1> ;		Return:
  4940                              <1> ;			Status in AH (>0 = error code)
  4941                              <1> ;			if CF = 1 -> error code in AH
  4942                              <1> ;			if CF = 0 -> successful
  4943                              <1> ;			AL = undefined
  4944                              <1> ;
  4945                              <1> ;		Modified registers: (only) EAX
  4946                              <1> 	
  4947                              <1> 
  4948                              <1> ; 11/07/2022
  4949                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  4950                              <1> 
  4951                              <1> DISK_IO:
  4952                              <1> 	; 11/07/2022
  4953                              <1> 	; save registers
  4954 00001F4C 57                  <1> 	push	edi			; ANY
  4955 00001F4D 56                  <1> 	push	esi			; ANY
  4956 00001F4E 53                  <1> 	push	ebx			; BUFFER ADDRESS
  4957 00001F4F 51                  <1> 	push	ecx			; SECTOR ADDRESS (LBA)
  4958 00001F50 52                  <1> 	push	edx			; DRIVE NUMBER (DL)
  4959                              <1> 
  4960                              <1> 	;cmp	dl, 80h			; TEST FOR FIXED DISK DRIVE
  4961                              <1> 	;;jae	short A1		; YES, HANDLE HERE
  4962                              <1> 	;;;;int	40H			; DISKETTE HANDLER
  4963                              <1> 	;;;call	int40h
  4964                              <1> 	;;jb	DISKETTE_IO_1
  4965                              <1> 	;; 24/12/2021
  4966                              <1> 	;jnb	short A1
  4967                              <1> 	;jmp	DISKETTE_IO_1
  4968                              <1> 
  4969                              <1> 	; 11/07/2022
  4970 00001F51 80FA80              <1> 	cmp	dl, 80h
  4971 00001F54 730B                <1> 	jae	short A1
  4972                              <1> 
  4973 00001F56 E8CAF6FFFF          <1> 	call	DISKETTE_IO_1
  4974                              <1> 
  4975                              <1> DISK_IO_RTN:
  4976                              <1> 	; restore registers
  4977 00001F5B 5A                  <1> 	pop	edx
  4978 00001F5C 59                  <1> 	pop	ecx
  4979 00001F5D 5B                  <1> 	pop	ebx
  4980 00001F5E 5E                  <1> 	pop	esi
  4981 00001F5F 5F                  <1> 	pop	edi
  4982 00001F60 C3                  <1> 	retn	
  4983                              <1> 
  4984                              <1> ;RET_2:
  4985                              <1> ;	retf	4			; BACK TO CALLER
  4986                              <1> 
  4987                              <1> A1:
  4988                              <1> 	; 11/07/2022
  4989                              <1> 	;sti				; ENABLE INTERRUPTS
  4990                              <1> 	;cmp	dl, (80h + S_MAX_FILE - 1)
  4991                              <1> 	;ja	short RET_2
  4992                              <1> 	
  4993                              <1> 	; 18/01/2015
  4994                              <1> 	;;or	ah, ah
  4995                              <1> 	;or	al, al ; 11/07/2022 (reset function)
  4996                              <1> 	;jz	short A3 ; 08/07/2022
  4997                              <1> 	
  4998                              <1> 	;;cmp	ah, 5  ; Alternate reset
  4999                              <1> 	;cmp	al, 5  ; 11/07/2022
  5000                              <1> 	;je	short A2
  5001                              <1> 	
  5002                              <1> 	; 11/07/2022 - no need to check
  5003                              <1> 	;		 (only kernel calls diskio functions)
  5004                              <1> 	;;cmp	ah, M1L/4 ; cmp ah, 6
  5005                              <1> 	;jb	short A3
  5006                              <1> 	;; BAD COMMAND
  5007                              <1>         ;mov     byte [DISK_STATUS1], BAD_CMD
  5008                              <1> ;RET_2:
  5009                              <1> 	;retf	4
  5010                              <1> 
  5011                              <1> 	; 11/07/2022
  5012                              <1> 	;stc
  5013                              <1> 	;retn
  5014                              <1> A2:
  5015                              <1> 	;sub	ah, ah	; Reset
  5016                              <1> 	; 11/07/2022
  5017                              <1> 	;sub	al, al
  5018                              <1> A3:
  5019                              <1> 					; SAVE REGISTERS DURING OPERATION
  5020 00001F61 C8080000            <1> 	enter	8,0			; SAVE (EBP) AND MAKE ROOM FOR @CMD_BLOCK
  5021                              <1> 	
  5022                              <1> 	; 11/07/2022
  5023                              <1> 	; 08/07/2022
  5024                              <1> 	;push	ebx			;  IN THE STACK, THE COMMAND BLOCK IS:
  5025                              <1> 	;push	ecx			;   @CMD_BLOCK == BYTE PTR [EBP]-8
  5026                              <1> 	;push	edx
  5027                              <1> 	;push	esi
  5028                              <1> 	;push	edi
  5029                              <1> 	
  5030 00001F65 E80D000000          <1> 	call	DISK_IO_CONT		; PERFORM THE OPERATION
  5031                              <1> 
  5032 00001F6A C9                  <1> 	leave	; 11/07/2022
  5033                              <1> 	
  5034 00001F6B 8A25[9B670000]      <1> 	mov	ah, [DISK_STATUS1]	; GET STATUS FROM OPERATION
  5035 00001F71 80FC01              <1> 	cmp	ah, 1			; SET THE CARRY FLAG TO INDICATE
  5036 00001F74 F5                  <1> 	cmc				; SUCCESS OR FAILURE
  5037                              <1> 	
  5038                              <1> 	;pop	edi			; RESTORE REGISTERS
  5039                              <1> 	;pop	esi
  5040                              <1>       	;pop	edx
  5041                              <1> 	;pop	ecx
  5042                              <1> 	;pop	ebx
  5043                              <1> 	
  5044                              <1> 	;leave				; ADJUST (ESP) AND RESTORE (EBP)
  5045                              <1> 	
  5046                              <1> 	; 11/07/2022
  5047                              <1> 	;retf	4			; THROW AWAY SAVED FLAGS
  5048                              <1> 
  5049 00001F75 EBE4                <1> 	jmp	short DISK_IO_RTN
  5050                              <1> 
  5051                              <1> DISK_IO_CONT:
  5052                              <1> 	; 17/07/2022
  5053                              <1> 	; 11/07/2022
  5054                              <1> 	;	INPUT:
  5055                              <1> 	;	    AL = 0 : reset
  5056                              <1> 	;	    AL = 1 : read
  5057                              <1> 	;	    Al = 2 : write
  5058                              <1> 	; 	
  5059                              <1> 	; 10/07/2022
  5060                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5061                              <1> SU0:
  5062 00001F77 C605[9B670000]00    <1> 	mov	byte [DISK_STATUS1], 0 	; RESET THE STATUS INDICATOR
  5063                              <1> 	; 10/07/2022
  5064 00001F7E 89DE                <1> 	mov	esi, ebx ; 21/02/2015	; DATA (BUFFER) ADDRESS
  5065                              <1> 
  5066 00001F80 8A1D[9C670000]      <1> 	mov	bl, [HF_NUM]		; GET NUMBER OF DRIVES
  5067 00001F86 80E27F              <1> 	and	dl, 7Fh			; GET DRIVE AS 0 OR 1
  5068                              <1> 					; (get drive number as 0 to 3)
  5069 00001F89 38D3                <1> 	cmp	bl, dl
  5070                              <1>         ;;jbe	BAD_COMMAND_POP         ; INVALID DRIVE
  5071                              <1>         ;jbe    BAD_COMMAND ;; 14/02/2015
  5072                              <1> 	; 24/12/2021
  5073 00001F8B 7705                <1> 	ja	short su0_su1
  5074 00001F8D E98D000000          <1> 	jmp	BAD_COMMAND
  5075                              <1> su0_su1:
  5076                              <1>         ;;03/01/2015
  5077 00001F92 29DB                <1> 	sub	ebx, ebx
  5078 00001F94 88D3                <1> 	mov	bl, dl
  5079 00001F96 883D[B0670000]      <1> 	mov	[LBAMode], bh  ; 0
  5080                              <1> 	;test	byte [ebx+hd0_type], 1	; LBA ready ?
  5081                              <1> 	;jz	short su1		; no
  5082                              <1> 	;inc	byte [LBAMode]
  5083                              <1> ;su1:
  5084                              <1> 	; 21/02/2015 (32 bit modification)
  5085                              <1> 	; 04/01/2015
  5086                              <1> 	;push	ax ; ***
  5087                              <1> 	; 24/12/2021
  5088 00001F9C 50                  <1> 	push	eax ; *** ; function (in AL) ; 11/07/2022
  5089                              <1> 	; 24/12/2021
  5090 00001F9D 52                  <1> 	push	edx ; *
  5091 00001F9E 50                  <1> 	push	eax ; function (in AL)	; 11/07/2022
  5092 00001F9F E8CA030000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  5093                              <1> 	; 02/02/2015
  5094 00001FA4 668B4310            <1> 	mov	ax, [ebx+16]   ; I/O port base address (1F0h, 170h)
  5095 00001FA8 66A3[22620000]      <1> 	mov	[HF_PORT], ax
  5096 00001FAE 668B5312            <1> 	mov	dx, [ebx+18]   ; control port address (3F6h, 376h)
  5097 00001FB2 668915[24620000]    <1> 	mov	[HF_REG_PORT], dx
  5098 00001FB9 8A4314              <1> 	mov	al, [ebx+20]   ; head register upper nibble (A0h,B0h,E0h,F0h)
  5099                              <1> 	; 23/02/2015
  5100 00001FBC A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  5101 00001FBE 7406                <1> 	jz 	short su1
  5102 00001FC0 FE05[B0670000]      <1> 	inc	byte [LBAMode] ; 1 
  5103                              <1> su1: 	 
  5104 00001FC6 C0E804              <1> 	shr 	al, 4
  5105 00001FC9 2401                <1> 	and	al, 1			
  5106 00001FCB A2[26620000]        <1> 	mov	[hf_m_s], al 
  5107                              <1> 	;
  5108                              <1> 	; 03/01/2015
  5109 00001FD0 8A4308              <1> 	mov	al, [ebx+8]		; GET CONTROL BYTE MODIFIER
  5110                              <1> 	;mov	dx, [HF_REG_PORT]	; Device Control register	
  5111 00001FD3 EE                  <1> 	out	dx, al			; SET EXTRA HEAD OPTION
  5112                              <1> 					; Control Byte: (= 08h, here)
  5113                              <1> 					; bit 0 - 0
  5114                              <1> 					; bit 1 - nIEN (1 = disable irq)
  5115                              <1> 					; bit 2 - SRST (software RESET)
  5116                              <1> 					; bit 3 - use extra heads (8 to 15)
  5117                              <1> 					;         -always set to 1-	
  5118                              <1> 					; (bits 3 to 7 are reserved
  5119                              <1> 					;          for ATA devices)
  5120 00001FD4 8A25[9D670000]      <1> 	mov	ah, [CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  5121 00001FDA 80E4C0              <1> 	and	ah, 0C0h 		; CONTROL BYTE
  5122 00001FDD 08C4                <1> 	or	ah, al
  5123 00001FDF 8825[9D670000]      <1> 	mov	[CONTROL_BYTE], ah	
  5124                              <1> 	; 04/01/2015
  5125                              <1> 	;pop	ax
  5126                              <1> 	; 24/12/2021
  5127 00001FE5 58                  <1> 	pop	eax ; function (in AL) ; 11/07/2022
  5128                              <1> 	;pop	dx ; * ;; 14/02/2015
  5129                              <1> 	; 24/12/2021
  5130 00001FE6 5A                  <1> 	pop	edx ; *
  5131                              <1> 	;and	ah, ah	; Reset function ?
  5132 00001FE7 20C0                <1> 	and	al, al	; 11/07/2022
  5133 00001FE9 7506                <1> 	jnz	short su2
  5134                              <1> 	;pop	ax ; ***
  5135                              <1> 	; 24/12/2021
  5136 00001FEB 58                  <1> 	pop	eax ; *** 	
  5137                              <1> 	;;pop	bx
  5138 00001FEC E9EA000000          <1>         jmp     DISK_RESET
  5139                              <1> su2:
  5140                              <1> 	; 11/07/2022
  5141                              <1> 	; ecx = sector address (lba)
  5142                              <1> 	;  dl = hard disk drive number (80h, 81h .. 83h)	 
  5143                              <1> 	;  al = function (0 = read, 1 = write)	
  5144                              <1> 
  5145 00001FF1 803D[B0670000]00    <1> 	cmp	byte [LBAMode], 0
  5146 00001FF8 7620                <1> 	jna	short su3 ; convert LBA address to CHS parameters
  5147                              <1> 	
  5148                              <1> ;	; 02/02/2015 (LBA read/write function calls)
  5149                              <1> ;	;cmp	ah, 1Bh
  5150                              <1> ;	cmp	ah, 3 ; 08/07/2022
  5151                              <1> ;	jb	short lbarw1
  5152                              <1> ;	;;cmp	ah, 1Ch
  5153                              <1> ;	;cmp	ah, 4 ; 08/07/2022 
  5154                              <1> ;	;ja 	short invldfnc
  5155                              <1> ;	;;pop	dx ; * ; 14/02/2015
  5156                              <1> ;	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  5157                              <1> 
  5158 00001FFA 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  5159                              <1> 
  5160                              <1> 	; 11/07/2022
  5161                              <1> 	;; 14/02/2015
  5162                              <1> 	;mov	cl, dl ; 14/02/2015
  5163                              <1> 
  5164                              <1> 	;;mov	dx, bx
  5165                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  5166                              <1> 	;;mov	bx, di
  5167                              <1> 	;mov	si, di ; Buffer offset
  5168                              <1> 
  5169                              <1> 	; 11/07/2022
  5170                              <1> 	;jmp	short lbarw2
  5171                              <1> 
  5172                              <1> ;lbarw1:
  5173                              <1> ;	; convert CHS to LBA
  5174                              <1> ;	;
  5175                              <1> ;	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  5176                              <1> ;	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  5177                              <1> ;	;	+ Sector - 1
  5178                              <1> ;	;push	dx ; * ;; 14/02/2015
  5179                              <1> ;	; 24/12/2021
  5180                              <1> ;	push	edx ; *
  5181                              <1> ;	;xor	dh, dh
  5182                              <1> ;	xor	edx, edx
  5183                              <1> ;	mov	dl, [ebx+14]	; sectors per track (logical)
  5184                              <1> ;	;xor	ah, ah
  5185                              <1> ;	xor	eax, eax
  5186                              <1> ;	mov	al, [ebx+2]	; heads (logical) 
  5187                              <1> ;	dec	al
  5188                              <1> ;	;inc	ax		; 0 =  256
  5189                              <1> ;	inc	eax ; 24/12/2021
  5190                              <1> ;	mul 	dx
  5191                              <1> ;		; AX = # of Heads * Sectors/Track
  5192                              <1> ;	mov	dx, cx
  5193                              <1> ;	;and	cx, 3Fh	 ; sector (1 to 63)
  5194                              <1> ;	and	ecx, 3fh
  5195                              <1> ;	xchg	dl, dh
  5196                              <1> ;	shr	dh, 6
  5197                              <1> ;		; DX = cylinder (0 to 1023)
  5198                              <1> ;	;mul 	dx
  5199                              <1> ;		; DX:AX = # of Heads * Sectors/Track * Cylinder
  5200                              <1> ;	mul	edx
  5201                              <1> ;	dec	cl  ; sector - 1
  5202                              <1> ;	;add	ax, cx
  5203                              <1> ;	;adc	dx, 0
  5204                              <1> ;		; DX:AX = # of Heads * Sectors/Track * Cylinder + Sector -1
  5205                              <1> ;	add	eax, ecx
  5206                              <1> ;	;pop	cx ; * ; ch = head, cl = drive number (zero based)
  5207                              <1> ;	; 24/12/2021
  5208                              <1> ;	pop	ecx ; * ; ch = head, cl = drive number (zero based)
  5209                              <1> ;	;push	dx
  5210                              <1> ;	;push	ax
  5211                              <1> ;	push	eax
  5212                              <1> ;	mov	al, [ebx+14]  ; sectors per track (logical)	
  5213                              <1> ;	mul	ch
  5214                              <1> ;		; AX = Head * Sectors/Track
  5215                              <1> ;	cwd
  5216                              <1> ;	;pop	dx
  5217                              <1> ;	pop	edx
  5218                              <1> ;	;add	ax, dx
  5219                              <1> ;	;pop	dx
  5220                              <1> ;	;adc	dx, 0 ; add carry bit
  5221                              <1> ;	add	eax, edx
  5222                              <1> ;
  5223                              <1> ;lbarw2:
  5224                              <1> 	; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5225                              <1> 	
  5226 00001FFC 29D2                <1> 	sub	edx, edx ; 21/02/2015
  5227                              <1> 	
  5228                              <1> 	; 11/07/2022
  5229                              <1> 	;mov	dl, cl ; 21/02/2015
  5230                              <1>         
  5231 00001FFE C645F800            <1> 	mov     byte [CMD_BLOCK], 0 ; Features Register
  5232                              <1> 				; NOTE: Features register (1F1h, 171h)
  5233                              <1> 				; is not used for ATA device R/W functions. 
  5234                              <1> 				; It is old/obsolete 'write precompensation'
  5235                              <1> 				; register and error register
  5236                              <1> 				; for old ATA/IDE devices.
  5237                              <1> 	; 18/01/2014
  5238                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  5239 00002002 8A0D[26620000]      <1> 	mov	cl, [hf_m_s]
  5240                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  5241                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  5242                              <1> 				; bit 6 = 1 = LBA mode
  5243                              <1> 				; bit 7 = 1
  5244 00002008 80C90E              <1> 	or	cl, 0Eh ; 1110b
  5245                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  5246 0000200B 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  5247 00002010 C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  5248                              <1> 	;or	dh, ch
  5249 00002013 09C8                <1> 	or	eax, ecx	
  5250                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  5251                              <1> 				  ; (Sector Number Register)
  5252                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  5253                              <1> 				  ; (Cylinder Low Register)
  5254                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  5255                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  5256                              <1> 				  ; (Cylinder High Register)
  5257                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  5258                              <1> 				  ; (Drive/Head Register)
  5259                              <1> 	
  5260                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  5261 00002015 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  5262                              <1> 	;14/02/2015
  5263                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  5264 00002018 EB3D                <1> 	jmp	short su4
  5265                              <1> su3:
  5266                              <1> 	; 02/02/2015 
  5267                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  5268                              <1> 	;cmp 	ah, 14h
  5269                              <1> 	;jna 	short chsfnc
  5270                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5271                              <1> 	;cmp	ah, 2
  5272                              <1> 	;jna	short chsfnc
  5273                              <1> 	; 11/07/2022 
  5274                              <1> 	; (al = function, read = 1 or write = 2)
  5275 0000201A 3C02                <1> 	cmp	al, 2 
  5276 0000201C 760B                <1> 	jna	short chsfnc
  5277                              <1> invldfnc:
  5278                              <1>         ; 14/02/2015  
  5279                              <1> 	;pop	es ; **
  5280                              <1>         ;pop	ax ; ***
  5281                              <1>         ; 24/12/2021
  5282 0000201E 58                  <1> 	pop	eax ; ***
  5283                              <1> 	;;jmp	short BAD_COMMAND_POP
  5284                              <1> 	; 11/07/2022
  5285                              <1>         ;jmp     short BAD_COMMAND
  5286                              <1> 
  5287                              <1> 	; 11/07/2022
  5288                              <1> BAD_COMMAND:
  5289 0000201F C605[9B670000]01    <1> 	mov	byte [DISK_STATUS1], BAD_CMD  ; COMMAND ERROR
  5290                              <1> 	;mov	al, 0
  5291 00002026 28C0                <1> 	sub	al, al ; 0
  5292 00002028 C3                  <1> 	retn
  5293                              <1> 
  5294                              <1> chsfnc:	
  5295 00002029 668B4305            <1> 	mov	ax, [ebx+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  5296                              <1> 	;shr	ax, 2
  5297                              <1> 	; 17/07/2022
  5298 0000202D C1E802              <1> 	shr	eax, 2
  5299 00002030 8845F8              <1> 	mov	[CMD_BLOCK], al
  5300                              <1> 	;
  5301                              <1> 	;;mov	al, [ebx+8]		; GET CONTROL BYTE MODIFIER
  5302                              <1> 	;;push	edx ; *
  5303                              <1> 	;;mov	dx, [HF_REG_PORT]
  5304                              <1> 	;;out	dx, al			; SET EXTRA HEAD OPTION
  5305                              <1> 	;;pop	edx ; * 
  5306                              <1> 	;;mov	ah, [CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  5307                              <1> 	;;and	ah, 0C0h 		; CONTROL BYTE	
  5308                              <1> 	;;or	ah, al
  5309                              <1> 	;;mov	[CONTROL_BYTE], ah
  5310                              <1> 	;
  5311 00002033 88C8                <1> 	mov	al, cl			; GET SECTOR NUMBER
  5312 00002035 243F                <1> 	and	al, 3Fh
  5313 00002037 8845FA              <1> 	mov	[CMD_BLOCK+2], al
  5314 0000203A 886DFB              <1> 	mov	[CMD_BLOCK+3], ch 	; GET CYLINDER NUMBER
  5315 0000203D 88C8                <1> 	mov	al, cl
  5316 0000203F C0E806              <1> 	shr	al, 6
  5317 00002042 8845FC              <1> 	mov	[CMD_BLOCK+4], al	; CYLINDER HIGH ORDER 2 BITS
  5318                              <1> 	;;05/01/2015
  5319                              <1> 	;;mov	al, dl			; DRIVE NUMBER
  5320 00002045 A0[26620000]        <1> 	mov	al, [hf_m_s]
  5321 0000204A C0E004              <1> 	shl	al, 4
  5322 0000204D 80E60F              <1> 	and	dh, 0Fh			; HEAD NUMBER
  5323 00002050 08F0                <1> 	or	al, dh
  5324 00002052 0CA0                <1> 	or	al, 80h+20h		; ECC AND 512 BYTE SECTORS
  5325 00002054 8845FD              <1> 	mov	[CMD_BLOCK+5], al	; ECC/SIZE/DRIVE/HEAD
  5326                              <1> su4:
  5327                              <1> 	;; 14/02/2015
  5328                              <1>         ;;pop	ax
  5329                              <1>         ;;mov	[CMD_BLOCK+1], AL	; SECTOR COUNT
  5330                              <1>         ;;push	ax
  5331                              <1>         ;;mov	al, ah			; GET INTO LOW BYTE
  5332                              <1>         ;;xor	ah, ah			; ZERO HIGH BYTE
  5333                              <1>         ;;sal	ax, 1			; *2 FOR TABLE LOOKUP
  5334                              <1> 	;pop	ax ; ***
  5335                              <1> 	; 24/12/2021
  5336 00002057 58                  <1> 	pop	eax ; *** ; function (in AL) ; 11/07/2022
  5337                              <1> 	
  5338                              <1> 	;mov	[CMD_BLOCK+1], al
  5339 00002058 C645F901            <1>         mov	byte [CMD_BLOCK+1], 1 ; (always 1 sector r/w)
  5340                              <1> 
  5341                              <1> 	; 11/07/2022
  5342                              <1> 	;mov	ebx, esi
  5343                              <1> 	; (esi = buffer address)	
  5344                              <1> 
  5345 0000205C 3C02                <1> 	cmp	al, 2
  5346 0000205E 7433                <1> 	je	short DISK_WRITE
  5347                              <1> 
  5348                              <1> 	;jmp	short DISK_READ
  5349                              <1> 
  5350                              <1> ;	;xor	ebx, ebx
  5351                              <1> ;	;mov	bl, ah
  5352                              <1> ;
  5353                              <1> ;       ;xor	bh, bh
  5354                              <1> ;       ;sal	bx, 1
  5355                              <1> ;       sal	ebx, 2	; 32 bit offset (21/02/2015)
  5356                              <1> ;	;;mov	si, ax			; PUT INTO SI FOR BRANCH
  5357                              <1> ;       ;;cmp	ax, M1L			; TEST WITHIN RANGE
  5358                              <1> ;       ;;jnb	short BAD_COMMAND_POP
  5359                              <1> ;   	; 08/07/2022
  5360                              <1> ;	;cmp	ebx, M1L
  5361                              <1> ;	;jnb	short BAD_COMMAND
  5362                              <1> ;
  5363                              <1> ;	xchg	ebx, esi
  5364                              <1> ;
  5365                              <1> ;	;;;pop	ax			; RESTORE AX
  5366                              <1> ;	;;;pop	bx			; AND DATA ADDRESS
  5367                              <1> ;	
  5368                              <1> ;	;;push	cx
  5369                              <1> ;	;;push	ax			; ADJUST ES:BX
  5370                              <1> ;	;mov	cx, bx			; GET 3 HIGH ORDER NIBBLES OF BX
  5371                              <1> ;	;shr	cx, 4
  5372                              <1> ;	;mov	ax, es
  5373                              <1> ;	;add	ax, cx
  5374                              <1> ;	;mov	es, ax
  5375                              <1> ;	;and	bx, 000Fh		; ES:BX CHANGED TO ES:000X
  5376                              <1> ;	;;pop	ax
  5377                              <1> ;	;;pop	cx
  5378                              <1> ;
  5379                              <1> ;	jmp	dword [esi+M1]
  5380                              <1> 
  5381                              <1> ;;BAD_COMMAND_POP:
  5382                              <1> ;;	pop	ax
  5383                              <1> ;;	pop	bx
  5384                              <1> ;
  5385                              <1> ;	; 11/07/2022
  5386                              <1> ;BAD_COMMAND:
  5387                              <1> ;	mov	byte [DISK_STATUS1], BAD_CMD  ; COMMAND ERROR
  5388                              <1> ;	;mov	al, 0
  5389                              <1> ;	sub	al, al ; 0
  5390                              <1> ;	retn
  5391                              <1> 
  5392                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5393                              <1> 
  5394                              <1> ;----------------------------------------
  5395                              <1> ;	DISK READ ROUTINE    (AH = 01H) :
  5396                              <1> ;----------------------------------------
  5397                              <1> ; 
  5398                              <1> DISK_READ:
  5399 00002060 C645FE20            <1> 	mov	byte [CMD_BLOCK+6], READ_CMD
  5400                              <1>         ;jmp	COMMANDI
  5401                              <1> 
  5402                              <1> ; 16/07/2022
  5403                              <1> ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5404                              <1> 
  5405                              <1> ;----------------------------------------
  5406                              <1> ; COMMANDI				:
  5407                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  5408                              <1> ;	NSECTOR RETURNS ZERO		:
  5409                              <1> ;----------------------------------------
  5410                              <1> COMMANDI:
  5411                              <1> 	; 11/07/2022 
  5412                              <1> 	;	(check 64K boundary is not needed)
  5413                              <1> 	;call	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  5414                              <1> 	;jc	short CMD_ABORT
  5415                              <1> 	
  5416                              <1> 	;mov	di, bx
  5417                              <1> 	; 11/07/2022
  5418                              <1> 	; (esi = buffer address)
  5419                              <1> 	;mov	edi, ebx ; 21/02/2015
  5420 00002064 89F7                <1> 	mov	edi, esi ; 11/07/2022	
  5421                              <1> 
  5422 00002066 E8AE010000          <1> 	call	COMMAND 		; OUTPUT COMMAND
  5423 0000206B 7525                <1> 	jnz	short CMD_ABORT
  5424                              <1> CMD_I1:
  5425 0000206D E819020000          <1> 	call	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  5426 00002072 751E                <1> 	jnz	short TM_OUT		; TIME OUT
  5427                              <1> 	;;mov	cx,256			; SECTOR SIZE IN WORDS
  5428                              <1> 	;mov	ecx, 256 ; 21/02/2015	
  5429 00002074 29C9                <1> 	sub	ecx, ecx
  5430 00002076 FEC5                <1> 	inc	ch
  5431                              <1> 	; ecx = 256
  5432                              <1> 	;mov	dx, HF_PORT
  5433 00002078 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  5434 0000207F FA                  <1> 	cli
  5435 00002080 FC                  <1> 	cld
  5436 00002081 F3666D              <1> 	rep	insw			; GET THE SECTOR
  5437 00002084 FB                  <1> 	sti
  5438                              <1> 	
  5439                              <1> 	;test	byte [CMD_BLOCK+6], ECC_MODE ; CHECK FOR NORMAL INPUT
  5440                              <1> 	;jz	short CMD_I3
  5441                              <1> 	;call	WAIT_DRQ		; WAIT FOR DATA REQUEST
  5442                              <1> 	;jc	short TM_OUT
  5443                              <1> 	;;mov	dx, HF_PORT
  5444                              <1> 	;mov	dx,[HF_PORT]
  5445                              <1> 	;xor	ecx, ecx	
  5446                              <1> 	;;mov	ecx, 4  ; mov cx, 4	; OUTPUT THE ECC BYTES
  5447                              <1> 	;mov	cl, 4
  5448                              <1> ;CMD_I2: 
  5449                              <1> 	;inc	al, dx
  5450                              <1> 	;mov 	[edi], al ; 21/02/2015
  5451                              <1> 	;inc	edi
  5452                              <1> 	;loop	CMD_I2
  5453                              <1> CMD_I3:
  5454                              <1> 	; 16/07/2022
  5455                              <1> 	; wait for 400 ns
  5456 00002085 80C207              <1> 	add 	dl, 7
  5457 00002088 EC                  <1> 	in	al, dx
  5458 00002089 EC                  <1> 	in	al, dx
  5459 0000208A EC                  <1> 	in	al, dx
  5460                              <1> 	;
  5461 0000208B E817010000          <1> 	call	CHECK_STATUS
  5462 00002090 7500                <1> 	jnz	short CMD_ABORT		; ERROR RETURNED
  5463                              <1> 	; 11/07/2022
  5464                              <1> 	; (sector count = 1)
  5465                              <1> 	;dec	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  5466                              <1> 	;jnz	SHORT CMD_I1
  5467                              <1> CMD_ABORT:
  5468                              <1> TM_OUT: 
  5469 00002092 C3                  <1> 	retn
  5470                              <1> 
  5471                              <1> ;---------------------------------------------------
  5472                              <1> 
  5473                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5474                              <1> 
  5475                              <1> ;----------------------------------------
  5476                              <1> ;	DISK WRITE ROUTINE   (AH = 02H) :
  5477                              <1> ;----------------------------------------
  5478                              <1> 
  5479                              <1> DISK_WRITE:
  5480 00002093 C645FE30            <1> 	mov	byte [CMD_BLOCK+6], WRITE_CMD
  5481                              <1>         ;JMP	COMMANDO
  5482                              <1> 
  5483                              <1> ; 16/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  5484                              <1> ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5485                              <1> 
  5486                              <1> ;----------------------------------------
  5487                              <1> ; COMMANDO				:
  5488                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  5489                              <1> ;	NSECTOR RETURNS ZERO		:
  5490                              <1> ;----------------------------------------
  5491                              <1> COMMANDO:
  5492                              <1> 	; 11/07/2022 
  5493                              <1> 	;	(check 64K boundary is not needed)
  5494                              <1> 	;call	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  5495                              <1> 	;jc	short CMD_ABORT
  5496                              <1> CMD_OF:
  5497                              <1> 	; 11/07/2022
  5498                              <1> 	; (esi = ebx = buffer address)
  5499                              <1> 	;mov	esi, ebx ; 21/02/2015
  5500 00002097 E87D010000          <1> 	call	COMMAND 		; OUTPUT COMMAND
  5501 0000209C 75F4                <1> 	jnz	short CMD_ABORT
  5502 0000209E E83F020000          <1> 	call	WAIT_DRQ		; WAIT FOR DATA REQUEST
  5503 000020A3 72ED                <1> 	jc	short TM_OUT		; TOO LONG
  5504                              <1> CMD_O1:
  5505                              <1> 	; 16/07/2022
  5506 000020A5 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  5507                              <1> 
  5508                              <1> 	; 10/07/2022
  5509                              <1> 	;mov	ecx, 256 ; 21/02/2015
  5510 000020AC 31C9                <1> 	xor	ecx, ecx
  5511 000020AE FEC5                <1> 	inc	ch
  5512                              <1> 	; ecx = 256
  5513 000020B0 FA                  <1> 	cli
  5514 000020B1 FC                  <1> 	cld
  5515 000020B2 F3666F              <1> 	rep	outsw
  5516 000020B5 FB                  <1> 	sti
  5517                              <1> 
  5518                              <1> 	; 10/07/2022
  5519                              <1> 	;test	byte [CMD_BLOCK+6], ECC_MODE ; CHECK FOR NORMAL OUTPUT
  5520                              <1> 	;jz	short CMD_O3
  5521                              <1> 	;
  5522                              <1> 	;call	WAIT_DRQ		; WAIT FOR DATA REQUEST
  5523                              <1> 	;jc	short TM_OUT
  5524                              <1> 	;;mov	dx, HF_PORT
  5525                              <1> 	;mov	dx, [HF_PORT]
  5526                              <1> 	;sub	ecx, ecx	
  5527                              <1> 	;;mov	ecx, 4  ; mov cx, 4	; OUTPUT THE ECC BYTES
  5528                              <1> 	;mov	cl, 4
  5529                              <1> ;CMD_O2:
  5530                              <1> 	;;lodsb
  5531                              <1> 	;mov	al, [esi]
  5532                              <1> 	;out	dx, al
  5533                              <1> 	;inc	esi
  5534                              <1> 	;loop	CMD_O2
  5535                              <1> 
  5536                              <1> CMD_O3:
  5537 000020B6 E8D0010000          <1> 	call	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  5538 000020BB 75D5                <1> 	jnz	short TM_OUT		; ERROR RETURNED
  5539 000020BD E8E5000000          <1> 	call	CHECK_STATUS
  5540 000020C2 75CE                <1> 	jnz	short CMD_ABORT
  5541                              <1> 
  5542                              <1> 	; 11/07/2022
  5543                              <1> 	; (sector count = 1)
  5544                              <1> 	;test	byte [HF_STATUS], ST_DRQ ; CHECK FOR MORE
  5545                              <1> 	;jnz	short CMD_O1
  5546                              <1> 	
  5547                              <1> 	;mov	dx, HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  5548 000020C4 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  5549 000020CB 80C202              <1> 	add	dl, 2
  5550                              <1> 	;inc	dl
  5551                              <1> 	;inc	dl
  5552 000020CE EC                  <1> 	in	al, dx			;
  5553 000020CF A8FF                <1> 	test	al, 0FFh 		;
  5554 000020D1 7407                <1> 	jz	short CMD_O4		; COUNT = 0  OK
  5555 000020D3 C605[9B670000]BB    <1> 	mov	byte [DISK_STATUS1], UNDEF_ERR 
  5556                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  5557                              <1> CMD_O4:
  5558 000020DA C3                  <1> 	retn
  5559                              <1> 
  5560                              <1> ; 10/07/2022
  5561                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5562                              <1> 
  5563                              <1> ;----------------------------------------
  5564                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  5565                              <1> ;----------------------------------------
  5566                              <1> 
  5567                              <1> ; 18-1-2015 : one controller reset (not other one)
  5568                              <1> 
  5569                              <1> DISK_RESET:
  5570 000020DB FA                  <1> 	cli
  5571 000020DC E4A1                <1> 	in	al, INTB01		; GET THE MASK REGISTER
  5572                              <1> 	;JMP	$+2
  5573                              <1> 	IODELAY
  2172 000020DE EB00                <2>  jmp short $+2
  2173 000020E0 EB00                <2>  jmp short $+2
  5574                              <1> 	;and	al, 0BFh 		; ENABLE FIXED DISK INTERRUPT
  5575 000020E2 243F                <1> 	and	al, 3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  5576 000020E4 E6A1                <1> 	out	INTB01, al
  5577 000020E6 FB                  <1> 	sti				; START INTERRUPTS
  5578                              <1> 	; 14/02/2015
  5579                              <1> 	;mov	di, dx
  5580                              <1> 	; 24/12/2021
  5581 000020E7 89D7                <1> 	mov	edi, edx	
  5582                              <1> 	; 04/01/2015
  5583                              <1> 	;xor	di,di
  5584                              <1> drst0:
  5585 000020E9 B004                <1> 	mov	al, 04h  ; bit 2 - SRST 
  5586                              <1> 	;mov	dx, HF_REG_PORT
  5587 000020EB 668B15[24620000]    <1> 	mov	dx, [HF_REG_PORT]
  5588 000020F2 EE                  <1> 	out	dx, al			; RESET
  5589                              <1> ;	mov	cx, 10			; DELAY COUNT
  5590                              <1> ;DRD:	dec	cx
  5591                              <1> ;	jnz	short DRD		; WAIT 4.8 MICRO-SEC
  5592                              <1> 	;mov	cx, 2			; wait for 30 micro seconds	
  5593                              <1>         ;mov	ecx, 2 ; 21/02/2015
  5594                              <1> 	; 10/07/2022
  5595 000020F3 29C9                <1> 	sub	ecx, ecx
  5596 000020F5 B102                <1> 	mov	cl, 2
  5597 000020F7 E895F2FFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  5598                              <1>                                         ; 40 micro seconds)
  5599 000020FC A0[9D670000]        <1> 	mov	al, [CONTROL_BYTE]
  5600 00002101 240F                <1> 	and	al, 0Fh			; SET HEAD OPTION
  5601 00002103 EE                  <1> 	out	dx, al			; TURN RESET OFF
  5602 00002104 E8B2010000          <1> 	call	NOT_BUSY
  5603 00002109 7514                <1> 	jnz	short DRERR		; TIME OUT ON RESET
  5604 0000210B 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  5605 00002112 FEC2                <1> 	inc	dl  ; HF_PORT+1
  5606                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  5607                              <1>         ;mov	cl, 10
  5608                              <1>         ;mov     ecx, 10 ; 21/02/2015
  5609                              <1> 	; 10/07/2022
  5610                              <1> 	;xor	ecx, ecx
  5611 00002114 B10A                <1> 	mov	cl, 10 
  5612                              <1> drst1:
  5613 00002116 EC                  <1> 	in	al, dx			; GET RESET STATUS
  5614 00002117 3C01                <1> 	cmp	al, 1
  5615                              <1> 	; 04/01/2015
  5616 00002119 740C                <1> 	jz	short drst2
  5617                              <1> 	;jnz	short DRERR		; BAD RESET STATUS
  5618                              <1>         	; Drive/Head Register - bit 4
  5619                              <1> 	;loop	drst1
  5620                              <1> 	; 10/07/2022
  5621 0000211B FEC9                <1> 	dec	cl
  5622 0000211D 75F7                <1> 	jnz	short drst1
  5623                              <1> DRERR:	
  5624 0000211F C605[9B670000]05    <1> 	mov	byte [DISK_STATUS1], BAD_RESET ; CARD FAILED
  5625 00002126 C3                  <1> 	retn
  5626                              <1> drst2:
  5627                              <1> 	; 14/02/2015
  5628                              <1> 	;mov	dx, di
  5629                              <1> 	; 24/12/2021
  5630 00002127 89FA                <1> 	mov	edx, edi
  5631                              <1> ;drst3:
  5632                              <1> ;	; 05/01/2015
  5633                              <1> ;	shl 	di, 1
  5634                              <1> ;	; 04/01/2015
  5635                              <1> ;	mov	ax, [di+hd_cports]
  5636                              <1> ;	cmp	ax, [HF_REG_PORT]
  5637                              <1> ;	je	short drst4
  5638                              <1> ;	mov	[HF_REG_PORT], ax
  5639                              <1> ;	; 03/01/2015
  5640                              <1> ;	mov	ax, [di+hd_ports]
  5641                              <1> ;       mov     [HF_PORT], ax
  5642                              <1> ;	; 05/01/2014
  5643                              <1> ;	shr	di, 1
  5644                              <1> ;	; 04/01/2015
  5645                              <1> ;	jmp	short drst0	; reset other controller
  5646                              <1> ;drst4:
  5647                              <1> ;	; 05/01/2015
  5648                              <1> ;	shr	di, 1
  5649                              <1> ;	mov	al, [di+hd_dregs]
  5650                              <1> ;	and	al, 10h ; bit 4 only
  5651                              <1> ;	shr	al, 4 ; bit 4 -> bit 0
  5652                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  5653                              <1> 	;
  5654 00002129 A0[26620000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  5655 0000212E A801                <1> 	test	al, 1
  5656                              <1> 	;jnz	short drst6
  5657 00002130 7516                <1>         jnz     short drst4
  5658 00002132 8065FDEF            <1> 	and	byte [CMD_BLOCK+5], 0EFh ; SET TO DRIVE 0
  5659                              <1> ;drst5:
  5660                              <1> drst3:
  5661 00002136 E813000000          <1> 	call	INIT_DRV		; SET MAX HEADS
  5662                              <1> 	;mov	dx, di
  5663 0000213B E8A3000000          <1> 	call	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  5664                              <1> 	; 04/01/2014
  5665                              <1> ;	inc	di
  5666                              <1> ;	mov	dx, di
  5667                              <1> ;	cmp	dl, [HF_NUM]
  5668                              <1> ;	jb	short drst3
  5669                              <1> ;DRE:
  5670 00002140 C605[9B670000]00    <1> 	mov	byte [DISK_STATUS1], 0 	; IGNORE ANY SET UP ERRORS
  5671 00002147 C3                  <1> 	retn
  5672                              <1> ;drst6:
  5673                              <1> drst4:		; Drive/Head Register - bit 4
  5674 00002148 804DFD10            <1> 	or	byte [CMD_BLOCK+5], 010h ; SET TO DRIVE 1     
  5675                              <1>         ;jmp    short drst5
  5676 0000214C EBE8                <1>         jmp     short drst3
  5677                              <1> 
  5678                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5679                              <1> 
  5680                              <1> ;----------------------------------------
  5681                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  5682                              <1> ;----------------------------------------
  5683                              <1> 	; 03/01/2015
  5684                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  5685                              <1> 	; logical sector per logical track
  5686                              <1> 	; and logical heads - 1 would be set but
  5687                              <1> 	; it is seen as it will be good
  5688                              <1> 	; if physical parameters will be set here
  5689                              <1> 	; because, number of heads <= 16.
  5690                              <1> 	; (logical heads usually more than 16)
  5691                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  5692                              <1> 	;	== INT 13h physical parameters
  5693                              <1> 
  5694                              <1> ;INIT_DRV:
  5695                              <1> ;	mov	byte [CMD_BLOCK+6], SET_PARM_CMD
  5696                              <1> ;	call	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  5697                              <1> ;	mov	al, [es:bx+2]		; GET NUMBER OF HEADS
  5698                              <1> ;	dec	al			; CONVERT TO 0-INDEX
  5699                              <1> ;	mov	ah, [CMD_BLOCK+5] 	; GET SDH REGISTER
  5700                              <1> ;	and	ah, 0F0h 		; CHANGE HEAD NUMBER
  5701                              <1> ;	or	ah, al			; TO MAX HEAD
  5702                              <1> ;	mov	[CMD_BLOCK+5], ah
  5703                              <1> ;	mov	al, [es:bx+14]		; MAX SECTOR NUMBER
  5704                              <1> ;	mov	[CMD_BLOCK+1], al
  5705                              <1> ;	sub	ax, ax
  5706                              <1> ;	mov	[CMD_BLOCK+3], al 	; ZERO FLAGS
  5707                              <1> ;	call	COMMAND 		; TELL CONTROLLER
  5708                              <1> ;	jnz	short INIT_EXIT		; CONTROLLER BUSY ERROR
  5709                              <1> ;	call	NOT_BUSY		; WAIT FOR IT TO BE DONE
  5710                              <1> ;	jnz	short INIT_EXIT		; TIME OUT
  5711                              <1> ;	call	CHECK_STATUS
  5712                              <1> ;INIT_EXIT:
  5713                              <1> ;	retn
  5714                              <1> 
  5715                              <1> ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5716                              <1> 
  5717                              <1> ; 04/01/2015
  5718                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  5719                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  5720                              <1> INIT_DRV:
  5721                              <1> 	;xor	ah, ah
  5722 0000214E 31C0                <1> 	xor	eax, eax ; 21/02/2015
  5723 00002150 B00B                <1> 	mov	al, 11 ; Physical heads from translated HDPT
  5724 00002152 3825[B0670000]      <1>         cmp     [LBAMode], ah   ; 0
  5725 00002158 7702                <1> 	ja	short idrv0
  5726 0000215A B002                <1> 	mov	al, 2  ; Physical heads from standard HDPT
  5727                              <1> idrv0:
  5728                              <1> 	; DL = drive number (0 based)
  5729 0000215C E80D020000          <1> 	call	GET_VEC
  5730                              <1> 	;push	bx
  5731 00002161 53                  <1> 	push	ebx ; 21/02/2015
  5732                              <1> 	;add	bx, ax
  5733 00002162 01C3                <1> 	add	ebx, eax
  5734                              <1> 	;; 05/01/2015
  5735 00002164 8A25[26620000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  5736                              <1> 	;;and 	ah, 1 
  5737 0000216A C0E404              <1> 	shl	ah, 4
  5738 0000216D 80CCA0              <1> 	or	ah, 0A0h  ; Drive/Head register - 10100000b (A0h)	
  5739                              <1> 	;mov	al, [es:bx]
  5740 00002170 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  5741 00002172 FEC8                <1> 	dec	al	 ; last head number 
  5742                              <1> 	;and	al, 0Fh
  5743 00002174 08E0                <1> 	or	al, ah	 ; lower 4 bits for head number
  5744                              <1> 	;
  5745 00002176 C645FE91            <1> 	mov	byte [CMD_BLOCK+6], SET_PARM_CMD
  5746 0000217A 8845FD              <1> 	mov	[CMD_BLOCK+5], al
  5747                              <1> 	;pop	bx
  5748 0000217D 5B                  <1> 	pop	ebx
  5749 0000217E 29C0                <1> 	sub	eax, eax ; 21/02/2015
  5750 00002180 B004                <1> 	mov	al, 4 ; Physical sec per track from translated HDPT
  5751 00002182 803D[B0670000]00    <1> 	cmp	byte [LBAMode], 0
  5752 00002189 7702                <1> 	ja	short idrv1
  5753 0000218B B00E                <1> 	mov	al, 14 ; Physical sec per track from standard HDPT
  5754                              <1> idrv1:
  5755                              <1> 	;xor	ah, ah
  5756                              <1> 	;add	bx, ax
  5757 0000218D 01C3                <1> 	add	ebx, eax ; 21/02/2015
  5758                              <1> 	;mov	al, [es:bx]
  5759                              <1> 			; sector number
  5760 0000218F 8A03                <1> 	mov	al, [ebx]
  5761 00002191 8845F9              <1> 	mov	[CMD_BLOCK+1], al
  5762 00002194 28C0                <1> 	sub	al, al
  5763 00002196 8845FB              <1> 	mov	[CMD_BLOCK+3], al ; ZERO FLAGS
  5764 00002199 E87B000000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  5765 0000219E 751E                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  5766 000021A0 E816010000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  5767 000021A5 7517                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  5768                              <1> 	;call	CHECK_STATUS
  5769                              <1> 	;jmp	short CHECK_STATUS
  5770                              <1> ;INIT_EXIT:
  5771                              <1> 	;retn
  5772                              <1> 
  5773                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5774                              <1> 
  5775                              <1> ;----------------------------------------
  5776                              <1> ;	CHECK FIXED DISK STATUS 	:
  5777                              <1> ;----------------------------------------
  5778                              <1> CHECK_STATUS:
  5779 000021A7 E861010000          <1> 	call	CHECK_ST		; CHECK THE STATUS BYTE
  5780                              <1> 	;jnz	short CHECK_S1		; AN ERROR WAS FOUND
  5781                              <1> 	; 10/07/2022
  5782 000021AC 7510                <1> 	jnz	short CHECK_S2
  5783 000021AE A801                <1> 	test	al, ST_ERROR		; WERE THERE ANY OTHER ERRORS
  5784 000021B0 7405                <1> 	jz	short CHECK_S1		; NO ERROR REPORTED
  5785 000021B2 E894010000          <1> 	call	CHECK_ER		; ERROR REPORTED
  5786                              <1> CHECK_S1:
  5787 000021B7 803D[9B670000]00    <1> 	cmp	byte [DISK_STATUS1], 0 	; SET STATUS FOR CALLER
  5788                              <1> CHECK_S2:
  5789                              <1> INIT_EXIT:	; 10/07/2022
  5790 000021BE C3                  <1> 	retn
  5791                              <1> 
  5792                              <1> ;----------------------------------------
  5793                              <1> ;	TEST DISK READY      (AH = 10H) :
  5794                              <1> ;----------------------------------------
  5795                              <1> 
  5796                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  5797 000021BF E8F7000000          <1> 	call	NOT_BUSY
  5798 000021C4 751C                <1> 	jnz	short TR_EX
  5799 000021C6 8A45FD              <1> 	mov	al, [CMD_BLOCK+5] 	; SELECT DRIVE
  5800 000021C9 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  5801 000021D0 80C206              <1> 	add	dl, 6
  5802 000021D3 EE                  <1> 	out	dx, al
  5803 000021D4 E834010000          <1> 	call	CHECK_ST		; CHECK STATUS ONLY
  5804 000021D9 7507                <1> 	jnz	short TR_EX
  5805 000021DB C605[9B670000]00    <1> 	mov	byte [DISK_STATUS1], 0 	; WIPE OUT DATA CORRECTED ERROR
  5806                              <1> TR_EX:	
  5807 000021E2 C3                  <1> 	retn
  5808                              <1> 
  5809                              <1> ;----------------------------------------
  5810                              <1> ;	RECALIBRATE	     (AH = 11H) :
  5811                              <1> ;----------------------------------------
  5812                              <1> 
  5813                              <1> HDISK_RECAL:
  5814 000021E3 C645FE10            <1>         mov	byte [CMD_BLOCK+6], RECAL_CMD ; 10h, 16
  5815 000021E7 E82D000000          <1> 	call	COMMAND 		; START THE OPERATION
  5816 000021EC 7523                <1> 	jnz	short RECAL_EXIT	; ERROR
  5817 000021EE E898000000          <1> 	call	_WAIT			; WAIT FOR COMPLETION
  5818 000021F3 7407                <1> 	jz	short RECAL_X 		; TIME OUT ONE OK ?
  5819 000021F5 E891000000          <1> 	call	_WAIT			; WAIT FOR COMPLETION LONGER
  5820 000021FA 7515                <1> 	jnz	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  5821                              <1> RECAL_X:
  5822 000021FC E8A6FFFFFF          <1> 	call	CHECK_STATUS
  5823 00002201 803D[9B670000]40    <1> 	cmp	byte [DISK_STATUS1], BAD_SEEK ; SEEK NOT COMPLETE
  5824 00002208 7507                <1> 	jne	short RECAL_EXIT	; IS OK
  5825 0000220A C605[9B670000]00    <1> 	mov	byte [DISK_STATUS1], 0
  5826                              <1> RECAL_EXIT:
  5827 00002211 803D[9B670000]00    <1>         cmp	byte [DISK_STATUS1], 0
  5828 00002218 C3                  <1> 	retn
  5829                              <1> 
  5830                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5831                              <1> 
  5832                              <1> ;--------------------------------------------------------
  5833                              <1> ; COMMAND						:
  5834                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  5835                              <1> ; OUTPUT						:
  5836                              <1> ;	BL = STATUS					:
  5837                              <1> ;	BH = ERROR REGISTER				:
  5838                              <1> ;--------------------------------------------------------
  5839                              <1> 
  5840                              <1> COMMAND:
  5841                              <1> 	;push	ebx ; 10/07/2022	; WAIT FOR SEEK COMPLETE AND READY
  5842                              <1> 	;;mov	ecx, DELAY_2		; SET INITIAL DELAY BEFORE TEST
  5843                              <1> COMMAND1:
  5844                              <1> 	;;push	ecx			; SAVE LOOP COUNT
  5845 00002219 E8A1FFFFFF          <1> 	call	TST_RDY 		; CHECK DRIVE READY
  5846                              <1> 	;;pop	ecx
  5847                              <1> 	;pop	ebx ; 10/07/2022
  5848 0000221E 7418                <1> 	jz	short COMMAND2		; DRIVE IS READY
  5849 00002220 803D[9B670000]80    <1>         cmp	byte [DISK_STATUS1], TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  5850                              <1> 	;jz	short CMD_TIMEOUT
  5851                              <1> 	;;loop	COMMAND1		; KEEP TRYING FOR A WHILE
  5852                              <1> 	;jmp	short COMMAND4		; ITS NOT GOING TO GET READY
  5853 00002227 7507                <1> 	jne	short COMMAND4
  5854                              <1> CMD_TIMEOUT:
  5855 00002229 C605[9B670000]20    <1> 	mov	byte [DISK_STATUS1], BAD_CNTLR
  5856                              <1> COMMAND4:
  5857                              <1> 	;;pop	ebx ; 10/07/2022
  5858 00002230 803D[9B670000]00    <1>         cmp	byte [DISK_STATUS1], 0	; SET CONDITION CODE FOR CALLER
  5859 00002237 C3                  <1> 	retn
  5860                              <1> COMMAND2:
  5861                              <1> 	;;pop	ebx ; 10/07/2022
  5862                              <1> 	;push	edi ; 10/07/2022
  5863 00002238 C605[96670000]00    <1> 	mov	byte [HF_INT_FLAG], 0	; RESET INTERRUPT FLAG
  5864 0000223F FA                  <1> 	cli				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  5865 00002240 E4A1                <1> 	in	al, INTB01		; TURN ON SECOND INTERRUPT CHIP
  5866                              <1> 	;and	al, 0BFh
  5867 00002242 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  5868                              <1> 	;JMP	$+2
  5869                              <1> 	IODELAY
  2172 00002244 EB00                <2>  jmp short $+2
  2173 00002246 EB00                <2>  jmp short $+2
  5870 00002248 E6A1                <1> 	out	INTB01, al
  5871 0000224A E421                <1> 	in	al, INTA01		; LET INTERRUPTS PASS THRU TO
  5872 0000224C 24FB                <1> 	and	al, 0FBh 		; SECOND CHIP
  5873                              <1> 	;JMP	$+2
  5874                              <1> 	IODELAY
  2172 0000224E EB00                <2>  jmp short $+2
  2173 00002250 EB00                <2>  jmp short $+2
  5875 00002252 E621                <1> 	out	INTA01, al
  5876 00002254 FB                  <1> 	sti
  5877                              <1> 	;xor	edi, edi		; INDEX THE COMMAND TABLE
  5878                              <1> 	; 10/07/2022
  5879 00002255 31C9                <1> 	xor	ecx, ecx
  5880                              <1> 	;mov	dx, HF_PORT+1		; DISK ADDRESS
  5881 00002257 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  5882 0000225E FEC2                <1> 	inc	dl
  5883 00002260 F605[9D670000]C0    <1> 	test	byte [CONTROL_BYTE], 0C0h ; CHECK FOR RETRY SUPPRESSION
  5884 00002267 7411                <1> 	jz	short COMMAND3
  5885 00002269 8A45FE              <1> 	mov	al, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  5886 0000226C 24F0                <1> 	and	al, 0F0h 		; GET RID OF MODIFIERS
  5887 0000226E 3C20                <1> 	cmp	al, 20h			; 20H-40H IS READ, WRITE, VERIFY
  5888 00002270 7208                <1> 	jb	short COMMAND3
  5889 00002272 3C40                <1> 	cmp	al, 40h
  5890 00002274 7704                <1> 	ja	short COMMAND3
  5891 00002276 804DFE01            <1> 	or	byte [CMD_BLOCK+6], NO_RETRIES 
  5892                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  5893                              <1> COMMAND3:
  5894                              <1> 	;mov	al, [CMD_BLOCK+edi]	; GET THE COMMAND STRING BYTE
  5895                              <1> 	; 10/07/2022
  5896 0000227A 8A440DF8            <1> 	mov	al, [CMD_BLOCK+ecx]
  5897 0000227E EE                  <1> 	out	dx, al			; GIVE IT TO CONTROLLER
  5898                              <1> 	IODELAY
  2172 0000227F EB00                <2>  jmp short $+2
  2173 00002281 EB00                <2>  jmp short $+2
  5899                              <1> 	;inc	edi			; NEXT BYTE IN COMMAND BLOCK
  5900                              <1> 	; 10/07/2022
  5901 00002283 41                  <1> 	inc	ecx
  5902                              <1> 	;inc	dx			; NEXT DISK ADAPTER REGISTER
  5903 00002284 42                  <1> 	inc	edx   ; 10/07/2022	
  5904                              <1> 	;cmp	di, 7 ; 01/01/2015	; ALL DONE?
  5905                              <1> 	;jne	short COMMAND3		; NO--GO DO NEXT ONE
  5906 00002285 80F907              <1> 	cmp	cl, 7 ; 10/07/2022
  5907 00002288 72F0                <1> 	jb	short COMMAND3
  5908                              <1> 	;pop	edi ; 10/07/2022
  5909 0000228A C3                  <1> 	retn				; ZERO FLAG IS SET
  5910                              <1> 
  5911                              <1> ;CMD_TIMEOUT:
  5912                              <1> ;	mov	byte [DISK_STATUS1], BAD_CNTLR
  5913                              <1> ;COMMAND4:
  5914                              <1> ;	pop	ebx
  5915                              <1> ;	cmp	byte [DISK_STATUS1], 0 	; SET CONDITION CODE FOR CALLER
  5916                              <1> ;	retn
  5917                              <1> 
  5918                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5919                              <1> 
  5920                              <1> ;----------------------------------------
  5921                              <1> ;	WAIT FOR INTERRUPT		:
  5922                              <1> ;----------------------------------------
  5923                              <1> ;WAIT:
  5924                              <1> _WAIT:
  5925 0000228B FB                  <1> 	sti				; MAKE SURE INTERRUPTS ARE ON
  5926                              <1> 	;sub	cx, cx			; SET INITIAL DELAY BEFORE TEST
  5927                              <1> 	;clc
  5928                              <1> 	;mov	ax, 9000h		; DEVICE WAIT INTERRUPT
  5929                              <1> 	;int	15h
  5930                              <1> 	;jc	short WT2		; DEVICE TIMED OUT
  5931                              <1> 	;mov	bl, DELAY_1		; SET DELAY COUNT
  5932                              <1> 
  5933                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  5934                              <1> 	;; 21/02/2015
  5935                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  5936                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  5937 0000228C B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  5938                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  5939                              <1> ;-----	WAIT LOOP
  5940                              <1> 
  5941                              <1> WT1:	
  5942                              <1> 	;test	byte [HF_INT_FLAG], 80h	; TEST FOR INTERRUPT
  5943 00002291 F605[96670000]C0    <1> 	test 	byte [HF_INT_FLAG], 0C0h
  5944                              <1> 	;loopz	WT1
  5945 00002298 7512                <1> 	jnz	short WT3		; INTERRUPT--LETS GO
  5946                              <1> 	;dec	bl
  5947                              <1> 	;jnz	short WT1		; KEEP TRYING FOR A WHILE
  5948                              <1> 
  5949                              <1> WT1_hi:
  5950 0000229A E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  5951 0000229C A810                <1> 	test	al, 10h			; transition on memory
  5952 0000229E 75FA                <1> 	jnz	short WT1_hi		; refresh.
  5953                              <1> WT1_lo:
  5954 000022A0 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  5955 000022A2 A810                <1> 	test	al, 10h			
  5956 000022A4 74FA                <1> 	jz	short WT1_lo
  5957 000022A6 E2E9                <1> 	loop	WT1
  5958                              <1> 	;;or	bl, bl
  5959                              <1> 	;;jz	short WT2	
  5960                              <1> 	;;dec	bl
  5961                              <1> 	;;jmp	short WT1
  5962                              <1> 	;dec	bl
  5963                              <1> 	;jnz	short WT1	
  5964                              <1> WT2:	
  5965                              <1> 	; 10/07/2022
  5966                              <1> 	;mov	byte [DISK_STATUS1], TIME_OUT ; REPORT TIME OUT ERROR
  5967 000022A8 B080                <1> 	mov	al, TIME_OUT
  5968 000022AA EB07                <1> 	jmp	short WT4
  5969                              <1> WT3:
  5970                              <1> 	;mov	byte [DISK_STATUS1], 0
  5971                              <1> 	;mov	byte [HF_INT_FLAG], 0
  5972 000022AC 28C0                <1> 	sub	al, al ; 0
  5973 000022AE A2[96670000]        <1> 	mov	byte [HF_INT_FLAG], al
  5974                              <1> WT4:
  5975                              <1> NB2:	
  5976 000022B3 A2[9B670000]        <1> 	mov	byte [DISK_STATUS1], al
  5977                              <1> 
  5978                              <1> 	;cmp	byte [DISK_STATUS1], 0 	; SET CONDITION CODE FOR CALLER
  5979 000022B8 20C0                <1> 	and	al, al
  5980                              <1> 	; zf = 0 -> time out, zf = 1 -> ok
  5981 000022BA C3                  <1> 	retn
  5982                              <1> 
  5983                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5984                              <1> 
  5985                              <1> ;----------------------------------------
  5986                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  5987                              <1> ;----------------------------------------
  5988                              <1> NOT_BUSY:
  5989 000022BB FB                  <1> 	sti				; MAKE SURE INTERRUPTS ARE ON
  5990                              <1> 	;push	ebx
  5991                              <1> 	;sub	cx, cx			; SET INITIAL DELAY BEFORE TEST
  5992 000022BC 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  5993 000022C3 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  5994                              <1> 	;mov	bl, DELAY_1
  5995                              <1> 					; wait for 10 seconds
  5996                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  5997                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  5998                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  5999 000022C6 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  6000                              <1> 	;
  6001                              <1> 	;;mov	byte [wait_count], 0    ; Reset wait counter
  6002                              <1> NB1:	
  6003 000022CB EC                  <1> 	in	al, dx			; CHECK STATUS
  6004                              <1> 	;test	al, ST_BUSY
  6005 000022CC 2480                <1> 	and	al, ST_BUSY
  6006                              <1> 	;loopnz NB1
  6007 000022CE 74E3                <1> 	jz	short NB2 ; al = 0	; NOT BUSY--LETS GO
  6008                              <1> 	;dec	bl			
  6009                              <1> 	;jnz	short NB1		; KEEP TRYING FOR A WHILE
  6010                              <1> 
  6011                              <1> NB1_hi: 
  6012 000022D0 E461                <1> 	in	al, SYS1		; wait for hi to lo
  6013 000022D2 A810                <1> 	test	al, 010h		; transition on memory
  6014 000022D4 75FA                <1> 	jnz	short NB1_hi		; refresh.
  6015                              <1> NB1_lo: 
  6016 000022D6 E461                <1> 	in	al, SYS1
  6017 000022D8 A810                <1> 	test	al, 010h
  6018 000022DA 74FA                <1> 	jz	short NB1_lo
  6019 000022DC E2ED                <1> 	loop	NB1
  6020                              <1> 	;dec	bl
  6021                              <1> 	;jnz	short NB1
  6022                              <1> 	;
  6023                              <1> 	;;cmp	byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  6024                              <1> 	;;jb	short NB1
  6025                              <1> 	;
  6026                              <1> 	;mov	byte [DISK_STATUS1], TIME_OUT ; REPORT TIME OUT ERROR
  6027                              <1> 	;jmp	short NB3
  6028 000022DE B080                <1> 	mov	al, TIME_OUT
  6029                              <1> ;NB2:	
  6030 000022E0 EBD1                <1> 	jmp	short NB2 ; 10/07/2022
  6031                              <1> 
  6032                              <1> ;	;mov	byte [DISK_STATUS1], 0
  6033                              <1> ;;NB3:	
  6034                              <1> ;	;pop	ebx
  6035                              <1> ;	mov	[DISK_STATUS1], al	;;; will be set after return
  6036                              <1> ;	;cmp	byte [DISK_STATUS1], 0 	; SET CONDITION CODE FOR CALLER
  6037                              <1> ;	or	al, al			; (zf = 0 --> timeout)
  6038                              <1> ;	retn
  6039                              <1> 
  6040                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6041                              <1> 
  6042                              <1> ;----------------------------------------
  6043                              <1> ;	WAIT FOR DATA REQUEST		:
  6044                              <1> ;----------------------------------------
  6045                              <1> WAIT_DRQ:
  6046                              <1> 	;mov	cx, DELAY_3
  6047                              <1> 	;mov	dx, HF_PORT+7
  6048 000022E2 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  6049 000022E9 80C207              <1> 	add	dl, 7
  6050                              <1> 	;;mov	bl, WAIT_HDU_DRQ_HI	; 0
  6051                              <1> 	;mov	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  6052                              <1> 					; (but it is written as 2000
  6053                              <1> 					; micro seconds in ATORGS.ASM file
  6054                              <1> 					; of Award Bios - 1999, D1A0622)
  6055 000022EC B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  6056                              <1> WQ_1:
  6057 000022F1 EC                  <1> 	in	al, dx			; GET STATUS
  6058 000022F2 A808                <1> 	test	al, ST_DRQ		; WAIT FOR DRQ
  6059 000022F4 7516                <1> 	jnz	short WQ_OK
  6060                              <1> 	;loop	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  6061                              <1> WQ_hi:	
  6062 000022F6 E461                <1> 	in	al, SYS1		; wait for hi to lo
  6063 000022F8 A810                <1> 	test	al, 010h		; transition on memory
  6064 000022FA 75FA                <1> 	jnz	short WQ_hi		; refresh.
  6065                              <1> WQ_lo:  
  6066 000022FC E461                <1> 	in	al, SYS1
  6067 000022FE A810                <1> 	test	al, 010h
  6068 00002300 74FA                <1> 	jz	short WQ_lo
  6069 00002302 E2ED                <1> 	loop	WQ_1
  6070                              <1> 
  6071 00002304 C605[9B670000]80    <1> 	mov	byte [DISK_STATUS1], TIME_OUT ; ERROR
  6072 0000230B F9                  <1> 	stc
  6073                              <1> WQ_OK:
  6074 0000230C C3                  <1> 	retn
  6075                              <1> ;WQ_OK:
  6076                              <1> 	;clc
  6077                              <1> 	;retn
  6078                              <1> 
  6079                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6080                              <1> 
  6081                              <1> ;----------------------------------------
  6082                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  6083                              <1> ;----------------------------------------
  6084                              <1> CHECK_ST:
  6085                              <1> 	;mov	dx, HF_PORT+7		; GET THE STATUS
  6086 0000230D 668B15[22620000]    <1> 	mov	dx, [HF_PORT]
  6087 00002314 80C207              <1> 	add	dl, 7
  6088 00002317 EC                  <1> 	in	al, dx
  6089 00002318 A2[95670000]        <1> 	mov	[HF_STATUS], al
  6090                              <1> 	;mov	ah, 0
  6091 0000231D 28E4                <1> 	sub	ah, ah ; 0
  6092 0000231F A880                <1> 	test	al, ST_BUSY		; IF STILL BUSY
  6093 00002321 751A                <1> 	jnz	short CKST_EXIT		; REPORT OK
  6094 00002323 B4CC                <1> 	mov	ah, WRITE_FAULT
  6095 00002325 A820                <1> 	test 	al, ST_WRT_FLT		; CHECK FOR WRITE FAULT
  6096 00002327 7514                <1> 	jnz	short CKST_EXIT
  6097 00002329 B4AA                <1> 	mov	ah, NOT_RDY
  6098 0000232B A840                <1> 	test	al, ST_READY		; CHECK FOR NOT READY
  6099 0000232D 740E                <1> 	jz	short CKST_EXIT
  6100 0000232F B440                <1> 	mov	ah, BAD_SEEK
  6101 00002331 A810                <1> 	test	al, ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  6102 00002333 7408                <1> 	jz	short CKST_EXIT
  6103 00002335 B411                <1> 	mov	ah, DATA_CORRECTED
  6104 00002337 A804                <1> 	test	al, ST_CORRCTD		; CHECK FOR CORRECTED ECC
  6105 00002339 7502                <1> 	jnz	short CKST_EXIT
  6106                              <1> 	;mov	ah, 0
  6107 0000233B 30E4                <1> 	xor	ah, ah ; 0
  6108                              <1> CKST_EXIT:
  6109 0000233D 8825[9B670000]      <1> 	mov	[DISK_STATUS1], ah	; SET ERROR FLAG
  6110 00002343 80FC11              <1> 	cmp	ah, DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  6111 00002346 7402                <1> 	je	short CKST_EX1
  6112                              <1> 	;cmp	ah, 0
  6113 00002348 20E4                <1> 	and	ah, ah
  6114                              <1> CKST_EX1:
  6115 0000234A C3                  <1> 	retn
  6116                              <1> 
  6117                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6118                              <1> 
  6119                              <1> ;----------------------------------------
  6120                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  6121                              <1> ;----------------------------------------
  6122                              <1> CHECK_ER:
  6123                              <1> 	;mov	dx, HF_PORT+1		; GET THE ERROR REGISTER
  6124 0000234B 668B15[22620000]    <1> 	mov	dx, [HF_PORT]		;
  6125 00002352 FEC2                <1> 	inc	dl
  6126 00002354 EC                  <1> 	in	al, dx
  6127                              <1> 	; 10/07/2022
  6128                              <1> 	;mov	[HF_ERROR], al
  6129                              <1> 	;push	ebx	; 21/02/2015
  6130 00002355 29C9                <1> 	sub	ecx, ecx
  6131                              <1> 	;mov	ecx, 8			; TEST ALL 8 BITS
  6132 00002357 B108                <1> 	mov	cl, 8
  6133                              <1> CK1:	
  6134 00002359 D0E0                <1> 	shl	al, 1			; MOVE NEXT ERROR BIT TO CARRY
  6135 0000235B 7202                <1> 	jc	short CK2		; FOUND THE ERROR
  6136 0000235D E2FA                <1> 	loop	CK1			; KEEP TRYING
  6137                              <1> CK2:
  6138                              <1> 	;mov	ebx, ERR_TBL		; COMPUTE ADDRESS OF
  6139                              <1> 	;add	ebx, ecx		; ERROR CODE
  6140 0000235F 81C1[18620000]      <1> 	add	ecx, ERR_TBL ; 10/07/2022	
  6141                              <1> 
  6142                              <1> 	;;;mov	ah, byte [cs:bx]	; GET ERROR CODE
  6143                              <1> 	;;mov	ah, [bx]
  6144                              <1> 	;mov	ah, [ebx] ; 21/02/2015
  6145 00002365 8A21                <1> 	mov	ah, [ecx]	
  6146                              <1> CKEX:
  6147 00002367 8825[9B670000]      <1> 	mov	[DISK_STATUS1], ah	; SAVE ERROR CODE
  6148                              <1> 	; 10/07/2022
  6149                              <1> 	;pop	ebx
  6150                              <1> 	;;cmp	ah, 0
  6151                              <1> 	;and	ah, ah
  6152 0000236D C3                  <1> 	retn
  6153                              <1> 
  6154                              <1> ;--------------------------------------------------------
  6155                              <1> ; CHECK_DMA						:
  6156                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  6157                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  6158                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  6159                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  6160                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  6161                              <1> ;  -ERROR OTHERWISE					:
  6162                              <1> ;--------------------------------------------------------
  6163                              <1> 
  6164                              <1> 	; 11/07/2022
  6165                              <1> 	; (not needed for hard disks and 32 bit OS)
  6166                              <1> 	;
  6167                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6168                              <1> ;CHECK_DMA:
  6169                              <1> ;	;;push	ax			; SAVE REGISTERS
  6170                              <1> ;	;; 24/12/2021
  6171                              <1> ;	;;push	eax
  6172                              <1> ;	;mov	ax, 8000h		; AH = MAX # SECTORS
  6173                              <1> ;					; AL = MAX OFFSET
  6174                              <1> ;	; 10/07/2022
  6175                              <1> ;	;test	byte [CMD_BLOCK+6], ECC_MODE
  6176                              <1> ;	;jz	short CKD1
  6177                              <1> ;	;mov	ax, 7F04h		; ECC IS 4 MORE BYTES
  6178                              <1> ;CKD1:	
  6179                              <1> ;	;cmp	ah, [CMD_BLOCK+1]	; NUMBER OF SECTORS
  6180                              <1> ;	;ja	short CKDOK		; IT WILL FIT
  6181                              <1> ;	;jb	short CKDERR		; TOO MANY
  6182                              <1> ;	
  6183                              <1> ;	cmp	byte [CMD_BLOCK+1], 80h
  6184                              <1> ;	jb	short CKDOK
  6185                              <1> ;	ja	short CKDERR
  6186                              <1> ;	;cmp	al, bl			; CHECK OFFSET ON MAX SECTORS
  6187                              <1> ;	;jb	short CKDERR		; ERROR
  6188                              <1> ;CKD2:
  6189                              <1> ;	or	bl, bl
  6190                              <1> ;	jz	short CKDR
  6191                              <1> ;	
  6192                              <1> ;;CKDOK:	
  6193                              <1> ;	;clc				; CLEAR CARRY
  6194                              <1> ;	;;pop	ax
  6195                              <1> ;	;; 24/12/2021
  6196                              <1> ;	;pop	eax
  6197                              <1> ;	;retn				; NORMAL RETURN
  6198                              <1> ;CKDERR: 
  6199                              <1> ;	stc				; INDICATE ERROR
  6200                              <1> ;	mov	byte [DISK_STATUS1], DMA_BOUNDARY
  6201                              <1> ;	;;pop	ax
  6202                              <1> ;	;; 24/12/2021
  6203                              <1> ;	;pop	eax	
  6204                              <1> ;	retn
  6205                              <1> ;
  6206                              <1> ;	; 10/07/2022
  6207                              <1> ;CKDOK:
  6208                              <1> ;	clc
  6209                              <1> ;CKDR:
  6210                              <1> ;	retn
  6211                              <1> 
  6212                              <1> ;----------------------------------------
  6213                              <1> ;	SET UP EBX-> DISK PARMS	        :
  6214                              <1> ;----------------------------------------
  6215                              <1> 					
  6216                              <1> ; INPUT -> DL = 0 based drive number
  6217                              <1> ; OUTPUT -> EBX = disk parameter table address
  6218                              <1> 
  6219                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6220                              <1> 
  6221                              <1> GET_VEC:
  6222                              <1> 	;sub	ax, ax			; GET DISK PARAMETER ADDRESS
  6223                              <1> 	;mov	es, ax
  6224                              <1> 	;test	dl, 1
  6225                              <1> 	;jz	short GV_0
  6226                              <1> ;	les	bx, [HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  6227                              <1> ;	jmp	short GV_EXIT
  6228                              <1> ;GV_0:
  6229                              <1> ;	les 	bx,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  6230                              <1> ;
  6231 0000236E 31DB                <1> 	xor	ebx, ebx
  6232 00002370 88D3                <1> 	mov	bl, dl
  6233                              <1> 	;02/01/2015
  6234                              <1> 	;xor	bh, bh
  6235                              <1> 	;shl	bl, 1			; port address offset
  6236                              <1> 	;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  6237                              <1> 	;shl	bl, 1			; dpt pointer offset
  6238 00002372 C0E302              <1> 	shl	bl, 2
  6239                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  6240 00002375 81C3[A0670000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  6241                              <1> 	;push	word [bx+2]		; dpt segment
  6242                              <1> 	;pop	es
  6243                              <1> 	;mov	bx, [bx]		; dpt offset
  6244 0000237B 8B1B                <1> 	mov	ebx, [ebx]		
  6245                              <1> ;GV_EXIT:
  6246 0000237D C3                  <1> 	retn
  6247                              <1> 
  6248                              <1> 	; 24/12/2021 - Retro UNIX 386 v1.1
  6249                              <1> hdc1_int: ; 21/02/2015
  6250                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  6251                              <1> ;								:
  6252                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  6253                              <1> ;								:
  6254                              <1> ;----------------------------------------------------------------
  6255                              <1> 
  6256                              <1> ; 22/12/2014
  6257                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  6258                              <1> ;	 '11/15/85'
  6259                              <1> ; AWARD BIOS 1999 (D1A0622) 
  6260                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  6261                              <1> 
  6262                              <1> ;int_76h:
  6263                              <1> HD_INT:
  6264                              <1> 	;push	ax
  6265                              <1> 	; 24/12/2021
  6266 0000237E 50                  <1> 	push	eax
  6267 0000237F 1E                  <1> 	push	ds
  6268                              <1> 	;CALL	DDS
  6269                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  6270 00002380 66B81000            <1> 	mov	ax, KDATA
  6271 00002384 8ED8                <1> 	mov 	ds, ax
  6272                              <1> 	;
  6273                              <1> 	;;MOV	@HF_INT_FLAG, 0FFH	; ALL DONE
  6274                              <1>         ;mov	byte [CS:HF_INT_FLAG], 0FFh
  6275 00002386 C605[96670000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  6276                              <1> 	;
  6277                              <1> 	;push	dx
  6278                              <1> 	; 24/12/2021
  6279 0000238D 52                  <1> 	push	edx
  6280 0000238E 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  6281                              <1> 					; Clear Controller
  6282                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  6283 00002392 EC                  <1> 	in	al, dx			;
  6284                              <1> 	;pop	dx
  6285                              <1> 	; 24/12/2021
  6286 00002393 5A                  <1> 	pop	edx
  6287                              <1> 	NEWIODELAY
  2177 00002394 E6EB                <2>  out 0EBh,al
  6288                              <1> 	;
  6289 00002396 B020                <1> 	mov	al, EOI			; NON-SPECIFIC END OF INTERRUPT
  6290 00002398 E6A0                <1> 	out	INTB00, al		; FOR CONTROLLER #2
  6291                              <1> 	;JMP	$+2			; WAIT
  6292                              <1> 	NEWIODELAY
  2177 0000239A E6EB                <2>  out 0EBh,al
  6293 0000239C E620                <1> 	out	INTA00, al		; FOR CONTROLLER #1
  6294 0000239E 1F                  <1> 	pop	ds
  6295                              <1> 	;sti				; RE-ENABLE INTERRUPTS
  6296                              <1> 	;mov	ax, 9100h		; DEVICE POST
  6297                              <1> 	;int	15h			; INTERRUPT
  6298                              <1> irq15_iret: ; 25/02/2015
  6299                              <1> 	;pop	ax
  6300                              <1> 	; 24/12/2021
  6301 0000239F 58                  <1> 	pop	eax
  6302 000023A0 CF                  <1> 	iretd				; RETURN FROM INTERRUPT
  6303                              <1> 
  6304                              <1> 	; 24/12/2021 - Retro UNIX 386 v1.1
  6305                              <1> hdc2_int: ; 21/02/2015
  6306                              <1> ;--- HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) ----------------------
  6307                              <1> ;								:
  6308                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  6309                              <1> ;								:
  6310                              <1> ;----------------------------------------------------------------
  6311                              <1> 
  6312                              <1> ;int_77h:
  6313                              <1> HD1_INT:
  6314                              <1> 	;push	ax
  6315                              <1> 	; 24/12/2021
  6316 000023A1 50                  <1> 	push	eax
  6317                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  6318                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  6319 000023A2 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  6320 000023A4 E6A0                <1> 	out	0A0h, al
  6321 000023A6 EB00                <1>         jmp short $+2
  6322 000023A8 EB00                <1> 	jmp short $+2
  6323 000023AA E4A0                <1> 	in	al, 0A0h
  6324 000023AC 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  6325 000023AE 74EF                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  6326                              <1> 	;
  6327 000023B0 1E                  <1> 	push	ds
  6328                              <1> 	;CALL	DDS
  6329                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  6330 000023B1 66B81000            <1> 	mov	ax, KDATA
  6331 000023B5 8ED8                <1> 	mov 	ds, ax
  6332                              <1> 	;
  6333                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  6334                              <1>         ;or	byte [CS:HF_INT_FLAG], 0C0h 
  6335 000023B7 800D[96670000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  6336                              <1> 	;
  6337                              <1> 	;push	dx
  6338                              <1> 	; 24/12/2021
  6339 000023BE 52                  <1> 	push	edx
  6340 000023BF 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  6341                              <1> 					; Clear Controller (Award BIOS 1999)
  6342 000023C3 EBCD                <1> 	jmp	short Clear_IRQ1415
  6343                              <1> 
  6344                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  6345                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  6346                              <1> 
  6347                              <1> ;////////////////////////////////////////////////////////////////////
  6348                              <1> ;; END OF DISK I/O SYTEM ///
  2086                                  %include 'memory.s'  ; 09/03/2015
  2087                              <1> ; Retro UNIX 386 v2 - memory.s - 26/01/2020
  2088                              <1> ; Last Modification: 17/07/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.3)
  2089                              <1> ; ----------------------------------------------------------------------------
  2090                              <1> ;
  2091                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
  2092                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
  2093                              <1> ; 18/10/2015 (!not completed!)
  2094                              <1> ;
  2095                              <1> ; Source code for NASM - Netwide Assembler (2.11)
  2096                              <1> 
  2097                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
  2098                              <1> 
  2099                              <1> ;;04/11/2014 (unix386.s)	
  2100                              <1> ;PDE_A_PRESENT	equ 1		; Present flag for PDE
  2101                              <1> ;PDE_A_WRITE	equ 2		; Writable (write permission) flag
  2102                              <1> ;PDE_A_USER	equ 4		; User (non-system/kernel) page flag
  2103                              <1> ;;
  2104                              <1> ;PTE_A_PRESENT	equ 1		; Present flag for PTE (bit 0)
  2105                              <1> ;PTE_A_WRITE	equ 2		; Writable (write permission) flag (bit 1)
  2106                              <1> ;PTE_A_USER	equ 4		; User (non-system/kernel) page flag (bit 2)
  2107                              <1> ;PTE_A_ACCESS   equ 32		; Accessed flag (bit 5) ; 09/03/2015
  2108                              <1> 
  2109                              <1> ; 27/04/2015
  2110                              <1> ; 09/03/2015
  2111                              <1> PAGE_SIZE 	equ 4096	; page size in bytes
  2112                              <1> PAGE_SHIFT 	equ 12		; page table shift count
  2113                              <1> PAGE_D_SHIFT 	equ 22 ; 12+10	; page directory shift count
  2114                              <1> PAGE_OFF	equ 0FFFh	; 12 bit byte offset in page frame
  2115                              <1> PTE_MASK 	equ 03FFh	; page table entry mask
  2116                              <1> PTE_DUPLICATED  equ 200h	; duplicated page sign (AVL bit 0)
  2117                              <1> PDE_A_CLEAR	equ 0F000h	; to clear PDE attribute bits
  2118                              <1> PTE_A_CLEAR	equ 0F000h	; to clear PTE attribute bits
  2119                              <1> LOGIC_SECT_SIZE equ 512		; logical sector size
  2120                              <1> ERR_MAJOR_PF	equ 0E0h	; major error: page fault
  2121                              <1> ; 15/10/2016 (TRDOS 386 v2)
  2122                              <1> ERR_MINOR_IM	equ 4 ;15/10/2016 (1->4); insufficient (out of) memory
  2123                              <1> ERR_MINOR_PV	equ 6 ;15/10/2016 (3->6); protection violation
  2124                              <1> SWP_DISK_READ_ERR 	   equ 40
  2125                              <1> SWP_DISK_NOT_PRESENT_ERR   equ 41
  2126                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 42
  2127                              <1> SWP_NO_FREE_SPACE_ERR      equ 43
  2128                              <1> SWP_DISK_WRITE_ERR         equ 44
  2129                              <1> SWP_NO_PAGE_TO_SWAP_ERR    equ 45
  2130                              <1> PTE_A_ACCESS_BIT equ 5	; Bit 5 (accessed flag)        
  2131                              <1> SECTOR_SHIFT     equ 3	; sector shift (to convert page block number)
  2132                              <1> ; 10/06/2021 (Retro UNIX 386 v2)
  2133                              <1> ; 12/07/2016 (TRDOS 386 v2) 
  2134                              <1> PTE_SHARED	 equ 400h		; AVL bit 1, direct memory access bit	
  2135                              <1> 					; (Indicates that the page is not allocated
  2136                              <1> 					; for the process, it is a shared or system
  2137                              <1>                                         ; page, it must not be deallocated!)
  2138                              <1> ; 14/12/2020
  2139                              <1> ; (Linear Frame Buffer - video memory mark : AVL bit 1, outside M.A.T.)
  2140                              <1> PDE_EXTERNAL	equ 400h	; Page directory entry for external memory blocks
  2141                              <1> PTE_EXTERNAL	equ 400h	; Allocated kernel pages for Linear Frame Buffer
  2142                              <1> 				; (Out of memory allocation table)	
  2143                              <1> ;
  2144                              <1> ;; Retro Unix 386 v1 - paging method/principles
  2145                              <1> ;;
  2146                              <1> ;; 10/10/2014
  2147                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
  2148                              <1> ;;
  2149                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
  2150                              <1> ;;	(virtual address = physical address)
  2151                              <1> ;; KERNEL PAGE TABLES:
  2152                              <1> ;;	Kernel page directory and all page tables are
  2153                              <1> ;;	on memory as initialized, as equal to physical memory
  2154                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
  2155                              <1> ;;
  2156                              <1> ;;	what for: User pages may be swapped out, when accessing
  2157                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
  2158                              <1> ;;	kernel would have to swap it in! But it is also may be
  2159                              <1> ;;	in use by a user process. (In system/kernel mode
  2160                              <1> ;;	kernel can access all memory pages even if they are
  2161                              <1> ;;	reserved/allocated for user processes. Swap out/in would
  2162                              <1> ;;	cause conflicts.) 
  2163                              <1> ;;	
  2164                              <1> ;;	As result of these conditions,
  2165                              <1> ;;	all kernel pages must be initialized as equal to 
  2166                              <1> ;;	physical layout for preventing page faults. 
  2167                              <1> ;;	Also, calling "allocate page" procedure after
  2168                              <1> ;;	a page fault can cause another page fault (double fault)
  2169                              <1> ;;	if all kernel page tables would not be initialized.
  2170                              <1> ;;
  2171                              <1> ;;	[first_page] = Beginning of users space, as offset to 
  2172                              <1> ;;	memory allocation table. (double word aligned)
  2173                              <1> ;;
  2174                              <1> ;;	[next_page] = first/next free space to be searched
  2175                              <1> ;;	as offset to memory allocation table. (dw aligned)
  2176                              <1> ;;
  2177                              <1> ;;	[last_page] = End of memory (users space), as offset
  2178                              <1> ;;	to memory allocation table. (double word aligned)
  2179                              <1> ;;
  2180                              <1> ;; USER PAGE TABLES:
  2181                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
  2182                              <1> ;;		'ready only' marked copies of the 
  2183                              <1> ;;		parent process's page table entries (for
  2184                              <1> ;;		same physical memory).
  2185                              <1> ;;		(A page will be copied to a new page after
  2186                              <1> ;;		 if it causes R/W page fault.)
  2187                              <1> ;;
  2188                              <1> ;;	Every user process has own (different)
  2189                              <1> ;;	page directory and page tables.	
  2190                              <1> ;;
  2191                              <1> ;;	Code starts at virtual address 0, always.
  2192                              <1> ;;	(Initial value of EIP is 0 in user mode.)
  2193                              <1> ;;	(Programs can be written/developed as simple
  2194                              <1> ;;	 flat memory programs.)
  2195                              <1> ;;
  2196                              <1> ;; MEMORY ALLOCATION STRATEGY:
  2197                              <1> ;;	Memory page will be allocated by kernel only 
  2198                              <1> ;;		(in kernel/system mode only).
  2199                              <1> ;;	* After a
  2200                              <1> ;;	  - 'not present' page fault
  2201                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
  2202                              <1> ;;	* For loading (opening, reading) a file or disk/drive
  2203                              <1> ;;	* As responce to 'allocate additional memory blocks' 
  2204                              <1> ;;	  request by running process.
  2205                              <1> ;;	* While creating a process, allocating a new buffer,
  2206                              <1> ;;	  new page tables etc.
  2207                              <1> ;;
  2208                              <1> ;;	At first,
  2209                              <1> ;;	- 'allocate page' procedure will be called;
  2210                              <1> ;,	   if it will return with a valid (>0) physical address
  2211                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
  2212                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
  2213                              <1> ;;	- 'allocate page' will be called for allocating page
  2214                              <1> ;;	   directory, page table and running space (data/code).
  2215                              <1> ;;	- every successful 'allocate page' call will decrease
  2216                              <1> ;;	  'free_pages' count (pointer).
  2217                              <1> ;;	- 'out of (insufficient) memory error' will be returned
  2218                              <1> ;;	  if 'free_pages' points to a ZERO.
  2219                              <1> ;;	- swapping out and swapping in (if it is not a new page)
  2220                              <1> ;;	  procedures will be called as responce to 'out of memory'
  2221                              <1> ;;	  error except errors caused by attribute conflicts.
  2222                              <1> ;;	 (swapper functions)	 
  2223                              <1> ;;					
  2224                              <1> ;;	At second,
  2225                              <1> ;;	- page directory entry will be updated then page table
  2226                              <1> ;;	  entry will be updated.		
  2227                              <1> ;;
  2228                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
  2229                              <1> ;;	- M.A.T. has a size according to available memory as
  2230                              <1> ;;	  follows:
  2231                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
  2232                              <1> ;;		  - a bit with value of 0 means allocated page
  2233                              <1> ;;		  - a bit with value of 1 means a free page
  2234                              <1> ;,	- 'free_pages' pointer holds count of free pages
  2235                              <1> ;;	  depending on M.A.T.
  2236                              <1> ;;		(NOTE: Free page count will not be checked
  2237                              <1> ;;		again -on M.A.T.- after initialization. 
  2238                              <1> ;;		Kernel will trust on initial count.)
  2239                              <1> ;,	- 'free_pages' count will be decreased by allocation
  2240                              <1> ;;	  and it will be increased by deallocation procedures.
  2241                              <1> ;;	
  2242                              <1> ;;	- Available memory will be calculated during
  2243                              <1> ;;	  the kernel's initialization stage (in real mode).
  2244                              <1> ;;	  Memory allocation table and kernel page tables 
  2245                              <1> ;;	  will be formatted/sized as result of available
  2246                              <1> ;;	  memory calculation before paging is enabled.
  2247                              <1> ;;
  2248                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
  2249                              <1> ;;	- Memory Allocation Table size will be 128 KB.
  2250                              <1> ;;	- Memory allocation for kernel page directory size 
  2251                              <1> ;;	  is always 4 KB. (in addition to total allocation size
  2252                              <1> ;;	  for page tables)
  2253                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
  2254                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
  2255                              <1> ;;	- User (available) space will be started 
  2256                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
  2257                              <1> ;;	- The first 640 KB is for kernel's itself plus
  2258                              <1> ;;	  memory allocation table and kernel's page directory
  2259                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
  2260                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
  2261                              <1> ;; 	  for buffers.
  2262                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
  2263                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
  2264                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
  2265                              <1> ;;
  2266                              <1> ;; For 1GB Available Memory:
  2267                              <1> ;;	- Memory Allocation Table size will be 32 KB.
  2268                              <1> ;;	- Memory allocation for kernel page directory size 
  2269                              <1> ;;	  is always 4 KB. (in addition to total allocation size
  2270                              <1> ;;	  for page tables)
  2271                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
  2272                              <1> ;;	  is 1 MB (256*4*1024 bytes).
  2273                              <1> ;;	- User (available) space will be started 
  2274                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
  2275                              <1> ;;	- The first 640 KB is for kernel's itself plus
  2276                              <1> ;;	  memory allocation table and kernel's page directory
  2277                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
  2278                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
  2279                              <1> ;; 	  for buffers.
  2280                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
  2281                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
  2282                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
  2283                              <1> ;;
  2284                              <1> ;;
  2285                              <1> 
  2286                              <1> ;;************************************************************************************
  2287                              <1> ;; 
  2288                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
  2289                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
  2290                              <1> 
  2291                              <1> ;; Main factor: "sys fork" system call 
  2292                              <1> ;;	
  2293                              <1> ;; 		FORK
  2294                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
  2295                              <1> ;;  writable pages ---->|
  2296                              <1> ;;                      |----> child - duplicated PTEs, read only pages
  2297                              <1> ;; 
  2298                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
  2299                              <1> ;; 
  2300                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
  2301                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
  2302                              <1> ;;       -while R/W bit is 0-. 
  2303                              <1> ;; 
  2304                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
  2305                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
  2306                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
  2307                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
  2308                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
  2309                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
  2310                              <1> ;; 
  2311                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
  2312                              <1> ;; # Parent's read only pages are copied to new child pages. 
  2313                              <1> ;;   Parent's PTE attributes are not changed.
  2314                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
  2315                              <1> ;;    destroy/mix previous fork result).
  2316                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
  2317                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
  2318                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
  2319                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
  2320                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
  2321                              <1> ;;   as Child's Page Table Entries without copying actual page.
  2322                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
  2323                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
  2324                              <1> ;; 
  2325                              <1> ;; !? WHAT FOR (duplication after duplication):
  2326                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
  2327                              <1> ;; program/executable code continues from specified location as child process, 
  2328                              <1> ;; returns back previous code location as parent process, every child after 
  2329                              <1> ;; every sys fork uses last image of code and data just prior the fork.
  2330                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
  2331                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
  2332                              <1> ;; was copied to child's process segment (all of code and data) according to
  2333                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
  2334                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
  2335                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
  2336                              <1> ;; (complete running image of parent process) to the child process; 
  2337                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
  2338                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
  2339                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
  2340                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
  2341                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
  2342                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
  2343                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
  2344                              <1> ;; new/fresh pages will be used to load and run new executable/program.
  2345                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
  2346                              <1> ;; for sharing same read only pages between parent and child processes.
  2347                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
  2348                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
  2349                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
  2350                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
  2351                              <1> ;; -deallocation problem-.
  2352                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
  2353                              <1> ;; 
  2354                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
  2355                              <1> ;; # Page fault handler will do those:
  2356                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
  2357                              <1> ;;   - If it is reset/clear, there is a child uses same page.
  2358                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
  2359                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
  2360                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
  2361                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
  2362                              <1> ;;     read only page will be converted to writable and unique page which belongs
  2363                              <1> ;;     to child process.)	
  2364                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
  2365                              <1> ;; # Page fault handler will do those:
  2366                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
  2367                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
  2368                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
  2369                              <1> ;;     address or not. 
  2370                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
  2371                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
  2372                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
  2373                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
  2374                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
  2375                              <1> ;; 
  2376                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
  2377                              <1> ;;       will be set as writable (and unique) in case of child process was using 
  2378                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
  2379                              <1> ;;       duplication method details, it is not possible multiple child processes
  2380                              <1> ;;       were using same page with duplicated PTEs.
  2381                              <1> ;; 
  2382                              <1> ;;************************************************************************************   
  2383                              <1> 
  2384                              <1> ;; 08/10/2014
  2385                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
  2386                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
  2387                              <1> 
  2388                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
  2389                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
  2390                              <1> ;; (25/08/2014, Revision: 5057) file 
  2391                              <1> ;; by KolibriOS Team (2004-2012)
  2392                              <1> 
  2393                              <1> allocate_page:
  2394                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
  2395                              <1> 	;	 (temporary modifications)
  2396                              <1> 	; 01/07/2015
  2397                              <1> 	; 05/05/2015
  2398                              <1> 	; 30/04/2015
  2399                              <1> 	; 16/10/2014
  2400                              <1> 	; 08/10/2014
  2401                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
  2402                              <1> 	;
  2403                              <1> 	; INPUT -> none
  2404                              <1> 	;
  2405                              <1> 	; OUTPUT ->
  2406                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
  2407                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
  2408                              <1> 	;
  2409                              <1> 	;	CF = 1 and EAX = 0 
  2410                              <1> 	; 		   if there is not a free page to be allocated	
  2411                              <1> 	;
  2412                              <1> 	; Modified Registers -> none (except EAX)
  2413                              <1> 	;
  2414 000023C5 A1[10670000]        <1> 	mov	eax, [free_pages]
  2415 000023CA 21C0                <1> 	and	eax, eax
  2416 000023CC 7438                <1> 	jz	short out_of_memory
  2417                              <1> 	;
  2418 000023CE 53                  <1> 	push	ebx
  2419 000023CF 51                  <1> 	push	ecx
  2420                              <1> 	;
  2421 000023D0 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
  2422 000023D5 89D9                <1> 	mov	ecx, ebx
  2423                              <1>  				     ; NOTE: 32 (first_page) is initial
  2424                              <1> 				     ; value of [next_page].
  2425                              <1> 				     ; It points to the first available
  2426                              <1> 				     ; page block for users (ring 3) ...	
  2427                              <1> 				     ; (MAT offset 32 = 1024/32)	
  2428                              <1> 				     ; (at the of the first 4 MB)		
  2429 000023D7 031D[14670000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
  2430                              <1> 				 ; next_free_page >> 5
  2431 000023DD 030D[18670000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
  2432                              <1> 				 ; (total_pages - 1) >> 5
  2433                              <1> al_p_scan:
  2434 000023E3 39CB                <1> 	cmp	ebx, ecx
  2435 000023E5 770A                <1> 	ja	short al_p_notfound
  2436                              <1> 	;
  2437                              <1> 	; 01/07/2015
  2438                              <1> 	; AMD64 Architecture Programmers Manual
  2439                              <1> 	; Volume 3:
  2440                              <1> 	; General-Purpose and System Instructions
  2441                              <1> 	;
  2442                              <1> 	; BSF - Bit Scan Forward
  2443                              <1> 	;
  2444                              <1> 	;   Searches the value in a register or a memory location
  2445                              <1> 	;   (second operand) for the least-significant set bit. 
  2446                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
  2447                              <1> 	;   and stores the index of the least-significant set bit in a destination
  2448                              <1> 	;   register (first operand). If the second operand contains 0, 
  2449                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
  2450                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
  2451                              <1> 	;   of the searched value
  2452                              <1> 	;
  2453 000023E7 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
  2454                              <1> 			   ; Clear ZF if a bit is found set (1) and 
  2455                              <1> 			   ; loads the destination with an index to
  2456                              <1> 			   ; first set bit. (0 -> 31) 
  2457                              <1> 			   ; Sets ZF to 1 if no bits are found set.
  2458 000023EA 751C                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
  2459                              <1> 			 ;
  2460                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
  2461                              <1> 			 ;	  with value of 1 means 
  2462                              <1> 			 ;	  the corresponding page is free 
  2463                              <1> 			 ;	  (Retro UNIX 386 v1 feature only!)
  2464 000023EC 83C304              <1> 	add	ebx, 4
  2465                              <1> 			 ; We return back for searching next page block
  2466                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
  2467                              <1> 			 ;	 we always will find at least 1 free page here.
  2468 000023EF EBF2                <1>         jmp     short al_p_scan
  2469                              <1> 	;
  2470                              <1> al_p_notfound:
  2471 000023F1 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
  2472 000023F7 890D[14670000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
  2473                              <1> 				 ; (deallocate_page procedure will change it)
  2474 000023FD 31C0                <1> 	xor	eax, eax
  2475 000023FF A3[10670000]        <1> 	mov	[free_pages], eax ; 0
  2476 00002404 59                  <1> 	pop	ecx
  2477 00002405 5B                  <1> 	pop	ebx
  2478                              <1> 	;
  2479                              <1> ; 17/04/2021
  2480                              <1> ; ('swap_out' procedure call is disabled as temporary)
  2481                              <1> 
  2482                              <1> out_of_memory:
  2483                              <1> ;	call	swap_out
  2484                              <1> ;	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
  2485                              <1> ;	;
  2486                              <1> ;	sub 	eax, eax ; 0
  2487 00002406 F9                  <1> 	stc
  2488 00002407 C3                  <1> 	retn
  2489                              <1> 
  2490                              <1> al_p_found:
  2491 00002408 89D9                <1> 	mov	ecx, ebx
  2492 0000240A 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
  2493 00002410 890D[14670000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
  2494                              <1> 				 ; address/offset (to the next)
  2495 00002416 FF0D[10670000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
  2496                              <1> 	;
  2497 0000241C 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2498                              <1> 				 ; is copied into the Carry Flag and then cleared
  2499                              <1> 				 ; in the destination.
  2500                              <1> 				 ;
  2501                              <1> 				 ; Reset the bit which is corresponding to the 
  2502                              <1> 				 ; (just) allocated page.
  2503                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
  2504 0000241F C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
  2505 00002422 01C8                <1> 	add	eax, ecx	 ; = page number
  2506 00002424 C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
  2507                              <1> 	; EAX = physical address of memory page
  2508                              <1> 	;
  2509                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
  2510                              <1> 	;       according to this EAX value...
  2511 00002427 59                  <1> 	pop	ecx
  2512 00002428 5B                  <1> 	pop	ebx
  2513                              <1> al_p_ok:
  2514 00002429 C3                  <1> 	retn
  2515                              <1> 
  2516                              <1> make_page_dir:
  2517                              <1> 	; 18/04/2015
  2518                              <1> 	; 12/04/2015
  2519                              <1> 	; 23/10/2014
  2520                              <1> 	; 16/10/2014
  2521                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
  2522                              <1> 	;
  2523                              <1> 	; INPUT ->
  2524                              <1> 	;	none
  2525                              <1> 	; OUTPUT ->
  2526                              <1> 	;	(EAX = 0)
  2527                              <1> 	;	cf = 1 -> insufficient (out of) memory error
  2528                              <1> 	;	cf = 0 ->
  2529                              <1> 	;	u.pgdir = page directory (physical) address of the current
  2530                              <1> 	;		  process/user.
  2531                              <1> 	;
  2532                              <1> 	; Modified Registers -> EAX
  2533                              <1> 	;
  2534 0000242A E896FFFFFF          <1> 	call	allocate_page
  2535 0000242F 7216                <1> 	jc	short mkpd_error
  2536                              <1> 	;
  2537 00002431 A3[A46C0000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
  2538                              <1> 				  ; (Physical address)
  2539                              <1> clear_page:
  2540                              <1> 	; 18/04/2015
  2541                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
  2542                              <1> 	;
  2543                              <1> 	; INPUT ->
  2544                              <1> 	;	EAX = physical address of the page
  2545                              <1> 	; OUTPUT ->
  2546                              <1> 	;	all bytes of the page will be cleared
  2547                              <1> 	;
  2548                              <1> 	; Modified Registers -> none
  2549                              <1> 	;
  2550 00002436 57                  <1> 	push	edi
  2551 00002437 51                  <1> 	push	ecx
  2552 00002438 50                  <1> 	push	eax
  2553 00002439 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  2554 0000243E 89C7                <1> 	mov	edi, eax
  2555 00002440 31C0                <1> 	xor	eax, eax
  2556 00002442 F3AB                <1> 	rep	stosd
  2557 00002444 58                  <1> 	pop	eax
  2558 00002445 59                  <1> 	pop	ecx
  2559 00002446 5F                  <1> 	pop	edi
  2560                              <1> mkpd_error:
  2561                              <1> mkpt_error:
  2562 00002447 C3                  <1> 	retn
  2563                              <1> 
  2564                              <1> make_page_table:
  2565                              <1> 	; 23/06/2015
  2566                              <1> 	; 18/04/2015
  2567                              <1> 	; 12/04/2015
  2568                              <1> 	; 16/10/2014
  2569                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
  2570                              <1> 	;
  2571                              <1> 	; INPUT ->
  2572                              <1> 	;	EBX = virtual (linear) address
  2573                              <1> 	;	ECX = page table attributes (lower 12 bits)
  2574                              <1> 	;	      (higher 20 bits must be ZERO)
  2575                              <1> 	;	      (bit 0 must be 1)	 
  2576                              <1> 	;	u.pgdir = page directory (physical) address
  2577                              <1> 	; OUTPUT ->
  2578                              <1> 	;	EDX = Page directory entry address
  2579                              <1> 	;	EAX = Page table address
  2580                              <1> 	;	cf = 1 -> insufficient (out of) memory error
  2581                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
  2582                              <1> 	;
  2583                              <1> 	; Modified Registers -> EAX, EDX
  2584                              <1> 	;
  2585 00002448 E878FFFFFF          <1> 	call	allocate_page
  2586 0000244D 72F8                <1> 	jc	short mkpt_error
  2587 0000244F E811000000          <1> 	call	set_pde	
  2588 00002454 EBE0                <1> 	jmp	short clear_page
  2589                              <1> 
  2590                              <1> make_page:
  2591                              <1> 	; 24/07/2015
  2592                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
  2593                              <1> 	;
  2594                              <1> 	; INPUT ->
  2595                              <1> 	;	EBX = virtual (linear) address
  2596                              <1> 	;	ECX = page attributes (lower 12 bits)
  2597                              <1> 	;	      (higher 20 bits must be ZERO)
  2598                              <1> 	;	      (bit 0 must be 1)	 
  2599                              <1> 	;	u.pgdir = page directory (physical) address
  2600                              <1> 	; OUTPUT ->
  2601                              <1> 	;	EBX = Virtual address
  2602                              <1> 	;	(EDX = PTE value)
  2603                              <1> 	;	EAX = Physical address
  2604                              <1> 	;	cf = 1 -> insufficient (out of) memory error
  2605                              <1> 	;
  2606                              <1> 	; Modified Registers -> EAX, EDX
  2607                              <1> 	;
  2608 00002456 E86AFFFFFF          <1> 	call	allocate_page
  2609 0000245B 7207                <1> 	jc	short mkp_err
  2610 0000245D E821000000          <1> 	call	set_pte	
  2611 00002462 73D2                <1> 	jnc	short clear_page ; 18/04/2015
  2612                              <1> mkp_err:
  2613 00002464 C3                  <1> 	retn
  2614                              <1> 
  2615                              <1> set_pde:	; Set page directory entry (PDE)
  2616                              <1> 	; 20/07/2015
  2617                              <1> 	; 18/04/2015
  2618                              <1> 	; 12/04/2015
  2619                              <1> 	; 23/10/2014
  2620                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
  2621                              <1> 	;
  2622                              <1> 	; INPUT ->
  2623                              <1> 	;	EAX = physical address
  2624                              <1> 	;	      (use present value if EAX = 0)
  2625                              <1> 	;	EBX = virtual (linear) address
  2626                              <1> 	;	ECX = page table attributes (lower 12 bits)
  2627                              <1> 	;	      (higher 20 bits must be ZERO)
  2628                              <1> 	;	      (bit 0 must be 1)	 
  2629                              <1> 	;	u.pgdir = page directory (physical) address
  2630                              <1> 	; OUTPUT ->
  2631                              <1> 	;	EDX = PDE address
  2632                              <1> 	;	EAX = page table address (physical)
  2633                              <1> 	;	;(CF=1 -> Invalid page address)
  2634                              <1> 	;
  2635                              <1> 	; Modified Registers -> EDX
  2636                              <1> 	;
  2637 00002465 89DA                <1> 	mov	edx, ebx
  2638 00002467 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
  2639 0000246A C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
  2640 0000246D 0315[A46C0000]      <1> 	add	edx, [u.pgdir]
  2641                              <1> 	;
  2642 00002473 21C0                <1> 	and	eax, eax
  2643 00002475 7506                <1> 	jnz	short spde_1
  2644                              <1> 	;
  2645 00002477 8B02                <1> 	mov	eax, [edx]  ; old PDE value
  2646                              <1> 	;test	al, 1
  2647                              <1> 	;jz	short spde_2
  2648 00002479 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
  2649                              <1> spde_1:
  2650                              <1> 	;and	cx, 0FFFh
  2651 0000247D 8902                <1> 	mov	[edx], eax
  2652 0000247F 66090A              <1> 	or	[edx], cx
  2653 00002482 C3                  <1> 	retn
  2654                              <1> ;spde_2: ; error
  2655                              <1> ;	stc
  2656                              <1> ;	retn
  2657                              <1> 
  2658                              <1> set_pte:	; Set page table entry (PTE)
  2659                              <1> 	; 24/07/2015
  2660                              <1> 	; 20/07/2015
  2661                              <1> 	; 23/06/2015
  2662                              <1> 	; 18/04/2015
  2663                              <1> 	; 12/04/2015
  2664                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
  2665                              <1> 	;
  2666                              <1> 	; INPUT ->
  2667                              <1> 	;	EAX = physical page address
  2668                              <1> 	;	      (use present value if EAX = 0)
  2669                              <1> 	;	EBX = virtual (linear) address
  2670                              <1> 	;	ECX = page attributes (lower 12 bits)
  2671                              <1> 	;	      (higher 20 bits must be ZERO)
  2672                              <1> 	;	      (bit 0 must be 1)	 
  2673                              <1> 	;	u.pgdir = page directory (physical) address
  2674                              <1> 	; OUTPUT ->
  2675                              <1> 	;	EAX = physical page address
  2676                              <1> 	;	(EDX = PTE value)
  2677                              <1> 	;	EBX = virtual address
  2678                              <1> 	;
  2679                              <1> 	;	CF = 1 -> error
  2680                              <1> 	;
  2681                              <1> 	; Modified Registers -> EAX, EDX
  2682                              <1> 	;
  2683 00002483 50                  <1> 	push	eax
  2684 00002484 A1[A46C0000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
  2685 00002489 E837000000          <1> 	call 	get_pde
  2686                              <1> 		; EDX = PDE address
  2687                              <1> 		; EAX = PDE value
  2688 0000248E 5A                  <1> 	pop	edx ; physical page address
  2689 0000248F 722A                <1> 	jc	short spte_err ; PDE not present
  2690                              <1> 	;
  2691 00002491 53                  <1> 	push	ebx ; 24/07/2015
  2692 00002492 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
  2693                              <1> 			    ; EDX = PT address (physical)	
  2694 00002496 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
  2695 00002499 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
  2696                              <1> 			 ; clear higher 10 bits (PD bits)
  2697 0000249F C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
  2698 000024A2 01C3                <1> 	add	ebx, eax
  2699                              <1> 	;
  2700 000024A4 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
  2701 000024A6 A801                <1> 	test	al, 1
  2702 000024A8 740C                <1> 	jz	short spte_0
  2703 000024AA 09D2                <1> 	or	edx, edx
  2704 000024AC 750F                <1> 	jnz	short spte_1
  2705 000024AE 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
  2706 000024B2 89C2                <1> 	mov	edx, eax
  2707 000024B4 EB09                <1> 	jmp	short spte_2	
  2708                              <1> spte_0:
  2709                              <1> 	; If this PTE contains a swap (disk) address,
  2710                              <1> 	; it can be updated by using 'swap_in' procedure
  2711                              <1> 	; only!
  2712 000024B6 21C0                <1> 	and	eax, eax
  2713 000024B8 7403                <1> 	jz	short spte_1
  2714                              <1> 	; 24/07/2015
  2715                              <1> 	; swapped page ! (on disk)
  2716 000024BA 5B                  <1> 	pop	ebx
  2717                              <1> spte_err:
  2718 000024BB F9                  <1> 	stc
  2719 000024BC C3                  <1> 	retn
  2720                              <1> spte_1: 
  2721 000024BD 89D0                <1> 	mov	eax, edx
  2722                              <1> spte_2:
  2723 000024BF 09CA                <1> 	or	edx, ecx
  2724                              <1> 	; 23/06/2015
  2725 000024C1 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
  2726                              <1> 	; 24/07/2015
  2727 000024C3 5B                  <1> 	pop	ebx
  2728 000024C4 C3                  <1> 	retn
  2729                              <1> 
  2730                              <1> get_pde:	; Get present value of the relevant PDE
  2731                              <1> 	; 20/07/2015
  2732                              <1> 	; 18/04/2015
  2733                              <1> 	; 12/04/2015
  2734                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
  2735                              <1> 	;
  2736                              <1> 	; INPUT ->
  2737                              <1> 	;	EBX = virtual (linear) address
  2738                              <1> 	;	EAX = page directory (physical) address
  2739                              <1> 	; OUTPUT ->
  2740                              <1> 	;	EDX = Page directory entry address
  2741                              <1> 	;	EAX = Page directory entry value
  2742                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
  2743                              <1> 	; Modified Registers -> EDX, EAX
  2744                              <1> 	;
  2745 000024C5 89DA                <1> 	mov	edx, ebx
  2746 000024C7 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
  2747 000024CA C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
  2748 000024CD 01C2                <1> 	add	edx, eax ; page directory address (physical)
  2749 000024CF 8B02                <1> 	mov	eax, [edx]
  2750 000024D1 A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
  2751 000024D3 751F                <1> 	jnz	short gpte_retn
  2752 000024D5 F9                  <1> 	stc
  2753                              <1> gpde_retn:	
  2754 000024D6 C3                  <1> 	retn
  2755                              <1> 
  2756                              <1> get_pte:
  2757                              <1> 		; Get present value of the relevant PTE
  2758                              <1> 	; 29/07/2015
  2759                              <1> 	; 20/07/2015
  2760                              <1> 	; 18/04/2015
  2761                              <1> 	; 12/04/2015
  2762                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
  2763                              <1> 	;
  2764                              <1> 	; INPUT ->
  2765                              <1> 	;	EBX = virtual (linear) address
  2766                              <1> 	;	EAX = page directory (physical) address
  2767                              <1> 	; OUTPUT ->
  2768                              <1> 	;	EDX = Page table entry address (if CF=0)
  2769                              <1> 	;	      Page directory entry address (if CF=1)
  2770                              <1> 	;            (Bit 0 value is 0 if PT is not present)
  2771                              <1> 	;	EAX = Page table entry value (page address)
  2772                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
  2773                              <1> 	; Modified Registers -> EAX, EDX
  2774                              <1> 	;
  2775 000024D7 E8E9FFFFFF          <1> 	call 	get_pde
  2776 000024DC 72F8                <1> 	jc	short gpde_retn	; page table is not present
  2777                              <1> 	;jnc	short gpte_1
  2778                              <1> 	;retn
  2779                              <1> ;gpte_1:
  2780 000024DE 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
  2781 000024E2 89DA                <1> 	mov	edx, ebx
  2782 000024E4 C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
  2783 000024E7 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
  2784                              <1> 			 ; clear higher 10 bits (PD bits)
  2785 000024ED C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
  2786 000024F0 01C2                <1> 	add	edx, eax
  2787 000024F2 8B02                <1> 	mov	eax, [edx]
  2788                              <1> gpte_retn:
  2789 000024F4 C3                  <1> 	retn
  2790                              <1> 
  2791                              <1> deallocate_page_dir:
  2792                              <1> 	; 15/09/2015
  2793                              <1> 	; 05/08/2015
  2794                              <1> 	; 30/04/2015
  2795                              <1> 	; 28/04/2015
  2796                              <1> 	; 17/10/2014
  2797                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
  2798                              <1> 	;
  2799                              <1> 	; INPUT ->
  2800                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
  2801                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
  2802                              <1> 	; OUTPUT ->
  2803                              <1> 	;	All of page tables in the page directory
  2804                              <1> 	;	and page dir's itself will be deallocated
  2805                              <1> 	;	except 'read only' duplicated pages (will be converted
  2806                              <1> 	;	to writable pages).
  2807                              <1> 	;
  2808                              <1> 	; Modified Registers -> EAX
  2809                              <1> 	;
  2810                              <1> 	;
  2811 000024F5 56                  <1> 	push	esi
  2812 000024F6 51                  <1> 	push	ecx
  2813 000024F7 50                  <1> 	push	eax
  2814 000024F8 89C6                <1> 	mov	esi, eax 
  2815 000024FA 31C9                <1> 	xor	ecx, ecx
  2816                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
  2817                              <1> 	; it must not be deallocated
  2818 000024FC 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
  2819                              <1> dapd_0:
  2820 000024FE AD                  <1> 	lodsd
  2821 000024FF A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
  2822 00002501 7409                <1> 	jz	short dapd_1	
  2823 00002503 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
  2824 00002507 E812000000          <1> 	call	deallocate_page_table			
  2825                              <1> dapd_1:
  2826 0000250C 41                  <1> 	inc	ecx ; page directory entry index
  2827 0000250D 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
  2828 00002513 72E9                <1> 	jb	short dapd_0
  2829                              <1> dapd_2:
  2830 00002515 58                  <1> 	pop	eax
  2831 00002516 E870000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
  2832 0000251B 59                  <1> 	pop	ecx
  2833 0000251C 5E                  <1> 	pop	esi
  2834 0000251D C3                  <1> 	retn
  2835                              <1> 
  2836                              <1> deallocate_page_table:
  2837                              <1> 	; 17/07/2022
  2838                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
  2839                              <1> 	;	 (temporary modifications)
  2840                              <1> 	; 12/07/2016 (TRDOS 386 v2)
  2841                              <1> 	; 19/09/2015
  2842                              <1> 	; 15/09/2015
  2843                              <1> 	; 05/08/2015
  2844                              <1> 	; 30/04/2015
  2845                              <1> 	; 28/04/2015
  2846                              <1> 	; 24/10/2014
  2847                              <1> 	; 23/10/2014
  2848                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
  2849                              <1> 	;
  2850                              <1> 	; INPUT ->
  2851                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
  2852                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
  2853                              <1> 	;	(ECX = page directory entry index)
  2854                              <1> 	; OUTPUT ->
  2855                              <1> 	;	All of pages in the page table and page table's itself
  2856                              <1> 	;	will be deallocated except 'read only' duplicated pages
  2857                              <1> 	;	(will be converted to writable pages).
  2858                              <1> 	;
  2859                              <1> 	; Modified Registers -> EAX
  2860                              <1> 	;
  2861 0000251E 56                  <1> 	push	esi
  2862 0000251F 57                  <1> 	push	edi
  2863 00002520 52                  <1> 	push	edx
  2864 00002521 50                  <1> 	push	eax ; *
  2865 00002522 89C6                <1> 	mov	esi, eax 
  2866 00002524 31FF                <1> 	xor	edi, edi ; 0
  2867                              <1> dapt_0:
  2868 00002526 AD                  <1> 	lodsd
  2869 00002527 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
  2870 00002529 7453                <1> 	jz	short dapt_1
  2871                              <1> 	;
  2872 0000252B A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
  2873                              <1> 				  ; (must be 1)
  2874 0000252D 753D                <1> 	jnz	short dapt_3
  2875                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
  2876 0000252F 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
  2877                              <1> 				   ; as child's page ?
  2878 00002533 7442                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
  2879                              <1> 	; check the parent's PTE value is read only & same page or not.. 
  2880                              <1> 	; ECX = page directory entry index (0-1023)
  2881 00002535 53                  <1> 	push	ebx
  2882 00002536 51                  <1> 	push	ecx
  2883                              <1> 	;shl	cx, 2 ; *4 
  2884                              <1> 	; 17/07/2022
  2885 00002537 C1E102              <1> 	shl	ecx, 2
  2886 0000253A 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
  2887 0000253C 8B0B                <1> 	mov	ecx, [ebx]
  2888 0000253E F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
  2889 00002541 7427                <1> 	jz	short dapt_2	; parent process does not use this page
  2890 00002543 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  2891                              <1> 	; EDI = page table entry index (0-1023)
  2892 00002548 89FA                <1> 	mov	edx, edi 
  2893                              <1> 	;shl	dx, 2 ; *4
  2894                              <1> 	; 17/07/2022
  2895 0000254A C1E202              <1> 	shl	edx, 2 
  2896 0000254D 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
  2897 0000254F 8B1A                <1> 	mov	ebx, [edx]
  2898 00002551 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
  2899 00002554 7414                <1> 	jz	short dapt_2	; parent process does not use this page
  2900 00002556 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
  2901 0000255A 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
  2902 0000255F 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
  2903 00002561 7507                <1> 	jne	short dapt_2	; not same page
  2904                              <1> 				; deallocate the child's page
  2905 00002563 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
  2906 00002566 59                  <1> 	pop	ecx
  2907 00002567 5B                  <1> 	pop	ebx
  2908 00002568 EB0D                <1> 	jmp	short dapt_4
  2909                              <1> 
  2910                              <1> ; 17/04/2021
  2911                              <1> ; ('dapt_1' is disabled as temporary)
  2912                              <1> ;
  2913                              <1> ;dapt_1:
  2914                              <1> ;	or	eax, eax	; swapped page ?
  2915                              <1> ;	jz	short dapt_5	; no
  2916                              <1> ;				; yes
  2917                              <1> ;	shr	eax, 1
  2918                              <1> ;	call	unlink_swap_block ; Deallocate swapped page block
  2919                              <1> ;				  ; on the swap disk (or in file)
  2920                              <1> ;	jmp	short dapt_5
  2921                              <1> dapt_2:
  2922 0000256A 59                  <1> 	pop	ecx
  2923 0000256B 5B                  <1> 	pop	ebx
  2924                              <1> dapt_3:	
  2925                              <1> 	; 12/07/2016
  2926 0000256C 66A90004            <1> 	test	ax, PTE_SHARED ; shared or direct memory access indicator
  2927 00002570 7505                <1> 	jnz	short dapt_4   ; AVL bit 1 = 1, do not deallocate this page!
  2928                              <1> 	;
  2929                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
  2930 00002572 E814000000          <1> 	call	deallocate_page ; set the mem allocation bit of this page
  2931                              <1> dapt_4:
  2932 00002577 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
  2933                              <1> dapt_1:	; 17/04/2021 (temporary)
  2934                              <1> dapt_5:
  2935 0000257E 47                  <1> 	inc	edi ; page table entry index
  2936 0000257F 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
  2937 00002585 729F                <1> 	jb	short dapt_0
  2938                              <1> 	;
  2939 00002587 58                  <1> 	pop	eax ; *
  2940 00002588 5A                  <1> 	pop	edx
  2941 00002589 5F                  <1> 	pop	edi	
  2942 0000258A 5E                  <1> 	pop	esi
  2943                              <1> 	;
  2944                              <1> 	;call	deallocate_page	; deallocate the page table's itself
  2945                              <1> 	;retn
  2946                              <1> 
  2947                              <1> deallocate_page:
  2948                              <1> 	; 15/09/2015
  2949                              <1> 	; 28/04/2015
  2950                              <1> 	; 10/03/2015
  2951                              <1> 	; 17/10/2014
  2952                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
  2953                              <1> 	;
  2954                              <1> 	; INPUT -> 
  2955                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
  2956                              <1> 	; OUTPUT ->
  2957                              <1> 	;	[free_pages] is increased
  2958                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
  2959                              <1> 	;	CF = 1 if the page is already deallocated
  2960                              <1> 	; 	       (or not allocated) before.  
  2961                              <1> 	;
  2962                              <1> 	; Modified Registers -> EAX
  2963                              <1> 	;
  2964 0000258B 53                  <1> 	push	ebx
  2965 0000258C 52                  <1> 	push	edx
  2966                              <1> 	;
  2967 0000258D C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
  2968                              <1> 				     ; 12 bits right
  2969                              <1> 				     ; to get page number
  2970 00002590 89C2                <1> 	mov	edx, eax
  2971                              <1> 	; 15/09/2015
  2972 00002592 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2973                              <1> 				     ; (1 allocation bit = 1 page)
  2974                              <1> 				     ; (1 allocation bytes = 8 pages)
  2975 00002595 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2976                              <1> 				     ; (to get 32 bit position)			
  2977                              <1> 	;
  2978 00002598 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
  2979 0000259D 01D3                <1> 	add	ebx, edx
  2980 0000259F 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
  2981                              <1> 				     ; (allocation bit position)	 
  2982 000025A2 3B15[14670000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
  2983                              <1> 				     ; than the address in 'next_page' ?
  2984                              <1> 				     ; (next/first free page value)		
  2985 000025A8 7306                <1> 	jnb	short dap_1	     ; no	
  2986 000025AA 8915[14670000]      <1> 	mov	[next_page], edx     ; yes
  2987                              <1> dap_1:
  2988 000025B0 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
  2989                              <1> 				     ; set relevant bit to 1.
  2990                              <1> 				     ; set CF to the previous bit value	
  2991                              <1> 	;cmc			     ; complement carry flag	
  2992                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
  2993                              <1> 				     ; if the page is already deallocated
  2994                              <1> 				     ; before.	
  2995 000025B3 FF05[10670000]      <1>         inc     dword [free_pages]
  2996                              <1> dap_2:
  2997 000025B9 5A                  <1> 	pop	edx
  2998 000025BA 5B                  <1> 	pop	ebx
  2999 000025BB C3                  <1> 	retn
  3000                              <1> 
  3001                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3002                              <1> ;;                                                              ;;
  3003                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
  3004                              <1> ;; Distributed under terms of the GNU General Public License    ;;
  3005                              <1> ;;                                                              ;;
  3006                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3007                              <1> 
  3008                              <1> ;;$Revision: 5057 $
  3009                              <1> 
  3010                              <1> 
  3011                              <1> ;;align 4
  3012                              <1> ;;proc alloc_page
  3013                              <1> 
  3014                              <1> ;;        pushfd
  3015                              <1> ;;        cli
  3016                              <1> ;;        push    ebx
  3017                              <1> ;;;//-
  3018                              <1> ;;        cmp     [pg_data.pages_free], 1
  3019                              <1> ;;        jle     .out_of_memory
  3020                              <1> ;;;//-
  3021                              <1> ;;
  3022                              <1> ;;        mov     ebx, [page_start]
  3023                              <1> ;;        mov     ecx, [page_end]
  3024                              <1> ;;.l1:
  3025                              <1> ;;        bsf     eax, [ebx];
  3026                              <1> ;;        jnz     .found
  3027                              <1> ;;        add     ebx, 4
  3028                              <1> ;;        cmp     ebx, ecx
  3029                              <1> ;;        jb      .l1
  3030                              <1> ;;        pop     ebx
  3031                              <1> ;;        popfd
  3032                              <1> ;;        xor     eax, eax
  3033                              <1> ;;        ret
  3034                              <1> ;;.found:
  3035                              <1> ;;;//-
  3036                              <1> ;;        dec     [pg_data.pages_free]
  3037                              <1> ;;        jz      .out_of_memory
  3038                              <1> ;;;//-
  3039                              <1> ;;        btr     [ebx], eax
  3040                              <1> ;;        mov     [page_start], ebx
  3041                              <1> ;;        sub     ebx, sys_pgmap
  3042                              <1> ;;        lea     eax, [eax+ebx*8]
  3043                              <1> ;;        shl     eax, 12
  3044                              <1> ;;;//-       dec [pg_data.pages_free]
  3045                              <1> ;;        pop     ebx
  3046                              <1> ;;        popfd
  3047                              <1> ;;        ret
  3048                              <1> ;;;//-
  3049                              <1> ;;.out_of_memory:
  3050                              <1> ;;        mov     [pg_data.pages_free], 1
  3051                              <1> ;;        xor     eax, eax
  3052                              <1> ;;        pop     ebx
  3053                              <1> ;;        popfd
  3054                              <1> ;;        ret
  3055                              <1> ;;;//-
  3056                              <1> ;;endp
  3057                              <1> 
  3058                              <1> duplicate_page_dir:
  3059                              <1> 	; 21/09/2015
  3060                              <1> 	; 31/08/2015
  3061                              <1> 	; 20/07/2015
  3062                              <1> 	; 28/04/2015
  3063                              <1> 	; 27/04/2015
  3064                              <1> 	; 18/04/2015
  3065                              <1> 	; 12/04/2015
  3066                              <1> 	; 18/10/2014
  3067                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
  3068                              <1> 	;
  3069                              <1> 	; INPUT -> 
  3070                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
  3071                              <1> 	;		    page directory.
  3072                              <1> 	; OUTPUT ->
  3073                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
  3074                              <1> 	;	       page directory.
  3075                              <1> 	;	(New page directory with new page table entries.)
  3076                              <1> 	;	(New page tables with read only copies of the parent's
  3077                              <1> 	;	pages.)
  3078                              <1> 	;	EAX = 0 -> Error (CF = 1)
  3079                              <1> 	;
  3080                              <1> 	; Modified Registers -> none (except EAX)
  3081                              <1> 	;
  3082 000025BC E804FEFFFF          <1> 	call	allocate_page
  3083 000025C1 723E                <1> 	jc	short dpd_err
  3084                              <1> 	;
  3085 000025C3 55                  <1> 	push	ebp ; 20/07/2015
  3086 000025C4 56                  <1> 	push	esi
  3087 000025C5 57                  <1> 	push	edi
  3088 000025C6 53                  <1> 	push	ebx
  3089 000025C7 51                  <1> 	push	ecx
  3090 000025C8 8B35[A46C0000]      <1> 	mov	esi, [u.pgdir]
  3091 000025CE 89C7                <1> 	mov	edi, eax
  3092 000025D0 50                  <1> 	push	eax ; save child's page directory address
  3093                              <1> 	; 31/08/2015
  3094                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  3095                              <1> 	; (use same system space for all user page tables) 
  3096 000025D1 A5                  <1> 	movsd
  3097 000025D2 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  3098 000025D7 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  3099                              <1> dpd_0:	
  3100 000025DC AD                  <1> 	lodsd
  3101                              <1> 	;or	eax, eax
  3102                              <1>         ;jnz     short dpd_1
  3103 000025DD A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  3104 000025DF 7508                <1> 	jnz	short dpd_1
  3105                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
  3106 000025E1 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  3107 000025E7 EB0F                <1> 	jmp	short dpd_2
  3108                              <1> dpd_1:	
  3109 000025E9 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  3110 000025ED 89C3                <1> 	mov	ebx, eax
  3111                              <1> 	; EBX = Parent's page table address
  3112 000025EF E81F000000          <1> 	call	duplicate_page_table
  3113 000025F4 720C                <1> 	jc	short dpd_p_err
  3114                              <1> 	; EAX = Child's page table address
  3115 000025F6 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  3116                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  3117                              <1> 			 ; (present, writable, user)
  3118                              <1> dpd_2:
  3119 000025F8 AB                  <1> 	stosd
  3120 000025F9 E2E1                <1> 	loop	dpd_0
  3121                              <1> 	;
  3122 000025FB 58                  <1> 	pop	eax  ; restore child's page directory address
  3123                              <1> dpd_3:
  3124 000025FC 59                  <1> 	pop	ecx
  3125 000025FD 5B                  <1> 	pop	ebx
  3126 000025FE 5F                  <1> 	pop	edi
  3127 000025FF 5E                  <1> 	pop	esi
  3128 00002600 5D                  <1> 	pop	ebp ; 20/07/2015
  3129                              <1> dpd_err:
  3130 00002601 C3                  <1> 	retn
  3131                              <1> dpd_p_err:
  3132                              <1> 	; release the allocated pages missing (recover free space)
  3133 00002602 58                  <1> 	pop	eax  ; the new page directory address (physical)
  3134 00002603 8B1D[A46C0000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  3135 00002609 E8E7FEFFFF          <1> 	call 	deallocate_page_dir
  3136 0000260E 29C0                <1> 	sub	eax, eax ; 0
  3137 00002610 F9                  <1> 	stc
  3138 00002611 EBE9                <1> 	jmp	short dpd_3	
  3139                              <1> 
  3140                              <1> duplicate_page_table:
  3141                              <1> 	; 31/12/2021 - Retro UNIX 386 v1.2
  3142                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
  3143                              <1> 	;	 (temporary modifications)
  3144                              <1> 	; 16/04/2021 (Retro UNIX 386 v2)
  3145                              <1> 	; 20/02/2017 (TRDOS 386 v2)
  3146                              <1> 	; 21/09/2015
  3147                              <1> 	; 20/07/2015
  3148                              <1> 	; 05/05/2015
  3149                              <1> 	; 28/04/2015
  3150                              <1> 	; 27/04/2015
  3151                              <1> 	; 18/04/2015
  3152                              <1> 	; 18/10/2014
  3153                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
  3154                              <1> 	;
  3155                              <1> 	; INPUT -> 
  3156                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  3157                              <1> 	;       20/02/2017		 
  3158                              <1> 	;	EBP = Linear address of the page (from 'duplicate_page_dir')
  3159                              <1> 	;	      (Linear address = CORE + user's virtual address) 	
  3160                              <1> 	; OUTPUT ->
  3161                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  3162                              <1> 	;	      (with 'read only' attribute of page table entries)
  3163                              <1> 	;	20/02/2017
  3164                              <1> 	;	EBP = Next linear page address (for 'duplicate_page_dir')
  3165                              <1> 	;	
  3166                              <1> 	;	CF = 1 -> error 
  3167                              <1> 	;
  3168                              <1> 	; Modified Registers -> EBP (except EAX)
  3169                              <1> 	;
  3170 00002613 E8ADFDFFFF          <1> 	call	allocate_page
  3171 00002618 725B                <1> 	jc	short dpt_err
  3172                              <1> 	;
  3173 0000261A 50                  <1> 	push	eax ; *
  3174 0000261B 56                  <1> 	push	esi
  3175 0000261C 57                  <1> 	push	edi
  3176 0000261D 52                  <1> 	push	edx
  3177 0000261E 51                  <1> 	push	ecx
  3178                              <1> 	;
  3179 0000261F 89DE                <1> 	mov	esi, ebx
  3180 00002621 89C7                <1> 	mov	edi, eax
  3181 00002623 89C2                <1> 	mov	edx, eax
  3182 00002625 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  3183                              <1> dpt_0:
  3184 0000262B AD                  <1> 	lodsd
  3185 0000262C 21C0                <1> 	and	eax, eax
  3186 0000262E 7435                <1> 	jz	short dpt_3
  3187 00002630 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  3188                              <1> 	; 17/04/2021 (temporary)
  3189 00002632 7503                <1> 	jnz	short dpt_1
  3190                              <1> 	;jz	short dpt_p_err
  3191                              <1> 	; 31/12/2021
  3192 00002634 F9                  <1> 	stc
  3193 00002635 EB39                <1> 	jmp	short dpt_p_err
  3194                              <1> 
  3195                              <1> ; 17/04/2021
  3196                              <1> ; ('reload_page' procedure call is disabled as temporary)
  3197                              <1> ;
  3198                              <1> ;	; 20/07/2015
  3199                              <1> ;	; ebp = virtual (linear) address of the memory page
  3200                              <1> ;	call	reload_page ; 28/04/2015
  3201                              <1> ;	jc	short dpt_p_err
  3202                              <1> dpt_1:
  3203                              <1> 	; 21/09/2015
  3204 00002637 89C1                <1> 	mov	ecx, eax
  3205 00002639 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  3206 0000263D F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
  3207 00002640 751A                <1> 	jnz	short dpt_2
  3208                              <1> 	; Read only (parent) page
  3209                              <1> 	; 	- there is a third process which uses this page -
  3210                              <1> 	; Allocate a new page for the child process
  3211 00002642 E87EFDFFFF          <1> 	call	allocate_page
  3212 00002647 7227                <1> 	jc	short dpt_p_err
  3213 00002649 57                  <1> 	push	edi
  3214 0000264A 56                  <1> 	push	esi
  3215 0000264B 89CE                <1> 	mov	esi, ecx
  3216 0000264D 89C7                <1> 	mov	edi, eax
  3217 0000264F B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  3218 00002654 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  3219 00002656 5E                  <1> 	pop	esi
  3220 00002657 5F                  <1> 	pop	edi
  3221                              <1> 	;
  3222                              <1> 
  3223                              <1> ; 17/04/2021
  3224                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
  3225                              <1> ; 
  3226                              <1> ;	push	ebx
  3227                              <1> ;	push	eax
  3228                              <1> ;	; 20/07/2015
  3229                              <1> ;	mov	ebx, ebp
  3230                              <1> ;	; ebx = virtual (linear) address of the memory page
  3231                              <1> ;	call	add_to_swap_queue
  3232                              <1> ;	pop	eax
  3233                              <1> ;	pop	ebx
  3234                              <1> 
  3235                              <1> 	; 21/09/2015
  3236 00002658 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  3237                              <1> 		; user + writable + present page
  3238 0000265A EB09                <1> 	jmp	short dpt_3
  3239                              <1> dpt_2:
  3240                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  3241 0000265C 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
  3242                              <1> 		    ; (read only page!)
  3243 0000265E 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
  3244 00002661 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
  3245                              <1> dpt_3:
  3246 00002665 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  3247                              <1> 	;
  3248 00002666 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  3249                              <1> 	;
  3250 0000266C 39D7                <1> 	cmp	edi, edx
  3251 0000266E 72BB                <1> 	jb	short dpt_0
  3252                              <1> dpt_p_err:
  3253 00002670 59                  <1> 	pop	ecx
  3254 00002671 5A                  <1> 	pop	edx
  3255 00002672 5F                  <1> 	pop	edi
  3256 00002673 5E                  <1> 	pop	esi
  3257 00002674 58                  <1> 	pop	eax ; *
  3258                              <1> dpt_err:
  3259 00002675 C3                  <1> 	retn
  3260                              <1> 
  3261                              <1> page_fault_handler: ; CPU EXCEPTION 0Eh (14) : Page Fault !
  3262                              <1> 	; 31/12/2021 - Retro UNIX 386 v1.2
  3263                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
  3264                              <1> 	;	 (temporary modifications)
  3265                              <1> 	; 21/09/2015
  3266                              <1> 	; 19/09/2015
  3267                              <1> 	; 17/09/2015
  3268                              <1> 	; 28/08/2015
  3269                              <1> 	; 20/07/2015
  3270                              <1> 	; 28/06/2015
  3271                              <1> 	; 03/05/2015
  3272                              <1> 	; 30/04/2015
  3273                              <1> 	; 18/04/2015
  3274                              <1> 	; 12/04/2015
  3275                              <1> 	; 30/10/2014
  3276                              <1> 	; 11/09/2014
  3277                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
  3278                              <1> 	;
  3279                              <1> 	; Note: This is not an interrupt/exception handler.
  3280                              <1> 	;	This is a 'page fault remedy' subroutine 
  3281                              <1> 	;	which will be called by standard/uniform
  3282                              <1> 	;	exception handler.
  3283                              <1> 	;
  3284                              <1> 	; INPUT -> 
  3285                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
  3286                              <1> 	;
  3287                              <1> 	;	cr2 = the virtual (linear) address 
  3288                              <1> 	;	      which has caused to page fault (19/09/2015)
  3289                              <1> 	;
  3290                              <1> 	; OUTPUT ->
  3291                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  3292                              <1> 	;	EAX = 0 -> no error
  3293                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
  3294                              <1> 	;
  3295                              <1> 	; Modified Registers -> none (except EAX)
  3296                              <1> 	;	
  3297                              <1>         ;
  3298                              <1>         ; ERROR CODE:
  3299                              <1> 	;	 31  .....	4   3	2   1	0
  3300                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  3301                              <1> 	;	|   Reserved  | I | R | U | W | P |
  3302                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  3303                              <1> 	;
  3304                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
  3305                              <1>     	;		a page-protection violation. When not set,
  3306                              <1> 	;		it was caused by a non-present page.
  3307                              <1> 	; W : WRITE   -	When set, the page fault was caused by
  3308                              <1> 	;		a page write. When not set, it was caused
  3309                              <1> 	;		by a page read.
  3310                              <1> 	; U : USER    -	When set, the page fault was caused 
  3311                              <1> 	;		while CPL = 3. 
  3312                              <1> 	;		This does not necessarily mean that
  3313                              <1> 	;		the page fault was a privilege violation.
  3314                              <1> 	; R : RESERVD -	When set, the page fault was caused by
  3315                              <1> 	;     WRITE	reading a 1 in a reserved field.
  3316                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
  3317                              <1> 	;     FETCH	an instruction fetch
  3318                              <1> 	;
  3319                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
  3320                              <1> 	;  31               22                  12 11                    0
  3321                              <1> 	; +-------------------+-------------------+-----------------------+
  3322                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
  3323                              <1>        	; +-------------------+-------------------+-----------------------+
  3324                              <1> 	;
  3325                              <1> 
  3326                              <1> 	;; CR3 REGISTER (Control Register 3)
  3327                              <1> 	;  31                                   12             5 4 3 2   0
  3328                              <1> 	; +---------------------------------------+-------------+---+-----+
  3329                              <1>       	; |                                       |  		|P|P|     |
  3330                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
  3331                              <1>       	; |                                       | 		|D|T|     |
  3332                              <1>    	; +---------------------------------------+-------------+---+-----+
  3333                              <1> 	;
  3334                              <1> 	;	PWT    - WRITE THROUGH
  3335                              <1> 	;	PCD    - CACHE DISABLE		
  3336                              <1> 	;
  3337                              <1> 	;
  3338                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
  3339                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  3340                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  3341                              <1>       	; |                                       |     | | | | |P|P|U|R| |
  3342                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
  3343                              <1>       	; |                                       |     | | | | |D|T|S|W| |
  3344                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  3345                              <1> 	;
  3346                              <1>         ;       P      - PRESENT
  3347                              <1>         ;       R/W    - READ/WRITE
  3348                              <1>         ;       U/S    - USER/SUPERVISOR
  3349                              <1> 	;	PWT    - WRITE THROUGH
  3350                              <1> 	;	PCD    - CACHE DISABLE	
  3351                              <1> 	;	A      - ACCESSED	
  3352                              <1>         ;       D      - DIRTY (IGNORED)
  3353                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  3354                              <1> 	;	G      - GLOBAL	(IGNORED) 
  3355                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  3356                              <1> 	;
  3357                              <1> 	;
  3358                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
  3359                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  3360                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  3361                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
  3362                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
  3363                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
  3364                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  3365                              <1> 	;
  3366                              <1>         ;       P      - PRESENT
  3367                              <1>         ;       R/W    - READ/WRITE
  3368                              <1>         ;       U/S    - USER/SUPERVISOR
  3369                              <1> 	;	PWT    - WRITE THROUGH
  3370                              <1> 	;	PCD    - CACHE DISABLE	
  3371                              <1> 	;	A      - ACCESSED	
  3372                              <1>         ;       D      - DIRTY
  3373                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  3374                              <1> 	;	G      - GLOBAL	 
  3375                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  3376                              <1> 	;
  3377                              <1> 	;
  3378                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
  3379                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  3380                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  3381                              <1>       	; |                                       |     | | | | | | |U|R| |
  3382                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
  3383                              <1>       	; |                                       |     | | | | | | |S|W| |
  3384                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  3385                              <1> 	;
  3386                              <1>         ;       P      - PRESENT
  3387                              <1>         ;       R/W    - READ/WRITE
  3388                              <1>         ;       U/S    - USER/SUPERVISOR
  3389                              <1>         ;       D      - DIRTY
  3390                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  3391                              <1> 	;
  3392                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
  3393                              <1> 	;
  3394                              <1> 	;
  3395                              <1> 	;; Invalid Page Table Entry
  3396                              <1> 	; 31                                                           1 0
  3397                              <1>       	; +-------------------------------------------------------------+-+
  3398                              <1>       	; |                                                             | |
  3399                              <1>       	; |                          AVAILABLE                          |0|
  3400                              <1>       	; |                                                             | |
  3401                              <1>       	; +-------------------------------------------------------------+-+
  3402                              <1> 	;
  3403                              <1> 
  3404 00002676 53                  <1> 	push	ebx
  3405 00002677 52                  <1> 	push	edx
  3406 00002678 51                  <1> 	push	ecx
  3407                              <1> 	;
  3408                              <1> 	; 21/09/2015 (debugging)
  3409 00002679 FF05[BC6C0000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
  3410 0000267F FF05[BC670000]      <1> 	inc	dword [PF_Count]  ; total page fault count	
  3411                              <1> 	; 28/06/2015
  3412                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
  3413 00002685 8A15[B4670000]      <1> 	mov	dl, [error_code]
  3414                              <1> 	;
  3415 0000268B F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
  3416                              <1> 			; sign
  3417 0000268E 7416                <1> 	jz	short pfh_alloc_np
  3418                              <1> 	; 
  3419                              <1> 	; If it is not a 'write on read only page' type page fault
  3420                              <1> 	; major page fault error with minor reason must be returned without 
  3421                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
  3422                              <1> 	; after return here!
  3423                              <1> 	; Page fault will be remedied, by copying page contents
  3424                              <1> 	; to newly allocated page with write permission;
  3425                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
  3426                              <1> 	; used for working with minimum possible memory usage. 
  3427                              <1> 	; sys_fork will duplicate page directory and tables of parent  
  3428                              <1> 	; process with 'read only' flag. If the child process attempts to
  3429                              <1> 	; write on these read only pages, page fault will be directed here
  3430                              <1> 	; for allocating a new page with same data/content. 
  3431                              <1> 	;
  3432                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
  3433                              <1> 	; will not force to separate CODE and DATA space 
  3434                              <1> 	; in a process/program... 
  3435                              <1> 	; CODE segment/section may contain DATA!
  3436                              <1> 	; It is flat, smoth and simplest programming method already as in 
  3437                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
  3438                              <1> 	;	
  3439 00002690 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
  3440                              <1> 			; sign
  3441 00002693 744F                <1>         jz	short pfh_p_err
  3442                              <1> 	; 31/08/2015
  3443 00002695 F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
  3444                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
  3445 00002698 744A                <1>         jz	short pfh_pv_err
  3446                              <1> 	;
  3447                              <1> 	; make a new page and copy the parent's page content
  3448                              <1> 	; as the child's new page content
  3449                              <1> 	;
  3450 0000269A 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
  3451                              <1> 			 ; which has caused to page fault
  3452 0000269D E87C000000          <1> 	call 	copy_page
  3453 000026A2 7239                <1>         jc	short pfh_im_err ; insufficient memory
  3454                              <1> 	;
  3455 000026A4 EB72                <1>         jmp     pfh_cpp_ok
  3456                              <1> 	;
  3457                              <1> pfh_alloc_np:
  3458 000026A6 E81AFDFFFF          <1> 	call	allocate_page	; (allocate a new page)
  3459 000026AB 7230                <1>         jc	short pfh_im_err ; 'insufficient memory' error
  3460                              <1> pfh_chk_cpl:
  3461                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  3462                              <1> 		; (Lower 12 bits are ZERO, because 
  3463                              <1> 		;	the address is on a page boundary)
  3464 000026AD 80E204              <1> 	and	dl, 4	; CPL = 3 ?
  3465 000026B0 7505                <1> 	jnz	short pfh_um
  3466                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
  3467 000026B2 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
  3468                              <1> 			 ; of the current/active page directory
  3469                              <1> 			 ; (Always kernel/system mode page directory, here!)
  3470                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
  3471 000026B5 EB06                <1> 	jmp	short pfh_get_pde
  3472                              <1> 	;
  3473                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
  3474 000026B7 8B1D[A46C0000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
  3475                              <1> 			; Physical address of the USER's page directory
  3476                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
  3477                              <1> pfh_get_pde:
  3478 000026BD 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
  3479 000026C0 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
  3480                              <1> 			 ; which has been caused to page fault
  3481                              <1> 			 ;
  3482 000026C3 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
  3483 000026C6 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
  3484                              <1> 	;
  3485 000026C9 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
  3486 000026CB 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
  3487 000026CD F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
  3488 000026D0 741A                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
  3489                              <1> 			  	  ; set/validate page directory entry
  3490 000026D2 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  3491 000026D7 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
  3492 000026D9 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
  3493 000026DB EB25                <1> 	jmp	short pfh_get_pte
  3494                              <1> 
  3495                              <1> 	; 31/12/2021 (short jump)
  3496                              <1> pfh_im_err:
  3497 000026DD B8E4000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
  3498                              <1> 			; Major (Primary) Error: Page Fault
  3499                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
  3500 000026E2 EB36                <1> 	jmp	short pfh_err_retn
  3501                              <1> 
  3502                              <1> 	; 31/12/2021
  3503                              <1> pfh_p_err: ; 09/03/2015
  3504                              <1> pfh_pv_err:
  3505                              <1> 	; Page fault was caused by a protection-violation
  3506 000026E4 B8E6000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
  3507                              <1> 			; Major (Primary) Error: Page Fault
  3508                              <1> 			; Minor (Secondary) Error: Protection violation !
  3509 000026E9 F9                  <1> 	stc
  3510 000026EA EB2E                <1> 	jmp	short pfh_err_retn
  3511                              <1> 
  3512                              <1> pfh_set_pde:
  3513                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
  3514                              <1> 	;;	 (So, we know this PDE is empty or invalid)
  3515                              <1> 	;
  3516 000026EC 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
  3517 000026EE 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
  3518 000026F0 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
  3519 000026F2 89C3                <1> 	mov	ebx, eax
  3520 000026F4 E8CCFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
  3521 000026F9 72E2                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
  3522                              <1> pfh_spde_1:
  3523                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  3524 000026FB 89C1                <1> 	mov	ecx, eax
  3525 000026FD E834FDFFFF          <1> 	call	clear_page ; Clear page content
  3526                              <1> pfh_get_pte:
  3527 00002702 0F20D0              <1> 	mov	eax, cr2 ; virtual address
  3528                              <1> 			 ; which has been caused to page fault
  3529 00002705 89C7                <1> 	mov	edi, eax ; 20/07/2015
  3530 00002707 C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
  3531                              <1> 			 ; higher 20 bits of the page fault address 
  3532 0000270A 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
  3533 0000270F C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
  3534 00002712 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
  3535                              <1> ; 17/04/2021 temporary
  3536                              <1> ;	mov	eax, [ebx] ; get previous value of pte
  3537                              <1> ;		; bit 0 of EAX is always 0 (otherwise we would not be here)
  3538                              <1> ; 17/04/2021
  3539                              <1> ; ('swap_in' procedure call has been disabled as temporary)
  3540                              <1> ;
  3541                              <1> ;	and	eax, eax
  3542                              <1> ;	jz	short pfh_gpte_1
  3543                              <1> ;	; 20/07/2015
  3544                              <1> ;	xchg	ebx, ecx ; new page address (physical)
  3545                              <1> ;	push	ebp ; 20/07/2015
  3546                              <1> ;	mov	ebp, cr2
  3547                              <1> ;		; ECX = physical address of the page table entry
  3548                              <1> ;		; EBX = Memory page address (physical!)
  3549                              <1> ;		; EAX = Swap disk (offset) address
  3550                              <1> ;		; EBP = virtual address (page fault address)
  3551                              <1> ;	call	swap_in
  3552                              <1> ;	pop	ebp
  3553                              <1> ;	jc      short pfh_err_retn
  3554                              <1> ;	xchg	ecx, ebx
  3555                              <1> ;		; EBX = physical address of the page table entry
  3556                              <1> ;		; ECX = new page
  3557                              <1> pfh_gpte_1:
  3558 00002714 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
  3559 00002716 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
  3560                              <1> pfh_cpp_ok:
  3561                              <1> ; 17/04/2021
  3562                              <1> ; ('add_to_swap_queue' procedure call has been disabled as temporary)
  3563                              <1> ;
  3564                              <1> ;	; 20/07/2015
  3565                              <1> ;	mov	ebx, cr2
  3566                              <1> ;	call 	add_to_swap_queue
  3567                              <1> 	;
  3568                              <1> 	; The new PTE (which contains the new page) will be added to 
  3569                              <1> 	; the swap queue, here. 
  3570                              <1> 	; (Later, if memory will become insufficient, 
  3571                              <1> 	; one page will be swapped out which is at the head of 
  3572                              <1> 	; the swap queue by using FIFO and access check methods.)
  3573                              <1> 	;
  3574 00002718 31C0                <1> 	xor	eax, eax  ; 0
  3575                              <1> 	;
  3576                              <1> pfh_err_retn:
  3577 0000271A 59                  <1> 	pop	ecx
  3578 0000271B 5A                  <1> 	pop	edx
  3579 0000271C 5B                  <1> 	pop	ebx
  3580 0000271D C3                  <1> 	retn 
  3581                              <1> 	
  3582                              <1> copy_page:
  3583                              <1> 	; 17/07/2022
  3584                              <1> 	; 16/04/2021
  3585                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
  3586                              <1> 	; 22/09/2015
  3587                              <1> 	; 21/09/2015
  3588                              <1> 	; 19/09/2015
  3589                              <1> 	; 07/09/2015
  3590                              <1> 	; 31/08/2015
  3591                              <1> 	; 20/07/2015
  3592                              <1> 	; 05/05/2015
  3593                              <1> 	; 03/05/2015
  3594                              <1> 	; 18/04/2015
  3595                              <1> 	; 12/04/2015
  3596                              <1> 	; 30/10/2014
  3597                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
  3598                              <1> 	;
  3599                              <1> 	; INPUT -> 
  3600                              <1> 	;	EBX = Virtual (linear) address of source page
  3601                              <1> 	;	     (Page fault address)
  3602                              <1> 	; OUTPUT ->
  3603                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
  3604                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  3605                              <1> 	;	EAX = 0 (CF = 1) 
  3606                              <1> 	;		if there is not a free page to be allocated
  3607                              <1> 	;	(page content of the source page will be copied
  3608                              <1> 	;	onto the target/new page) 	
  3609                              <1> 	;
  3610                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
  3611                              <1> 	;
  3612                              <1> 
  3613                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
  3614                              <1> 	; INPUT: 
  3615                              <1> 	;	EBX = Virtual (linear) address of source page
  3616                              <1> 	;	     (Page fault address)
  3617                              <1> 	; OUTPUT:
  3618                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
  3619                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  3620                              <1> 	;	EAX = 0 (CF = 1) 
  3621                              <1> 	;		if there is not a free page to be allocated
  3622                              <1> 	;	(page content of the source page will be copied
  3623                              <1> 	;	onto the target/new page) 	
  3624                              <1> 	;
  3625                              <1> 	; Modified Registers -> ecx, ebx (except EAX) ; 16/04/2021
  3626                              <1> 	
  3627 0000271E 56                  <1> 	push	esi ; *
  3628 0000271F 57                  <1> 	push	edi ; **
  3629                              <1> 	; 16/04/2021
  3630                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
  3631                              <1> 	;push	ebx ; ***
  3632                              <1> 	;push	ecx ; ****
  3633 00002720 31F6                <1> 	xor 	esi, esi
  3634 00002722 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
  3635 00002725 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
  3636 00002727 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
  3637 0000272A 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
  3638 0000272D 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
  3639 0000272F 031D[A46C0000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
  3640 00002735 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
  3641 00002737 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
  3642 0000273B 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
  3643 0000273D 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  3644                              <1> 	;shl	bx, 2	   ; shift 2 bits left to get PTE offset
  3645                              <1> 	; 17/07/2022
  3646 00002743 C1E302              <1> 	shl	ebx, 2
  3647 00002746 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
  3648                              <1> 	; 07/09/2015
  3649 00002748 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
  3650                              <1> 				     ; read only page as a child process?)	
  3651 0000274D 7509                <1> 	jnz	short cpp_0 ; yes
  3652 0000274F 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
  3653 00002751 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
  3654 00002756 EB31                <1> 	jmp	short cpp_1
  3655                              <1> cpp_0:
  3656 00002758 89FE                <1> 	mov	esi, edi
  3657 0000275A 0335[A86C0000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
  3658 00002760 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
  3659 00002762 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  3660 00002766 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
  3661 00002768 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  3662                              <1> 	;shl	si, 2	   ; shift 2 bits left to get PTE offset
  3663                              <1> 	; 17/07/2022
  3664 0000276E C1E602              <1> 	shl	esi, 2
  3665 00002771 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
  3666 00002773 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
  3667                              <1> 	; 21/09/2015
  3668 00002775 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
  3669 00002777 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
  3670                              <1> 	;
  3671 0000277B F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
  3672 0000277E 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
  3673                              <1> 	;
  3674 00002780 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
  3675 00002785 39C8                <1> 	cmp	eax, ecx   ; Same page?	
  3676 00002787 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
  3677                              <1> 			    ; Convert child's page to writable page
  3678                              <1> cpp_1:
  3679 00002789 E837FCFFFF          <1> 	call	allocate_page
  3680 0000278E 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
  3681 00002790 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
  3682 00002792 7405                <1> 	jz	short cpp_2
  3683                              <1> 		; Convert read only page to writable page 
  3684                              <1> 		;(for the parent of the current process)
  3685                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
  3686                              <1> 	; 22/09/2015
  3687 00002794 890E                <1> 	mov	[esi], ecx
  3688 00002796 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
  3689                              <1> 				 ; 1+2+4 = 7
  3690                              <1> cpp_2:
  3691 00002799 89C7                <1> 	mov	edi, eax ; new page address of the child process
  3692                              <1> 	; 07/09/2015
  3693 0000279B 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
  3694 0000279D B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  3695 000027A2 F3A5                <1> 	rep	movsd ; 31/08/2015
  3696                              <1> cpp_3:		
  3697 000027A4 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
  3698 000027A6 8903                <1> 	mov	[ebx], eax ; Update PTE
  3699 000027A8 28C0                <1> 	sub	al, al ; clear attributes
  3700                              <1> cpp_4:
  3701                              <1> 	; 16/04/2021
  3702                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
  3703                              <1> 	;pop	ecx ; ****
  3704                              <1> 	;pop	ebx ; ***
  3705 000027AA 5F                  <1> 	pop	edi ; **
  3706 000027AB 5E                  <1> 	pop	esi ; *
  3707 000027AC C3                  <1> 	retn
  3708                              <1> 
  3709                              <1> ;; 28/04/2015
  3710                              <1> ;; 24/10/2014
  3711                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
  3712                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
  3713                              <1> ;;
  3714                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
  3715                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
  3716                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
  3717                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
  3718                              <1> ;;
  3719                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
  3720                              <1> ;;
  3721                              <1> ;; Method:
  3722                              <1> ;;	Swap page queue is a list of allocated pages with physical
  3723                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
  3724                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
  3725                              <1> ;;	When a new page is being allocated, swap queue is updated
  3726                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
  3727                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
  3728                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
  3729                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
  3730                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
  3731                              <1> ;;	offset value becomes it's previous offset value - 4.
  3732                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
  3733                              <1> ;;	the queue/list is not shifted.
  3734                              <1> ;;	After the queue/list shift, newly allocated page is added
  3735                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
  3736                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
  3737                              <1> ;;	will not be added to the tail of swap page queue.  		 
  3738                              <1> ;;	
  3739                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
  3740                              <1> ;;	the first non-accessed, writable page in the list, 
  3741                              <1> ;;	from the head to the tail. The list is shifted to left 
  3742                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
  3743                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
  3744                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
  3745                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
  3746                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
  3747                              <1> ;;	procedure will be failed)...
  3748                              <1> ;;
  3749                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
  3750                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
  3751                              <1> ;;	(PTE) will be added to the tail of the queue after
  3752                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
  3753                              <1> ;;	the queue will be rotated and the PTE in the head will be
  3754                              <1> ;;	added to the tail after resetting 'accessed' bit. 
  3755                              <1> ;;
  3756                              <1> ;;
  3757                              <1> ;;	
  3758                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
  3759                              <1> ;;
  3760                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
  3761                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
  3762                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
  3763                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
  3764                              <1> ;;
  3765                              <1> ;; [swpd_next] = the first free block address in swapped page records
  3766                              <1> ;;    		 for next free block search by 'swap_out' procedure.
  3767                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
  3768                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
  3769                              <1> ;; 		 (entire swap space must be accessed by using
  3770                              <1> ;;		 31 bit offset address) 
  3771                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
  3772                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
  3773                              <1> ;;		  0 for file, or beginning sector of the swap partition
  3774                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
  3775                              <1> ;;
  3776                              <1> ;; 					
  3777                              <1> ;; Method:
  3778                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
  3779                              <1> ;;	procedure swaps out a page from memory to the swap disk 
  3780                              <1> ;;	(partition) or swap file to get a new free page at the memory.
  3781                              <1> ;;	Swapping out is performed by using swap page queue.
  3782                              <1> ;;
  3783                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
  3784                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
  3785                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
  3786                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
  3787                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
  3788                              <1> ;;	Absolute physical (logical) address of the swapped page is 
  3789                              <1> ;;	calculated by adding offset value to the swap partition's 
  3790                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
  3791                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
  3792                              <1> ;;	and offset value is equal to absolute (physical or logical)
  3793                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
  3794                              <1> ;;	is in a partitioned virtual hard disk.) 
  3795                              <1> ;;
  3796                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
  3797                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
  3798                              <1> ;;
  3799                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
  3800                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
  3801                              <1> ;;
  3802                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
  3803                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
  3804                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
  3805                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
  3806                              <1> ;;	it means relevant (respective) block is in use, and, 
  3807                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
  3808                              <1> ;;      swap disk/file block is free.
  3809                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
  3810                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
  3811                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
  3812                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
  3813                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
  3814                              <1> ;;	------------------------------------------------------------
  3815                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
  3816                              <1> ;;	------------------------------------------------------------
  3817                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
  3818                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
  3819                              <1> ;;
  3820                              <1> ;;	..............................................................
  3821                              <1> ;;
  3822                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
  3823                              <1> ;;	then it searches Swap Allocation Table if free count is not
  3824                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
  3825                              <1> ;;	position with value of 1 on the table is converted to swap
  3826                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
  3827                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
  3828                              <1> ;;	number of physical swap disk or virtual swap disk)
  3829                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
  3830                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
  3831                              <1> ;;	(memory page). That will be a direct disk write procedure.
  3832                              <1> ;;	(for preventing late memory allocation, significant waiting). 
  3833                              <1> ;;	If disk write procedure returns with error or free count of 
  3834                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
  3835                              <1> ;;	'insufficient memory error' (cf=1). 
  3836                              <1> ;;
  3837                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
  3838                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
  3839                              <1> ;;	in other words, 'swap_out' will not check the table for other
  3840                              <1> ;;	free blocks after a disk write error. It will return to 
  3841                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
  3842                              <1> ;;
  3843                              <1> ;;	After writing the page on to swap disk/file address/sector,
  3844                              <1> ;;	'swap_out' procedure returns with that swap (offset) sector
  3845                              <1> ;;	address (cf=0). 
  3846                              <1> ;;
  3847                              <1> ;;	..............................................................
  3848                              <1> ;;
  3849                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
  3850                              <1> ;;	file sectors at specified memory page. Then page allocation
  3851                              <1> ;;	procedure updates relevant page table entry with 'present' 
  3852                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
  3853                              <1> ;;	to do, except to terminate the process which is the owner of
  3854                              <1> ;;	the swapped page.
  3855                              <1> ;;
  3856                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
  3857                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
  3858                              <1> ;;	updates [swpd_first] pointer if it is required.
  3859                              <1> ;;
  3860                              <1> ;;	..............................................................	 
  3861                              <1> ;;
  3862                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
  3863                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
  3864                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
  3865                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
  3866                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
  3867                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
  3868                              <1> ;;
  3869                              <1> 
  3870                              <1> ; 17/04/2021
  3871                              <1> ; ('swap_in' procedure call is disabled as temporary)
  3872                              <1> 
  3873                              <1> ; 30/11/2021 - temporary !
  3874                              <1> ;swap_in:
  3875                              <1> 	; 31/08/2015
  3876                              <1> 	; 20/07/2015
  3877                              <1> 	; 28/04/2015
  3878                              <1> 	; 18/04/2015
  3879                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  3880                              <1> 	;
  3881                              <1> 	; INPUT -> 
  3882                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
  3883                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
  3884                              <1> 	;	EAX = Offset Address for the swapped page on the
  3885                              <1> 	;	      swap disk or in the swap file.
  3886                              <1> 	;
  3887                              <1> 	; OUTPUT ->
  3888                              <1> 	;	EAX = 0 if loading at memory has been successful
  3889                              <1> 	;
  3890                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
  3891                              <1> 	;		  or sector not present or drive not ready
  3892                              <1> 	;	     EAX = Error code
  3893                              <1> 	;	     [u.error] = EAX 
  3894                              <1> 	;		       = The last error code for the process
  3895                              <1> 	;		         (will be reset after returning to user)	  
  3896                              <1> 	;
  3897                              <1> 	; Modified Registers -> EAX
  3898                              <1> 	;
  3899                              <1> 
  3900                              <1> ;       cmp     dword [swp_drv], 0
  3901                              <1> ;	jna	short swpin_dnp_err
  3902                              <1> ;
  3903                              <1> ;	cmp	eax, [swpd_size]
  3904                              <1> ;	jnb	short swpin_snp_err
  3905                              <1> ;
  3906                              <1> ;	push	esi
  3907                              <1> ;	push	ebx
  3908                              <1> ;	push	ecx
  3909                              <1> ;	mov	esi, [swp_drv]	
  3910                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  3911                              <1> ;		; Note: Even if corresponding physical disk's sector 
  3912                              <1> ;		; size different than 512 bytes, logical disk sector
  3913                              <1> ;		; size is 512 bytes and disk reading procedure
  3914                              <1> ;		; will be performed for reading 4096 bytes
  3915                              <1> ;		; (2*2048, 8*512). 
  3916                              <1> ;	; ESI = Logical disk description table address
  3917                              <1> ;	; EBX = Memory page (buffer) address (physical!)
  3918                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
  3919                              <1> ;	; ECX = Sector count ; 8 sectors
  3920                              <1> ;	push	eax
  3921                              <1> ;	call	logical_disk_read
  3922                              <1> ;	pop	eax
  3923                              <1> ;	jnc	short swpin_read_ok
  3924                              <1> ;	;
  3925                              <1> ;	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
  3926                              <1> ;	mov	[u.error], eax
  3927                              <1> ;	jmp	short swpin_retn
  3928                              <1> ;	;
  3929                              <1> ;swpin_read_ok:
  3930                              <1> ;	; EAX = Offset address (logical sector number)
  3931                              <1> ;	call	unlink_swap_block  ; Deallocate swap block	
  3932                              <1> ;	;
  3933                              <1> ;	; EBX = Memory page (buffer) address (physical!)
  3934                              <1> ;	; 20/07/2015
  3935                              <1> ;	mov	ebx, ebp ; virtual address (page fault address)
  3936                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  3937                              <1> ;	mov	bl, [u.uno] ; current process number
  3938                              <1> ;	; EBX = Virtual (Linear) address & process number combination
  3939                              <1> ;	call	swap_queue_shift
  3940                              <1> ;	; eax = 0 ; 10/06/2016 (if ebx input > 0, eax output = 0)
  3941                              <1> ;	;sub	eax, eax  ; 0 ; Error Code = 0  (no error)
  3942                              <1> ;	; zf = 1
  3943                              <1> ;swpin_retn:
  3944                              <1> ;	pop	ecx
  3945                              <1> ;	pop	ebx
  3946                              <1> ;	pop	esi
  3947                              <1> ;	retn
  3948                              <1> ;
  3949                              <1> ;swpin_dnp_err:
  3950                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR
  3951                              <1> ;swpin_err_retn:
  3952                              <1> ;	mov	[u.error], eax
  3953                              <1> ;	stc
  3954                              <1> ;	retn
  3955                              <1> ;
  3956                              <1> ;swpin_snp_err:
  3957                              <1> ;	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
  3958                              <1> ;	jmp	short swpin_err_retn
  3959                              <1> 
  3960                              <1> ; 17/04/2021
  3961                              <1> ; ('swap_out' procedure call is disabled as temporary)
  3962                              <1> 
  3963                              <1> ; 30/11/2021 - temporary !
  3964                              <1> ;swap_out:
  3965                              <1> 	; 10/06/2016
  3966                              <1> 	; 07/06/2016
  3967                              <1>         ; 23/05/2016
  3968                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  3969                              <1> 	; 24/10/2014 - 31/08/2015 (Retro UNIX 386 v1)
  3970                              <1> 	;
  3971                              <1> 	; INPUT -> 
  3972                              <1> 	;	none
  3973                              <1> 	;
  3974                              <1> 	; OUTPUT ->
  3975                              <1> 	;	EAX = Physical page address (which is swapped out
  3976                              <1> 	;	      for allocating a new page)
  3977                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
  3978                              <1> 	;		  or sector not present or drive not ready
  3979                              <1> 	;	     EAX = Error code
  3980                              <1> 	;	     [u.error] = EAX 
  3981                              <1> 	;		       = The last error code for the process
  3982                              <1> 	;		         (will be reset after returning to user)	  
  3983                              <1> 	;
  3984                              <1> 	; Modified Registers -> none (except EAX)
  3985                              <1> 	;
  3986                              <1> 
  3987                              <1> ;	cmp 	word [swpq_count], 1
  3988                              <1> ;       jc      swpout_im_err ; 'insufficient memory'
  3989                              <1> ;
  3990                              <1> ;       ;cmp    dword [swp_drv], 1
  3991                              <1> ;	;jc	short swpout_dnp_err ; 'swap disk/file not present'
  3992                              <1> ;
  3993                              <1> ;       cmp     dword [swpd_free], 1
  3994                              <1> ;       jc      swpout_nfspc_err ; 'no free space on swap disk'
  3995                              <1> ;
  3996                              <1> ;	push	ebx ; *
  3997                              <1> ;swpout_1:
  3998                              <1> ;	; 10/06/2016
  3999                              <1> ;	xor	ebx, ebx ; shift the queue and return a PTE value
  4000                              <1> ;	call	swap_queue_shift
  4001                              <1> ;	and	eax, eax	; 0 = empty queue (improper entries)
  4002                              <1> ;       jz      swpout_npts_err        ; There is not any proper PTE
  4003                              <1> ;				       ; pointer in the swap queue
  4004                              <1> ;	; EAX = PTE value of the page
  4005                              <1> ;	; EBX = PTE address of the page
  4006                              <1> ;	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  4007                              <1> ;	;
  4008                              <1> ;	; 07/06/2016
  4009                              <1> ;	; 19/05/2016
  4010                              <1> ;	; check this page is in timer events or not
  4011                              <1> ;	
  4012                              <1> ;swpout_timer_page_0:
  4013                              <1> ;	push	edx ; **
  4014                              <1> ;
  4015                              <1> ;	; 07/06/2016
  4016                              <1> ;	cmp	byte [timer_events], 0 
  4017                              <1> ;	jna	short swpout_2
  4018                              <1> ;	;
  4019                              <1> ;	mov	dl, [timer_events]
  4020                              <1> ;
  4021                              <1> ;	push	ecx ; ***
  4022                              <1> ;	push	ebx ; ****
  4023                              <1> ;	mov	ebx, timer_set ; beginning address of timer event
  4024                              <1> ;			       ; structures 
  4025                              <1> ;swpout_timer_page_1:
  4026                              <1> ;	mov	cl, [ebx]
  4027                              <1> ;	or	cl, cl ; 0 = free, >0 = process number
  4028                              <1> ;	jz	short swpout_timer_page_3
  4029                              <1> ;	mov	ecx, [ebx+12] ; response (signal return) address
  4030                              <1> ;	and	cx, PTE_A_CLEAR ; clear offset part (right 12 bits)
  4031                              <1> ;				; of the response byte address, to
  4032                              <1> ;				; get beginning of the page address)
  4033                              <1> ;	cmp	eax, ecx
  4034                              <1> ;	jne	short swpout_timer_page_2 ; not same page
  4035                              <1> ;	
  4036                              <1> ;	; !same page!
  4037                              <1> ;	;
  4038                              <1> ;	; NOTE: // 19/05/2016 // - TRDOS 386 feature only ! -
  4039                              <1> ;	; This page will be used by the kernel to put timer event
  4040                              <1> ;	; response (signal return) byte at the requested address;
  4041                              <1> ;	; in order to prevent a possible wrong write (while
  4042                              <1> ;	; this page is swapped out) on physical memory,
  4043                              <1> ;	; we must protect this page against to be swapped out!
  4044                              <1> ;	;
  4045                              <1> ;	pop	ebx ; ****
  4046                              <1> ;	pop	ecx ; ***
  4047                              <1> ;	pop	edx ; **
  4048                              <1> ;	jmp	short swpout_1	; do not swap out this page !
  4049                              <1> ; 
  4050                              <1> ;swpout_timer_page_2:
  4051                              <1> ;	; 07/06/2016
  4052                              <1> ;	dec	dl
  4053                              <1> ;	jz	short swpout_timer_page_4
  4054                              <1> ;swpout_timer_page_3:
  4055                              <1> ;	;cmp	ebx, timer_set + 240 ; last timer event (15*16) 
  4056                              <1> ;	;jnb	short swpout_timer_page_4
  4057                              <1> ;	add	ebx, 16
  4058                              <1> ;	jmp	short swpout_timer_page_1	
  4059                              <1> ;
  4060                              <1> ;swpout_timer_page_4:
  4061                              <1> ;	pop	ebx ; ****
  4062                              <1> ;	pop	ecx ; ***
  4063                              <1> ;swpout_2:
  4064                              <1> ;	mov	edx, ebx	       ; Page table entry address	
  4065                              <1> ;	mov	ebx, eax	       ; Buffer (Page) Address				
  4066                              <1> ;	;
  4067                              <1> ;	call	link_swap_block
  4068                              <1> ;	jnc	short swpout_3	       ; It may not be needed here	
  4069                              <1> ;				       ; because [swpd_free] value
  4070                              <1> ;				       ; was checked at the beginging. 	
  4071                              <1> ;	pop	edx ; **
  4072                              <1> ;	pop	ebx ; *
  4073                              <1> ;	jmp	short swpout_nfspc_err 
  4074                              <1> ;swpout_3:
  4075                              <1> ;	test	eax, 80000000h ; test bit 31 (this may not be needed!)
  4076                              <1> ;	jnz	short swpout_nfspc_err  ; 10/06/2016 (bit 31 = 1 !)
  4077                              <1> ;	;	
  4078                              <1> ;	push	esi ; **
  4079                              <1> ;	push	ecx ; ***
  4080                              <1> ;	push	eax ; sector address ; (31 bit !, bit 31 = 0)
  4081                              <1> ;	mov	esi, [swp_drv]	
  4082                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  4083                              <1> ;		; Note: Even if corresponding physical disk's sector 
  4084                              <1> ;		; size different than 512 bytes, logical disk sector
  4085                              <1> ;		; size is 512 bytes and disk writing procedure
  4086                              <1> ;		; will be performed for writing 4096 bytes
  4087                              <1> ;		; (2*2048, 8*512). 
  4088                              <1> ;	; ESI = Logical disk description table address
  4089                              <1> ;	; EBX = Buffer (Page) address
  4090                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
  4091                              <1> ;	; ECX = Sector count ; 8 sectors
  4092                              <1> ;	; edx = PTE address
  4093                              <1> ;	call	logical_disk_write
  4094                              <1> ;	; edx = PTE address
  4095                              <1> ;	pop	ecx ; sector address	
  4096                              <1> ;	jnc	short swpout_write_ok
  4097                              <1> ;	;
  4098                              <1> ;	;; call	unlink_swap_block ; this block must be left as 'in use'
  4099                              <1> ;swpout_dw_err:
  4100                              <1> ;	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
  4101                              <1> ;	mov	[u.error], eax
  4102                              <1> ;	jmp	short swpout_retn
  4103                              <1> ;	;
  4104                              <1> ;swpout_write_ok:
  4105                              <1> ;	; EBX = Buffer (page) address
  4106                              <1> ;	; EDX = Page Table Entry address
  4107                              <1> ;	; ECX = Swap disk sector (file block) address (31 bit)
  4108                              <1> ;	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
  4109                              <1> ;	mov 	[edx], ecx 
  4110                              <1> ;		; bit 0 = 0 (swapped page)
  4111                              <1> ;	mov	eax, ebx
  4112                              <1> ;swpout_retn:
  4113                              <1> ;	pop	ecx ; ***
  4114                              <1> ;	pop	esi ; **
  4115                              <1> ;	pop	ebx ; *
  4116                              <1> ;	retn
  4117                              <1> ;
  4118                              <1> ;;swpout_dnp_err:
  4119                              <1> ;;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
  4120                              <1> ;;	jmp	short swpout_err_retn
  4121                              <1> ;swpout_nfspc_err:
  4122                              <1> ;	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
  4123                              <1> ;swpout_err_retn:
  4124                              <1> ;	mov	[u.error], eax
  4125                              <1> ;	;stc
  4126                              <1> ;	retn
  4127                              <1> ;swpout_npts_err:
  4128                              <1> ;	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
  4129                              <1> ;	pop	ebx
  4130                              <1> ;	jmp	short swpout_err_retn
  4131                              <1> ;swpout_im_err:
  4132                              <1> ;	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
  4133                              <1> ;	jmp	short swpout_err_retn
  4134                              <1> 
  4135                              <1> ; 17/04/2021
  4136                              <1> ; ('swap_queue_shift' procedure call is disabled as temporary)
  4137                              <1> 
  4138                              <1> ; 30/11/2021 - temporary !
  4139                              <1> ;swap_queue_shift:
  4140                              <1> 	; 26/03/2017
  4141                              <1> 	; 10/06/2016
  4142                              <1> 	; 09/06/2016 - TRDOS 386 (TRDOS v2.0)
  4143                              <1> 	; 23/10/2014 - 20/07/2015 (Retro UNIX 386 v1)
  4144                              <1> 	;
  4145                              <1> 	; INPUT ->
  4146                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
  4147                              <1> 	;	      and process number combination (bit 0 to 11)
  4148                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
  4149                              <1> 	;	
  4150                              <1> 	; OUTPUT ->
  4151                              <1> 	;	If EBX input > 0 
  4152                              <1> 	;	   the queue will be shifted 4 bytes (dword),
  4153                              <1> 	; 	   from the tail to the head, up to entry offset
  4154                              <1> 	; 	   which points to EBX input value or nothing
  4155                              <1> 	;	   to do if EBX value is not found on the queue.
  4156                              <1> 	;	   (The entry -with EBX value- will be removed
  4157                              <1> 	;	   from the queue if it is found.)
  4158                              <1> 	;
  4159                              <1> 	;	   EAX = 0		
  4160                              <1> 	;
  4161                              <1> 	;	If EBX input = 0
  4162                              <1> 	;	   the queue will be shifted 4 bytes (dword),
  4163                              <1> 	; 	   from the tail to the head, if the PTE address
  4164                              <1> 	;	   which is pointed in head of the queue is marked
  4165                              <1> 	;	   as "accessed" or it is marked as "non present".
  4166                              <1> 	;	   (If "accessed" flag of the PTE -which is pointed
  4167                              <1> 	;	   in the head- is set -to 1-, it will be reset
  4168                              <1> 	;	   -to 0- and then, the queue will be rotated 
  4169                              <1> 	;	   -without dropping pointer of the PTE from 
  4170                              <1> 	;	   the queue- for 4 bytes on head to tail direction.
  4171                              <1> 	;	   Pointer in the head will be moved into the tail,
  4172                              <1> 	;	   other PTEs will be shifted on head direction.)
  4173                              <1> 	;
  4174                              <1> 	;	   Swap queue will be shifted up to the first
  4175                              <1> 	;	   'present' or 'non accessed' page will be found
  4176                              <1> 	;	   (as pointed) on the queue head (then it will be
  4177                              <1>         ;          removed/dropped from the queue).
  4178                              <1> 	;
  4179                              <1> 	;	   EAX (> 0) = PTE value of the page which is
  4180                              <1> 	;		 (it's pointer -virtual address-) dropped
  4181                              <1> 	;		 (removed) from swap queue.
  4182                              <1> 	;	   EBX = PTE address of the page (if EAX > 0)
  4183                              <1> 	;	         which is (it's pointer -virtual address-)
  4184                              <1> 	;		 dropped (removed) from swap queue.
  4185                              <1> 	;
  4186                              <1> 	;	   EAX = 0 -> empty swap queue ! 
  4187                              <1> 	;
  4188                              <1> 	; Modified Registers -> EAX, EBX
  4189                              <1> 	;
  4190                              <1> ;	movzx   eax, word [swpq_count]  ; Max. 1024
  4191                              <1> ;	and	ax, ax
  4192                              <1> ;	jz	short swpqs_retn
  4193                              <1> ;	push	edi
  4194                              <1> ;	push	esi
  4195                              <1> ;	push	ecx
  4196                              <1> ;	mov	esi, swap_queue
  4197                              <1> ;	mov	ecx, eax
  4198                              <1> ;	or	ebx, ebx
  4199                              <1> ;	jz	short swpqs_7
  4200                              <1> ;swpqs_1:
  4201                              <1> ;	lodsd
  4202                              <1> ;	cmp	eax, ebx
  4203                              <1> ;	je	short swpqs_2
  4204                              <1> ;	loop	swpqs_1
  4205                              <1> ;	; 10/06/2016
  4206                              <1> ;	sub	eax, eax 
  4207                              <1> ;	jmp	short swpqs_6
  4208                              <1> ;swpqs_2:
  4209                              <1> ;	mov	edi, esi
  4210                              <1> ;	sub 	edi, 4
  4211                              <1> ;swpqs_3:
  4212                              <1> ;	dec	word [swpq_count]
  4213                              <1> ;	jz	short swpqs_5
  4214                              <1> ;swpqs_4:
  4215                              <1> ;	dec 	ecx
  4216                              <1> ;	rep	movsd	; shift up (to the head)
  4217                              <1> ;swpqs_5:
  4218                              <1> ;	xor	eax, eax
  4219                              <1> ;	mov	[edi], eax
  4220                              <1> ;swpqs_6:
  4221                              <1> ;	pop	ecx
  4222                              <1> ;	pop	esi
  4223                              <1> ;	pop	edi
  4224                              <1> ;swpqs_retn:
  4225                              <1> ;	retn		
  4226                              <1> ;swpqs_7:
  4227                              <1> ;	mov	edi, esi ; head
  4228                              <1> ;	lodsd
  4229                              <1> ;	; 20/07/2015
  4230                              <1> ;	mov	ebx, eax
  4231                              <1> ;	and	ebx, ~PAGE_OFF ; ~0FFFh 
  4232                              <1> ;		      ; ebx = virtual address (at page boundary)	
  4233                              <1> ;	and	eax, PAGE_OFF ; 0FFFh
  4234                              <1> ;		      ; ax = process number (1 to 4095)
  4235                              <1> ;	cmp	al, [u.uno]
  4236                              <1> ;		; Max. 16 (nproc) processes for Retro UNIX 386 v1
  4237                              <1> ;	jne	short swpqs_8
  4238                              <1> ;	mov	eax, [u.pgdir]
  4239                              <1> ;	jmp	short swpqs_9
  4240                              <1> ;swpqs_8:
  4241                              <1> ;	; 09/06/2016
  4242                              <1> ;	cmp	byte [eax+p.stat-1], 0
  4243                              <1> ;	jna	short swpqs_3     ; free (or terminated) process
  4244                              <1> ;	cmp	byte [eax+p.stat-1], 2 ; waiting
  4245                              <1> ;	ja	short swpqs_3 	  ; zombie (3) or undefined ?	
  4246                              <1> ;
  4247                              <1> ;	;shl	ax, 2
  4248                              <1> ;	shl	al, 2
  4249                              <1> ;	mov 	eax, [eax+p.upage-4]
  4250                              <1> ;	or	eax, eax
  4251                              <1> ;	jz	short swpqs_3 ; invalid upage
  4252                              <1> ;	add	eax, u.pgdir - user
  4253                              <1> ;			 ; u.pgdir value for the process
  4254                              <1> ;			 ; is in [eax]
  4255                              <1> ;	mov	eax, [eax]
  4256                              <1> ;	and	eax, eax
  4257                              <1> ;	jz	short swpqs_3 ; invalid page directory
  4258                              <1> ;swpqs_9:
  4259                              <1> ;	push	edx
  4260                              <1> ;	; eax = page directory
  4261                              <1> ;	; ebx = virtual address
  4262                              <1> ;	call	get_pte
  4263                              <1> ;	mov	ebx, edx	; PTE address
  4264                              <1> ;	pop	edx
  4265                              <1> ;	; 10/06/2016
  4266                              <1> ;	jc	short swpqs_13 ; empty PDE
  4267                              <1> ;	; EAX = PTE value
  4268                              <1> ;	test	al, PTE_A_PRESENT ; bit 0 = 1
  4269                              <1> ;	jz	short swpqs_13  ; Drop non-present page
  4270                              <1> ;			        ; from the queue (head)
  4271                              <1> ;	test	al, PTE_A_WRITE	; bit 1 = 0 (read only)
  4272                              <1> ;	jz	short swpqs_13  ; Drop read only page
  4273                              <1> ;			        ; from the queue (head) 	
  4274                              <1> ;	;test	al, PTE_A_ACCESS ; bit 5 = 1 (Accessed)
  4275                              <1> ;	;jnz	short swpqs_11  ; present
  4276                              <1> ;			        ; accessed page
  4277                              <1> ;       btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
  4278                              <1> ;	jc	short swpqs_11  ; accessed page
  4279                              <1> ;
  4280                              <1> ;	dec	ecx
  4281                              <1> ;	mov	[swpq_count], cx
  4282                              <1> ;       jz      short swpqs_10
  4283                              <1> ;		; esi = head + 4
  4284                              <1> ;		; edi = head
  4285                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  4286                              <1> ;swpqs_10:
  4287                              <1> ;	mov	[edi], ecx ; 0
  4288                              <1> ;	jmp	short swpqs_6 ; 26/03/2017
  4289                              <1> ;
  4290                              <1> ;swpqs_11:
  4291                              <1> ;	mov	[ebx], eax     ; save changed attribute
  4292                              <1> ;	; Rotation (head -> tail)
  4293                              <1> ;	dec	ecx     ; entry count -> last entry number		
  4294                              <1> ;	jz	short swpqs_10
  4295                              <1> ;		; esi = head + 4
  4296                              <1> ;		; edi = head
  4297                              <1> ;	mov	eax, [edi] ; 20/07/2015
  4298                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  4299                              <1> ;	mov	[edi], eax ; head -> tail ; [k] = [1]
  4300                              <1> ;
  4301                              <1> ;	mov	cx, [swpq_count]
  4302                              <1> ;
  4303                              <1> ;swpqs_12:
  4304                              <1> ;	mov	esi, swap_queue ; head
  4305                              <1> ;       jmp     swpqs_7
  4306                              <1> ;
  4307                              <1> ;swpqs_13:
  4308                              <1> ;	dec	ecx
  4309                              <1> ;	mov	[swpq_count], cx
  4310                              <1> ;       jz      swpqs_5
  4311                              <1> ;	jmp	short swpqs_12
  4312                              <1> 
  4313                              <1> ; 17/04/2021
  4314                              <1> ; ('add_to_swp_queue' procedure call is disabled as temporary)
  4315                              <1> 
  4316                              <1> ; 30/11/2021 - temporary !
  4317                              <1> ;add_to_swap_queue:
  4318                              <1> 	; 20/02/2017
  4319                              <1> 	; 20/07/2015
  4320                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  4321                              <1> 	;
  4322                              <1> 	; Adds new page to swap queue
  4323                              <1> 	; (page directories and page tables must not be added
  4324                              <1> 	; to swap queue)	
  4325                              <1> 	;
  4326                              <1> 	; INPUT ->
  4327                              <1> 	;	EBX = Linear (Virtual) addr for current process
  4328                              <1> 	;	[u.uno]
  4329                              <1> 	;	20/02/2017
  4330                              <1> 	;	(Linear address = CORE + user's virtual address)
  4331                              <1> 	;
  4332                              <1> 	; OUTPUT ->
  4333                              <1> 	;	EAX = [swpq_count]
  4334                              <1> 	;	      (after the PTE has been added)
  4335                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
  4336                              <1> 	;	      the PTE could not be added.
  4337                              <1> 	;
  4338                              <1> 	; Modified Registers -> EAX
  4339                              <1> 	;
  4340                              <1> ;	push	ebx
  4341                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  4342                              <1> ;	mov	bl, [u.uno] ; current process number
  4343                              <1> ;	call	swap_queue_shift ; drop from the queue if
  4344                              <1> ;				 ; it is already on the queue
  4345                              <1> ;		; then add it to the tail of the queue
  4346                              <1> ;	movzx	eax, word [swpq_count]
  4347                              <1> ;	cmp	ax, 1024
  4348                              <1> ;	jb	short atsq_1
  4349                              <1> ;	sub	ax, ax
  4350                              <1> ;	pop	ebx
  4351                              <1> ;	retn
  4352                              <1> ;atsq_1:
  4353                              <1> ;	push	esi
  4354                              <1> ;	mov	esi, swap_queue
  4355                              <1> ;	and	ax, ax
  4356                              <1> ;	jz	short atsq_2
  4357                              <1> ;	shl	ax, 2	; convert to offset
  4358                              <1> ;	add	esi, eax
  4359                              <1> ;	shr	ax, 2
  4360                              <1> ;atsq_2:
  4361                              <1> ;	inc	ax
  4362                              <1> ;	mov	[esi], ebx ; Virtual address + [u.uno] combination
  4363                              <1> ;	mov	[swpq_count], ax
  4364                              <1> ;	pop	esi
  4365                              <1> ;	pop	ebx
  4366                              <1> ;	retn
  4367                              <1> 
  4368                              <1> ; 17/04/2021
  4369                              <1> ; ('unlink_swap_block' procedure call is disabled as temporary)
  4370                              <1> 
  4371                              <1> ; 30/11/2021 - temporary !
  4372                              <1> ;unlink_swap_block:
  4373                              <1> 	; 15/09/2015
  4374                              <1> 	; 30/04/2015
  4375                              <1> 	; 18/04/2015
  4376                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  4377                              <1> 	;
  4378                              <1> 	; INPUT -> 
  4379                              <1> 	;	EAX = swap disk/file offset address
  4380                              <1> 	;	      (bit 1 to bit 31)
  4381                              <1> 	; OUTPUT ->
  4382                              <1> 	;	[swpd_free] is increased
  4383                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
  4384                              <1> 	;
  4385                              <1> 	; Modified Registers -> EAX
  4386                              <1> 	;
  4387                              <1> ;	push	ebx
  4388                              <1> ;	push	edx
  4389                              <1> ;	;
  4390                              <1> ;	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
  4391                              <1> ;				     ; 3 bits right
  4392                              <1> ;				     ; to get swap block/page number
  4393                              <1> ;	mov	edx, eax
  4394                              <1> ;	; 15/09/2015
  4395                              <1> ;	shr	edx, 3		     ; to get offset to S.A.T.
  4396                              <1> ;				     ; (1 allocation bit = 1 page)
  4397                              <1> ;				     ; (1 allocation bytes = 8 pages)
  4398                              <1> ;	and	dl, 0FCh 	     ; clear lower 2 bits
  4399                              <1> ;				     ; (to get 32 bit position)			
  4400                              <1> ;	;
  4401                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table address
  4402                              <1> ;	add	ebx, edx
  4403                              <1> ;	and	eax, 1Fh	     ; lower 5 bits only
  4404                              <1> ;				     ; (allocation bit position)	 
  4405                              <1> ;	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
  4406                              <1> ;				     ; than the address in 'swpd_next' ?
  4407                              <1> ;				     ; (next/first free block value)		
  4408                              <1> ;	jnb	short uswpbl_1	     ; no	
  4409                              <1> ;	mov	[swpd_next], eax     ; yes	
  4410                              <1> ;uswpbl_1:
  4411                              <1> ;	bts	[ebx], eax	     ; unlink/release/deallocate block
  4412                              <1> ;				     ; set relevant bit to 1.
  4413                              <1> ;				     ; set CF to the previous bit value	
  4414                              <1> ;	cmc			     ; complement carry flag	
  4415                              <1> ;	jc	short uswpbl_2	     ; do not increase swfd_free count
  4416                              <1> ;				     ; if the block is already deallocated
  4417                              <1> ;				     ; before.	
  4418                              <1> ;       inc     dword [swpd_free]
  4419                              <1> ;uswpbl_2:
  4420                              <1> ;	pop	edx
  4421                              <1> ;	pop	ebx
  4422                              <1> ;	retn
  4423                              <1> 
  4424                              <1> ; 17/04/2021
  4425                              <1> ; ('link_swap_block' procedure call is disabled as temporary)
  4426                              <1> 
  4427                              <1> ; 30/11/2021 - temporary !
  4428                              <1> ;link_swap_block:
  4429                              <1> 	; 01/07/2015
  4430                              <1> 	; 18/04/2015
  4431                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  4432                              <1> 	;
  4433                              <1> 	; INPUT -> none
  4434                              <1> 	;
  4435                              <1> 	; OUTPUT ->
  4436                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
  4437                              <1> 	;	      in sectors (corresponding 
  4438                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
  4439                              <1> 	;
  4440                              <1> 	;	CF = 1 and EAX = 0 
  4441                              <1> 	; 		   if there is not a free block to be allocated	
  4442                              <1> 	;
  4443                              <1> 	; Modified Registers -> none (except EAX)
  4444                              <1> 	;
  4445                              <1> 
  4446                              <1> ;	;mov	eax, [swpd_free]
  4447                              <1> ;	;and	eax, eax
  4448                              <1> ;	;jz	short out_of_swpspc
  4449                              <1> ;	;
  4450                              <1> ;	push	ebx
  4451                              <1> ;	push	ecx
  4452                              <1> ;	;
  4453                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
  4454                              <1> ;	mov	ecx, ebx
  4455                              <1> ;	add	ebx, [swpd_next] ; Free block searching starts from here
  4456                              <1> ;				 ; next_free_swap_block >> 5
  4457                              <1> ;	add	ecx, [swpd_last] ; Free block searching ends here
  4458                              <1> ;				 ; (total_swap_blocks - 1) >> 5
  4459                              <1> ;lswbl_scan:
  4460                              <1> ;	cmp	ebx, ecx
  4461                              <1> ;	ja	short lswbl_notfound
  4462                              <1> ;	;
  4463                              <1> ;	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
  4464                              <1> ;			   ; Clears ZF if a bit is found set (1) and 
  4465                              <1> ;			   ; loads the destination with an index to
  4466                              <1> ;			   ; first set bit. (0 -> 31) 
  4467                              <1> ;			   ; Sets ZF to 1 if no bits are found set.
  4468                              <1> ;	; 01/07/2015
  4469                              <1> ;	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
  4470                              <1> ;			 ;
  4471                              <1> ;			 ; NOTE:  a Swap Disk Allocation Table bit 
  4472                              <1> ;			 ;	  with value of 1 means 
  4473                              <1> ;			 ;	  the corresponding page is free 
  4474                              <1> ;			 ;	  (Retro UNIX 386 v1 feaure only!)
  4475                              <1> ;	add	ebx, 4
  4476                              <1> ;			 ; We return back for searching next page block
  4477                              <1> ;			 ; NOTE: [swpd_free] is not ZERO; so, 
  4478                              <1> ;			 ;	 we always will find at least 1 free block here.
  4479                              <1> ;	jmp    	short lswbl_scan
  4480                              <1> ;	;
  4481                              <1> ;lswbl_notfound:	
  4482                              <1> ;	sub	ecx, swap_alloc_table
  4483                              <1> ;	mov	[swpd_next], ecx ; next/first free page = last page 
  4484                              <1> ;				 ; (unlink_swap_block procedure will change it)
  4485                              <1> ;	xor	eax, eax
  4486                              <1> ;	mov	[swpd_free], eax
  4487                              <1> ;	stc
  4488                              <1> ;lswbl_ok:
  4489                              <1> ;	pop	ecx
  4490                              <1> ;	pop	ebx
  4491                              <1> ;	retn
  4492                              <1> ;	;
  4493                              <1> ;;out_of_swpspc:
  4494                              <1> ;;	stc
  4495                              <1> ;;	retn
  4496                              <1> ;
  4497                              <1> ;lswbl_found:
  4498                              <1> ;	mov	ecx, ebx
  4499                              <1> ;	sub	ecx, swap_alloc_table
  4500                              <1> ;	mov	[swpd_next], ecx ; Set first free block searching start
  4501                              <1> ;				 ; address/offset (to the next)
  4502                              <1> ;       dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
  4503                              <1> ;	;
  4504                              <1> ;	btr	[ebx], eax	 ; The destination bit indexed by the source value
  4505                              <1> ;				 ; is copied into the Carry Flag and then cleared
  4506                              <1> ;				 ; in the destination.
  4507                              <1> ;				 ;
  4508                              <1> ;				 ; Reset the bit which is corresponding to the 
  4509                              <1> ;				 ; (just) allocated block.
  4510                              <1> ;	shl	ecx, 5		 ; (block offset * 32) + block index
  4511                              <1> ;	add	eax, ecx	 ; = block number
  4512                              <1> ;	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
  4513                              <1> ;				 ; 1 block =  8 sectors
  4514                              <1> ;	;
  4515                              <1> ;	; EAX = offset address of swap disk/file sector (beginning of the block)
  4516                              <1> ;	;
  4517                              <1> ;	; NOTE: The relevant page table entry will be updated
  4518                              <1> ;	;       according to this EAX value...
  4519                              <1> ;	;
  4520                              <1> ;	jmp	short lswbl_ok
  4521                              <1> 
  4522                              <1> ; 17/04/2021
  4523                              <1> ; ('logical_disk_read' procedure call is disabled as temporary)
  4524                              <1> 
  4525                              <1> ; 30/11/2021 - temporary !
  4526                              <1> ;logical_disk_read:
  4527                              <1> 	; 20/07/2015
  4528                              <1> 	; 09/03/2015 (temporary code here)
  4529                              <1> 	;
  4530                              <1> 	; INPUT ->
  4531                              <1> 	; 	ESI = Logical disk description table address
  4532                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  4533                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  4534                              <1> 	; 	ECX = Sector count
  4535                              <1> 	;
  4536                              <1> 	;
  4537                              <1> ;	retn
  4538                              <1> 
  4539                              <1> ; 17/04/2021
  4540                              <1> ; ('logical_disk_write' procedure call is disabled as temporary)
  4541                              <1> 
  4542                              <1> ; 30/11/2021 - temporary !
  4543                              <1> ;logical_disk_write:
  4544                              <1> 	; 20/07/2015
  4545                              <1> 	; 09/03/2015 (temporary code here)
  4546                              <1> 	;
  4547                              <1> 	; INPUT ->
  4548                              <1> 	; 	ESI = Logical disk description table address
  4549                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  4550                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  4551                              <1> 	; 	ECX = Sector count
  4552                              <1> 	;
  4553                              <1> ;	retn
  4554                              <1> 
  4555                              <1> get_physical_addr:
  4556                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
  4557                              <1> 	;	(temporary modifications)
  4558                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
  4559                              <1> 	; 18/10/2015
  4560                              <1> 	; 29/07/2015
  4561                              <1> 	; 20/07/2015
  4562                              <1> 	; 04/06/2015
  4563                              <1> 	; 20/05/2015
  4564                              <1> 	; 28/04/2015
  4565                              <1> 	; 18/04/2015
  4566                              <1> 	; Get physical address
  4567                              <1> 	;     (allocates a new page for user if it is not present)
  4568                              <1> 	;	
  4569                              <1> 	; (This subroutine is needed for mapping user's virtual 
  4570                              <1> 	; (buffer) address to physical address (of the buffer).)
  4571                              <1> 	; ('sys write', 'sys read' system calls...)
  4572                              <1> 	;
  4573                              <1> 	; INPUT ->
  4574                              <1> 	;	EBX = virtual address
  4575                              <1> 	;	u.pgdir = page directory (physical) address
  4576                              <1> 	;
  4577                              <1> 	; OUTPUT ->
  4578                              <1> 	;	EAX = physical address 
  4579                              <1> 	;	EBX = linear address	
  4580                              <1> 	;	EDX = physical address of the page frame
  4581                              <1> 	;	      (with attribute bits)
  4582                              <1> 	;	ECX = byte count within the page frame
  4583                              <1> 	;
  4584                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
  4585                              <1> 	;
  4586                              <1> 
  4587                              <1> 	; 19/04/2020 - Retro UNIX386 v2
  4588 000027AD A1[A46C0000]        <1> 	mov	eax, [u.pgdir]
  4589                              <1> 
  4590                              <1> ifs_get_physical_addr: ; 19/04/2020 - Retro UNIX 386 v2
  4591                              <1> 	
  4592 000027B2 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
  4593                              <1> 	;
  4594                              <1> 	;mov	eax, [u.pgdir]
  4595 000027B8 E81AFDFFFF          <1> 	call	get_pte
  4596                              <1> 		; EDX = Page table entry address (if CF=0)
  4597                              <1> 	        ;       Page directory entry address (if CF=1)
  4598                              <1> 		;       (Bit 0 value is 0 if PT is not present)
  4599                              <1> 		; EAX = Page table entry value (page address)
  4600                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
  4601 000027BD 731C                <1> 	jnc	short gpa_1
  4602                              <1> 	;
  4603 000027BF E801FCFFFF          <1> 	call	allocate_page
  4604 000027C4 724B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
  4605                              <1> gpa_0:
  4606 000027C6 E86BFCFFFF          <1> 	call 	clear_page
  4607                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  4608 000027CB 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
  4609                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
  4610                              <1> 			   ; (user, writable, present page)	
  4611 000027CD 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  4612 000027CF A1[A46C0000]        <1> 	mov	eax, [u.pgdir]	
  4613 000027D4 E8FEFCFFFF          <1> 	call	get_pte
  4614 000027D9 7236                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  4615                              <1> gpa_1:
  4616                              <1> 	; EAX = PTE value, EDX = PTE address
  4617 000027DB A801                <1> 	test 	al, PTE_A_PRESENT
  4618 000027DD 750A                <1> 	jnz	short gpa_3
  4619 000027DF 09C0                <1> 	or	eax, eax
  4620 000027E1 7420                <1> 	jz	short gpa_4  ; Allocate a new page
  4621                              <1> 
  4622                              <1> ; 17/04/2021
  4623                              <1> ; ('reload_page' procedure call is disabled as temporary)
  4624 000027E3 EB2C                <1> 	jmp	short gpa_im_err  ; temporary !
  4625                              <1> 
  4626                              <1> 	; 20/07/2015
  4627                              <1> ;	push	ebp
  4628                              <1> ;	mov	ebp, ebx ; virtual (linear) address
  4629                              <1> ;	; reload swapped page
  4630                              <1> ;	call	reload_page ; 28/04/2015
  4631                              <1> ;	pop	ebp
  4632                              <1> ;	jc	short gpa_retn
  4633                              <1> gpa_2:
  4634                              <1> ; 17/04/2021
  4635                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
  4636                              <1> 
  4637                              <1> 	; 20/07/2015
  4638                              <1> 	; 20/05/2015
  4639                              <1> 	; add this page to swap queue
  4640                              <1> ;	push	eax 
  4641                              <1> ;	; EBX = Linear (CORE+virtual) address ; 20/02/2017 
  4642                              <1> ;	call 	add_to_swap_queue
  4643                              <1> ;	pop	eax
  4644                              <1> 		; PTE address in EDX
  4645                              <1> 		; virtual address in EBX
  4646                              <1> 
  4647                              <1> 	; EAX = memory page address
  4648 000027E5 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
  4649                              <1> 				  ; present flag, bit 0 = 1
  4650                              <1> 				  ; user flag, bit 2 = 1	
  4651                              <1> 				  ; writable flag, bit 1 = 1
  4652 000027E7 8902                <1> 	mov	[edx], eax  ; Update PTE value
  4653                              <1> gpa_3:
  4654                              <1> 	; 18/10/2015
  4655 000027E9 89D9                <1> 	mov	ecx, ebx
  4656 000027EB 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
  4657 000027F1 89C2                <1> 	mov 	edx, eax
  4658 000027F3 662500F0            <1> 	and	ax, PTE_A_CLEAR
  4659 000027F7 01C8                <1> 	add	eax, ecx
  4660 000027F9 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
  4661 000027FB 81C100100000        <1> 	add	ecx, PAGE_SIZE
  4662 00002801 F8                  <1> 	clc
  4663                              <1> gpa_retn:
  4664 00002802 C3                  <1> 	retn	
  4665                              <1> gpa_4:	
  4666 00002803 E8BDFBFFFF          <1> 	call	allocate_page
  4667 00002808 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  4668 0000280A E827FCFFFF          <1> 	call	clear_page
  4669 0000280F EBD4                <1> 	jmp	short gpa_2
  4670                              <1> 
  4671                              <1> gpa_im_err:	
  4672 00002811 B804000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  4673                              <1> 				  ; Major error = 0 (No protection fault)	
  4674 00002816 C3                  <1> 	retn
  4675                              <1> 
  4676                              <1> ; 17/04/2021
  4677                              <1> ; ('reload_page' procedure call is disabled as temporary)
  4678                              <1> 
  4679                              <1> ; 30/11/2021 - temporary !
  4680                              <1> ;reload_page:
  4681                              <1> 	; 20/07/2015
  4682                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
  4683                              <1> 	;
  4684                              <1> 	; Reload (Restore) swapped page at memory
  4685                              <1> 	;
  4686                              <1> 	; INPUT -> 
  4687                              <1> 	;	EBP = Virtual (linear) memory address
  4688                              <1> 	;	EAX = PTE value (swap disk sector address)
  4689                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
  4690                              <1> 	; OUTPUT ->
  4691                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
  4692                              <1> 	;
  4693                              <1> 	;	CF = 1 and EAX = error code
  4694                              <1> 	;
  4695                              <1> 	; Modified Registers -> none (except EAX)
  4696                              <1> 	;
  4697                              <1> ;	shr	eax, 1   ; Convert PTE value to swap disk address 
  4698                              <1> ;	push	ebx      ;
  4699                              <1> ;	mov	ebx, eax ; Swap disk (offset) address	
  4700                              <1> ;	call	allocate_page
  4701                              <1> ;	jc	short rlp_im_err
  4702                              <1> ;	xchg 	eax, ebx	
  4703                              <1> ;	; EBX = Physical memory (page) address
  4704                              <1> ;	; EAX = Swap disk (offset) address
  4705                              <1> ;	; EBP = Virtual (linear) memory address
  4706                              <1> ;	call	swap_in
  4707                              <1> ;	jc	short rlp_swp_err  ; (swap disk/file read error)
  4708                              <1> ;	mov	eax, ebx	
  4709                              <1> ;rlp_retn:
  4710                              <1> ;	pop	ebx
  4711                              <1> ;	retn
  4712                              <1> ;	
  4713                              <1> ;rlp_im_err:	
  4714                              <1> ;	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  4715                              <1> ;				  ; Major error = 0 (No protection fault)	
  4716                              <1> ;	jmp	short rlp_retn
  4717                              <1> ;
  4718                              <1> ;rlp_swp_err:
  4719                              <1> ;	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
  4720                              <1> ;	jmp	short rlp_retn
  4721                              <1> 
  4722                              <1> copy_page_dir:
  4723                              <1> 	; 17/04/2021 (temporary modifications)
  4724                              <1> 	; 19/09/2015
  4725                              <1> 	; temporary - 07/09/2015
  4726                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  4727                              <1> 	;
  4728                              <1> 	; INPUT -> 
  4729                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
  4730                              <1> 	;		    page directory.
  4731                              <1> 	; OUTPUT ->
  4732                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
  4733                              <1> 	;	       page directory.
  4734                              <1> 	;	(New page directory with new page table entries.)
  4735                              <1> 	;	(New page tables with read only copies of the parent's
  4736                              <1> 	;	pages.)
  4737                              <1> 	;	EAX = 0 -> Error (CF = 1)
  4738                              <1> 	;
  4739                              <1> 	; Modified Registers -> none (except EAX)
  4740                              <1> 	;
  4741 00002817 E8A9FBFFFF          <1> 	call	allocate_page
  4742 0000281C 723E                <1> 	jc	short cpd_err
  4743                              <1> 	;
  4744 0000281E 55                  <1> 	push	ebp ; 20/07/2015
  4745 0000281F 56                  <1> 	push	esi
  4746 00002820 57                  <1> 	push	edi
  4747 00002821 53                  <1> 	push	ebx
  4748 00002822 51                  <1> 	push	ecx
  4749 00002823 8B35[A46C0000]      <1> 	mov	esi, [u.pgdir]
  4750 00002829 89C7                <1> 	mov	edi, eax
  4751 0000282B 50                  <1> 	push	eax ; save child's page directory address
  4752                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  4753                              <1> 	; (use same system space for all user page tables) 
  4754 0000282C A5                  <1> 	movsd
  4755 0000282D BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  4756 00002832 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  4757                              <1> cpd_0:	
  4758 00002837 AD                  <1> 	lodsd
  4759                              <1> 	;or	eax, eax
  4760                              <1>         ;jnz	short cpd_1
  4761 00002838 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  4762 0000283A 7508                <1> 	jnz	short cpd_1
  4763                              <1>  	; (virtual address at the end of the page table)	
  4764 0000283C 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  4765 00002842 EB0F                <1> 	jmp	short cpd_2
  4766                              <1> cpd_1:	
  4767 00002844 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  4768 00002848 89C3                <1> 	mov	ebx, eax
  4769                              <1> 	; EBX = Parent's page table address
  4770 0000284A E81F000000          <1> 	call	copy_page_table
  4771 0000284F 720C                <1> 	jc	short cpd_p_err
  4772                              <1> 	; EAX = Child's page table address
  4773 00002851 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  4774                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  4775                              <1> 			 ; (present, writable, user)
  4776                              <1> cpd_2:
  4777 00002853 AB                  <1> 	stosd
  4778 00002854 E2E1                <1> 	loop	cpd_0
  4779                              <1> 	;
  4780 00002856 58                  <1> 	pop	eax  ; restore child's page directory address
  4781                              <1> cpd_3:
  4782 00002857 59                  <1> 	pop	ecx
  4783 00002858 5B                  <1> 	pop	ebx
  4784 00002859 5F                  <1> 	pop	edi
  4785 0000285A 5E                  <1> 	pop	esi
  4786 0000285B 5D                  <1> 	pop	ebp
  4787                              <1> cpd_err:
  4788 0000285C C3                  <1> 	retn
  4789                              <1> cpd_p_err:
  4790                              <1> 	; release the allocated pages missing (recover free space)
  4791 0000285D 58                  <1> 	pop	eax  ; the new page directory address (physical)
  4792 0000285E 8B1D[A46C0000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  4793 00002864 E88CFCFFFF          <1> 	call 	deallocate_page_dir
  4794 00002869 29C0                <1> 	sub	eax, eax ; 0
  4795 0000286B F9                  <1> 	stc
  4796 0000286C EBE9                <1> 	jmp	short cpd_3	
  4797                              <1> 
  4798                              <1> copy_page_table:
  4799                              <1> 	; 17/04/2021 (temporary modifications)
  4800                              <1> 	; 19/09/2015
  4801                              <1> 	; temporary - 07/09/2015
  4802                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  4803                              <1> 	;
  4804                              <1> 	; INPUT -> 
  4805                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  4806                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
  4807                              <1> 	; OUTPUT ->
  4808                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  4809                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  4810                              <1> 	;	CF = 1 -> error 
  4811                              <1> 	;
  4812                              <1> 	; Modified Registers -> EBP (except EAX)
  4813                              <1> 	;
  4814 0000286E E852FBFFFF          <1> 	call	allocate_page
  4815 00002873 7244                <1> 	jc	short cpt_err
  4816                              <1> 	;
  4817 00002875 50                  <1> 	push	eax ; *
  4818                              <1> 	;push 	ebx
  4819 00002876 56                  <1> 	push	esi
  4820 00002877 57                  <1> 	push	edi
  4821 00002878 52                  <1> 	push	edx
  4822 00002879 51                  <1> 	push	ecx
  4823                              <1> 	;
  4824 0000287A 89DE                <1> 	mov	esi, ebx
  4825 0000287C 89C7                <1> 	mov	edi, eax
  4826 0000287E 89C2                <1> 	mov	edx, eax
  4827 00002880 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  4828                              <1> cpt_0:
  4829 00002886 AD                  <1> 	lodsd
  4830 00002887 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 = 1
  4831                              <1> 	;jnz	short cpt_1 (*)
  4832                              <1> 	; 17/04/2021 (temporary (*)
  4833                              <1> 	;and	eax, eax (*)
  4834 00002889 741E                <1> 	jz	short cpt_2  ; 17/04/2021
  4835                              <1> 	
  4836                              <1> ; 17/04/2021
  4837                              <1> ; ('reload_page' procedure call is disabled as temporary)
  4838                              <1> ;
  4839                              <1> ;	; ebp = virtual (linear) address of the memory page
  4840                              <1> ;	call	reload_page ; 28/04/2015
  4841                              <1> ;	jc	short cpt_p_err
  4842                              <1> cpt_1:
  4843 0000288B 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  4844 0000288F 89C1                <1> 	mov	ecx, eax
  4845                              <1> 	; Allocate a new page for the child process
  4846 00002891 E82FFBFFFF          <1> 	call	allocate_page
  4847 00002896 721C                <1> 	jc	short cpt_p_err
  4848 00002898 57                  <1> 	push	edi
  4849 00002899 56                  <1> 	push	esi
  4850 0000289A 89CE                <1> 	mov	esi, ecx
  4851 0000289C 89C7                <1> 	mov	edi, eax
  4852 0000289E B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  4853 000028A3 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  4854 000028A5 5E                  <1> 	pop	esi
  4855 000028A6 5F                  <1> 	pop	edi
  4856                              <1> 	; 
  4857                              <1> ; 17/04/2021
  4858                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)	
  4859                              <1> ;
  4860                              <1> ;	push	ebx
  4861                              <1> ;	push	eax
  4862                              <1> ;	mov	ebx, ebp
  4863                              <1> ;	; ebx = virtual address of the memory page
  4864                              <1> ;	call	add_to_swap_queue
  4865                              <1> ;	pop	eax
  4866                              <1> ;	pop	ebx
  4867                              <1> 	;
  4868                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  4869 000028A7 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  4870                              <1> cpt_2:
  4871 000028A9 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  4872                              <1> 	;
  4873 000028AA 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  4874                              <1> 	;
  4875 000028B0 39D7                <1> 	cmp	edi, edx
  4876 000028B2 72D2                <1> 	jb	short cpt_0
  4877                              <1> cpt_p_err:
  4878 000028B4 59                  <1> 	pop	ecx
  4879 000028B5 5A                  <1> 	pop	edx
  4880 000028B6 5F                  <1> 	pop	edi
  4881 000028B7 5E                  <1> 	pop	esi
  4882                              <1> 	;pop	ebx
  4883 000028B8 58                  <1> 	pop	eax ; *
  4884                              <1> cpt_err:
  4885 000028B9 C3                  <1> 	retn
  4886                              <1> 
  4887                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
  4888                              <1> 
  4889                              <1> ;; Data:
  4890                              <1> 
  4891                              <1> ; 09/03/2015
  4892                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
  4893                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
  4894                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  4895                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  4896                              <1> ;swpd_next:  dd 0 ; next free page block
  4897                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
  2087                                  %include 'sysdefs.s' ; 09/03/2015
  2088                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2089                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2090                              <1> ; ****************************************************************************
  2091                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - SYSDEFS.INC
  2092                              <1> ; Last Modification: 12/06/2022
  2093                              <1> ;
  2094                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
  2095                              <1> ; (Modified from 
  2096                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
  2097                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
  2098                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
  2099                              <1> ; ----------------------------------------------------------------------------
  2100                              <1> ;
  2101                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2102                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2103                              <1> ; <Bell Laboratories (17/3/1972)>
  2104                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2105                              <1> ;
  2106                              <1> ; ****************************************************************************
  2107                              <1> 
  2108                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
  2109                              <1> ; (SB structure has been moved here from 'ux.s' 
  2110                              <1> ;	to overcome NASM's bss addressing bug !!!)
  2111                              <1> ; (('ux.s' bss section addresses are being overlapped
  2112                              <1> ;    when SB structure is defined in 'ux.s'))
  2113                              <1> 
  2114                              <1> struc SB ; SuperBlock
  2115                              <1> 
  2116 00000000 ????????            <1> .Header:	resd 1
  2117                              <1> ;.HiddenSects:
  2118 00000004 ????????            <1> .BootSectAddr:	resd 1	; Hidden Sectors
  2119                              <1> ;.TotalSects:
  2120 00000008 ????????            <1> .VolumeSize:	resd 1	; Entire Volume/Partition Size (includes ext. volume)
  2121 0000000C ????????            <1> .Version:	resd 1	
  2122 00000010 ????????            <1> .BlockSize:	resd 1	
  2123 00000014 ????????            <1> .InodeCount:	resd 1	
  2124 00000018 ????????            <1> .FreeMapAddr:	resd 1	
  2125 0000001C ????????            <1> .FreeMapSize:	resd 1	
  2126 00000020 ????????            <1> .InodeMapAddr:	resd 1	
  2127 00000024 ????????            <1> .InodeMapSize:	resd 1	
  2128 00000028 ????????            <1> .InodeTblAddr:	resd 1	
  2129 0000002C ????????            <1> .InodeTblSize:	resd 1	
  2130 00000030 ????????            <1> .FreeInodes:	resd 1	
  2131 00000034 ????????            <1> .FirstFreeIno:	resd 1	
  2132 00000038 ????????            <1> .FreeBlocks:	resd 1	
  2133 0000003C ????????            <1> .FirstFreeBlk:	resd 1	
  2134 00000040 <res 13h>           <1> .BootSecParms:	resb 19	; v1
  2135 00000053 ??????????          <1> .BSExtension:	resb 5	; v2 HDFS
  2136 00000058 ??                  <1> .Status:	resb 1	; 12/05/2021 (system modification status) (*)
  2137 00000059 ??                  <1> .Pdrv:		resb 1  ; Physical disk number (index) ; 12/05/2021 (*) 
  2138 0000005A ????                <1> .Uno:		resw 1	; user/process number ; 12/05/2021 (*)
  2139 0000005C ????????            <1> .ModifTime:	resd 1	; (last) modification time (*)
  2140 00000060 ????????            <1> .ExtdVolTbl:	resd 1	; Extended Volume Start/Table Address
  2141 00000064 ????????            <1> .ExtdVolSize:	resd 1	; Extended Volume (swap section etc.) Size	
  2142 00000068 ??                  <1> .LBA_rw:	resb 1
  2143 00000069 ??                  <1> .ClusterSize:	resb 1
  2144 0000006A ??                  <1> .ReadOnly:	resb 1	; (SB will not be written to disk if bit 0 is 1)
  2145 0000006B ??                  <1> .Mounted:	resb 1
  2146 0000006C ????????            <1> .MountInode:	resd 1  ; double word
  2147 00000070 ??                  <1> .DevMajor:	resb 1
  2148 00000071 ??                  <1> .DevMinor:	resb 1
  2149 00000072 ??                  <1> .LongName:	resb 1
  2150 00000073 ??                  <1> .Direntry32:	resb 1
  2151                              <1> ; 18/07/2021
  2152 00000074 ????????            <1> .FileBuffer:	resd 1
  2153 00000078 ????????            <1> .ItabBuffer:	resd 1
  2154 0000007C ????????            <1> .ImapBuffer:	resd 1
  2155 00000080 ????????            <1> .FmapBuffer:	resd 1
  2156                              <1>  ; 15/07/2021
  2157 00000084 ????????            <1> .LastInode:	resd 1
  2158                              <1> ; 02/05/2021
  2159 00000088 ????????            <1> .FmapIndex:	resd 1
  2160 0000008C ????????            <1> .ImapIndex:	resd 1
  2161 00000090 ????????            <1> .ItableIndex:	resd 1
  2162 00000094 <res 168h>          <1> .Reserved:	resb 508-148 ; 18/07/2021
  2163 000001FC ????????            <1> .Footer:	resd 1
  2164                              <1> 
  2165                              <1> endstruc
  2166                              <1> 
  2167                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
  2168                              <1> ; (file structure has been moved here from 'ux.s' 
  2169                              <1> ;	to overcome NASM's bss addressing bug !!!)
  2170                              <1> ; (('ux.s' bss section addresses are being overlapped
  2171                              <1> ;    when file structure is defined in 'ux.s'))
  2172                              <1> 
  2173                              <1> ; 22/11/2021
  2174                              <1> ; 21/07/2021 - Retro UNIX 386 v2 open file structure revision
  2175                              <1> 
  2176                              <1> struc file	; open files (fsp) structure
  2177 00000000 ????                <1>   .inode:  resw 1  ; inode number of open file (32 bit)
  2178 00000002 ????                <1>   .i32:	   resw 1  ; higher word of inode number (reserved)
  2179 00000004 ??                  <1>   .drive:  resb 1  ; logical drive (disk) number
  2180 00000005 ??                  <1>   .flags:  resb 1  ; open mode and status
  2181 00000006 ??                  <1>   .count:  resb 1  ; number of processes that have file open
  2182                              <1>   ;.rsvd:  resb 1  ; reserved byte (for next versions)
  2183 00000007 ??                  <1>   .mnt:    resb 1  ; mnttab index+1 (0 = not mounted)
  2184 00000008 ????????            <1>   .offset: resd 1  ; file offset/pointer (64 bit) 
  2185 0000000C ????????            <1>   .o64:	   resd 1  ; higher 32 bit of file offset
  2186                              <1>  .size:  ; = 16		
  2187                              <1> endstruc 
  2188                              <1> 
  2189                              <1> nproc 	equ	16  ; number of processes
  2190                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
  2191                              <1> ;nbuf	equ	6   ; number of buffers (04/02/2016)
  2192                              <1> nbuf	equ	16  ; number of buffers ; 11/06/2022		
  2193                              <1> nfiles  equ	50  ; NFILES equ 50 ; 02/01/2022
  2194                              <1> 
  2195                              <1> ; 27/12/2021
  2196                              <1> ;NFILES	  equ   32  ; temporary ! ( 27/12/2021)
  2197                              <1> ; 02/01/2022
  2198                              <1> ;OPENFILES equ	10  ; open files (for user) ; 28/03/2020
  2199                              <1> 
  2200                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
  2201                              <1> ;core	equ 	0  	    ; 19/04/2013	
  2202                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
  2203                              <1> 	; (if total size of argument list and arguments is 128 bytes)
  2204                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
  2205                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
  2206                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
  2207                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
  2208                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
  2209                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
  2210                              <1> 	; '/core' dump file size = 32768 bytes
  2211                              <1>  
  2212                              <1> ; 08/03/2014 
  2213                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)
  2214                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
  2215                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
  2216                              <1> 
  2217                              <1> ; 30/08/2013
  2218                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
  2219                              <1> 
  2220                              <1> ; 05/02/2014
  2221                              <1> ; process status
  2222                              <1> ;SFREE 	equ 0
  2223                              <1> ;SRUN	equ 1
  2224                              <1> ;SWAIT	equ 2
  2225                              <1> ;SZOMB	equ 3
  2226                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
  2227                              <1> 
  2228                              <1> ; 09/03/2015
  2229                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
  2230                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
  2231                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
  2232                              <1> 
  2233                              <1> ; 17/09/2015
  2234                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
  2235                              <1> 
  2236                              <1> ; 12/01/2022 (37,38,39)
  2237                              <1> ; 21/09/2015 (36) 
  2238                              <1> ; 01/07/2015 (35)
  2239                              <1> ; 14/07/2013 (0-34)
  2240                              <1> ; UNIX v1 system calls
  2241                              <1> _rele 	equ 0
  2242                              <1> _exit 	equ 1
  2243                              <1> _fork 	equ 2
  2244                              <1> _read 	equ 3
  2245                              <1> _write	equ 4
  2246                              <1> _open	equ 5
  2247                              <1> _close 	equ 6
  2248                              <1> _wait 	equ 7
  2249                              <1> _creat 	equ 8
  2250                              <1> _link 	equ 9
  2251                              <1> _unlink	equ 10
  2252                              <1> _exec	equ 11
  2253                              <1> _chdir	equ 12
  2254                              <1> _time 	equ 13
  2255                              <1> _mkdir 	equ 14
  2256                              <1> _chmod	equ 15
  2257                              <1> _chown	equ 16
  2258                              <1> _break	equ 17
  2259                              <1> _stat	equ 18
  2260                              <1> _seek	equ 19
  2261                              <1> _tell 	equ 20
  2262                              <1> _mount	equ 21
  2263                              <1> _umount	equ 22
  2264                              <1> _setuid	equ 23
  2265                              <1> _getuid	equ 24
  2266                              <1> _stime	equ 25
  2267                              <1> _quit	equ 26	
  2268                              <1> _intr	equ 27
  2269                              <1> _fstat	equ 28
  2270                              <1> _emt 	equ 29
  2271                              <1> _mdate 	equ 30
  2272                              <1> _stty 	equ 31
  2273                              <1> _gtty	equ 32
  2274                              <1> _ilgins	equ 33
  2275                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
  2276                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
  2277                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
  2278                              <1> ; 12/01/2022 - Retro UNIX 386 v1.2
  2279                              <1> ; Retro UNIX 386 v2 system calls
  2280                              <1> _setgid	equ 37
  2281                              <1> _getgid	equ 38
  2282                              <1> _sysver	equ 39 ; (get) Retro Unix 386 version
  2283                              <1> 
  2284                              <1> %macro sys 1-4
  2285                              <1>     ; 13/04/2015
  2286                              <1>     ; Retro UNIX 386 v1 system call.
  2287                              <1>     mov eax, %1
  2288                              <1>     %if %0 >= 2   
  2289                              <1>         mov ebx, %2
  2290                              <1>         %if %0 >= 3    
  2291                              <1>             mov ecx, %3
  2292                              <1>             %if %0 = 4
  2293                              <1>                mov edx, %4   
  2294                              <1>             %endif
  2295                              <1>         %endif
  2296                              <1>     %endif
  2297                              <1>     int 30h	   
  2298                              <1> %endmacro
  2299                              <1> 
  2300                              <1> ; 13/05/2015 - ERROR CODES
  2301                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
  2302                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
  2303                              <1> ; 14/05/2015
  2304                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
  2305                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
  2306                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
  2307                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error
  2308                              <1> ; 16/05/2015		
  2309                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
  2310                              <1> ; 18/05/2015
  2311                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
  2312                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
  2313                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
  2314                              <1> ; 07/06/2015
  2315                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
  2316                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
  2317                              <1> ; 09/06/2015
  2318                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
  2319                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
  2320                              <1> ; 16/06/2015
  2321                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
  2322                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
  2323                              <1> ; 22/06/2015
  2324                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
  2325                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
  2326                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
  2327                              <1> ; 23/06/2015
  2328                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
  2329                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
  2330                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
  2331                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
  2332                              <1> ; 27/06/2015
  2333                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
  2334                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
  2335                              <1> ; 29/06/2015
  2336                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error
  2337                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error
  2338                              <1> ; 08/02/2022 
  2339                              <1> ; (error numbers from TRDOS 386 v2.0 'sysdefs.s')
  2340                              <1> ; 10/10/2016
  2341                              <1> ERR_INV_FILE_NAME  equ 26 ; 'invalid file name !' error
  2342                              <1> ; 18/05/2016
  2343                              <1> ERR_MISC	   equ 27 ; miscellaneous/other errors
  2344                              <1> ; 15/10/2016
  2345                              <1> ERR_INV_FORMAT	   equ 28 ; 'invalid format !' error
  2346                              <1> ERR_INV_DATA	   equ 29 ; 'invalid data !' error
  2347                              <1> ; 16/10/2016
  2348                              <1> ERR_DISK_WRITE	   equ 30 ; 'disk write protected !'
  2349                              <1> ; 08/02/2022
  2350                              <1> ERR_INV_FS	   equ 28 ;'invalid fs/superblock !' error
  2351                              <1> 
  2352                              <1> ; 12/06/2022
  2353                              <1> ; printer errors
  2354                              <1> ERR_PRN_NOT_RDY	   equ 15 ; 'device not ready !' error
  2355                              <1> ERR_PRN_TIMEOUT	   equ 25 ; 'time out !' error
  2356                              <1> ERR_PRN_PAPER	   equ 31 ; 'out of paper !' error
  2357                              <1> ERR_PRN_IO	   equ 32 ; 'io error !' error
  2358                              <1> ERR_PRN_BUSY	   equ 34 ; 'busy !' error
  2359                              <1> 
  2360                              <1> ; 26/08/2015
  2361                              <1> ; 24/07/2015
  2362                              <1> ; 24/06/2015
  2363                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
  2364                              <1> ; 01/07/2015
  2365                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
  2366                              <1> ;
  2367                              <1> ; 26/11/2021 ('no free blocks on disk !' error)
  2368                              <1> ERR_ALLOC	   equ 33  ; 'disk allocation error !'	
  2369                              <1> ; 22/11/2021
  2370                              <1> ERR_READ_ONLY_FS   equ 30  ; 'read only file system !' error
  2371                              <1> ; 28/11/2021
  2372                              <1> ERR_INV_FILE	   equ 255 ; 'invalid file (inode) !' error
  2373                              <1> ; 04/12/2021
  2374                              <1> ERR_PERM_DENIED	   equ 11  ; 'permission denied !' error
  2375                              <1> ; 11/12/2021
  2376                              <1> ERR_INV_FUNC	   equ 1   ; 'invalid system call !' error
  2377                              <1> ; 10/01/2022
  2378                              <1> ERR_INO_ALLOC	   equ 33  ; 'inode allocation error !'
  2379                              <1> ERR_NOT_REGULAR    equ 255 ; 'not regular file directory !' error
  2380                              <1> 
  2381                              <1> ; 12/01/2022 - Retro UNIX 386 v1.2
  2382                              <1> %define s.time systm+504 ; boot/sysinit time (or current time)
  2383                              <1> 		
  2088                                  %include 'u0.s'      ; 15/03/2015
  2089                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2090                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2091                              <1> ; ****************************************************************************
  2092                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS0.INC
  2093                              <1> ; Last Modification: 17/07/2022
  2094                              <1> ; ----------------------------------------------------------------------------
  2095                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2096                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2097                              <1> ;
  2098                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2099                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2100                              <1> ; <Bell Laboratories (17/3/1972)>
  2101                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2102                              <1> ;
  2103                              <1> ; Retro UNIX 8086 v1 - U0.ASM (28/07/2014) //// UNIX v1 -> u0.s
  2104                              <1> ;
  2105                              <1> ; ****************************************************************************
  2106                              <1> 
  2107                              <1> sys_init:
  2108                              <1> 	; 23/02/2022
  2109                              <1> 	; 08/01/2022
  2110                              <1> 	; 01/01/2022
  2111                              <1> 	; 26/12/2021
  2112                              <1> 	; 27/11/2021
  2113                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 (test) compatibility modification
  2114                              <1> 	; 18/10/2015
  2115                              <1> 	; 28/08/2015
  2116                              <1> 	; 24/08/2015
  2117                              <1> 	; 14/08/2015
  2118                              <1> 	; 24/07/2015 
  2119                              <1> 	; 02/07/2015
  2120                              <1> 	; 01/07/2015
  2121                              <1> 	; 23/06/2015
  2122                              <1> 	; 15/04/2015
  2123                              <1> 	; 13/04/2015
  2124                              <1> 	; 11/03/2015 (Retro UNIX 386 v1 - Beginning)
  2125                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
  2126                              <1> 	;
  2127                              <1> 	;call	ldrv_init ; Logical drive description tables initialization
  2128                              <1> 	;
  2129                              <1> 	;; 14/02/2014
  2130                              <1> 	;; 14/07/2013
  2131                              <1> 	;mov	ax, 41
  2132                              <1> 	;mov	[rootdir], ax
  2133                              <1> 	;mov	[u.cdir], ax
  2134                              <1> 	;and	al, 1 ; 15/04/2015
  2135                              <1> 	
  2136                              <1> 	; 27/11/2021
  2137                              <1> 	; 18/04/2021 - Retro UNIX 386 v2
  2138 000028BA 31C0                <1> 	xor	eax, eax
  2139 000028BC FEC0                <1> 	inc	al	; eax = 1 (root directory inode) ; runix v2 fs
  2140 000028BE A3[266C0000]        <1> 	mov	[rootdir], eax ; = 1 ; 28/10/2021 (32 bit)
  2141 000028C3 A3[486C0000]        <1> 	mov	[u.cdir], eax ; 28/10/2021 (32 bit)
  2142                              <1> 
  2143 000028C8 A2[956C0000]        <1> 	mov	[u.uno], al ; = 1
  2144                              <1> 	;mov	[mpid], ax ; 1 
  2145                              <1> 	;mov	[p.pid], ax ; 1
  2146                              <1> 	; 01/01/2022
  2147 000028CD A2[246C0000]        <1> 	mov	[mpid], al
  2148 000028D2 A2[04680000]        <1> 	mov	[p.pid], al
  2149 000028D7 A2[64680000]        <1> 	mov	[p.stat], al ; SRUN, 05/02/2014
  2150                              <1> 	;
  2151 000028DC B004                <1> 	mov	al, time_count ; 30/08/2013
  2152 000028DE A2[8C6C0000]        <1> 	mov	[u.quant], al ; 14/07/2013
  2153                              <1> 	; 02/07/2015
  2154 000028E3 A1[08670000]        <1> 	mov	eax, [k_page_dir]
  2155 000028E8 A3[A46C0000]        <1> 	mov	[u.pgdir], eax ; reset
  2156                              <1> 	; 18/10/2015
  2157                              <1> 	;sub	eax, eax
  2158                              <1> 	;mov	[u.ppgdir], eax ; 0
  2159                              <1>         ;
  2160                              <1>  	; 23/02/2022
  2161                              <1>  	;call	epoch
  2162                              <1> 	;mov	[s.time], eax ; 13/03/2015
  2163                              <1> 	; 17/07/2013
  2164 000028ED E881060000          <1> 	call 	bf_init ; buffer initialization
  2165                              <1> 	; 23/02/2022
  2166                              <1> 	; (save sysinit time on sb0)
  2167 000028F2 E829030000          <1> 	call	epoch
  2168 000028F7 A3[EC6E0000]        <1> 	mov	[s.time], eax ; 13/03/2015
  2169                              <1> 	; 23/06/2015
  2170 000028FC E8C4FAFFFF          <1> 	call	allocate_page
  2171                              <1> 	;;jc	error
  2172                              <1> 	;jc	panic   ; jc short panic (01/07/2015)
  2173                              <1> 	; 05/12/2021
  2174 00002901 7305                <1> 	jnc	short sysinit_1
  2175 00002903 E989000000          <1> 	jmp	panic
  2176                              <1> sysinit_1:
  2177 00002908 A3[A06C0000]        <1> 	mov	[u.upage], eax ; user structure page	
  2178 0000290D A3[74680000]        <1> 	mov	[p.upage], eax
  2179                              <1> 	;
  2180 00002912 E81FFBFFFF          <1> 	call	clear_page
  2181                              <1> 	;
  2182                              <1> 	; 14/08/2015
  2183 00002917 FA                  <1> 	cli
  2184                              <1> 	; 14/03/2015
  2185                              <1> 	; 17/01/2014
  2186 00002918 E8D0010000          <1> 	call	sp_init ; serial port initialization
  2187                              <1> 	; 14/08/2015
  2188 0000291D FB                  <1> 	sti
  2189                              <1> 	;
  2190                              <1> 	; 30/06/2015
  2191                              <1> 	;mov	esi, kernel_init_ok_msg
  2192                              <1> 	;call 	print_msg
  2193                              <1> 	;
  2194 0000291E 30DB                <1> 	xor	bl, bl ; video page 0
  2195                              <1> vp_clr_nxt:  ; clear video pages (reset cursor positions)
  2196 00002920 E8CE330000          <1> 	call 	vp_clr  ; 17/07/2013
  2197 00002925 FEC3                <1> 	inc	bl
  2198 00002927 80FB08              <1> 	cmp	bl, 8
  2199 0000292A 72F4                <1> 	jb	short vp_clr_nxt
  2200                              <1> 	;
  2201                              <1> 	; 24/07/2015
  2202                              <1> 	;push	KDATA
  2203                              <1>         ;push	esp
  2204                              <1> 	;mov	[tss.esp0], esp
  2205                              <1>         ;mov	word [tss.ss0], KDATA
  2206                              <1> 	;
  2207                              <1> 	; 08/01/2022
  2208                              <1> 	; 24/08/2015
  2209                              <1> 	;; temporary (01/07/2015)
  2210                              <1> 	;mov	byte [u.quant], time_count ; 4 
  2211                              <1> 	;		       ; it is not needed here !
  2212                              <1> 	;;inc	byte [u.kcall] ; 'the caller is kernel' sign
  2213 0000292C FE0D[386C0000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
  2214                              <1> 			      ; 0 = executing a system call
  2215                              <1> 	;;sys 	_msg, kernel_init_ok_msg, 255, 0
  2216                              <1> 	;
  2217                              <1> 	;;; 06/08/2015
  2218                              <1> 	;;;call	getch ; wait for a key stroke
  2219                              <1> 	;;mov 	ecx, 0FFFFFFFh	
  2220                              <1> ;;sys_init_msg_wait:
  2221                              <1> ;;	push 	ecx
  2222                              <1> ;;	mov	al, 1
  2223                              <1> ;;	mov 	ah, [ptty] ; active (current) video page
  2224                              <1> ;;	call	getc_n
  2225                              <1> ;;	pop	ecx
  2226                              <1> ;;	jnz	short sys_init_msg_ok
  2227                              <1> ;;	loop	sys_init_msg_wait
  2228                              <1> 	;
  2229                              <1> ;;sys_init_msg_ok:
  2230                              <1> 	; 28/08/2015 (initial settings for the 1st 'rswap')
  2231 00002932 6A10                <1> 	push	KDATA ; ss
  2232 00002934 54                  <1> 	push	esp
  2233 00002935 9C                  <1> 	pushfd
  2234 00002936 6A08                <1> 	push	KCODE ; cs
  2235 00002938 68[65290000]        <1> 	push	init_exec ; eip
  2236 0000293D 8925[3C6C0000]      <1> 	mov	[u.sp], esp
  2237 00002943 1E                  <1> 	push	ds
  2238 00002944 06                  <1> 	push	es
  2239 00002945 0FA0                <1> 	push	fs
  2240 00002947 0FA8                <1> 	push	gs	
  2241 00002949 60                  <1> 	pushad
  2242 0000294A 8925[406C0000]      <1> 	mov	[u.usp], esp
  2243 00002950 E8051D0000          <1> 	call	wswap ; save current user (u) structure, user registers
  2244                              <1> 		      ; and interrupt return components (for IRET)
  2245 00002955 61                  <1> 	popad
  2246 00002956 6658                <1> 	pop	ax ; gs
  2247 00002958 6658                <1> 	pop	ax ; fs
  2248 0000295A 6658                <1> 	pop	ax ; es
  2249 0000295C 6658                <1> 	pop	ax ; ds	
  2250 0000295E 58                  <1> 	pop	eax ; eip (init_exec)
  2251 0000295F 6658                <1> 	pop	ax ; cs (KCODE)
  2252 00002961 58                  <1> 	pop	eax ; E-FLAGS
  2253 00002962 58                  <1> 	pop	eax ; esp
  2254 00002963 6658                <1> 	pop	ax ; ss (KDATA)
  2255                              <1> 	;
  2256                              <1> 	; 26/12/2021 ([u.ppgdir] is zero already)
  2257                              <1> 	;xor	eax, eax ; 0
  2258                              <1> 	;mov	[u.ppgdir], eax ; reset (to zero) for '/etc/init'
  2259                              <1> 	;
  2260                              <1> 	; 02/07/2015
  2261                              <1> 	; [u.pgdir ] = [k_page_dir]
  2262                              <1> 	; [u.ppgdir] = 0 (page dir of the parent process)
  2263                              <1> 	;     (The caller is os kernel sign for 'sysexec')
  2264                              <1> init_exec:
  2265                              <1> 	; 13/03/2013
  2266                              <1> 	; 24/07/2013
  2267 00002965 BB[87290000]        <1> 	mov	ebx, init_file
  2268 0000296A B9[7F290000]        <1> 	mov	ecx, init_argp
  2269                              <1> 	; EBX contains 'etc/init' asciiz file name address  
  2270                              <1> 	; ECX contains address of argument list pointer
  2271                              <1> 	;
  2272                              <1> 	;dec 	byte [sysflg] ; FFh = ready for system call
  2273                              <1> 			      ; 0 = executing a system call
  2274                              <1> 	sys	_exec  ; execute file
  2285                              <2> 
  2286                              <2> 
  2287 0000296F B80B000000          <2>  mov eax, %1
  2288                              <2>  %if %0 >= 2
  2289                              <2>  mov ebx, %2
  2290                              <2>  %if %0 >= 3
  2291                              <2>  mov ecx, %3
  2292                              <2>  %if %0 = 4
  2293                              <2>  mov edx, %4
  2294                              <2>  %endif
  2295                              <2>  %endif
  2296                              <2>  %endif
  2297 00002974 CD30                <2>  int 30h
  2275 00002976 7319                <1> 	jnc	short panic
  2276                              <1> 	;
  2277 00002978 BE[20640000]        <1> 	mov	esi, etc_init_err_msg
  2278                              <1> 	; 22/11/2021
  2279                              <1> 	;call 	print_msg
  2280 0000297D EB17                <1> 	jmp	short key_to_reboot
  2281                              <1> 
  2282                              <1> ;align 4
  2283                              <1> init_argp:
  2284 0000297F [87290000]00000000  <1> 	dd 	init_file, 0  ; 23/06/2015 (dw -> dd)
  2285                              <1> init_file:
  2286                              <1> 	; 24/08/2015
  2287 00002987 2F6574632F696E6974- <1> 	db 	'/etc/init', 0
  2287 00002990 00                  <1>
  2288                              <1> panic:
  2289                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
  2290                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
  2291 00002991 BE[05640000]        <1> 	mov 	esi, panic_msg
  2292                              <1> key_to_reboot: ; 22/11/2021
  2293 00002996 E819000000          <1> 	call 	print_msg
  2294                              <1> ;key_to_reboot:
  2295                              <1> 	; 15/11/2015
  2296 0000299B E8A1310000          <1> 	call 	getch 
  2297                              <1> 		; wait for a character from the current tty
  2298                              <1> 	;
  2299 000029A0 B00A                <1> 	mov	al, 0Ah
  2300 000029A2 8A1D[36670000]      <1> 	mov	bl, [ptty] ; [active_page]
  2301 000029A8 B407                <1> 	mov	ah, 07h ; Black background, 
  2302                              <1> 			; light gray forecolor
  2303 000029AA E8EBE8FFFF          <1> 	call 	write_tty
  2304 000029AF E98AE5FFFF          <1> 	jmp	cpu_reset 
  2305                              <1> 
  2306                              <1> print_msg:
  2307                              <1> 	; 01/07/2015
  2308                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
  2309                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
  2310                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  2311                              <1> 	;
  2312                              <1> 	;
  2313 000029B4 AC                  <1> 	lodsb
  2314                              <1> pmsg1:
  2315 000029B5 56                  <1> 	push 	esi
  2316 000029B6 0FB61D[36670000]    <1> 	movzx	ebx, byte [ptty]
  2317 000029BD B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
  2318 000029BF E8D6E8FFFF          <1> 	call 	write_tty
  2319 000029C4 5E                  <1> 	pop	esi
  2320 000029C5 AC                  <1> 	lodsb
  2321 000029C6 20C0                <1> 	and 	al, al
  2322 000029C8 75EB                <1> 	jnz 	short pmsg1
  2323 000029CA C3                  <1> 	retn
  2324                              <1> 	
  2325                              <1> ctrlbrk:
  2326                              <1> 	; 06/02/2022
  2327                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  2328                              <1> 	; 12/11/2015
  2329                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
  2330                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
  2331                              <1> 	;
  2332                              <1> 	; INT 1Bh (control+break) handler		
  2333                              <1> 	;
  2334                              <1>       	; Retro Unix 8086 v1 feature only!
  2335                              <1>       	;
  2336 000029CB 66833D[906C0000]00  <1> 	cmp 	word [u.intr], 0
  2337 000029D3 764B                <1> 	jna 	short cbrk4
  2338                              <1> cbrk0:
  2339                              <1> 	; 12/11/2015
  2340                              <1> 	; 06/12/2013
  2341 000029D5 66833D[926C0000]00  <1> 	cmp 	word [u.quit], 0
  2342 000029DD 7441                <1> 	jz	short cbrk4
  2343                              <1> 	;
  2344                              <1> 	; 20/09/2013	
  2345                              <1> 	;push 	ax
  2346                              <1> 	; 04/12/2021
  2347 000029DF 50                  <1> 	push	eax
  2348                              <1> 
  2349                              <1> 	; 06/02/2022
  2350                              <1> 	; (repetitive ctrl+brk check) 
  2351 000029E0 66A1[926C0000]      <1> 	mov	ax, [u.quit]
  2352 000029E6 6640                <1> 	inc	ax ; 0FFFFh -> 0
  2353 000029E8 7435                <1> 	jz	short cbrk3
  2354                              <1> 
  2355                              <1> 	; 06/12/2013
  2356 000029EA A0[36670000]        <1> 	mov	al, [ptty]
  2357                              <1> 	;
  2358                              <1> 	; 12/11/2015
  2359                              <1> 	;
  2360                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
  2361                              <1> 	; or ctrl+break from console (pseudo) tty
  2362                              <1> 	; (!redirection!)
  2363                              <1> 	;
  2364 000029EF 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
  2365 000029F1 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
  2366                              <1> 	;	
  2367                              <1> 	; Serial port interrupt handler sets [ptty]
  2368                              <1> 	; to the port's tty number (as temporary).
  2369                              <1> 	;
  2370                              <1> 	; If active process is using a stdin or 
  2371                              <1> 	; stdout redirection (by the shell),
  2372                              <1>         ; console tty keyboard must be available
  2373                              <1> 	; to terminate running process,
  2374                              <1> 	; in order to prevent a deadlock. 
  2375                              <1> 	;
  2376 000029F3 52                  <1> 	push	edx
  2377 000029F4 0FB615[956C0000]    <1> 	movzx	edx, byte [u.uno]
  2378 000029FB 3A82[43680000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
  2379 00002A01 5A                  <1> 	pop	edx
  2380 00002A02 7412                <1> 	je	short cbrk2
  2381                              <1> cbrk1:
  2382 00002A04 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
  2383                              <1> 	; 06/12/2013
  2384 00002A06 3A05[7A6C0000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
  2385 00002A0C 7408                <1> 	je	short cbrk2	
  2386 00002A0E 3A05[7B6C0000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
  2387 00002A14 7509                <1> 	jne	short cbrk3	
  2388                              <1> cbrk2:
  2389                              <1> 	;; 06/12/2013
  2390                              <1> 	;mov	ax, [u.quit]
  2391                              <1> 	;and	ax, ax
  2392                              <1> 	;jz	short cbrk3
  2393                              <1> 	;
  2394                              <1> 	;xor	ax, ax ; 0
  2395                              <1> 	;dec	ax
  2396                              <1> 	; 04/12/2021
  2397 00002A16 31C0                <1> 	xor	eax, eax ; 0
  2398 00002A18 48                  <1> 	dec	eax ; 0FFFFFFFFh
  2399                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
  2400 00002A19 66A3[926C0000]      <1> 	mov	[u.quit], ax
  2401                              <1> cbrk3:
  2402                              <1> 	;pop	ax
  2403                              <1> 	; 04/12/2021
  2404 00002A1F 58                  <1> 	pop	eax
  2405                              <1> cbrk4:
  2406 00002A20 C3                  <1> 	retn
  2407                              <1> 
  2408                              <1> com2_int:
  2409                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
  2410                              <1> 	; 07/11/2015 
  2411                              <1> 	; 24/10/2015
  2412                              <1> 	; 23/10/2015
  2413                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
  2414                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
  2415                              <1> 	; < serial port 2 interrupt handler >
  2416                              <1> 	;
  2417 00002A21 890424              <1> 	mov 	[esp], eax ; overwrite call return address
  2418                              <1> 	;;push	eax
  2419                              <1> 	; 08/01/2022
  2420 00002A24 29C0                <1> 	sub	eax, eax
  2421 00002A26 B009                <1> 	mov	al, 9
  2422                              <1> 	;mov	ax, 9
  2423 00002A28 EB07                <1> 	jmp	short comm_int
  2424                              <1> com1_int:
  2425                              <1> 	; 07/11/2015
  2426                              <1> 	; 24/10/2015
  2427 00002A2A 890424              <1> 	mov 	[esp], eax ; overwrite call return address
  2428                              <1> 	; 23/10/2015
  2429                              <1> 	;push	eax
  2430                              <1> 	; 08/01/2022
  2431 00002A2D 29C0                <1> 	sub	eax, eax
  2432 00002A2F B008                <1> 	mov	al, 8
  2433                              <1> 	;mov	ax, 8
  2434                              <1> comm_int:
  2435                              <1> 	; 08/01/2022
  2436                              <1> 	; 20/11/2015
  2437                              <1> 	; 18/11/2015
  2438                              <1> 	; 17/11/2015
  2439                              <1> 	; 16/11/2015
  2440                              <1> 	; 09/11/2015
  2441                              <1> 	; 08/11/2015
  2442                              <1> 	; 07/11/2015
  2443                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
  2444                              <1> 	; 01/11/2015
  2445                              <1> 	; 26/10/2015
  2446                              <1> 	; 23/10/2015
  2447 00002A31 53                  <1> 	push	ebx
  2448 00002A32 56                  <1> 	push	esi
  2449 00002A33 57                  <1> 	push	edi
  2450 00002A34 1E                  <1> 	push 	ds
  2451 00002A35 06                  <1> 	push 	es
  2452                              <1> 	; 18/11/2015
  2453 00002A36 0F20DB              <1> 	mov	ebx, cr3
  2454 00002A39 53                  <1> 	push	ebx ; ****
  2455                              <1> 	;
  2456 00002A3A 51                  <1> 	push	ecx ; ***
  2457 00002A3B 52                  <1> 	push	edx ; **
  2458                              <1> 	;
  2459 00002A3C BB10000000          <1> 	mov	ebx, KDATA
  2460 00002A41 8EDB                <1> 	mov	ds, bx
  2461 00002A43 8EC3                <1> 	mov	es, bx
  2462                              <1> 	;
  2463 00002A45 8B0D[08670000]      <1> 	mov	ecx, [k_page_dir]
  2464 00002A4B 0F22D9              <1> 	mov	cr3, ecx
  2465                              <1> 	; 20/11/2015
  2466                              <1> 	; Interrupt identification register
  2467 00002A4E 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
  2468                              <1> 	;
  2469 00002A52 3C08                <1> 	cmp 	al, 8 
  2470 00002A54 7702                <1> 	ja 	short com_i0
  2471                              <1> 	;
  2472                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.1)
  2473                              <1> 	; 20/11/2015
  2474                              <1> 	; 17/11/2015
  2475                              <1> 	; 16/11/2015
  2476                              <1> 	; 15/11/2015
  2477                              <1> 	; 24/10/2015
  2478                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
  2479                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
  2480                              <1> 	; < serial port 1 interrupt handler >
  2481                              <1> 	;
  2482 00002A56 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
  2483                              <1> com_i0:
  2484                              <1> 	;push	eax ; *
  2485                              <1> 	; 07/11/2015
  2486 00002A58 A2[76670000]        <1> 	mov 	byte [ccomport], al
  2487                              <1> 	; 09/11/2015
  2488                              <1> 	;movzx	ebx, ax ; 8 or 9
  2489                              <1> 	; 08/01/2022
  2490 00002A5D 89C3                <1> 	mov	ebx, eax ; 8 or 9
  2491                              <1> 	; 17/11/2015
  2492                              <1>  	; reset request for response status
  2493 00002A5F 88A3[6C670000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
  2494                              <1> 	;
  2495                              <1> 	; 20/11/2015
  2496 00002A65 EC                  <1> 	in	al, dx		; read interrupt id. register
  2497 00002A66 EB00                <1> 	JMP	$+2	   	; I/O DELAY
  2498 00002A68 2404                <1> 	and	al, 4		; received data available?	
  2499 00002A6A 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
  2500                              <1> 	;
  2501                              <1> 	; 20/11/2015
  2502 00002A6C 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
  2503 00002A6F EC                  <1> 	in	al, dx     	; read character
  2504                              <1> 	;JMP	$+2	   	; I/O DELAY
  2505                              <1> 	; 08/11/2015
  2506                              <1> 	; 07/11/2015
  2507 00002A70 89DE                <1> 	mov	esi, ebx 
  2508 00002A72 89DF                <1> 	mov	edi, ebx
  2509 00002A74 81C6[70670000]      <1> 	add 	esi, rchar - 8 ; points to last received char
  2510 00002A7A 81C7[72670000]      <1> 	add	edi, schar - 8 ; points to last sent char
  2511 00002A80 8806                <1> 	mov	[esi], al ; received char (current char)
  2512                              <1> 	; query
  2513 00002A82 20C0                <1> 	and	al, al
  2514 00002A84 7527                <1> 	jnz	short com_i2
  2515                              <1>    	; response
  2516                              <1> 	; 17/11/2015
  2517                              <1> 	; set request for response status
  2518 00002A86 FE83[6C670000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
  2519                              <1> 	;
  2520 00002A8C 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
  2521 00002A90 EC                  <1> 	in	al, dx	   	; read line status register 
  2522 00002A91 EB00                <1> 	JMP	$+2	   	; I/O DELAY
  2523 00002A93 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
  2524 00002A95 7445                <1> 	jz	short com_eoi 	; no
  2525 00002A97 B0FF                <1> 	mov 	al, 0FFh   	; response			
  2526 00002A99 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
  2527 00002A9D EE                  <1> 	out	dx, al	   	; send on serial port
  2528                              <1> 	; 17/11/2015
  2529 00002A9E 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
  2530 00002AA1 7502                <1> 	jne 	short com_i1    ; no
  2531 00002AA3 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
  2532                              <1> com_i1:
  2533                              <1> 	; 17/11/2015
  2534                              <1> 	; reset request for response status (again)
  2535 00002AA5 FE8B[6C670000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
  2536 00002AAB EB2F                <1> 	jmp	short com_eoi
  2537                              <1> com_i2:	
  2538                              <1> 	; 08/11/2015
  2539 00002AAD 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
  2540 00002AAF 7417                <1> 	je	short com_i3	; (check for response signal)
  2541                              <1> 	; 07/11/2015
  2542 00002AB1 3C04                <1> 	cmp	al, 04h	; EOT
  2543 00002AB3 751C                <1> 	jne	short com_i4	
  2544                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
  2545                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
  2546                              <1> 	; 08/11/2015
  2547                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
  2548 00002AB5 861D[36670000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
  2549 00002ABB E80BFFFFFF          <1> 	call 	ctrlbrk
  2550 00002AC0 861D[36670000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
  2551                              <1> 	;mov	al, 04h ; EOT
  2552                              <1> 	; 08/11/2015
  2553 00002AC6 EB09                <1> 	jmp	short com_i4	
  2554                              <1> com_i3:
  2555                              <1> 	; 08/11/2015
  2556                              <1> 	; If 0FFh has been received just after a query
  2557                              <1> 	; (schar, ZERO), it is a response signal.
  2558                              <1> 	; 17/11/2015
  2559 00002AC8 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
  2560 00002ACB 7704                <1> 	ja	short com_i4 ; no
  2561                              <1> 	; reset query status (schar)
  2562 00002ACD 8807                <1> 	mov	[edi], al ; 0FFh
  2563 00002ACF FEC0                <1> 	inc	al ; 0
  2564                              <1> com_i4:
  2565                              <1> 	; 27/07/2014
  2566                              <1> 	; 09/07/2014
  2567 00002AD1 D0E3                <1> 	shl	bl, 1	
  2568 00002AD3 81C3[38670000]      <1> 	add	ebx, ttychr
  2569                              <1> 	; 23/07/2014 (always overwrite)
  2570                              <1> 	;;cmp	word [ebx], 0
  2571                              <1> 	;;ja	short com_eoi
  2572                              <1> 	;
  2573 00002AD9 668903              <1> 	mov	[ebx], ax   ; Save ascii code
  2574                              <1> 			    ; scan code = 0
  2575                              <1> com_eoi:
  2576                              <1> 	;mov	al, 20h
  2577                              <1> 	;out	20h, al	   ; end of interrupt
  2578                              <1> 	;
  2579                              <1> 	; 07/11/2015
  2580                              <1>       	;pop	eax ; *
  2581 00002ADC A0[76670000]        <1> 	mov	al, byte [ccomport] ; current COM port
  2582                              <1> 	; al = tty number (8 or 9)
  2583 00002AE1 E84E1C0000          <1>         call	wakeup
  2584                              <1> com_iret:
  2585                              <1> 	; 23/10/2015
  2586 00002AE6 5A                  <1> 	pop	edx ; **
  2587 00002AE7 59                  <1> 	pop	ecx ; ***
  2588                              <1> 	; 18/11/2015
  2589                              <1> 	;pop	eax ; ****
  2590                              <1> 	;mov	cr3, eax
  2591                              <1> 	;jmp	iiret
  2592 00002AE8 E995DEFFFF          <1> 	jmp	iiretp
  2593                              <1> 
  2594                              <1> ;iiretp: ; 01/09/2015
  2595                              <1> ;	; 28/08/2015
  2596                              <1> ;	pop	eax ; (*) page directory
  2597                              <1> ;	mov	cr3, eax
  2598                              <1> ;iiret:
  2599                              <1> ;	; 22/08/2014
  2600                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2601                              <1> ;	out	20h, al	; 8259 PORT
  2602                              <1> ;	;
  2603                              <1> ;	pop	es
  2604                              <1> ;	pop	ds
  2605                              <1> ;	pop	edi
  2606                              <1> ;	pop	esi
  2607                              <1> ;	pop	ebx ; 29/08/2014
  2608                              <1> ;	pop 	eax
  2609                              <1> ;	iretd
  2610                              <1> 
  2611                              <1> sp_init:
  2612                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
  2613                              <1> 	; 07/11/2015
  2614                              <1> 	; 29/10/2015
  2615                              <1> 	; 26/10/2015
  2616                              <1> 	; 23/10/2015
  2617                              <1> 	; 29/06/2015
  2618                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
  2619                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
  2620                              <1> 	; Initialization of Serial Port Communication Parameters
  2621                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
  2622                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
  2623                              <1> 	;
  2624                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
  2625                              <1> 	;
  2626                              <1> 	; INPUT:  (29/06/2015)
  2627                              <1> 	;	AL = 0 for COM1
  2628                              <1> 	;	     1 for COM2
  2629                              <1> 	;	AH = Communication parameters	
  2630                              <1> 	;
  2631                              <1> 	;  (*) Communication parameters (except BAUD RATE):
  2632                              <1> 	;	Bit	4	3	2	1	0
  2633                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
  2634                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
  2635                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
  2636                              <1> 	;		11 = even
  2637                              <1> 	;  Baud rate setting bits: (29/06/2015)
  2638                              <1> 	;		Retro UNIX 386 v1 feature only !
  2639                              <1> 	;	Bit	7    6    5  | Baud rate
  2640                              <1> 	;		------------------------
  2641                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
  2642                              <1> 	;		0    0    1  | 9600 (12)
  2643                              <1> 	;		0    1    0  | 19200 (6) 
  2644                              <1> 	;		0    1	  1  | 38400 (3) 
  2645                              <1> 	;		1    0	  0  | 14400 (8)
  2646                              <1> 	;		1    0	  1  | 28800 (4)
  2647                              <1> 	;		1    1    0  | 57600 (2)
  2648                              <1> 	;		1    1    1  | 115200 (1) 	
  2649                              <1> 	
  2650                              <1> 	; References:	
  2651                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
  2652                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
  2653                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
  2654                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
  2655                              <1> 	;
  2656                              <1> 	; Set communication parameters for COM1 (= 03h)	
  2657                              <1> 	;
  2658 00002AED BB[72670000]        <1> 	mov	ebx, com1p		; COM1 parameters  
  2659 00002AF2 66BAF803            <1> 	mov	dx, 3F8h		; COM1
  2660                              <1> 	; 29/10/2015
  2661 00002AF6 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
  2662 00002AFA E84F000000          <1> 	call	sp_i3	; call A4	
  2663 00002AFF A880                <1> 	test	al, 80h
  2664 00002B01 740E                <1> 	jz	short sp_i0 ; OK..
  2665                              <1> 		; Error !
  2666                              <1> 	;mov	dx, 3F8h
  2667 00002B03 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
  2668                              <1> 	;mov	cx, 30Eh  ; divisor = 12 (9600 baud)
  2669                              <1> 	; 08/01/2022
  2670 00002B06 B10E                <1> 	mov	cl, 0Eh ; cx = 30Eh, divisor = 12 (9600 baud)
  2671 00002B08 E841000000          <1> 	call	sp_i3	; call A4	
  2672 00002B0D A880                <1> 	test	al, 80h
  2673 00002B0F 7508                <1> 	jnz	short sp_i1
  2674                              <1> sp_i0:
  2675                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
  2676                              <1>         ; (INT 14h initialization code disables interrupts.)
  2677                              <1> 	;
  2678 00002B11 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
  2679 00002B14 E8BF000000          <1> 	call	sp_i5 ; 29/06/2015
  2680                              <1> sp_i1:
  2681 00002B19 43                  <1> 	inc	ebx
  2682 00002B1A 66BAF802            <1> 	mov	dx, 2F8h		; COM2
  2683                              <1> 	; 29/10/2015
  2684                              <1> 	;mov	cx, 301h  ; divisor = 1 (115200 baud)
  2685                              <1> 	; 08/01/2022
  2686 00002B1E B101                <1> 	mov	cl, 01h ; cx = 301h, divisor = 1 (115200 baud)
  2687 00002B20 E829000000          <1> 	call	sp_i3	; call A4	
  2688 00002B25 A880                <1> 	test	al, 80h
  2689 00002B27 740E                <1> 	jz	short sp_i2 ; OK..
  2690                              <1> 		; Error !
  2691                              <1> 	;mov	dx, 2F8h
  2692 00002B29 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
  2693                              <1> 	;mov	cx, 30Eh  ; divisor = 12 (9600 baud)
  2694                              <1> 	; 08/01/2022
  2695 00002B2C B10E                <1> 	mov	cl, 0Eh ; cx = 30Eh, divisor = 12 (9600 baud)
  2696 00002B2E E81B000000          <1> 	call	sp_i3	; call A4	
  2697 00002B33 A880                <1> 	test	al, 80h
  2698 00002B35 7516                <1> 	jnz	short sp_i7
  2699                              <1> sp_i2:
  2700 00002B37 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
  2701                              <1> sp_i6:
  2702                              <1> 	;; COM2 - enabling IRQ 3
  2703                              <1> 	; 08/01/2022
  2704 00002B3A B4F7                <1> 	mov	ah, 0F7h ; enable IRQ 3 (COM2)
  2705                              <1> 	; 07/11/2015
  2706                              <1> 	; 26/10/2015
  2707                              <1> 	;pushf
  2708                              <1> 	;cli
  2709                              <1> 	;;
  2710                              <1> 	;;mov	dx, 2FCh   		; modem control register
  2711                              <1> 	;mov	dl, 0FCh ; 08/01/2022
  2712                              <1> 	;in	al, dx 	   		; read register
  2713                              <1> 	;JMP	$+2	   		; I/O DELAY
  2714                              <1> 	;or	al, 8      		; enable bit 3 (OUT2)
  2715                              <1> 	;out	dx, al     		; write back to register
  2716                              <1> 	;JMP	$+2	   		; I/O DELAY
  2717                              <1> 	;;mov	dx, 2F9h   		; interrupt enable register
  2718                              <1> 	;mov	dl, 0F9h ; 08/01/2022
  2719                              <1> 	;in	al, dx     		; read register
  2720                              <1> 	;JMP	$+2	   		; I/O DELAY
  2721                              <1> 	;;or	al, 1      		; receiver data interrupt enable and
  2722                              <1> 	;or	al, 3	   		; transmitter empty interrupt enable
  2723                              <1> 	;out	dx, al 	   		; write back to register
  2724                              <1> 	;JMP	$+2        		; I/O DELAY
  2725                              <1> 	;in	al, 21h    		; read interrupt mask register
  2726                              <1> 	;JMP	$+2	   		; I/O DELAY
  2727                              <1> 	;and	al, 0F7h   		; enable IRQ 3 (COM2)
  2728                              <1> 	;out	21h, al    		; write back to register
  2729                              <1> 	;
  2730                              <1> 	; 08/01/2022
  2731 00002B3C 9C                  <1> 	pushf
  2732 00002B3D E8AA000000          <1> 	call	sp_i8
  2733                              <1> 	; 23/10/2015
  2734 00002B42 B8[212A0000]        <1> 	mov 	eax, com2_int
  2735 00002B47 A3[3E300000]        <1> 	mov	[com2_irq3], eax
  2736                              <1> 	; 26/10/2015
  2737 00002B4C 9D                  <1> 	popf	
  2738                              <1> sp_i7:
  2739 00002B4D C3                  <1> 	retn
  2740                              <1> 
  2741                              <1> sp_i3:
  2742                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
  2743                              <1> 	; 28/10/2015
  2744 00002B4E FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
  2745 00002B50 B000                <1> 	mov	al, 0
  2746 00002B52 EE                  <1> 	out	dx, al			; disable serial port interrupt
  2747 00002B53 EB00                <1> 	JMP	$+2			; I/O DELAY
  2748 00002B55 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
  2749 00002B58 B080                <1> 	mov	al, 80h			
  2750 00002B5A EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
  2751                              <1> 	;-----	SET BAUD RATE DIVISOR
  2752                              <1> 	; 26/10/2015
  2753 00002B5B 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
  2754                              <1> 					; of the divisor value
  2755 00002B5E 88C8                <1> 	mov	al, cl	; 1
  2756 00002B60 EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
  2757                              <1> 					; 2 = 57600 baud
  2758                              <1> 					; 3 = 38400 baud
  2759                              <1> 					; 6 = 19200 baud
  2760                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
  2761 00002B61 EB00                <1> 	JMP	$+2			; I/O DELAY
  2762 00002B63 28C0                <1> 	sub	al, al
  2763 00002B65 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
  2764                              <1> 					; of the divisor value
  2765 00002B67 EE                  <1> 	out	dx, al ; 0
  2766 00002B68 EB00                <1> 	JMP	$+2			; I/O DELAY
  2767                              <1> 	;	
  2768 00002B6A 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
  2769                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
  2770 00002B6C 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
  2771 00002B6F EE                  <1> 	out	dx, al			
  2772 00002B70 EB00                <1> 	JMP	$+2			; I/O DELAY
  2773                              <1> 	; 29/10/2015
  2774 00002B72 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
  2775 00002B74 30C0                <1> 	xor	al, al			; 0
  2776 00002B76 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
  2777 00002B77 EB00                <1> 	JMP	$+2	
  2778                              <1> sp_i4:
  2779                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
  2780                              <1> 	; 29/06/2015 (line status after modem status)
  2781 00002B79 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
  2782                              <1> sp_i4s:
  2783 00002B7C EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
  2784 00002B7D EB00                <1> 	JMP	$+2			; I/O DELAY
  2785 00002B7F 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
  2786 00002B81 FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
  2787                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
  2788 00002B83 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
  2789                              <1> 	; AL = Line status, AH = Modem status
  2790 00002B84 C3                  <1> 	retn
  2791                              <1> 
  2792                              <1> sp_status:
  2793                              <1> 	; 29/06/2015
  2794                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
  2795                              <1> 	; Get serial port status
  2796 00002B85 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
  2797 00002B89 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
  2798                              <1> 					; dx = 2FEh for COM2
  2799 00002B8B EBEF                <1> 	jmp	short sp_i4s
  2800                              <1> 
  2801                              <1> sp_setp: ; Set serial port communication parameters
  2802                              <1> 	; 08/01/2022
  2803                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
  2804                              <1> 	; 07/11/2015
  2805                              <1> 	; 29/10/2015
  2806                              <1> 	; 29/06/2015
  2807                              <1> 	; Retro UNIX 386 v1 feature only !	
  2808                              <1> 	;
  2809                              <1> 	; INPUT:
  2810                              <1> 	;	AL = 0 for COM1
  2811                              <1> 	;	     1 for COM2
  2812                              <1> 	;	AH = Communication parameters (*)
  2813                              <1> 	; OUTPUT:
  2814                              <1> 	;	CL = Line status
  2815                              <1> 	;	CH = Modem status
  2816                              <1> 	;   If cf = 1 -> Error code in [u.error]
  2817                              <1> 	;		 'invalid parameter !' 
  2818                              <1> 	;		 	 or
  2819                              <1> 	;		 'device not ready !' error
  2820                              <1> 	;	
  2821                              <1> 	;  (*) Communication parameters (except BAUD RATE):
  2822                              <1> 	;	Bit	4	3	2	1	0
  2823                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
  2824                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
  2825                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
  2826                              <1> 	;		11 = even
  2827                              <1> 	;  Baud rate setting bits: (29/06/2015)
  2828                              <1> 	;		Retro UNIX 386 v1 feature only !
  2829                              <1> 	;	Bit	7    6    5  | Baud rate
  2830                              <1> 	;		------------------------
  2831                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
  2832                              <1> 	;		0    0    1  | 9600 (12)
  2833                              <1> 	;		0    1    0  | 19200 (6) 
  2834                              <1> 	;		0    1	  1  | 38400 (3) 
  2835                              <1> 	;		1    0	  0  | 14400 (8)
  2836                              <1> 	;		1    0	  1  | 28800 (4)
  2837                              <1> 	;		1    1    0  | 57600 (2)
  2838                              <1> 	;		1    1    1  | 115200 (1) 
  2839                              <1> 	;
  2840                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
  2841                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
  2842                              <1> 	;
  2843                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
  2844                              <1> 	;
  2845 00002B8D 66BAF803            <1> 	mov	dx, 3F8h
  2846 00002B91 BB[72670000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
  2847 00002B96 3C01                <1> 	cmp	al, 1
  2848 00002B98 7770                <1> 	ja 	short sp_invp_err
  2849 00002B9A 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
  2850 00002B9C FECE                <1> 	dec	dh ; 2F8h
  2851 00002B9E 43                  <1> 	inc	ebx ; COM2 control byte offset
  2852                              <1> sp_setp1:
  2853                              <1> 	; 29/10/2015
  2854 00002B9F 8823                <1> 	mov	[ebx], ah
  2855 00002BA1 0FB6CC              <1> 	movzx 	ecx, ah
  2856 00002BA4 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
  2857 00002BA7 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
  2858 00002BAA 8A81[192C0000]      <1> 	mov	al, [ecx+b_div_tbl]
  2859 00002BB0 6689C1              <1> 	mov	cx, ax
  2860 00002BB3 E896FFFFFF          <1> 	call	sp_i3
  2861 00002BB8 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
  2862 00002BBB A880                <1> 	test	al, 80h
  2863 00002BBD 740F                <1> 	jz	short sp_setp2
  2864 00002BBF C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
  2865                              <1> stp_dnr_err:
  2866 00002BC2 C705[B86C0000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
  2866 00002BCA 0000                <1>
  2867                              <1> 	; CL = Line status, CH = Modem status
  2868 00002BCC F9                  <1> 	stc
  2869 00002BCD C3                  <1> 	retn
  2870                              <1> sp_setp2:
  2871 00002BCE 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
  2872                              <1>         ;jna	sp_i6
  2873                              <1> 		      ; COM1 (3F?h)
  2874                              <1> 	; 24/12/2021
  2875 00002BD1 7705                <1> 	ja	short sp_i5
  2876 00002BD3 E962FFFFFF          <1> 	jmp	sp_i6
  2877                              <1> sp_i5: 
  2878                              <1> 	; 08/01/2022
  2879 00002BD8 B4EF                <1> 	mov	ah, 0EFh ; enable IRQ 4 (COM1)
  2880                              <1> 	; 07/11/2015
  2881                              <1> 	; 26/10/2015
  2882                              <1> 	; 29/06/2015
  2883                              <1> 	;
  2884                              <1> 	;; COM1 - enabling IRQ 4
  2885                              <1> 	;pushf
  2886                              <1> 	;cli
  2887                              <1> 	;;mov	dx, 3FCh   		; modem control register
  2888                              <1> 	;mov	dl, 0FCh ; 08/01/2022
  2889                              <1> 	;in	al, dx 	   		; read register
  2890                              <1> 	;JMP	$+2			; I/O DELAY
  2891                              <1> 	;or	al, 8      		; enable bit 3 (OUT2)
  2892                              <1> 	;out	dx, al     		; write back to register
  2893                              <1> 	;JMP	$+2			; I/O DELAY
  2894                              <1> 	;;mov	dx, 3F9h   		; interrupt enable register
  2895                              <1> 	;mov	dl, 0F9h ; 08/01/2022
  2896                              <1> 	;in	al, dx     		; read register
  2897                              <1> 	;JMP	$+2			; I/O DELAY
  2898                              <1> 	;;or	al, 1      		; receiver data interrupt enable and
  2899                              <1> 	;or	al, 3	   		; transmitter empty interrupt enable
  2900                              <1> 	;out	dx, al 	   		; write back to register
  2901                              <1> 	;JMP	$+2        		; I/O DELAY
  2902                              <1> 	;in	al, 21h    		; read interrupt mask register
  2903                              <1> 	;JMP	$+2			; I/O DELAY
  2904                              <1> 	;and	al, 0EFh   		; enable IRQ 4 (COM1)
  2905                              <1> 	;out	21h, al    		; write back to register
  2906                              <1> 	;
  2907                              <1> 	; 08/01/2022
  2908 00002BDA 9C                  <1> 	pushf
  2909 00002BDB E80C000000          <1> 	call	sp_i8
  2910                              <1> 	; 23/10/2015
  2911 00002BE0 B8[2A2A0000]        <1> 	mov 	eax, com1_int
  2912 00002BE5 A3[3A300000]        <1> 	mov	[com1_irq4], eax
  2913                              <1> 	; 26/10/2015
  2914 00002BEA 9D                  <1> 	popf
  2915 00002BEB C3                  <1> 	retn
  2916                              <1> 
  2917                              <1> sp_i8:
  2918                              <1> 	; 08/01/2022
  2919                              <1> 	;pushf
  2920 00002BEC FA                  <1> 	cli
  2921                              <1> 	;
  2922                              <1> 	;mov	dx, 2FCh  ; 3FCh	; modem control register
  2923 00002BED B2FC                <1> 	mov	dl, 0FCh
  2924 00002BEF EC                  <1> 	in	al, dx 	   		; read register
  2925 00002BF0 EB00                <1> 	JMP	$+2	   		; I/O DELAY
  2926 00002BF2 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
  2927 00002BF4 EE                  <1> 	out	dx, al     		; write back to register
  2928 00002BF5 EB00                <1> 	JMP	$+2	   		; I/O DELAY
  2929                              <1> 	;mov	dx, 2F9h  ; 3F9h 	; interrupt enable register
  2930 00002BF7 B2F9                <1> 	mov	dl, 0F9h
  2931 00002BF9 EC                  <1> 	in	al, dx     		; read register
  2932 00002BFA EB00                <1> 	JMP	$+2	   		; I/O DELAY
  2933                              <1> 	;or	al, 1      		; receiver data interrupt enable and
  2934 00002BFC 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
  2935 00002BFE EE                  <1> 	out	dx, al 	   		; write back to register
  2936 00002BFF EB00                <1> 	JMP	$+2        		; I/O DELAY
  2937 00002C01 E421                <1> 	in	al, 21h    		; read interrupt mask register
  2938 00002C03 EB00                <1> 	JMP	$+2	   		; I/O DELAY
  2939                              <1> 	;and	al, 0F7h  ; 0EFh	; enable IRQ 3 (COM2)
  2940 00002C05 20E0                <1> 	and	al, ah	; 0F7h or 0EFh 
  2941 00002C07 E621                <1> 	out	21h, al    		; write back to register
  2942                              <1> 	;
  2943                              <1> 	;popf	
  2944 00002C09 C3                  <1> 	retn
  2945                              <1> 
  2946                              <1> sp_invp_err:
  2947 00002C0A C705[B86C0000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
  2947 00002C12 0000                <1>
  2948 00002C14 31C9                <1> 	xor	ecx, ecx
  2949 00002C16 49                  <1> 	dec	ecx ; 0FFFFh
  2950 00002C17 F9                  <1> 	stc
  2951 00002C18 C3                  <1> 	retn
  2952                              <1> 
  2953                              <1> ; 29/10/2015
  2954                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
  2955 00002C19 010C0603080401      <1> 	db	1, 12, 6, 3, 8, 4, 1
  2956                              <1> 
  2957                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014) 
  2958                              <1> epoch:
  2959                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  2960                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
  2961                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
  2962                              <1> 	; 'epoch' procedure prototype: 
  2963                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
  2964                              <1> 	; 14/11/2012
  2965                              <1> 	; unixboot.asm (boot file configuration)
  2966                              <1> 	; version of "epoch" procedure in "unixproc.asm"
  2967                              <1> 	; 21/7/2012
  2968                              <1> 	; 15/7/2012
  2969                              <1> 	; 14/7/2012		
  2970                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
  2971                              <1> 	; compute current date and time as UNIX Epoch/Time
  2972                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
  2973                              <1> 	;
  2974                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
  2975                              <1> 	;
  2976 00002C20 E818010000          <1> 	call 	get_rtc_time		; Return Current Time
  2977 00002C25 86E9                <1>         xchg 	ch,cl
  2978 00002C27 66890D[78640000]    <1>         mov 	[hour], cx
  2979 00002C2E 86F2                <1>         xchg 	dh,dl
  2980 00002C30 668915[7A640000]    <1>         mov 	[second], dx
  2981                              <1> 	;
  2982 00002C37 E832010000          <1>         call 	get_rtc_date		; Return Current Date
  2983 00002C3C 86E9                <1>         xchg 	ch,cl
  2984 00002C3E 66890D[74640000]    <1>         mov 	[year], cx
  2985 00002C45 86F2                <1>         xchg 	dh,dl
  2986 00002C47 668915[76640000]    <1>         mov 	[month], dx
  2987                              <1> 	;
  2988 00002C4E 66B93030            <1> 	mov 	cx, 3030h
  2989                              <1> 	;
  2990 00002C52 A0[78640000]        <1> 	mov 	al, [hour] ; Hour
  2991                              <1>         	; AL <= BCD number)
  2992 00002C57 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
  2993                              <1> 					; AH = AL / 10h
  2994                              <1> 					; AL = AL MOD 10h
  2995 00002C59 D50A                <1>         aad 	; AX= AH*10+AL
  2996 00002C5B A2[78640000]        <1> 	mov 	[hour], al
  2997 00002C60 A0[79640000]        <1> 	mov 	al, [hour+1] ; Minute
  2998                              <1>         	; AL <= BCD number)
  2999 00002C65 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
  3000                              <1> 					; AH = AL / 10h
  3001                              <1> 					; AL = AL MOD 10h
  3002 00002C67 D50A                <1>         aad 	; AX= AH*10+AL
  3003 00002C69 A2[79640000]        <1> 	mov 	[minute], al
  3004 00002C6E A0[7A640000]        <1> 	mov 	al, [second] ; Second
  3005                              <1>         	; AL <= BCD number)
  3006 00002C73 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
  3007                              <1> 					; AH = AL / 10h
  3008                              <1> 					; AL = AL MOD 10h
  3009 00002C75 D50A                <1>         aad 	; AX= AH*10+AL
  3010 00002C77 A2[7A640000]        <1> 	mov 	[second], al
  3011 00002C7C 66A1[74640000]      <1> 	mov 	ax, [year] ; Year (century)
  3012                              <1> 	;push 	ax
  3013                              <1> 	; 04/12/2021
  3014 00002C82 50                  <1> 	push	eax
  3015                              <1> 	   	; AL <= BCD number)
  3016 00002C83 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
  3017                              <1> 					; AH = AL / 10h
  3018                              <1> 					; AL = AL MOD 10h
  3019 00002C85 D50A                <1>         aad 	; AX= AH*10+AL
  3020 00002C87 B464                <1> 	mov 	ah, 100
  3021 00002C89 F6E4                <1> 	mul 	ah
  3022 00002C8B 66A3[74640000]      <1> 	mov 	[year], ax
  3023                              <1> 	;pop	ax
  3024                              <1> 	; 04/12/2021
  3025 00002C91 58                  <1> 	pop	eax
  3026 00002C92 88E0                <1> 	mov	al, ah
  3027                              <1>         	; AL <= BCD number)
  3028 00002C94 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
  3029                              <1> 					; AH = AL / 10h
  3030                              <1> 					; AL = AL MOD 10h
  3031 00002C96 D50A                <1>         aad 	; AX= AH*10+AL
  3032 00002C98 660105[74640000]    <1> 	add 	[year], ax
  3033 00002C9F A0[76640000]        <1> 	mov 	al, [month] ; Month
  3034                              <1>            	; AL <= BCD number)
  3035 00002CA4 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
  3036                              <1> 					; AH = AL / 10h
  3037                              <1> 					; AL = AL MOD 10h
  3038 00002CA6 D50A                <1>         aad 	; AX= AH*10+AL
  3039 00002CA8 A2[76640000]        <1> 	mov 	[month], al	
  3040 00002CAD A0[77640000]        <1>         mov     al, [month+1]      	; Day
  3041                              <1>            	; AL <= BCD number)
  3042 00002CB2 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
  3043                              <1> 					; AH = AL / 10h
  3044                              <1> 					; AL = AL MOD 10h
  3045 00002CB4 D50A                <1>         aad 	; AX= AH*10+AL
  3046 00002CB6 A2[77640000]        <1>         mov     [day], al
  3047                              <1> 	
  3048                              <1> _epoch:
  3049                              <1> 	; 17/07/2022
  3050                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
  3051                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1)
  3052                              <1> 	;
  3053                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
  3054                              <1> 	;
  3055                              <1> 	; Derived from DALLAS Semiconductor
  3056                              <1> 	; Application Note 31 (DS1602/DS1603)
  3057                              <1> 	; 6 May 1998
  3058 00002CBB 29C0                <1> 	sub 	eax, eax
  3059 00002CBD 66A1[74640000]      <1> 	mov 	ax, [year]
  3060 00002CC3 662DB207            <1> 	sub 	ax, 1970
  3061 00002CC7 BA6D010000          <1> 	mov 	edx, 365
  3062 00002CCC F7E2                <1> 	mul 	edx
  3063 00002CCE 31DB                <1> 	xor 	ebx, ebx
  3064 00002CD0 8A1D[76640000]      <1> 	mov 	bl, [month]
  3065 00002CD6 FECB                <1> 	dec 	bl
  3066 00002CD8 D0E3                <1> 	shl 	bl, 1
  3067                              <1> 	;sub	edx, edx
  3068 00002CDA 668B93[7C640000]    <1> 	mov 	dx, [EBX+DMonth]
  3069 00002CE1 8A1D[77640000]      <1>         mov     bl, [day]
  3070 00002CE7 FECB                <1> 	dec 	bl
  3071 00002CE9 01D0                <1> 	add 	eax, edx
  3072 00002CEB 01D8                <1> 	add 	eax, ebx
  3073                              <1> 			; EAX = days since 1/1/1970
  3074 00002CED 668B15[74640000]    <1> 	mov 	dx, [year]
  3075 00002CF4 6681EAB107          <1> 	sub 	dx, 1969
  3076                              <1> 	;shr 	dx, 1
  3077                              <1> 	;shr 	dx, 1		
  3078                              <1> 	; 17/07/2022
  3079 00002CF9 C1EA02              <1> 	shr	edx, 2
  3080                              <1> 		; (year-1969)/4
  3081 00002CFC 01D0                <1> 	add 	eax, edx
  3082                              <1> 			; + leap days since 1/1/1970
  3083 00002CFE 803D[76640000]02    <1> 	cmp 	byte [month], 2	; if past february
  3084 00002D05 7610                <1> 	jna 	short cte1
  3085 00002D07 668B15[74640000]    <1> 	mov 	dx, [year]
  3086 00002D0E 6683E203            <1> 	and 	dx, 3 ; year mod 4
  3087 00002D12 7503                <1> 	jnz 	short cte1		
  3088                              <1> 			; and if leap year
  3089 00002D14 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
  3090                              <1> cte1: 			; compute seconds since 1/1/1970
  3091 00002D17 BA18000000          <1> 	mov 	edx, 24
  3092 00002D1C F7E2                <1> 	mul	edx
  3093 00002D1E 8A15[78640000]      <1> 	mov 	dl, [hour]
  3094 00002D24 01D0                <1> 	add 	eax, edx
  3095                              <1> 		; EAX = hours since 1/1/1970 00:00:00
  3096                              <1> 	;mov	ebx, 60
  3097 00002D26 B33C                <1> 	mov	bl, 60
  3098 00002D28 F7E3                <1> 	mul	ebx
  3099 00002D2A 8A15[79640000]      <1> 	mov 	dl, [minute]
  3100 00002D30 01D0                <1> 	add 	eax, edx
  3101                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
  3102                              <1> 	;mov 	ebx, 60
  3103 00002D32 F7E3                <1> 	mul	ebx
  3104 00002D34 8A15[7A640000]      <1> 	mov 	dl, [second]
  3105 00002D3A 01D0                <1> 	add 	eax, edx
  3106                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
  3107 00002D3C C3                  <1> 	retn
  3108                              <1> 
  3109                              <1> get_rtc_time:
  3110                              <1> 	; 15/03/2015
  3111                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
  3112                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
  3113                              <1> 	; INT 1Ah
  3114                              <1> 	; (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,	:
  3115                              <1> 	;       (CH) = HOURS IN BCD (00-23)			:
  3116                              <1> 	;       (CL) = MINUTES IN BCD (00-59)			:
  3117                              <1> 	;       (DH) = SECONDS IN BCD (00-59)			:
  3118                              <1> 	;       (DL) = DAYLIGHT SAVINGS ENABLE (00-01).		:
  3119                              <1> 	;								
  3120                              <1> RTC_20: 				; GET RTC TIME
  3121 00002D3D FA                  <1> 	cli
  3122 00002D3E E8DBDDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
  3123 00002D43 7227                <1> 	JC	short RTC_29		; EXIT IF ERROR (CY= 1)
  3124                              <1> 
  3125 00002D45 B000                <1> 	MOV	AL, CMOS_SECONDS 	; SET ADDRESS OF SECONDS
  3126 00002D47 E8BCDDFFFF          <1> 	CALL	CMOS_READ		; GET SECONDS
  3127 00002D4C 88C6                <1> 	MOV	DH, AL			; SAVE
  3128 00002D4E B00B                <1> 	MOV	AL, CMOS_REG_B		; ADDRESS ALARM REGISTER
  3129 00002D50 E8B3DDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
  3130 00002D55 2401                <1> 	AND	AL, 00000001B		; MASK FOR VALID DSE BIT
  3131 00002D57 88C2                <1> 	MOV	DL, AL			; SET [DL] TO ZERO FOR NO DSE BIT
  3132 00002D59 B002                <1> 	MOV	AL, CMOS_MINUTES 	; SET ADDRESS OF MINUTES
  3133 00002D5B E8A8DDFFFF          <1> 	CALL	CMOS_READ		; GET MINUTES
  3134 00002D60 88C1                <1> 	MOV	CL, AL			; SAVE
  3135 00002D62 B004                <1> 	MOV	AL, CMOS_HOURS		; SET ADDRESS OF HOURS
  3136 00002D64 E89FDDFFFF          <1> 	CALL	CMOS_READ		; GET HOURS
  3137 00002D69 88C5                <1> 	MOV	CH, AL			; SAVE
  3138 00002D6B F8                  <1> 	CLC				; SET CY= 0
  3139                              <1> RTC_29:
  3140 00002D6C FB                  <1> 	sti
  3141 00002D6D C3                  <1> 	RETn				; RETURN WITH RESULT IN CARRY FLAG
  3142                              <1> 
  3143                              <1> get_rtc_date:
  3144                              <1> 	; 15/03/2015
  3145                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
  3146                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
  3147                              <1> 	; INT 1Ah
  3148                              <1> 	; (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,:
  3149                              <1> 	;      (CH) = CENTURY IN BCD (19 OR 20) 		       :
  3150                              <1> 	;      (CL) = YEAR IN BCD (00-99)			       :
  3151                              <1> 	;      (DH) = MONTH IN BCD (01-12)			       :
  3152                              <1> 	;      (DL) = DAY IN BCD (01-31).		
  3153                              <1> 	;
  3154                              <1> RTC_40: 				; GET RTC DATE
  3155 00002D6E FA                  <1> 	cli
  3156 00002D6F E8AADDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
  3157 00002D74 7225                <1> 	JC	short RTC_49		; EXIT IF ERROR (CY= 1)
  3158                              <1> 
  3159 00002D76 B007                <1> 	MOV	AL, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
  3160 00002D78 E88BDDFFFF          <1> 	CALL	CMOS_READ		; READ DAY OF MONTH
  3161 00002D7D 88C2                <1> 	MOV	DL, AL			; SAVE
  3162 00002D7F B008                <1> 	MOV	AL, CMOS_MONTH		; ADDRESS MONTH
  3163 00002D81 E882DDFFFF          <1> 	CALL	CMOS_READ		; READ MONTH
  3164 00002D86 88C6                <1> 	MOV	DH, AL			; SAVE
  3165 00002D88 B009                <1> 	MOV	AL, CMOS_YEAR		; ADDRESS YEAR
  3166 00002D8A E879DDFFFF          <1> 	CALL	CMOS_READ		; READ YEAR
  3167 00002D8F 88C1                <1> 	MOV	CL, AL			; SAVE
  3168 00002D91 B032                <1> 	MOV	AL, CMOS_CENTURY 	; ADDRESS CENTURY LOCATION
  3169 00002D93 E870DDFFFF          <1> 	CALL	CMOS_READ		; GET CENTURY BYTE
  3170 00002D98 88C5                <1> 	MOV	CH, AL			; SAVE
  3171 00002D9A F8                  <1> 	CLC				; SET CY=0
  3172                              <1> RTC_49:
  3173 00002D9B FB                  <1> 	sti
  3174 00002D9C C3                  <1> 	RETn				; RETURN WITH RESULTS IN CARRY FLAG
  3175                              <1> 
  3176                              <1> set_date_time:
  3177                              <1> convert_from_epoch:
  3178                              <1> 	; 02/06/2022 (BugFix)
  3179                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
  3180                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
  3181                              <1> 	; 'convert_from_epoch' procedure prototype: 
  3182                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
  3183                              <1> 	;
  3184                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
  3185                              <1> 	;
  3186                              <1> 	; Derived from DALLAS Semiconductor
  3187                              <1> 	; Application Note 31 (DS1602/DS1603)
  3188                              <1> 	; 6 May 1998
  3189                              <1> 	;
  3190                              <1> 	; INPUT:
  3191                              <1> 	; EAX = Unix (Epoch) Time
  3192                              <1> 	;
  3193 00002D9D 31D2                <1> 	xor 	edx, edx
  3194                              <1> 	; 02/06/2022
  3195 00002D9F 31C9                <1> 	xor	ecx, ecx
  3196 00002DA1 31DB                <1> 	xor	ebx, ebx
  3197                              <1> 	;mov 	ecx, 60
  3198 00002DA3 B13C                <1> 	mov	cl, 60
  3199 00002DA5 F7F1                <1> 	div	ecx
  3200                              <1> 	;mov 	[imin], eax  ; whole minutes
  3201                              <1> 			     ; since 1/1/1970
  3202                              <1> 	;mov 	[second], dx ; leftover seconds
  3203 00002DA7 8815[7A640000]      <1> 	mov	[second], dl ; 02/06/2022
  3204 00002DAD 29D2                <1> 	sub 	edx, edx
  3205 00002DAF F7F1                <1> 	div	ecx
  3206                              <1> 	;mov 	[ihrs], eax  ; whole hours
  3207                              <1> 	;		     ; since 1/1/1970
  3208                              <1> 	;mov 	[minute], dx ; leftover minutes
  3209 00002DB1 8815[79640000]      <1> 	mov	[minute], dl ; 02/06/2022
  3210 00002DB7 31D2                <1> 	xor	edx, edx
  3211                              <1> 	;mov 	cx, 24
  3212 00002DB9 B118                <1> 	mov 	cl, 24
  3213 00002DBB F7F1                <1> 	div	ecx
  3214                              <1> 	;mov 	[iday], ax   ; whole days
  3215                              <1> 			     ; since 1/1/1970
  3216                              <1> 	;mov 	[hour], dx   ; leftover hours
  3217 00002DBD 8815[78640000]      <1> 	mov	[hour], dl   ; 02/06/2022
  3218                              <1> 
  3219 00002DC3 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
  3220                              <1> 			     ; 1/1/1968 	
  3221                              <1> 		;mov 	[iday], ax
  3222 00002DC8 50                  <1> 	push 	eax
  3223 00002DC9 29D2                <1> 	sub	edx, edx
  3224 00002DCB B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
  3225 00002DD0 F7F1                <1> 	div	ecx
  3226 00002DD2 59                  <1> 	pop 	ecx
  3227                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
  3228                              <1> 	;push	dx
  3229                              <1> 	; 02/06/2022
  3230 00002DD3 52                  <1> 	push 	edx
  3231                              <1> 	;mov 	[qday], dx   ; days since quadyr began
  3232 00002DD4 6683FA3C            <1> 	cmp 	dx, 31+29    ; if past feb 29 then
  3233 00002DD8 F5                  <1> 	cmc		     ; add this quadyr's leap day
  3234 00002DD9 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
  3235                              <1> 	;mov 	[lday], ax   ; since 1968			  
  3236                              <1> 	;mov 	cx, [iday]
  3237 00002DDC 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
  3238 00002DDD 29C8                <1> 	sub 	eax, ecx     ; iday - lday
  3239 00002DDF B96D010000          <1> 	mov 	ecx, 365
  3240 00002DE4 31D2                <1> 	xor	edx, edx
  3241                              <1> 	; EAX = iday-lday, EDX = 0
  3242 00002DE6 F7F1                <1> 	div	ecx
  3243                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
  3244                              <1> 	;jday = iday - (iyrs*365) - lday
  3245                              <1> 	;mov	[jday], dx   ; days since 1/1 of current year
  3246                              <1> 	;add	eax, 1968
  3247 00002DE8 6605B007            <1> 	add 	ax, 1968     ; compute year
  3248 00002DEC 66A3[74640000]      <1> 	mov 	[year], ax
  3249                              <1> 	;mov 	cx, dx
  3250                              <1> 	; 02/06/2022
  3251 00002DF2 89D1                <1> 	mov	ecx, edx
  3252                              <1> 	;mov 	dx, [qday]
  3253                              <1> 	;pop	dx
  3254                              <1> 	; 02/06/2022
  3255 00002DF4 5A                  <1> 	pop 	edx
  3256 00002DF5 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
  3257 00002DFA 7709                <1> 	ja 	short cfe1   ; jday = jday +1
  3258 00002DFC 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
  3259 00002E00 F5                  <1>         cmc		     ; add a leap day to the # of whole
  3260 00002E01 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
  3261                              <1> cfe1:			
  3262                              <1> 	;mov 	[jday], cx
  3263                              <1> 	;mov 	bx, 12       ; estimate month
  3264                              <1> 	;sub	ebx, ebx
  3265                              <1> 	; 02/06/2022
  3266 00002E05 B30C                <1> 	mov	bl, 12
  3267 00002E07 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
  3268 00002E0B 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
  3269                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
  3270                              <1> 	;cmp 	cx, dx       ; mday = # of days passed from 1/1
  3271                              <1> 	; 02/06/2022
  3272 00002E0F 39D1                <1> 	cmp	ecx, edx 	 		
  3273 00002E11 7319                <1> 	jnb 	short cfe3
  3274                              <1> 	;dec 	bx           ; month = month - 1
  3275 00002E13 FECB                <1> 	dec	bl			
  3276                              <1> 	;shl 	bx, 1
  3277 00002E15 D0E3                <1> 	shl	bl, 1
  3278 00002E17 668B93[7C640000]    <1> 	mov 	dx, [ebx+DMonth] ; # elapsed days at 1st of month
  3279                              <1> 	;shr 	bx, 1        ; bx = month - 1 (0 to 11)
  3280                              <1> 	; 02/06/2022
  3281 00002E1E D0EB                <1> 	shr	bl, 1
  3282 00002E20 80FB01              <1> 	cmp	bl, 1
  3283                              <1> 	;cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
  3284 00002E23 76EA                <1> 	jna 	short cfe2   ; then mday = mday + 1
  3285 00002E25 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
  3286 00002E27 75E6                <1> 	jnz 	short cfe2   ; add leap day (to mday)
  3287                              <1> 	;inc 	dx           ; mday = mday + 1
  3288 00002E29 42                  <1> 	inc	edx
  3289 00002E2A EBE3                <1> 	jmp 	short cfe2
  3290                              <1> cfe3:
  3291                              <1> 	;inc 	bx	     ; -> bx = month, 1 to 12
  3292                              <1> 	; 02/06/2022
  3293 00002E2C FEC3                <1> 	inc	bl
  3294                              <1> 	;mov 	[month], bx
  3295 00002E2E 881D[76640000]      <1> 	mov	[month], bl
  3296                              <1> 	;sub 	cx, dx	     ; day = jday - mday + 1	
  3297 00002E34 29D1                <1> 	sub	ecx, edx
  3298                              <1> 	;inc 	cx 			  
  3299 00002E36 FEC1                <1> 	inc	cl
  3300                              <1> 	;mov 	[day], cx
  3301 00002E38 880D[77640000]      <1> 	mov	[day], cl    ; 02/06/2022
  3302                              <1> 
  3303                              <1> 	; eax, ebx, ecx, edx is changed at return
  3304                              <1> 	; output ->
  3305                              <1> 	; [year], [month], [day], [hour], [minute], [second]
  3306                              <1> 	
  3307                              <1> 	; 02/06/2022 (BugFix)	
  3308                              <1> _set_date:
  3309 00002E3E 66A1[74640000]      <1> 	mov	ax, [year]
  3310 00002E44 B520                <1> 	mov	ch, 20h ; century (bcd)
  3311 00002E46 662DD007            <1> 	sub	ax, 2000
  3312 00002E4A 7306                <1> 	jnc	short set_date
  3313 00002E4C B519                <1> 	mov	ch, 19h ; century (bcd) 
  3314 00002E4E 6683C064            <1> 	add	ax, 100	
  3315                              <1> 	; 02/06/2022
  3316                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
  3317                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
  3318                              <1> set_date:
  3319                              <1>         ;mov	al, [year+1]
  3320                              <1> 	;aam 	; ah = al / 10, al = al mod 10
  3321                              <1> 	;db 	0D5h, 10h    ; Undocumented inst. AAD
  3322                              <1> 	;		     ; AL = AH * 10h + AL
  3323                              <1> 	;mov 	ch, al ; century (BCD)
  3324                              <1> 	;mov 	al, [year]
  3325                              <1> 	; al = year (0-99) ; 01/06/2022
  3326 00002E52 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
  3327 00002E54 D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
  3328                              <1> 			     ; AL = AH * 10h + AL
  3329 00002E56 88C1                <1> 	mov 	cl, al ; year (BCD)
  3330 00002E58 A0[76640000]        <1>         mov 	al, [month]
  3331 00002E5D D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
  3332 00002E5F D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
  3333                              <1> 			     ; AL = AH * 10h + AL
  3334 00002E61 88C6                <1> 	mov 	dh, al ; month (BCD)
  3335 00002E63 A0[77640000]        <1> 	mov 	al, [day]
  3336 00002E68 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
  3337 00002E6A D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
  3338                              <1> 			     ; AL = AH * 10h + AL
  3339                              <1> 	; 02/06/2022 (BugFix)
  3340 00002E6C 88C2                <1> 	mov 	dl, al ; day (BCD)
  3341                              <1> 
  3342                              <1> 	; Set real-time clock date
  3343 00002E6E E879000000          <1> 	call	set_rtc_date
  3344                              <1> set_time:
  3345                              <1>         ; Read real-time clock time 
  3346                              <1> 	; (get day light saving time bit status)
  3347 00002E73 FA                  <1>  	cli
  3348 00002E74 E8A5DCFFFF          <1> 	CALL	UPD_IPR 	; CHECK FOR UPDATE IN PROCESS
  3349                              <1> 	; cf = 1 -> al = 0
  3350 00002E79 7207                <1>         jc      short stime1
  3351 00002E7B B00B                <1> 	MOV	AL, CMOS_REG_B	; ADDRESS ALARM REGISTER
  3352 00002E7D E886DCFFFF          <1> 	CALL	CMOS_READ	; READ CURRENT VALUE OF DSE BIT
  3353                              <1> stime1:
  3354 00002E82 FB                  <1> 	sti
  3355 00002E83 2401                <1> 	AND	AL, 00000001B	; MASK FOR VALID DSE BIT
  3356 00002E85 88C2                <1> 	MOV	DL, AL		; SET [DL] TO ZERO FOR NO DSE BIT
  3357                              <1> 	; DL = 1 or 0 (day light saving time)
  3358                              <1> 	;	
  3359 00002E87 A0[78640000]        <1> 	mov 	al, [hour]
  3360 00002E8C D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
  3361 00002E8E D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
  3362                              <1> 			     ; AL = AH * 10h + AL
  3363 00002E90 88C5                <1> 	mov 	ch, al ; hour (BCD)
  3364 00002E92 A0[79640000]        <1>         mov     al, [minute]
  3365 00002E97 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
  3366 00002E99 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
  3367                              <1> 			     ; AL = AH * 10h + AL
  3368 00002E9B 88C1                <1> 	mov 	cl, al       ; minute (BCD)
  3369 00002E9D A0[7A640000]        <1>         mov     al, [second]
  3370 00002EA2 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
  3371 00002EA4 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
  3372                              <1> 			     ; AL = AH * 10h + AL
  3373 00002EA6 88C6                <1> 	mov 	dh, al	     ; second (BCD)
  3374                              <1> 
  3375                              <1> 	; Set real-time clock time
  3376                              <1>  	; call	set_rtc_time
  3377                              <1> set_rtc_time:
  3378                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
  3379                              <1> 	; 15/03/2015
  3380                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
  3381                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
  3382                              <1> 	; INT 1Ah
  3383                              <1> 	; (AH) = 03H  SET THE REAL TIME CLOCK USING,			:
  3384                              <1> 	;      (CH) = HOURS IN BCD (00-23)			       	:
  3385                              <1> 	;      (CL) = MINUTES IN BCD (00-59)			       	:
  3386                              <1> 	;      (DH) = SECONDS IN BCD (00-59)			       	:
  3387                              <1> 	;      (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.    :
  3388                              <1> 	;								:
  3389                              <1> 	;  NOTE: (DL)= 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED. :
  3390                              <1> 	;        (DL)= 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN  :
  3391                              <1> 	;         APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN :
  3392                              <1> 	;         OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.	  :
  3393                              <1> 	;
  3394                              <1> RTC_30: 				; SET RTC TIME
  3395 00002EA8 FA                  <1> 	cli
  3396 00002EA9 E870DCFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
  3397 00002EAE 7305                <1> 	JNC	short RTC_35		; GO AROUND IF CLOCK OPERATING
  3398 00002EB0 E886000000          <1> 	CALL	RTC_STA 		; ELSE TRY INITIALIZING CLOCK
  3399                              <1> RTC_35:
  3400 00002EB5 88F4                <1> 	MOV	AH, DH			; GET TIME BYTE - SECONDS
  3401 00002EB7 B000                <1> 	MOV	AL, CMOS_SECONDS 	; ADDRESS SECONDS
  3402 00002EB9 E89D000000          <1> 	CALL	CMOS_WRITE		; UPDATE SECONDS
  3403 00002EBE 88CC                <1> 	MOV	AH, CL			; GET TIME BYTE - MINUTES
  3404 00002EC0 B002                <1> 	MOV	AL, CMOS_MINUTES 	; ADDRESS MINUTES
  3405 00002EC2 E894000000          <1> 	CALL	CMOS_WRITE		; UPDATE MINUTES
  3406 00002EC7 88EC                <1> 	MOV	AH, CH			; GET TIME BYTE - HOURS
  3407 00002EC9 B004                <1> 	MOV	AL, CMOS_HOURS		; ADDRESS HOURS
  3408 00002ECB E88B000000          <1> 	CALL	CMOS_WRITE		; UPDATE ADDRESS
  3409                              <1> 	;MOV	AX, X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
  3410 00002ED0 66B80B0B            <1> 	MOV	AX, 257*CMOS_REG_B 	; 
  3411 00002ED4 E82FDCFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT TIME
  3412 00002ED9 2462                <1> 	AND	AL, 01100010B		; MASK FOR VALID BIT POSITIONS
  3413 00002EDB 0C02                <1> 	OR	AL, 00000010B		; TURN ON 24 HOUR MODE
  3414 00002EDD 80E201              <1> 	AND	DL, 00000001B		; USE ONLY THE DSE BIT
  3415 00002EE0 08D0                <1> 	OR	AL, DL			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
  3416 00002EE2 86E0                <1> 	XCHG	AH, AL			; PLACE IN WORK REGISTER AND GET ADDRESS
  3417 00002EE4 E872000000          <1> 	CALL	CMOS_WRITE		; SET NEW ALARM BITS
  3418 00002EE9 F8                  <1> 	CLC				; SET CY= 0
  3419 00002EEA FB                  <1> 	sti
  3420 00002EEB C3                  <1> 	RETn				; RETURN WITH CY= 0
  3421                              <1> 
  3422                              <1> set_rtc_date:
  3423                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
  3424                              <1> 	; 15/03/2015
  3425                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
  3426                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
  3427                              <1> 	; INT 1Ah
  3428                              <1> 	; (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING, :
  3429                              <1> 	;     (CH) = CENTURY IN BCD (19 OR 20)			   :
  3430                              <1> 	;     (CL) = YEAR IN BCD (00-99)			   :
  3431                              <1> 	;     (DH) = MONTH IN BCD (01-12)			   :
  3432                              <1> 	;     (DL) = DAY IN BCD (01-31).
  3433                              <1> 	;
  3434                              <1> RTC_50: 				; SET RTC DATE
  3435 00002EEC FA                  <1> 	cli
  3436 00002EED E82CDCFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
  3437 00002EF2 7305                <1> 	JNC	short RTC_55		; GO AROUND IF NO ERROR
  3438 00002EF4 E842000000          <1> 	CALL	RTC_STA 		; ELSE INITIALIZE CLOCK
  3439                              <1> RTC_55:
  3440 00002EF9 66B80600            <1> 	MOV	AX, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
  3441 00002EFD E859000000          <1> 	CALL	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
  3442 00002F02 88D4                <1> 	MOV	AH, DL			; GET DAY OF MONTH BYTE
  3443 00002F04 B007                <1> 	MOV	AL, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
  3444 00002F06 E850000000          <1> 	CALL	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
  3445 00002F0B 88F4                <1> 	MOV	AH, DH			; GET MONTH
  3446 00002F0D B008                <1> 	MOV	AL, CMOS_MONTH		; ADDRESS MONTH BYTE
  3447 00002F0F E847000000          <1> 	CALL	CMOS_WRITE		; WRITE MONTH REGISTER
  3448 00002F14 88CC                <1> 	MOV	AH, CL			; GET YEAR BYTE
  3449 00002F16 B009                <1> 	MOV	AL, CMOS_YEAR		; ADDRESS YEAR REGISTER
  3450 00002F18 E83E000000          <1> 	CALL	CMOS_WRITE		; WRITE YEAR REGISTER
  3451 00002F1D 88EC                <1> 	MOV	AH, CH			; GET CENTURY BYTE
  3452 00002F1F B032                <1> 	MOV	AL, CMOS_CENTURY 	; ADDRESS CENTURY BYTE
  3453 00002F21 E835000000          <1> 	CALL	CMOS_WRITE		; WRITE CENTURY LOCATION
  3454                              <1> 	;MOV	AX, X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
  3455 00002F26 66B80B0B            <1> 	MOV	AX, 257*CMOS_REG_B 	; 
  3456 00002F2A E8D9DBFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT SETTINGS
  3457 00002F2F 247F                <1> 	AND	AL, 07FH 		; CLEAR 'SET BIT'
  3458 00002F31 86E0                <1> 	XCHG	AH, AL			; MOVE TO WORK REGISTER
  3459 00002F33 E823000000          <1> 	CALL	CMOS_WRITE		; AND START CLOCK UPDATING
  3460 00002F38 F8                  <1> 	CLC				; SET CY= 0
  3461 00002F39 FB                  <1> 	sti
  3462 00002F3A C3                  <1> 	RETn				; RETURN CY=0
  3463                              <1> 
  3464                              <1> 	; 15/03/2015
  3465                              <1> RTC_STA:				; INITIALIZE REAL TIME CLOCK
  3466 00002F3B B426                <1> 	mov	ah, 26h
  3467 00002F3D B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK
  3468 00002F3F E817000000          <1> 	CALL	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
  3469 00002F44 B482                <1> 	mov	ah, 82h
  3470 00002F46 B00B                <1> 	mov 	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION
  3471 00002F48 E80E000000          <1> 	CALL	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
  3472 00002F4D B00C                <1> 	MOV	AL, CMOS_REG_C		; ADDRESS REGISTER C
  3473 00002F4F E8B4DBFFFF          <1> 	CALL	CMOS_READ		; READ REGISTER C TO INITIALIZE
  3474 00002F54 B00D                <1> 	MOV	AL, CMOS_REG_D		; ADDRESS REGISTER D
  3475                              <1> 	;CALL	CMOS_READ		; READ REGISTER D TO INITIALIZE
  3476                              <1> 	;RETn
  3477                              <1> 	; 06/02/2022
  3478 00002F56 E9ADDBFFFF          <1> 	jmp	CMOS_READ
  3479                              <1> 
  3480                              <1> 	; 15/03/2015
  3481                              <1> 	; IBM PC/XT Model 286 BIOS source code ----- 10/06/85 (test4.asm)
  3482                              <1> CMOS_WRITE:			; WRITE (AH) TO LOCATION (AL)
  3483 00002F5B 9C                  <1> 	pushf			; SAVE INTERRUPT ENABLE STATUS AND FLAGS
  3484                              <1> 	;push	ax		; SAVE WORK REGISTER VALUES
  3485 00002F5C D0C0                <1> 	rol	al, 1		; MOVE NMI BIT TO LOW POSITION
  3486 00002F5E F9                  <1> 	stc			; FORCE NMI BIT ON IN CARRY FLAG
  3487 00002F5F D0D8                <1> 	rcr	al, 1		; HIGH BIT ON TO DISABLE NMI - OLD IN CY
  3488 00002F61 FA                  <1> 	cli			; DISABLE INTERRUPTS
  3489 00002F62 E670                <1> 	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
  3490 00002F64 88E0                <1> 	mov	al, ah		; GET THE DATA BYTE TO WRITE
  3491 00002F66 E671                <1> 	out	CMOS_DATA, al	; PLACE IN REQUESTED CMOS LOCATION
  3492 00002F68 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
  3493 00002F6A D0D8                <1> 	rcr	al, 1		; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
  3494 00002F6C E670                <1> 	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
  3495 00002F6E 90                  <1> 	nop			; I/O DELAY
  3496 00002F6F E471                <1> 	in	al, CMOS_DATA	; OPEN STANDBY LATCH
  3497                              <1> 	;pop	ax		; RESTORE WORK REGISTERS
  3498 00002F71 9D                  <1> 	popf	
  3499 00002F72 C3                  <1> 	RETn
  3500                              <1> 
  3501                              <1> bf_init:
  3502                              <1> 	; 21/03/2022 (Retro UNIX 386 v1.2)
  3503                              <1> 	; 28/11/2021
  3504                              <1> 	; 14/08/2015
  3505                              <1> 	; 02/07/2015
  3506                              <1> 	; 01/07/2015
  3507                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
  3508                              <1> 	; Buffer (pointer) initialization !
  3509                              <1> 	; 
  3510                              <1> 	; 17/07/2013 - 24/07/2013
  3511                              <1> 	; Retro UNIX 8086 v1 (U9.ASM)
  3512                              <1> 	; (Retro UNIX 8086 v1 feature only !)
  3513                              <1> 	;
  3514 00002F73 BF[D46B0000]        <1> 	mov	edi, bufp 
  3515 00002F78 B8[84970000]        <1> 	mov	eax, buffer + (nbuf*520) 
  3516 00002F7D 29D2                <1> 	sub	edx, edx
  3517 00002F7F FECA                <1> 	dec	dl
  3518 00002F81 31C9                <1> 	xor	ecx, ecx
  3519 00002F83 49                  <1> 	dec	ecx
  3520                              <1> bi0:
  3521 00002F84 2D08020000          <1> 	sub	eax, 520 ; 8 header + 512 data
  3522 00002F89 AB                  <1> 	stosd
  3523 00002F8A 89C6                <1> 	mov	esi, eax
  3524 00002F8C 8916                <1> 	mov	[esi], edx ; 000000FFh
  3525                              <1> 			    ; Not a valid device sign
  3526 00002F8E 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
  3527                              <1> 		      ; Not a valid block number sign 	 	
  3528 00002F91 3D[04770000]        <1> 	cmp	eax, buffer
  3529 00002F96 77EC                <1> 	ja	short bi0
  3530 00002F98 B8[EC6C0000]        <1> 	mov	eax, sb0
  3531 00002F9D AB                  <1> 	stosd
  3532 00002F9E B8[F46E0000]        <1> 	mov	eax, sb1
  3533 00002FA3 AB                  <1> 	stosd
  3534 00002FA4 89C6                <1> 	mov	esi, eax ; offset sb1
  3535 00002FA6 8916                <1> 	mov	[esi], edx ; 000000FFh
  3536                              <1> 			   ; Not a valid device sign
  3537 00002FA8 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
  3538                              <1> 		      ; Not a valid block number sign 	 
  3539                              <1> 	; 14/08/2015
  3540                              <1> 	;call 	rdev_init
  3541                              <1> 	;retn
  3542                              <1> 
  3543                              <1> ; ----- Root file system initialization
  3544                              <1> 	
  3545                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
  3546                              <1> 	;	(Retro UNIX -runix- v2 file system) 
  3547                              <1> 	; 28/11/2021
  3548                              <1> rdev_init: ; root device, super block buffer initialization
  3549                              <1> 	; 14/08/2015
  3550                              <1> 	; Retro UNIX 386 v1 feature only !
  3551                              <1> 	;
  3552                              <1> 	; NOTE: Disk partitions (file systems), logical
  3553                              <1> 	; drive initialization, partition's start sector etc.
  3554                              <1> 	; will be coded here, later in 'ldrv_init'	
  3555                              <1> 
  3556 00002FAB 0FB605[28620000]    <1> 	movzx	eax, byte [boot_drv]
  3557                              <1> rdi_0:
  3558 00002FB2 3C80                <1> 	cmp	al, 80h
  3559 00002FB4 7202                <1> 	jb	short rdi_1
  3560 00002FB6 2C7E                <1> 	sub	al, 7Eh ; 80h = 2 (hd0), 81h = 3 (hd1)
  3561                              <1> rdi_1:
  3562 00002FB8 A2[226C0000]        <1> 	mov	[rdev], al
  3563                              <1> 	; 21/03/2022
  3564                              <1> 	;cmp	al, 2
  3565                              <1> 	;jnb	short rdi_2
  3566 00002FBD 08C0                <1> 	or	al, al
  3567 00002FBF 7504                <1> 	jnz	short rdi_2 ; hard disk boot
  3568                              <1> 	; floppy disk boot
  3569 00002FC1 31D2                <1> 	xor	edx, edx ; device number = 0
  3570                              <1> 			 ; (& fglags = 0)
  3571                              <1> 	; eax = 0 ; boot sector address = 0
  3572                              <1> 	;jmp	short rdi_5
  3573 00002FC3 EB22                <1> 	jmp	short rdi_4
  3574                              <1> rdi_2:
  3575                              <1> 	; load masterboot sector
  3576                              <1> 	; to get runix v2 partition's boot sector address
  3577                              <1> 	;	
  3578 00002FC5 BB[FC700000]        <1> 	mov	ebx, mbrbuf ; masterboot buffer header addr
  3579                              <1> 	;mov	[ebx], eax
  3580 00002FCA 8803                <1> 	mov	[ebx], al
  3581                              <1> 	;sub	al, al
  3582                              <1> 	;; eax = 0
  3583                              <1> 	;mov	[ebx+4], eax ; masterboot sector address
  3584 00002FCC E8E12A0000          <1> 	call	diskio
  3585 00002FD1 730A                <1> 	jnc	short rdi_3
  3586                              <1> rdi_err:
  3587 00002FD3 BE[FA2F0000]        <1> 	mov	esi, disk_read_err_msg
  3588 00002FD8 E9B9F9FFFF          <1> 	jmp	key_to_reboot
  3589                              <1> 
  3590                              <1> rdi_3:
  3591                              <1> 	; [ebx+8] = masterboot buffer (data) address 
  3592                              <1> 	;cmp	word [ebx+8+510], 0AA55h
  3593                              <1> 	;jc	short rdi_err
  3594                              <1> 
  3595 00002FDD 8D7308              <1> 	lea	esi, [ebx+8] 
  3596 00002FE0 E82D000000          <1> 	call	runix_p_bs    ; return start sector address of
  3597                              <1> 			      ; retro unix v2 partition in esi
  3598                              <1> 	;;jc	short rdi_err ; 'retn'
  3599                              <1> 	;jnc	short rdi_4 ; Runix v2 partition not found !?
  3600                              <1> 			    ; 21/03/2022	
  3601                              <1> 			    ; ((Here, if cf is 1, that means,
  3602                              <1> 			    ; runix v2 partition not found
  3603                              <1> 			    ; in the MBR partition table.
  3604                              <1> 			    ; But, at least, there is a valid
  3605                              <1> 			    ; runix v2 boot sector on the disk
  3606                              <1> 			    ; which started the kernel.
  3607                              <1> 			    ; So, runix v2 boot sector code
  3608                              <1> 			    ; may -must- be on physical sector 0
  3609                              <1> 			    ; and then the superblock may be
  3610                              <1> 			    ; -must be- on physical sector 1.)) 
  3611                              <1> 	;sub	eax, eax
  3612                              <1> 	; eax = 0
  3613                              <1> ;rdi_4:
  3614 00002FE5 8B13                <1> 	mov	edx, [ebx] ; restore device number in dl
  3615                              <1> ;rdi_5:
  3616                              <1> rdi_4:
  3617 00002FE7 BB[EC6C0000]        <1>         mov	ebx, sb0 ; super block buffer (header)
  3618                              <1> 
  3619 00002FEC 40                  <1> 	inc	eax	; default sector address of the sb
  3620                              <1> 			; (boot sector address + 1)
  3621                              <1> 
  3622                              <1> 	;mov 	[ebx], eax
  3623                              <1> 	;mov	al, 1 ; eax = 1
  3624                              <1> 	;mov	[ebx+4], eax ; super block address on disk
  3625                              <1> 	; 21/03/2022
  3626 00002FED 8913                <1> 	mov	[ebx], edx ; device number in DL
  3627                              <1> 			   ; (other bytes -flags- are zero)
  3628 00002FEF 894304              <1> 	mov	[ebx+4], eax ; superblock address on disk
  3629                              <1> 
  3630                              <1> 	;call 	diskio
  3631                              <1> 	;retn
  3632                              <1> 	; 28/11/2021
  3633                              <1> 	;jmp	diskio
  3634                              <1> 
  3635                              <1> 	; 21/03/2022
  3636 00002FF2 E8BB2A0000          <1> 	call	diskio
  3637 00002FF7 72DA                <1> 	jc	short rdi_err
  3638                              <1> 
  3639                              <1> 	; 21/03/2022
  3640                              <1> 	; Note: If superblock is defective or SB sector
  3641                              <1> 	;	address is wrong, "ERROR: /etc/init !?"
  3642                              <1> 	;	message will appear after here.
  3643                              <1> 	;	..because /etc/init inode will not be found..
  3644                              <1> 	;	So, i am not writing SB validation
  3645                              <1> 	;	(check) code here.
  3646                              <1> 	;
  3647                              <1> 	; ((Also, if we are here, everything should be normal!))
  3648                              <1> 
  3649 00002FF9 C3                  <1> 	retn
  3650                              <1> 
  3651                              <1> disk_read_err_msg:
  3652                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
  3653 00002FFA 070D0A              <1> 	db 07h, 0Dh, 0Ah
  3654 00002FFD 4469736B2072656164- <1> 	db "Disk read error ! "
  3654 00003006 206572726F72202120  <1>
  3655 0000300F 0D0A00              <1> 	db 0Dh, 0Ah, 0
  3656                              <1> 
  3657                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
  3658                              <1> runix_p_bs:
  3659                              <1> 	; get retro unix v2 partition's boot sector address
  3660                              <1> 	
  3661                              <1> 	; 09/05/2021
  3662                              <1> 	; 19/04/2021 - Retro UNIX 386 v2
  3663                              <1> 	; INPUT:
  3664                              <1> 	;	;;Masterboot buffer at offset mbrbuf
  3665                              <1> 	;	; 21/03/2022
  3666                              <1> 	;	esi = Masterboot buffer (data) address
  3667                              <1> 	; OUTPUT:
  3668                              <1> 	;	;;esi = start sector addr of retro unix v2 fs
  3669                              <1> 	;	; 21/03/2022
  3670                              <1> 	;	eax = start sector address of retro unix v2 fs
  3671                              <1> 	;
  3672                              <1> 	;	cf = 1 -> error, retro unix fs not found
  3673                              <1> 	;		(eax = 0)	
  3674                              <1> 	;
  3675                              <1> 	; Modified registers: esi, eax
  3676                              <1> 
  3677                              <1> 	ptBootable       equ 0
  3678                              <1> 	ptBeginHead      equ 1
  3679                              <1> 	ptBeginSector    equ 2
  3680                              <1> 	ptBeginCylinder  equ 3
  3681                              <1> 	ptFileSystemID   equ 4
  3682                              <1> 	ptEndHead        equ 5
  3683                              <1> 	ptEndSector      equ 6
  3684                              <1> 	ptEndCylinder    equ 7
  3685                              <1> 	ptStartSector    equ 8
  3686                              <1> 	ptSectors        equ 12
  3687                              <1> 
  3688                              <1> 	FS_RETROUNIX	 equ 71h ; runix v2 partition ID
  3689                              <1> 
  3690                              <1> 	;cmp	word [mbrbuf+510], 0AA55h
  3691 00003012 6681BEFE01000055AA  <1> 	cmp	word [esi+510], 0AA55h
  3692 0000301B 7515                <1> 	jne	short runix_p_nf
  3693                              <1> 
  3694                              <1> 	; partition table entries are at offset 1BEh
  3695                              <1> 	;mov	esi, mbrbuf+1BEh+ptFileSystemID
  3696 0000301D 81C6C2010000        <1> 	add	esi, 1BEh+ptFileSystemID
  3697 00003023 8D4640              <1> 	lea	eax, [esi+(4*16)] 
  3698                              <1> runix_p_bs_0:
  3699 00003026 803E71              <1> 	cmp	byte [esi], FS_RETROUNIX ; 71h
  3700 00003029 740B                <1> 	je	short runix_p_f ; it is retro unix partition
  3701 0000302B 83C610              <1> 	add	esi, 16
  3702                              <1> 	;cmp	esi, mbrbuf+1BEh+ptFileSystemID+(4*16) 
  3703 0000302E 39C6                <1> 	cmp	esi, eax
  3704 00003030 72F4                <1> 	jb	short runix_p_bs_0 	  
  3705                              <1> runix_p_nf:
  3706 00003032 29C0                <1> 	sub	eax, eax
  3707                              <1> 	; eax = 0
  3708 00003034 F9                  <1> 	stc
  3709 00003035 C3                  <1> 	retn
  3710                              <1> runix_p_f:
  3711                              <1> 	;mov	esi, [esi+ptStartSector-ptFileSystemID]
  3712 00003036 8B4604              <1> 	mov	eax, [esi+ptStartSector-ptFileSystemID]
  3713 00003039 C3                  <1> 	retn
  3714                              <1> 
  3715                              <1> ; 23/10/2015
  3716                              <1> com1_irq4:
  3717 0000303A [42300000]          <1> 	dd dummy_retn
  3718                              <1> com2_irq3:
  3719 0000303E [42300000]          <1> 	dd dummy_retn
  3720                              <1> 
  3721                              <1> dummy_retn:
  3722 00003042 C3                  <1> 	retn
  2089                                  %include 'u1.s'      ; 10/05/2015
  2090                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2091                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2092                              <1> ; ****************************************************************************
  2093                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS1.INC
  2094                              <1> ; Last Modification: 17/07/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.3)
  2095                              <1> ; ----------------------------------------------------------------------------
  2096                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2097                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2098                              <1> ;
  2099                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2100                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2101                              <1> ; <Bell Laboratories (17/3/1972)>
  2102                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2103                              <1> ;
  2104                              <1> ; Retro UNIX 8086 v1 - U1.ASM (12/07/2014) //// UNIX v1 -> u1.s
  2105                              <1> ;
  2106                              <1> ; ****************************************************************************
  2107                              <1> 
  2108                              <1> unkni: ; / used for all system calls
  2109                              <1> sysent: ; < enter to system call >
  2110                              <1> 	; 25/12/2021 (Retro UNIX 386 v1.2)
  2111                              <1> 	; 19/10/2015
  2112                              <1> 	; 21/09/2015
  2113                              <1> 	; 01/07/2015
  2114                              <1> 	; 19/05/2015
  2115                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2116                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
  2117                              <1> 	;
  2118                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
  2119                              <1> 	; The trap type is determined and an indirect jump is made to 
  2120                              <1> 	; the appropriate system call handler. If there is a trap inside
  2121                              <1> 	; the system a jump to panic is made. All user registers are saved 
  2122                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
  2123                              <1> 	; instructor is decoded to get the the system code part (see
  2124                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
  2125                              <1> 	; the indirect jump address is calculated. If a bad system call is
  2126                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
  2127                              <1> 	; is called. If the call is legitimate control passes to the
  2128                              <1> 	; appropriate system routine.
  2129                              <1> 	;
  2130                              <1> 	; Calling sequence:
  2131                              <1> 	;	Through a trap caused by any sys call outside the system.
  2132                              <1> 	; Arguments:
  2133                              <1> 	;	Arguments of particular system call.	
  2134                              <1> 	; ...............................................................
  2135                              <1> 	;	
  2136                              <1> 	; Retro UNIX 8086 v1 modification: 
  2137                              <1> 	;       System call number is in EAX register.
  2138                              <1> 	;
  2139                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
  2140                              <1> 	;	registers depending of function details.
  2141                              <1>   	;
  2142                              <1> 	; 16/04/2015
  2143 00003043 368925[3C6C0000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
  2144                              <1> 	; save user registers
  2145 0000304A 1E                  <1> 	push	ds
  2146 0000304B 06                  <1> 	push	es
  2147 0000304C 0FA0                <1> 	push	fs
  2148 0000304E 0FA8                <1> 	push	gs
  2149 00003050 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  2150                              <1> 	;
  2151                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
  2152                              <1> 	; 	(ESPACE is size of space in kernel stack 
  2153                              <1> 	;	for saving/restoring user registers.)
  2154                              <1> 	;
  2155 00003051 50                  <1> 	push	eax ; 01/07/2015
  2156 00003052 66B81000            <1> 	mov     ax, KDATA
  2157 00003056 8ED8                <1>         mov     ds, ax
  2158 00003058 8EC0                <1>         mov     es, ax
  2159 0000305A 8EE0                <1>         mov     fs, ax
  2160 0000305C 8EE8                <1>         mov     gs, ax
  2161 0000305E A1[08670000]        <1> 	mov	eax, [k_page_dir]
  2162 00003063 0F22D8              <1> 	mov	cr3, eax
  2163 00003066 58                  <1> 	pop	eax ; 01/07/2015
  2164                              <1> 	; 19/10/2015
  2165 00003067 FC                  <1> 	cld
  2166                              <1> 	;
  2167 00003068 FE05[386C0000]      <1> 	inc	byte [sysflg]
  2168                              <1> 		; incb sysflg / indicate a system routine is in progress
  2169 0000306E FB                  <1>         sti 	; 18/01/2014
  2170                              <1> 	;jnz	panic ; 24/05/2013
  2171                              <1> 	; 04/12/2021
  2172 0000306F 7405                <1> 	jz	short _1
  2173 00003071 E91BF9FFFF          <1> 	jmp	panic
  2174                              <1> 		; beq 1f
  2175                              <1> 		; jmp panic ; / called if trap inside system
  2176                              <1> ;1:
  2177                              <1> _1:	; 04/12/2021
  2178                              <1> 	; 16/04/2015
  2179 00003076 A3[446C0000]        <1> 	mov	[u.r0], eax
  2180 0000307B 8925[406C0000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
  2181                              <1> 	;
  2182                              <1> 		; mov $s.syst+2,clockp
  2183                              <1> 		; mov r0,-(sp) / save user registers 
  2184                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
  2185                              <1> 			   ; / in u.r0
  2186                              <1> 		; mov r1,-(sp)
  2187                              <1> 		; mov r2,-(sp)
  2188                              <1> 		; mov r3,-(sp)
  2189                              <1> 		; mov r4,-(sp)
  2190                              <1> 		; mov r5,-(sp)
  2191                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
  2192                              <1> 		             ; / arithmetic unit
  2193                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
  2194                              <1> 		             ; / extended arithmetic unit
  2195                              <1> 		; mov sc,-(sp) / "step count" register for the extended
  2196                              <1> 		             ; / arithmetic unit
  2197                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
  2198                              <1> 		; mov 18.(sp),r0 / store pc in r0
  2199                              <1> 		; mov -(r0),r0 / sys inst in r0 10400xxx
  2200                              <1> 		; sub $sys,r0 / get xxx code
  2201 00003081 C1E002              <1> 	shl	eax, 2
  2202                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
  2203 00003084 3DA0000000          <1> 	cmp	eax, end_of_syscalls - syscalls
  2204                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
  2205                              <1> 	;jnb	short badsys
  2206                              <1> 		; bhis badsys / yes, bad system call
  2207                              <1> 	; 25/12/2021
  2208 00003089 7205                <1> 	jb	short _2
  2209 0000308B E969010000          <1> 	jmp	badsys
  2210                              <1> _2:
  2211                              <1> 	; 25/12/2021
  2212                              <1> 	;cmc
  2213                              <1> 	;pushf	
  2214                              <1> 	;push	eax
  2215 00003090 8B2D[3C6C0000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
  2216                              <1> 	;mov	al, 0FEh ; 11111110b
  2217                              <1> 	;;adc	al, 0 ; al = al + cf
  2218                              <1> 	;and	[ebp+8], al ; flags (reset carry flag)
  2219 00003096 806508FE            <1> 	and	byte [ebp+8], 0FEh ; 11111110b ; 25/12/2021
  2220                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
  2221                              <1> 				 ; / and clear carry bit
  2222                              <1> 	;pop	ebp ; eax
  2223 0000309A 89C5                <1> 	mov	ebp, eax ; 25/12/2021
  2224                              <1> 	;popf
  2225                              <1>         ;;jc	badsys
  2226                              <1> 	;; 04/12/2021
  2227                              <1> 	;jnc	short _3
  2228                              <1> 	;jmp	badsys
  2229                              <1> ;_3:
  2230 0000309C A1[446C0000]        <1> 	mov	eax, [u.r0]
  2231                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
  2232 000030A1 FFA5[A7300000]      <1> 	jmp	dword [ebp+syscalls]
  2233                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
  2234                              <1> 		            ; / to proper system routine.
  2235                              <1> 
  2236                              <1> 	; 09/01/2022
  2237                              <1> 	; 01/01/2022 (/etc/init error, BugFix efforts, test)
  2238                              <1> syscalls: ; 1:
  2239                              <1> 	; 21/09/2015
  2240                              <1> 	; 01/07/2015
  2241                              <1> 	; 16/04/2015 (32 bit address modification) 
  2242 000030A7 [C3310000]          <1> 	dd sysrele	; / 0
  2243 000030AB [6B320000]          <1> 	dd sysexit 	; / 1
  2244 000030AF [95330000]          <1> 	dd sysfork 	; / 2
  2245 000030B3 [9A340000]          <1> 	dd sysread 	; / 3
  2246 000030B7 [AF340000]          <1> 	dd syswrite 	; / 4
  2247 000030BB [12350000]          <1> 	dd sysopen 	; / 5
  2248 000030BF [3B360000]          <1> 	dd sysclose 	; / 6
  2249 000030C3 [10330000]          <1> 	dd syswait 	; / 7
  2250 000030C7 [A3350000]          <1> 	dd syscreat 	; / 8
  2251 000030CB [F1390000]          <1> 	dd syslink 	; / 9
  2252 000030CF [7F3A0000]          <1> 	dd sysunlink 	; / 10
  2253 000030D3 [9F3B0000]          <1> 	dd sysexec 	; / 11
  2254 000030D7 [0C420000]          <1> 	dd syschdir 	; / 12
  2255 000030DB [0E430000]          <1> 	dd systime 	; / 13
  2256 000030DF [EA350000]          <1> 	dd sysmkdir 	; / 14
  2257 000030E3 [4B420000]          <1> 	dd syschmod 	; / 15
  2258 000030E7 [7A420000]          <1> 	dd syschown 	; / 16
  2259 000030EB [42430000]          <1> 	dd sysbreak 	; / 17
  2260 000030EF [423F0000]          <1> 	dd sysstat 	; / 18
  2261 000030F3 [50440000]          <1> 	dd sysseek 	; / 19
  2262 000030F7 [62440000]          <1> 	dd systell 	; / 20
  2263 000030FB [10540000]          <1> 	dd sysmount 	; / 21
  2264 000030FF [29550000]          <1> 	dd sysumount 	; / 22
  2265 00003103 [D3440000]          <1> 	dd syssetuid 	; / 23
  2266 00003107 [08450000]          <1> 	dd sysgetuid 	; / 24
  2267 0000310B [1D430000]          <1> 	dd sysstime 	; / 25
  2268 0000310F [C7440000]          <1> 	dd sysquit 	; / 26
  2269 00003113 [BB440000]          <1> 	dd sysintr 	; / 27
  2270 00003117 [293F0000]          <1> 	dd sysfstat 	; / 28
  2271 0000311B [56360000]          <1> 	dd sysemt 	; / 29
  2272 0000311F [A4360000]          <1> 	dd sysmdate 	; / 30
  2273 00003123 [01370000]          <1> 	dd sysstty 	; / 31
  2274 00003127 [EB380000]          <1> 	dd sysgtty 	; / 32
  2275 0000312B [9F360000]          <1> 	dd sysilgins 	; / 33
  2276 0000312F [DC5C0000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
  2277                              <1> 			     ; 11/06/2014
  2278 00003133 [095D0000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
  2279                              <1> 			     ; 01/07/2015
  2280 00003137 [E15D0000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
  2281                              <1> 			     ; 21/09/2015 - get last error number
  2282                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
  2283                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
  2284 0000313B [21450000]          <1> 	dd syssetgid	; 37
  2285 0000313F [44450000]          <1> 	dd sysgetgid	; 38
  2286                              <1> 	; 18/06/2021 - Retro UNIX 386 v2 (ref: TRDOS 386 v2)
  2287 00003143 [59450000]          <1> 	dd sysver	; 39 ; (get) Retro Unix 386 version
  2288                              <1> 
  2289                              <1> end_of_syscalls:
  2290                              <1> 
  2291                              <1> error:
  2292                              <1> 	; 11/12/2021 (Retro UNIX 386 v1.2)
  2293                              <1> 	; 17/09/2015
  2294                              <1> 	; 03/09/2015
  2295                              <1> 	; 01/09/2015
  2296                              <1> 	; 09/06/2015
  2297                              <1> 	; 13/05/2015
  2298                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2299                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
  2300                              <1> 	;
  2301                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
  2302                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
  2303                              <1> 	;
  2304                              <1> 	; INPUTS -> none
  2305                              <1> 	; OUTPUTS ->
  2306                              <1> 	;	processor status - carry (c) bit is set (means error)
  2307                              <1> 	;
  2308                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
  2309                              <1> 	; 	      Because, jumps to error procedure
  2310                              <1> 	;	      disrupts push-pop nesting balance)
  2311                              <1> 	;
  2312 00003147 8B2D[3C6C0000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
  2313 0000314D 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
  2314                              <1> 				 ; (system call will return with cf = 1)
  2315                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
  2316                              <1> 		               ; / users stack
  2317                              <1> 	; 17/09/2015
  2318 00003151 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
  2319                              <1> 				 ; for saving/restoring user registers	
  2320                              <1> 	;cmp	ebp, [u.usp]
  2321                              <1> 	;je	short err0	
  2322 00003154 892D[406C0000]      <1> 	mov	[u.usp], ebp
  2323                              <1> ;err0:
  2324                              <1> 	; 01/09/2015
  2325 0000315A 8B25[406C0000]      <1> 	mov	esp, [u.usp]	; Retro Unix 8086 v1 modification!
  2326                              <1> 				; 10/04/2013
  2327                              <1> 				; (If an I/O error occurs during disk I/O,
  2328                              <1> 				; related procedures will jump to 'error'
  2329                              <1> 				; procedure directly without returning to 
  2330                              <1> 				; the caller procedure. So, stack pointer
  2331                              <1> 				; must be restored here.)
  2332                              <1> 	; 13/05/2015
  2333                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
  2334                              <1> 	;	'get last error' system call later. 	
  2335                              <1> 
  2336                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
  2337 00003160 C605[B66C0000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
  2338                              <1> 
  2339                              <1> sysret: ; < return from system call>
  2340                              <1> 	; 11/12/2021
  2341                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  2342                              <1> 	; 30/11/2021
  2343                              <1> 	; 10/09/2015
  2344                              <1> 	; 29/07/2015
  2345                              <1> 	; 25/06/2015
  2346                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2347                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
  2348                              <1> 	;
  2349                              <1> 	; 'sysret' first checks to see if process is about to be 
  2350                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
  2351                              <1> 	; If not, following happens:	 
  2352                              <1> 	; 	1) The user's stack pointer is restored.
  2353                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
  2354                              <1> 	;	   i-node has been modified. If it has, it is written out
  2355                              <1> 	;	   via 'ppoke'.
  2356                              <1> 	;	3) If the super block has been modified, it is written out
  2357                              <1> 	;	   via 'ppoke'.				
  2358                              <1> 	;	4) If the dismountable file system's super block has been
  2359                              <1> 	;	   modified, it is written out to the specified device
  2360                              <1> 	;	   via 'ppoke'.
  2361                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
  2362                              <1> 	;	   during his execution. If so, 'tswap' is called to give
  2363                              <1> 	;	   another user a chance to run.
  2364                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
  2365                              <1> 	;	    (See 'sysrele' for conclusion.)		
  2366                              <1> 	;
  2367                              <1> 	; Calling sequence:
  2368                              <1> 	;	jump table or 'br sysret'
  2369                              <1> 	; Arguments: 
  2370                              <1> 	;	-	
  2371                              <1> 	; ...............................................................
  2372                              <1> 	;	
  2373                              <1> 	; ((AX=r1 for 'iget' input))
  2374                              <1> 	;	
  2375                              <1> 	;xor	ax, ax ; 04/05/2013
  2376                              <1> 	; 30/11/2021
  2377 00003167 31C0                <1> 	xor	eax, eax
  2378                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
  2379 00003169 FEC0                <1> 	inc	al ; 04/05/2013
  2380 0000316B 3805[946C0000]      <1> 	cmp	[u.bsys], al ; 1
  2381                              <1> 		; tstb u.bsys / is a process about to be terminated because
  2382                              <1> 	;jnb	sysexit ; 04/05/2013
  2383                              <1> 	;	; bne sysexit / of an error? yes, go to sysexit
  2384                              <1> 	; 04/12/2021
  2385 00003171 720F                <1> 	jb	short _3
  2386                              <1> 	; 11/12/2021
  2387 00003173 C705[B86C0000]0100- <1> 	mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
  2387 0000317B 0000                <1>
  2388 0000317D E9E9000000          <1> 	jmp	sysexit
  2389                              <1> _3:
  2390                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
  2391                              <1> 		; mov u.sp,sp / no point stack to users stack
  2392 00003182 FEC8                <1> 	dec 	al ; mov ax, 0
  2393                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
  2394 00003184 E8CE190000          <1> 	call	iget
  2395                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
  2396                              <1> 		            ; / it is written out
  2397                              <1> 	;xor 	ax, ax ; 0
  2398                              <1> 	; 30/11/2021
  2399 00003189 31C0                <1> 	xor	eax, eax
  2400 0000318B 3805[366C0000]      <1> 	cmp	[smod], al ; 0
  2401                              <1> 		; tstb	smod / has the super block been modified
  2402 00003191 7614                <1> 	jna	short sysret1
  2403                              <1> 		; beq	1f / no, 1f
  2404 00003193 A2[366C0000]        <1> 	mov	[smod], al ; 0
  2405                              <1> 		; clrb smod / yes, clear smod
  2406 00003198 BB[EC6C0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
  2407 0000319D 66810B0002          <1>    	or	word [ebx], 200h ;;
  2408                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
  2409                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
  2410                              <1> 		      	      ; / output
  2411                              <1> 	; AX = 0
  2412 000031A2 E86F280000          <1> 	call 	poke ; 07/08/2013
  2413                              <1> 	;call	ppoke
  2414                              <1> 	; AX = 0
  2415                              <1> 		; jsr r0,ppoke / write out modified super block to disk
  2416                              <1> sysret1: ;1:
  2417 000031A7 3805[376C0000]      <1> 	cmp	[mmod], al ; 0
  2418                              <1> 		; tstb	mmod / has the super block for the dismountable file
  2419                              <1> 		           ; / system
  2420 000031AD 7614                <1> 	jna	short sysrel0
  2421                              <1> 		; beq 1f / been modified?  no, 1f
  2422 000031AF A2[376C0000]        <1> 	mov	[mmod], al ; 0	
  2423                              <1> 		; clrb	mmod / yes, clear mmod
  2424                              <1>         ;mov    ax, [mntd]
  2425                              <1>         ;;mov   al, [mdev] ; 26/04/2013
  2426 000031B4 BB[F46E0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
  2427                              <1>         ;;mov	[ebx], al
  2428                              <1> 	;mov    [sb1], al
  2429                              <1> 		; movb	mntd,sb1 / set the I/O queue
  2430 000031B9 66810B0002          <1> 	or	word [ebx], 200h
  2431                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
  2432                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
  2433 000031BE E853280000          <1> 	call	poke ; 07/08/2013
  2434                              <1> 	;call	ppoke 
  2435                              <1> 		; jsr r0,ppoke / write it out to its device
  2436                              <1>         ;xor    al, al ; 26/04/2013       
  2437                              <1> ;1:
  2438                              <1> 		; tstb uquant / is the time quantum 0?
  2439                              <1> 		; bne 1f / no, don't swap it out
  2440                              <1> 
  2441                              <1> sysrele: ; < release >
  2442                              <1> 	; 14/10/2015
  2443                              <1> 	; 01/09/2015
  2444                              <1> 	; 24/07/2015
  2445                              <1> 	; 14/05/2015
  2446                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2447                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
  2448                              <1> 	;
  2449                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
  2450                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
  2451                              <1> 	; turns off the system flag. It then checked to see if there is
  2452                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
  2453                              <1> 	; the output gets flashed (see isintr) and interrupt action is
  2454                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
  2455                              <1> 	; the user, a rti is made.
  2456                              <1> 	;
  2457                              <1> 	; Calling sequence:
  2458                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
  2459                              <1> 	; Arguments:
  2460                              <1> 	;	-	
  2461                              <1> 	; ...............................................................
  2462                              <1> 	;	
  2463                              <1> 	; 23/02/2014 (swapret)
  2464                              <1> 	; 22/09/2013
  2465                              <1> sysrel0: ;1:
  2466 000031C3 803D[8C6C0000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
  2467                              <1> 		; tstb uquant / is the time quantum 0?
  2468 000031CA 7705                <1>         ja      short swapret
  2469                              <1> 		; bne 1f / no, don't swap it out
  2470                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
  2471 000031CC E808140000          <1> 	call	tswap
  2472                              <1> 		; jsr r0,tswap / yes, swap it out
  2473                              <1> ;
  2474                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
  2475                              <1> swapret: ;1:
  2476                              <1> 	; 10/09/2015
  2477                              <1> 	; 01/09/2015
  2478                              <1> 	; 14/05/2015
  2479                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
  2480                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
  2481                              <1> 	; cli
  2482                              <1> 	; 24/07/2015
  2483                              <1> 	;
  2484                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
  2485                              <1> 	;; mov	esp, [u.usp]
  2486                              <1> 
  2487                              <1> 	; 22/09/2013
  2488 000031D1 E8DA150000          <1> 	call	isintr
  2489                              <1> 	; 20/10/2013
  2490 000031D6 7405                <1> 	jz	short sysrel1
  2491 000031D8 E877000000          <1> 	call	intract
  2492                              <1> 		; jsr r0,isintr / is there an interrupt from the user
  2493                              <1> 		;     br intract / yes, output gets flushed, take interrupt
  2494                              <1> 		               ; / action
  2495                              <1> sysrel1:
  2496 000031DD FA                  <1> 	cli ; 14/10/2015
  2497 000031DE FE0D[386C0000]      <1> 	dec	byte [sysflg]
  2498                              <1> 		; decb sysflg / turn system flag off
  2499 000031E4 A1[A46C0000]        <1> 	mov     eax, [u.pgdir]
  2500 000031E9 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
  2501                              <1> 			  ; (others are different than kernel page tables) 
  2502                              <1> 	; 10/09/2015
  2503 000031EC 61                  <1> 	popad ; edi, esi, ebp, temp (increment esp by 4), ebx, edx, ecx, eax
  2504                              <1> 		; mov (sp)+,sc / restore user registers
  2505                              <1> 		; mov (sp)+,mq
  2506                              <1> 		; mov (sp)+,ac
  2507                              <1> 		; mov (sp)+,r5
  2508                              <1> 		; mov (sp)+,r4
  2509                              <1> 		; mov (sp)+,r3
  2510                              <1> 		; mov (sp)+,r2
  2511                              <1> 	;
  2512 000031ED A1[446C0000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
  2513 000031F2 0FA9                <1> 	pop	gs
  2514 000031F4 0FA1                <1> 	pop	fs
  2515 000031F6 07                  <1> 	pop	es
  2516 000031F7 1F                  <1> 	pop	ds
  2517 000031F8 CF                  <1> 	iretd	
  2518                              <1> 		; rti / no, return from interrupt
  2519                              <1> 
  2520                              <1> badsys:
  2521                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2522                              <1> 	; (Major Modification: 'core' dumping procedure in
  2523                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
  2524                              <1> 	;	has been changed to print 'Invalid System Call !'
  2525                              <1> 	;	message on the user's console tty.)
  2526                              <1> 	; (EIP, EAX values will be shown on screen with error message)
  2527                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
  2528                              <1> 	; (EAX = Function number)  
  2529                              <1> 	;
  2530 000031F9 FE05[946C0000]      <1> 	inc	byte [u.bsys]
  2531                              <1> 	;
  2532 000031FF 8B1D[3C6C0000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
  2533 00003205 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
  2534 00003207 E8BCE3FFFF          <1> 	call	dwordtohex
  2535 0000320C 8915[68640000]      <1> 	mov	[bsys_msg_eip], edx
  2536 00003212 A3[6C640000]        <1> 	mov	[bsys_msg_eip+4], eax
  2537 00003217 A1[446C0000]        <1> 	mov	eax, [u.r0]
  2538 0000321C E8A7E3FFFF          <1> 	call	dwordtohex
  2539 00003221 8915[58640000]      <1> 	mov	[bsys_msg_eax], edx
  2540 00003227 A3[5C640000]        <1> 	mov	[bsys_msg_eax+4], eax
  2541                              <1> 	; 11/12/2021
  2542                              <1> 	;xor	eax, eax
  2543                              <1> 	;mov	dword [u.base], badsys_msg ; "Invalid System Call !"
  2544                              <1> 	;mov	ebx, [u.fofp]
  2545                              <1> 	;mov	[ebx], eax
  2546                              <1> 	;;mov	eax, 1 ; inode number of console tty (for user)	
  2547                              <1> 	;inc	eax
  2548                              <1> 	; 11/12/2021 - Retro UNIX 386 v2 fs compatibility 
  2549                              <1> 	; (Retro UNIX 386 v1.2)
  2550                              <1> 	;mov	al, 8 ; /dev/tty inode number (runix v2 fs)
  2551                              <1> 	;; eax = 8 ; inode number of console tty (for user)	
  2552                              <1> 	;mov	dword [u.count], BSYS_M_SIZE
  2553                              <1> 		; writei
  2554                              <1> 		; INPUTS ->
  2555                              <1> 		;    r1 - inode number
  2556                              <1> 		;    u.count - byte count to be written
  2557                              <1> 		;    u.base - points to user buffer
  2558                              <1> 		;    u.fofp - points to word with current file offset
  2559                              <1> 		; OUTPUTS ->
  2560                              <1> 		;    u.count - cleared
  2561                              <1> 		;    u.nread - accumulates total bytes passed back	
  2562                              <1> 		;
  2563                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
  2564                              <1> 	;call	writei
  2565                              <1> 	;;mov	eax, 1
  2566                              <1> 	;jmp	sysexit
  2567                              <1> 
  2568                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
  2569 0000322C BE[39640000]        <1> 	mov	esi, badsys_msg ; "Invalid System Call !"
  2570 00003231 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  2571 00003238 8A83[43680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
  2572 0000323E C605[37670000]0F    <1> 	mov	byte [ccolor], 0Fh ; white (message) color
  2573 00003245 A2[796C0000]        <1> 	mov 	[u.ttyn], al ; current (active) tty (for user)
  2574 0000324A E8772B0000          <1> 	call	print_cmsg
  2575                              <1> 	;mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
  2576 0000324F E9F3FEFFFF          <1> 	jmp	error
  2577                              <1> 
  2578                              <1> 		; incb u.bsys / turn on the user's bad-system flag
  2579                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
  2580                              <1> 		; jsr r0,namei / get the i-number for the core image file
  2581                              <1> 		; br 1f / error
  2582                              <1> 		; neg r1 / negate the i-number to open the core image file
  2583                              <1> 		       ; / for writing
  2584                              <1> 		; jsr r0,iopen / open the core image file
  2585                              <1> 		; jsr r0,itrunc / free all associated blocks
  2586                              <1> 		; br 2f
  2587                              <1> ;1:
  2588                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
  2589                              <1> 		; jsr r0,maknod / make an i-node
  2590                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
  2591                              <1> ;2:
  2592                              <1> 		; mov $core,u.base / move address core to u.base
  2593                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
  2594                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
  2595                              <1> 		; clr u.off / clear user offset
  2596                              <1> 		; jsr r0,writei / write out the core image to the user
  2597                              <1> 		; mov $user,u.base / pt. u.base to user
  2598                              <1> 		; mov $64.,u.count / u.count = 64
  2599                              <1> 		; jsr r0,writei / write out all the user parameters
  2600                              <1> 		; neg r1 / make i-number positive
  2601                              <1> 		; jsr r0,iclose / close the core image file
  2602                              <1> 		; br sysexit /
  2603                              <1> ;3:
  2604                              <1> 		; <core\0\0>
  2605                              <1> 
  2606                              <1> intract: ; / interrupt action
  2607                              <1> 	; 14/10/2015
  2608                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2609                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
  2610                              <1> 	;
  2611                              <1> 	; Retro UNIX 8086 v1 modification !
  2612                              <1> 	; (Process/task switching and quit routine by using
  2613                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
  2614                              <1> 	;
  2615                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
  2616                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
  2617                              <1> 	;		'intract' will jump to 'sysexit'.
  2618                              <1> 	;	    Intract will return to the caller 
  2619                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
  2620                              <1> 	; 14/10/2015
  2621 00003254 FB                  <1> 	sti
  2622                              <1> 	; 07/12/2013	
  2623 00003255 66FF05[926C0000]    <1> 	inc 	word [u.quit]
  2624 0000325C 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
  2625 0000325E 66FF0D[926C0000]    <1> 	dec	word [u.quit]
  2626                              <1> 	; 16/04/2015
  2627 00003265 C3                  <1> 	retn
  2628                              <1> intrct0:	
  2629 00003266 58                  <1> 	pop	eax ; call intract -> retn
  2630                              <1> 	;
  2631 00003267 31C0                <1> 	xor 	eax, eax
  2632 00003269 FEC0                <1> 	inc	al  ; mov ax, 1
  2633                              <1> ;;;
  2634                              <1> 	; UNIX v1 original 'intract' routine... 
  2635                              <1> 	; / interrupt action
  2636                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
  2637                              <1> 		; bne 1f / no, 1f
  2638                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
  2639                              <1> 	; 1: / now in user area
  2640                              <1> 		; mov r1,-(sp) / save r1
  2641                              <1> 		; mov u.ttyp,r1 
  2642                              <1> 			; / pointer to tty buffer in control-to r1
  2643                              <1> 		; cmpb 6(r1),$177
  2644                              <1> 			; / is the interrupt char equal to "del"
  2645                              <1> 		; beq 1f / yes, 1f
  2646                              <1> 		; clrb 6(r1) 
  2647                              <1> 		        ; / no, clear the byte 
  2648                              <1> 			; / (must be a quit character)
  2649                              <1> 		; mov (sp)+,r1 / restore r1
  2650                              <1> 		; clr u.quit / clear quit flag
  2651                              <1> 		; bis $20,2(sp) 
  2652                              <1> 		    	; / set trace for quit (sets t bit of 
  2653                              <1> 			; / ps-trace trap)
  2654                              <1> 		; rti   ;  / return from interrupt
  2655                              <1> 	; 1: / interrupt char = del
  2656                              <1> 		; clrb 6(r1) / clear the interrupt byte 
  2657                              <1> 			   ; / in the buffer
  2658                              <1> 		; mov (sp)+,r1 / restore r1
  2659                              <1> 		; cmp u.intr,$core / should control be 
  2660                              <1> 				; / transferred to loc core?
  2661                              <1> 		; blo 1f
  2662                              <1> 		; jmp *u.intr / user to do rti yes, 
  2663                              <1> 				; / transfer to loc core
  2664                              <1> 	; 1:
  2665                              <1> 		; sys 1 / exit
  2666                              <1> 
  2667                              <1> sysexit: ; <terminate process>
  2668                              <1> 	; 17/07/2022
  2669                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
  2670                              <1> 	; 01/09/2015
  2671                              <1> 	; 31/08/2015
  2672                              <1> 	; 14/05/2015
  2673                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2674                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
  2675                              <1> 	;
  2676                              <1> 	; 'sysexit' terminates a process. First each file that
  2677                              <1> 	; the process has opened is closed by 'flose'. The process
  2678                              <1> 	; status is then set to unused. The 'p.pid' table is then
  2679                              <1> 	; searched to find children of the dying process. If any of
  2680                              <1> 	; children are zombies (died by not waited for), they are
  2681                              <1> 	; set free. The 'p.pid' table is then searched to find the
  2682                              <1> 	; dying process's parent. When the parent is found, it is
  2683                              <1> 	; checked to see if it is free or it is a zombie. If it is
  2684                              <1> 	; one of these, the dying process just dies. If it is waiting
  2685                              <1> 	; for a child process to die, it notified that it doesn't 
  2686                              <1> 	; have to wait anymore by setting it's status from 2 to 1
  2687                              <1> 	; (waiting to active). It is awakened and put on runq by
  2688                              <1> 	; 'putlu'. The dying process enters a zombie state in which
  2689                              <1> 	; it will never be run again but stays around until a 'wait'
  2690                              <1> 	; is completed by it's parent process. If the parent is not
  2691                              <1> 	; found, process just dies. This means 'swap' is called with
  2692                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
  2693                              <1> 	; to write out the process and 'rswap' reads the new process
  2694                              <1> 	; over the one that dies..i.e., the dying process is 
  2695                              <1> 	; overwritten and destroyed.	
  2696                              <1>  	;
  2697                              <1> 	; Calling sequence:
  2698                              <1> 	;	sysexit or conditional branch.
  2699                              <1> 	; Arguments:
  2700                              <1> 	;	-	
  2701                              <1> 	; ...............................................................
  2702                              <1> 	;	
  2703                              <1> 	; Retro UNIX 8086 v1 modification: 
  2704                              <1> 	;       System call number (=1) is in EAX register.
  2705                              <1> 	;
  2706                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
  2707                              <1> 	;       registers depending of function details.
  2708                              <1> 	;
  2709                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
  2710                              <1> 	;
  2711                              <1> ; / terminate process
  2712                              <1> 	; AX = 1
  2713                              <1> 	;dec 	ax ; 0
  2714                              <1> 	; 30/11/2021
  2715 0000326B 48                  <1> 	dec	eax ; 0
  2716 0000326C 66A3[906C0000]      <1> 	mov	[u.intr], ax ; 0
  2717                              <1> 		; clr u.intr / clear interrupt control word
  2718                              <1> 		; clr r1 / clear r1
  2719                              <1> 	; AX = 0
  2720                              <1> sysexit_1: ; 1:
  2721                              <1> 	; AX = File descriptor
  2722                              <1> 		; / r1 has file descriptor (index to u.fp list)
  2723                              <1> 		; / Search the whole list
  2724 00003272 E8690D0000          <1> 	call	fclose
  2725                              <1> 		; jsr r0,fclose / close all files the process opened
  2726                              <1> 	;; ignore error return
  2727                              <1> 		; br .+2 / ignore error return
  2728                              <1> 	;inc	ax
  2729 00003277 FEC0                <1> 	inc	al
  2730                              <1> 		; inc r1 / increment file descriptor
  2731                              <1> 	;cmp	ax, 10
  2732 00003279 3C0A                <1> 	cmp	al, 10
  2733                              <1> 		; cmp r1,$10. / end of u.fp list?
  2734 0000327B 72F5                <1> 	jb	short sysexit_1
  2735                              <1> 		; blt 1b / no, go back
  2736 0000327D 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
  2737                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
  2738 00003284 88A3[63680000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
  2739                              <1> 		; clrb p.stat-1(r1) / free the process
  2740                              <1> 	;shl	bx, 1
  2741 0000328A D0E3                <1> 	shl	bl, 1
  2742                              <1> 		; asl r1 / use r1 for index into the below tables
  2743 0000328C 668B8B[02680000]    <1> 	mov	cx, [ebx+p.pid-2]
  2744                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
  2745 00003293 668B93[22680000]    <1> 	mov	dx, [ebx+p.ppid-2]
  2746                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
  2747                              <1> 	; xor 	bx, bx ; 0
  2748 0000329A 30DB                <1> 	xor	bl, bl ; 0
  2749                              <1> 		; clr r2
  2750 0000329C 31F6                <1> 	xor	esi, esi ; 0
  2751                              <1> 		; clr r5 / initialize reg
  2752                              <1> sysexit_2: ; 1:
  2753                              <1> 	        ; / find children of this dying process, 
  2754                              <1> 		; / if they are zombies, free them
  2755                              <1> 	;add	bx, 2
  2756 0000329E 80C302              <1> 	add	bl, 2
  2757                              <1> 		; add $2,r2 / search parent process table 
  2758                              <1> 		          ; / for dying process's name
  2759 000032A1 66398B[22680000]    <1> 	cmp	[ebx+p.ppid-2], cx
  2760                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
  2761 000032A8 7513                <1> 	jne	short sysexit_4
  2762                              <1> 		; bne 3f / no
  2763                              <1> 	;shr	bx, 1
  2764 000032AA D0EB                <1> 	shr	bl, 1
  2765                              <1> 		; asr r2 / yes, it is a parent
  2766 000032AC 80BB[63680000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
  2767                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
  2768                              <1> 				     ; / dying process a zombie
  2769 000032B3 7506                <1> 	jne	short sysexit_3 
  2770                              <1> 		; bne 2f / no
  2771 000032B5 88A3[63680000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
  2772                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
  2773                              <1> sysexit_3: ; 2:
  2774                              <1> 	;shr	bx, 1
  2775 000032BB D0E3                <1> 	shl	bl, 1
  2776                              <1> 		; asl r2
  2777                              <1> sysexit_4: ; 3:
  2778                              <1> 		; / search the process name table 
  2779                              <1> 		; / for the dying process's parent
  2780 000032BD 663993[02680000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
  2781                              <1> 		; cmp p.pid-2(r2),r4 / found it?
  2782 000032C4 7502                <1> 	jne	short sysexit_5
  2783                              <1> 		; bne 3f / no
  2784 000032C6 89DE                <1> 	mov	esi, ebx
  2785                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
  2786                              <1> 		          ; / process # x2) in r5
  2787                              <1> sysexit_5: ; 3:
  2788                              <1> 	;cmp	bx, nproc + nproc
  2789 000032C8 80FB20              <1> 	cmp	bl, nproc + nproc
  2790                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
  2791 000032CB 72D1                <1> 	jb	short sysexit_2
  2792                              <1> 		; blt 1b / no, go back
  2793                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
  2794 000032CD 21F6                <1> 	and	esi, esi ; r5=r1
  2795 000032CF 7430                <1> 	jz	short sysexit_6
  2796                              <1> 		; beq 2f / no parent has been found. 
  2797                              <1> 		       ; / The process just dies
  2798                              <1> 	;shr	si, 1
  2799                              <1> 	; 17/07/2022
  2800 000032D1 D1EE                <1> 	shr	esi, 1
  2801                              <1> 		; asr r1 / set up index to p.stat
  2802 000032D3 8A86[63680000]      <1> 	mov	al, [esi+p.stat-1]
  2803                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
  2804 000032D9 20C0                <1> 	and	al, al
  2805 000032DB 7424                <1> 	jz	short sysexit_6
  2806                              <1> 		; beq 2f / if its been freed, 2f
  2807 000032DD 3C03                <1> 	cmp	al, 3
  2808                              <1> 		; cmp r2,$3 / is parent a zombie?
  2809 000032DF 7420                <1> 	je	short sysexit_6
  2810                              <1> 		; beq 2f / yes, 2f
  2811                              <1> 	; BH = 0
  2812 000032E1 8A1D[956C0000]      <1> 	mov	bl, [u.uno]
  2813                              <1> 		; movb u.uno,r3 / move dying process's number to r3
  2814 000032E7 C683[63680000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
  2815                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
  2816                              <1> 	; 05/02/2014
  2817 000032EE 3C01                <1> 	cmp	al, 1 ; SRUN
  2818 000032F0 740F                <1> 	je	short sysexit_6
  2819                              <1> 	;cmp	al, 2
  2820                              <1> 		; cmp r2,$2 / is the parent waiting for 
  2821                              <1> 			  ; / this child to die
  2822                              <1> 	;jne	short sysexit_6	
  2823                              <1> 		; bne 2f / yes, notify parent not to wait any more
  2824                              <1> 	; 05/02/2014
  2825                              <1> 	; p.stat = 2 --> waiting
  2826                              <1> 	; p.stat = 4 --> sleeping
  2827 000032F2 C686[63680000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
  2828                              <1> 	;dec	byte [esi+p.stat-1]
  2829                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
  2830 000032F9 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
  2831                              <1> 	; 
  2832                              <1> 	;mov	ebx, runq + 4
  2833                              <1> 		; mov $runq+4,r2 / on the runq
  2834 000032FC E8AF130000          <1> 	call	putlu
  2835                              <1> 		; jsr r0, putlu
  2836                              <1> sysexit_6: ; 2:
  2837                              <1> 	; 31/08/2015
  2838                              <1> 		; / the process dies
  2839 00003301 C605[956C0000]00    <1> 	mov	byte [u.uno], 0
  2840                              <1> 		; clrb u.uno / put zero as the process number, 
  2841                              <1> 	           ; / so "swap" will
  2842 00003308 E8D6120000          <1> 	call	swap
  2843                              <1> 		; jsr r0,swap / overwrite process with another process
  2844                              <1> hlt_sys:
  2845                              <1> 	;sti ; 18/01/2014
  2846                              <1> hlts0:
  2847 0000330D F4                  <1> 	hlt
  2848 0000330E EBFD                <1> 	jmp	short hlts0
  2849                              <1> 		; 0 / and thereby kill it; halt?
  2850                              <1> 
  2851                              <1> syswait: ; < wait for a processs to die >
  2852                              <1> 	; 09/02/2022
  2853                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
  2854                              <1> 	; 17/09/2015
  2855                              <1> 	; 02/09/2015
  2856                              <1> 	; 01/09/2015
  2857                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
  2858                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
  2859                              <1> 	;
  2860                              <1> 	; 'syswait' waits for a process die. 
  2861                              <1> 	; It works in following way:
  2862                              <1> 	;    1) From the parent process number, the parent's 
  2863                              <1> 	; 	process name is found. The p.ppid table of parent
  2864                              <1> 	;	names is then searched for this process name.
  2865                              <1> 	;	If a match occurs, r2 contains child's process
  2866                              <1> 	;	number. The child status is checked to see if it is
  2867                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
  2868                              <1> 	;	If it is, the child process is freed and it's name
  2869                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
  2870                              <1> 	;	If the child is not a zombie, nothing happens and
  2871                              <1> 	;	the search goes on through the p.ppid table until
  2872                              <1> 	;	all processes are checked or a zombie is found.
  2873                              <1> 	;    2) If no zombies are found, a check is made to see if
  2874                              <1> 	;	there are any children at all. If there are none,
  2875                              <1> 	;	an error return is made. If there are, the parent's
  2876                              <1> 	;	status is set to 2 (waiting for child to die),
  2877                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
  2878                              <1> 	;	is made to wait on the next process.
  2879                              <1> 	;
  2880                              <1> 	; Calling sequence:
  2881                              <1> 	;	?
  2882                              <1> 	; Arguments:
  2883                              <1> 	;	-
  2884                              <1> 	; Inputs: - 
  2885                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
  2886                              <1> 	; ...............................................................
  2887                              <1> 	;				
  2888                              <1> 	
  2889                              <1> ; / wait for a process to die
  2890                              <1> 
  2891                              <1> syswait_0:
  2892 00003310 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
  2893                              <1> 		; movb u.uno,r1 / put parents process number in r1
  2894 00003317 D0E3                <1> 	shl	bl, 1
  2895                              <1> 	;shl	bx, 1
  2896                              <1> 		; asl r1 / x2 to get index into p.pid table
  2897 00003319 668B83[02680000]    <1> 	mov	ax, [ebx+p.pid-2]
  2898                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
  2899 00003320 31F6                <1> 	xor	esi, esi
  2900                              <1> 		; clr r2
  2901 00003322 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
  2902                              <1> 	;xor 	cl, cl
  2903                              <1> 		; clr r3 / initialize reg 3
  2904                              <1> syswait_1: ; 1:
  2905                              <1> 	; 09/02/2022
  2906 00003324 46                  <1> 	inc	esi
  2907 00003325 46                  <1> 	inc	esi
  2908                              <1> 	;add	si, 2
  2909                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
  2910                              <1> 			  ; / search table of parent processes 
  2911                              <1> 			  ; / for this process name
  2912 00003326 663B86[22680000]    <1> 	cmp	ax, [esi+p.ppid-2]
  2913                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
  2914                              <1> 			            ; / process number
  2915 0000332D 7531                <1> 	jne	short syswait_3
  2916                              <1> 		; bne 3f / branch if no match of parent process name
  2917                              <1> 	;inc	cx
  2918 0000332F FEC1                <1> 	inc	cl
  2919                              <1> 		; inc r3 / yes, a match, r3 indicates number of children
  2920                              <1> 	; 09/02/2022
  2921 00003331 D1EE                <1> 	shr	esi, 1
  2922                              <1> 	;shr	si, 1
  2923                              <1> 		; asr r2 / r2/2 to get index to p.stat table
  2924                              <1> 	; The possible states ('p.stat' values) of a process are:
  2925                              <1> 	;	0 = free or unused
  2926                              <1> 	;	1 = active
  2927                              <1> 	;	2 = waiting for a child process to die
  2928                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
  2929 00003333 80BE[63680000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
  2930                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
  2931 0000333A 7522                <1> 	jne	short syswait_2
  2932                              <1> 		; bne 2f / no, skip it
  2933 0000333C 88BE[63680000]      <1> 	mov	[esi+p.stat-1], bh ; 0
  2934                              <1> 		; clrb p.stat-1(r2) / yes, free it
  2935                              <1> 	; 09/02/2022
  2936 00003342 D1E6                <1> 	shl	esi, 1
  2937                              <1> 	;shl	si, 1
  2938                              <1> 		; asl r2 / r2x2 to get index into p.pid table
  2939 00003344 0FB786[02680000]    <1> 	movzx	eax, word [esi+p.pid-2]
  2940 0000334B A3[446C0000]        <1> 	mov	[u.r0], eax
  2941                              <1> 		; mov p.pid-2(r2),*u.r0 
  2942                              <1> 			      ; / put childs process name in (u.r0)
  2943                              <1> 	;
  2944                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
  2945                              <1> 	;
  2946                              <1> 	; Parent process ID -p.ppid- field (of the child process)
  2947                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
  2948                              <1> 	; system call loop from the application/program if it calls
  2949                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
  2950                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
  2951                              <1> 	;
  2952                              <1> 	; Note: syswait will return with error if there is not a
  2953                              <1> 	;       zombie or running process to wait.	
  2954                              <1> 	;
  2955                              <1> 	;sub	ax, ax
  2956                              <1> 	; 08/01/2022
  2957 00003350 29C0                <1> 	sub	eax, eax
  2958 00003352 668986[22680000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
  2959 00003359 E90BFEFFFF          <1> 	jmp	sysret0 ; ax = 0
  2960                              <1> 	;
  2961                              <1> 	;jmp	sysret
  2962                              <1> 		; br sysret1 / return cause child is dead
  2963                              <1> syswait_2: ; 2:
  2964                              <1> 	; 09/02/2022
  2965 0000335E D1E6                <1> 	shl	esi, 1
  2966                              <1> 	;shl	si, 1
  2967                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
  2968                              <1> syswait_3: ; 3:
  2969 00003360 6683FE20            <1> 	cmp	si, nproc+nproc
  2970                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
  2971 00003364 72BE                <1> 	jb	short syswait_1
  2972                              <1> 		; blt 1b / no, continue search
  2973                              <1> 	;and	cx, cx
  2974 00003366 20C9                <1> 	and	cl, cl
  2975                              <1> 		; tst r3 / one gets here if there are no children 
  2976                              <1> 		       ; / or children that are still active
  2977                              <1> 	; 30/10/2013
  2978 00003368 7515                <1> 	jnz	short syswait_4
  2979                              <1> 	;jz	error
  2980                              <1> 		; beq error1 / there are no children, error
  2981 0000336A 890D[446C0000]      <1> 	mov	[u.r0], ecx ; 0
  2982                              <1> 	; 09/02/2022
  2983 00003370 C705[B86C0000]1B00- <1> 	mov	dword [u.error], ERR_MISC ; 27
  2983 00003378 0000                <1>
  2984                              <1> 			; miscellaneous/other errors
  2985 0000337A E9C8FDFFFF          <1> 	jmp	error
  2986                              <1> syswait_4:
  2987 0000337F 8A1D[956C0000]      <1> 	mov	bl, [u.uno]
  2988                              <1> 		; movb u.uno,r1 / there are children so put 
  2989                              <1> 			      ; / parent process number in r1
  2990 00003385 FE83[63680000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
  2991                              <1> 		; incb p.stat-1(r1) / it is waiting for 
  2992                              <1> 				  ; / other children to die
  2993                              <1> 	; 04/11/2013
  2994 0000338B E853120000          <1> 	call	swap
  2995                              <1> 		; jsr r0,swap / swap it out, because it's waiting
  2996 00003390 E97BFFFFFF          <1> 	jmp	syswait_0
  2997                              <1> 		; br syswait / wait on next process
  2998                              <1> 
  2999                              <1> sysfork: ; < create a new process >
  3000                              <1> 	; 27/02/2022
  3001                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
  3002                              <1> 	; 18/09/2015
  3003                              <1> 	; 04/09/2015
  3004                              <1> 	; 02/09/2015
  3005                              <1> 	; 01/09/2015
  3006                              <1> 	; 28/08/2015
  3007                              <1> 	; 14/05/2015
  3008                              <1> 	; 10/05/2015
  3009                              <1> 	; 09/05/2015
  3010                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
  3011                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
  3012                              <1> 	;
  3013                              <1> 	; 'sysfork' creates a new process. This process is referred
  3014                              <1> 	; to as the child process. This new process core image is
  3015                              <1> 	; a copy of that of the caller of 'sysfork'. The only
  3016                              <1> 	; distinction is the return location and the fact that (u.r0)
  3017                              <1> 	; in the old process (parent) contains the process id (p.pid)
  3018                              <1> 	; of the new process (child). This id is used by 'syswait'.
  3019                              <1> 	; 'sysfork' works in the following manner: 	
  3020                              <1> 	;    1) The process status table (p.stat) is searched to find
  3021                              <1> 	;	a process number that is unused. If none are found
  3022                              <1> 	;	an error occurs.
  3023                              <1> 	;    2) when one is found, it becomes the child process number
  3024                              <1> 	;	and it's status (p.stat) is set to active.
  3025                              <1> 	;    3) If the parent had a control tty, the interrupt 
  3026                              <1> 	;	character in that tty buffer is cleared.
  3027                              <1> 	;    4) The child process is put on the lowest priority run 
  3028                              <1> 	;	queue via 'putlu'.
  3029                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
  3030                              <1> 	;	it is a unique number) and is put in the child's unique
  3031                              <1> 	;	identifier; process id (p.pid).
  3032                              <1> 	;    6) The process name of the parent is then obtained and
  3033                              <1> 	;	placed in the unique identifier of the parent process
  3034                              <1> 	;	name is then put in 'u.r0'.	
  3035                              <1> 	;    7) The child process is then written out on disk by
  3036                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
  3037                              <1> 	;	and the child is born. (The child process is written 
  3038                              <1> 	;	out on disk/drum with 'u.uno' being the child process
  3039                              <1> 	;	number.)
  3040                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
  3041                              <1> 	;    9) The child process name is put in 'u.r0'.
  3042                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
  3043                              <1> 	;	create the return address for the parent process.
  3044                              <1> 	;   11) The 'u.fp' list as then searched to see what files
  3045                              <1> 	;	the parent has opened. For each file the parent has
  3046                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
  3047                              <1> 	;	to indicate that the child process also has opened
  3048                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
  3049                              <1> 	;
  3050                              <1> 	; Calling sequence:
  3051                              <1> 	;	from shell ?
  3052                              <1> 	; Arguments:
  3053                              <1> 	;	-
  3054                              <1> 	; Inputs: -
  3055                              <1> 	; Outputs: *u.r0 - child process name
  3056                              <1> 	; ...............................................................
  3057                              <1> 	;	
  3058                              <1> 	; Retro UNIX 8086 v1 modification: 
  3059                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
  3060                              <1> 	;	= process id of child a parent process returns
  3061                              <1> 	;	= process id of parent when a child process returns
  3062                              <1> 	;
  3063                              <1> 	;       In original UNIX v1, sysfork is called and returns as
  3064                              <1> 	;	in following manner: (with an example: c library, fork)
  3065                              <1> 	;	
  3066                              <1> 	;	1:
  3067                              <1> 	;		sys	fork
  3068                              <1> 	;			br 1f  / child process returns here
  3069                              <1> 	;		bes	2f     / parent process returns here
  3070                              <1> 	;		/ pid of new process in r0
  3071                              <1> 	;		rts	pc
  3072                              <1> 	;	2: / parent process condionally branches here
  3073                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
  3074                              <1> 	;		rts	pc
  3075                              <1> 	;
  3076                              <1> 	;	1: / child process brances here
  3077                              <1> 	;		clr	r0   / pid = 0 in child process
  3078                              <1> 	;		rts	pc
  3079                              <1> 	;
  3080                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
  3081                              <1> 	;		// pid = fork();
  3082                              <1> 	;		//
  3083                              <1> 	;		// pid == 0 in child process; 
  3084                              <1> 	;		// pid == -1 means error return
  3085                              <1> 	;		// in child, 
  3086                              <1> 	;		//	parents id is in par_uid if needed
  3087                              <1> 	;		
  3088                              <1> 	;		_fork:
  3089                              <1> 	;			mov	$.fork,eax
  3090                              <1> 	;			int	$0x30
  3091                              <1> 	;			jmp	1f
  3092                              <1> 	;			jnc	2f
  3093                              <1> 	;			jmp	cerror
  3094                              <1> 	;		1:
  3095                              <1> 	;			mov	eax,_par_uid
  3096                              <1> 	;			xor	eax,eax
  3097                              <1> 	;		2:
  3098                              <1> 	;			ret
  3099                              <1> 	;
  3100                              <1> 	;	In Retro UNIX 8086 v1,
  3101                              <1> 	;	'sysfork' returns in following manner:
  3102                              <1> 	;	
  3103                              <1> 	;		mov	ax, sys_fork
  3104                              <1> 	;		mov	bx, offset @f ; routine for child
  3105                              <1> 	;		int	20h
  3106                              <1> 	;		jc	error
  3107                              <1> 	;		
  3108                              <1> 	;	; Routine for parent process here (just after 'jc')
  3109                              <1> 	;		mov	word ptr [pid_of_child], ax
  3110                              <1> 	;		jmp	next_routine_for_parent	
  3111                              <1> 	;
  3112                              <1> 	;	@@: ; routine for child process here				
  3113                              <1> 	;		....	
  3114                              <1> 	;	NOTE: 'sysfork' returns to specified offset
  3115                              <1> 	;	       for child process by using BX input.
  3116                              <1> 	;	      (at first, parent process will return then 
  3117                              <1> 	;	      child process will return -after swapped in-
  3118                              <1> 	;	      'syswait' is needed in parent process
  3119                              <1> 	;	      if return from child process will be waited for.)
  3120                              <1> 	;	  				
  3121                              <1> 	
  3122                              <1> ; / create a new process
  3123                              <1> 	; EBX = return address for child process 
  3124                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
  3125 00003395 31F6                <1> 	xor 	esi, esi
  3126                              <1> 		; clr r1
  3127                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
  3128 00003397 46                  <1> 	inc	esi
  3129                              <1> 		; inc r1
  3130 00003398 80BE[63680000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
  3131                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
  3132 0000339F 760B                <1> 	jna	short sysfork_2	
  3133                              <1> 		; beq 1f / it's unused so branch
  3134 000033A1 6683FE10            <1> 	cmp	si, nproc
  3135                              <1> 		; cmp r1,$nproc / all processes checked
  3136 000033A5 72F0                <1> 	jb	short sysfork_1
  3137                              <1> 		; blt 1b / no, branch back
  3138                              <1> 	;
  3139                              <1> 	; Retro UNIX 8086 v1. modification:
  3140                              <1> 	;	Parent process returns from 'sysfork' to address 
  3141                              <1> 	;	which is just after 'sysfork' system call in parent
  3142                              <1> 	;	process. Child process returns to address which is put
  3143                              <1> 	;	in BX register by parent process for 'sysfork'. 
  3144                              <1> 	;
  3145                              <1> 		; add $2,18.(sp) / add 2 to pc when trap occured, points
  3146                              <1> 		             ; / to old process return
  3147                              <1> 		; br error1 / no room for a new process
  3148                              <1> sysfork_0:
  3149 000033A7 E99BFDFFFF          <1> 	jmp	error
  3150                              <1> sysfork_2: ; 1:
  3151 000033AC E814F0FFFF          <1> 	call	allocate_page
  3152                              <1> 	;jc	error
  3153                              <1> 	; 08/01/2022
  3154 000033B1 72F4                <1> 	jc	short sysfork_0
  3155                              <1> 
  3156 000033B3 50                  <1> 	push	eax   ; UPAGE (user structure page) address
  3157                              <1> 	; Retro UNIX 386 v1 modification!
  3158 000033B4 E803F2FFFF          <1> 	call	duplicate_page_dir
  3159                              <1> 		; EAX = New page directory 
  3160 000033B9 7308                <1> 	jnc	short sysfork_3
  3161 000033BB 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  3162 000033BC E8CAF1FFFF          <1> 	call 	deallocate_page
  3163                              <1> 	;jmp	error
  3164                              <1> 	; 08/01/2022
  3165 000033C1 EBE4                <1> 	jmp	short sysfork_0  ; error
  3166                              <1> sysfork_3:
  3167                              <1> 	; Retro UNIX 386 v1 modification !
  3168 000033C3 56                  <1> 	push	esi
  3169 000033C4 E891120000          <1> 	call	wswap ; save current user (u) structure, user registers
  3170                              <1> 		      ; and interrupt return components (for IRET)
  3171 000033C9 8705[A46C0000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
  3172 000033CF A3[A86C0000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
  3173 000033D4 5E                  <1> 	pop	esi
  3174 000033D5 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  3175                              <1> 		; [u.usp] = esp
  3176 000033D6 89F7                <1> 	mov	edi, esi
  3177                              <1> 	;shl	di, 2
  3178                              <1> 	; 08/01/2022
  3179 000033D8 C1E702              <1> 	shl	edi, 2
  3180 000033DB 8987[70680000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  3181 000033E1 A3[A06C0000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  3182                              <1> 	; 28/08/2015
  3183 000033E6 0FB605[956C0000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
  3184                              <1> 		; movb u.uno,-(sp) / save parent process number
  3185 000033ED 89C7                <1> 	mov	edi, eax
  3186 000033EF 50                  <1>         push	eax ; ** 
  3187 000033F0 8A87[43680000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
  3188                              <1> 	; 18/09/2015 (27/02/2022)
  3189 000033F6 8886[43680000]      <1> 	mov	[esi+p.ttyc-1], al ; set child's console tty
  3190                              <1> 	; 27/02/2022 (p.waitc is not used)
  3191                              <1> 	;mov	[esi+p.waitc-1], ah ; 0 ; reset child's wait channel
  3192                              <1> 	; 27/02/2022 (BugFix)
  3193                              <1> 	;mov	[esi+p.ttyc-1], ax ; al - set child's console tty
  3194                              <1> 	;			   ; ah - reset child's wait channel
  3195 000033FC 89F0                <1> 	mov	eax, esi
  3196 000033FE A2[956C0000]        <1> 	mov	[u.uno], al ; child process number
  3197                              <1> 		;movb r1,u.uno / set child process number to r1
  3198 00003403 FE86[63680000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
  3199                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
  3200                              <1> 				; / process to active status
  3201                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
  3202                              <1> 			      ; / control tty buffer in r2
  3203                              <1>                 ; beq 2f / branch, if no such tty assigned
  3204                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
  3205                              <1> 	; 2:
  3206 00003409 53                  <1> 	push	ebx  ; * return address for the child process
  3207                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  3208                              <1> 	; (Retro UNIX 8086 v1 modification!)
  3209                              <1> 		; mov $runq+4,r2
  3210 0000340A E8A1120000          <1> 	call	putlu 
  3211                              <1>  		; jsr r0,putlu / put child process on lowest priority 
  3212                              <1> 			   ; / run queue
  3213                              <1> 	; 08/01/2022
  3214 0000340F D1E6                <1> 	shl	esi, 1
  3215                              <1> 	;shl	si, 1
  3216                              <1> 		; asl r1 / multiply r1 by 2 to get index 
  3217                              <1> 		       ; / into p.pid table
  3218 00003411 66FF05[246C0000]    <1> 	inc	word [mpid]
  3219                              <1> 		; inc mpid / increment m.pid; get a new process name
  3220 00003418 66A1[246C0000]      <1> 	mov	ax, [mpid]
  3221 0000341E 668986[02680000]    <1> 	mov	[esi+p.pid-2], ax
  3222                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
  3223                              <1> 				    ; / in child process' name slot
  3224 00003425 5A                  <1> 	pop	edx  ; * return address for the child process
  3225                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  3226 00003426 5B                  <1>   	pop	ebx  ; **
  3227                              <1> 	;mov	ebx, [esp] ; ** parent process number
  3228                              <1> 		; movb (sp),r2 / put parent process number in r2
  3229                              <1> 	; 08/01/2022
  3230 00003427 D1E3                <1> 	shl	ebx, 1
  3231                              <1> 	;shl 	bx, 1
  3232                              <1> 		; asl r2 / multiply by 2 to get index into below tables
  3233                              <1> 	;movzx eax, word [ebx+p.pid-2]
  3234 00003429 668B83[02680000]    <1> 	mov	ax, [ebx+p.pid-2]
  3235                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
  3236                              <1> 				   ; / process
  3237 00003430 668986[22680000]    <1> 	mov	[esi+p.ppid-2], ax
  3238                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
  3239                              <1> 			  ; / in parent process slot for child
  3240 00003437 A3[446C0000]        <1> 	mov	[u.r0], eax	
  3241                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
  3242                              <1> 			     ; / at location where r0 was saved
  3243 0000343C 8B2D[3C6C0000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
  3244 00003442 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
  3245                              <1> 			   ; * return address for the child process
  3246                              <1> 		; mov $sysret1,-(sp) /
  3247                              <1> 		; mov sp,u.usp / contents of sp at the time when 
  3248                              <1> 			      ; / user is swapped out
  3249                              <1> 		; mov $sstack,sp / point sp to swapping stack space
  3250                              <1> 	; 04/09/2015 - 01/09/2015
  3251                              <1> 	; [u.usp] = esp
  3252 00003445 68[67310000]        <1> 	push	sysret ; ***
  3253 0000344A 8925[406C0000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
  3254                              <1> 			     ; (for child process)	
  3255 00003450 31C0                <1> 	xor 	eax, eax
  3256 00003452 66A3[7A6C0000]      <1> 	mov 	[u.ttyp], ax ; 0
  3257                              <1> 	;
  3258 00003458 E8FD110000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
  3259                              <1> 		;jsr r0,wswap / put child process out on drum
  3260                              <1> 		;jsr r0,unpack / unpack user stack
  3261                              <1> 		;mov u.usp,sp / restore user stack pointer
  3262                              <1> 		; tst (sp)+ / bump stack pointer
  3263                              <1> 	; Retro UNIX 386 v1 modification !
  3264 0000345D 58                  <1> 	pop	eax ; ***
  3265                              <1> 	; 08/01/2022
  3266 0000345E D1E3                <1> 	shl	ebx, 1
  3267                              <1> 	;shl 	bx, 1
  3268 00003460 8B83[70680000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
  3269 00003466 E818120000          <1> 	call	rswap ; restore parent process 'u' structure, 
  3270                              <1> 		      ; registers and return address (for IRET)
  3271                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
  3272 0000346B 0FB705[246C0000]    <1>         movzx   eax, word [mpid]
  3273 00003472 A3[446C0000]        <1> 	mov	[u.r0], eax
  3274                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
  3275                              <1> 			       ; / where r0 was saved
  3276                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
  3277                              <1> 			          ; / process return
  3278                              <1> 	;xor	ebx, ebx
  3279 00003477 31F6                <1> 	xor     esi, esi
  3280                              <1> 		;clr r1
  3281                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
  3282                              <1> 	      ; / opened by the parent process
  3283                              <1> 	; 08/01/2022
  3284                              <1> 	; 01/09/2015
  3285 00003479 30FF                <1> 	xor	bh, bh
  3286 0000347B 8A9E[4E6C0000]      <1> 	mov 	bl, [esi+u.fp]
  3287                              <1> 	; 08/01/2022
  3288                              <1> 	;mov 	al, [esi+u.fp]
  3289                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
  3290 00003481 08DB                <1> 	or	bl, bl
  3291                              <1> 	; 08/01/2022
  3292                              <1> 	;or	al, al
  3293 00003483 7409                <1> 	jz	short sysfork_5	
  3294                              <1> 		; beq 2f / file has not been opened by parent, 
  3295                              <1> 		       ; / so branch
  3296                              <1> 	;mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
  3297                              <1> 	; 08/01/2022
  3298                              <1> 	;mov	ah, 16 ; Retro UNIX 386 v2 fsp structure size = 16 bytes
  3299                              <1> 	;mul	ah
  3300                              <1> 	;;movzx	ebx, ax
  3301                              <1> 	;mov	bx, ax
  3302                              <1> 	;mov	ebx, eax ; 08/01/2022
  3303                              <1> 	;shl	bx, 3
  3304                              <1> 		; asl r2 / multiply by 8
  3305                              <1>        		; asl r2 / to get index into fsp table
  3306                              <1>        		; asl r2
  3307                              <1> 	; 08/01/2022
  3308 00003485 C1E304              <1> 	shl	ebx, 4 ; multiply by 16
  3309                              <1> 	; 08/01/2022
  3310 00003488 FE83[AA680000]      <1> 	inc	byte [ebx+fsp-10] ; Retro UNIX 386 v2 fs fsp structure
  3311                              <1>   	;inc	byte [ebx+fsp-2]
  3312                              <1> 		; incb fsp-2(r2) / increment number of processes
  3313                              <1> 			     ; / using file, because child will now be
  3314                              <1> 			     ; / using this file
  3315                              <1> sysfork_5: ; 2:
  3316 0000348E 46                  <1>         inc     esi
  3317                              <1> 		; inc r1 / get next open file
  3318 0000348F 6683FE0A            <1>         cmp     si, 10
  3319                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
  3320                              <1> 			  ; / can be opened
  3321 00003493 72E4                <1> 	jb	short sysfork_4	
  3322                              <1> 		; blt 1b / check next entry
  3323 00003495 E9CDFCFFFF          <1> 	jmp	sysret
  3324                              <1> 		; br sysret1
  3325                              <1> 
  3326                              <1> sysread: ; < read from file >
  3327                              <1> 	; 24/12/2021
  3328                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  3329                              <1> 	; 27/03/2020
  3330                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
  3331                              <1> 	; 13/05/2015
  3332                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3333                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  3334                              <1> 	;
  3335                              <1> 	; 'sysread' is given a buffer to read into and the number of
  3336                              <1> 	; characters to be read. If finds the file from the file
  3337                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
  3338                              <1> 	; is returned from a successful open call (sysopen).
  3339                              <1> 	; The i-number of file is obtained via 'rw1' and the data
  3340                              <1> 	; is read into core via 'readi'.
  3341                              <1> 	;
  3342                              <1> 	; Calling sequence:
  3343                              <1> 	;	sysread; buffer; nchars
  3344                              <1> 	; Arguments:
  3345                              <1> 	;	buffer - location of contiguous bytes where 
  3346                              <1> 	;		 input will be placed.
  3347                              <1> 	;	nchars - number of bytes or characters to be read.
  3348                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  3349                              <1> 	; Outputs: *u.r0 - number of bytes read.	
  3350                              <1> 	; ...............................................................
  3351                              <1> 	;				
  3352                              <1> 	; Retro UNIX 8086 v1 modification: 
  3353                              <1> 	;       'sysread' system call has three arguments; so,
  3354                              <1> 	;	* 1st argument, file descriptor is in BX register
  3355                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  3356                              <1> 	;	* 3rd argument, number of bytes is in DX register
  3357                              <1> 	;
  3358                              <1> 	;	AX register (will be restored via 'u.r0') will return
  3359                              <1> 	;	to the user with number of bytes read. 
  3360                              <1> 	;
  3361                              <1> 
  3362 0000349A E839000000          <1> 	call	rw1
  3363                              <1> 	;jc	error ; 13/05/2015, ax < 1
  3364                              <1> 	;	; jsr r0,rw1 / get i-number of file to be read into r1
  3365                              <1>        	; 04/12/2021
  3366 0000349F 7209                <1> 	jc	short sysread_err
  3367 000034A1 7529                <1> 	jnz	short rw3 ; error ! (permission denied)
  3368                              <1> 	;		; read a file while it is open for write!
  3369                              <1> 
  3370                              <1> 	; eax = inode number
  3371                              <1> 
  3372                              <1> 	; 04/12/2021
  3373                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
  3374                              <1> 	;test	ah, 80h
  3375                              <1> 	;	; tst r1 / negative i-number?
  3376                              <1> 	;;jnz	error
  3377                              <1> 	;;	; ble error1 / yes, error 1 to read
  3378                              <1> 	;;		   ; / it should be positive
  3379                              <1> 	;; 04/12/2021
  3380                              <1> 	;jnz	short sysread_err
  3381                              <1> 
  3382 000034A3 E81B1A0000          <1> 	call	readi
  3383                              <1> 		; jsr r0,readi / read data into core
  3384 000034A8 EB13                <1> 	jmp	short rw0
  3385                              <1> 		; br 1f
  3386                              <1> sysread_err:
  3387                              <1> syswrite_err:
  3388                              <1> 	; 04/12/2021
  3389 000034AA E998FCFFFF          <1> 	jmp	error
  3390                              <1> 
  3391                              <1> syswrite: ; < write to file >
  3392                              <1> 	; 24/12/2021
  3393                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  3394                              <1> 	; 27/03/2020
  3395                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
  3396                              <1> 	; 13/05/2015
  3397                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3398                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  3399                              <1> 	;
  3400                              <1> 	; 'syswrite' is given a buffer to write onto an output file
  3401                              <1> 	; and the number of characters to write. If finds the file
  3402                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
  3403                              <1> 	; descriptor is returned from a successful open or create call
  3404                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
  3405                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
  3406                              <1> 	;
  3407                              <1> 	; Calling sequence:
  3408                              <1> 	;	syswrite; buffer; nchars
  3409                              <1> 	; Arguments:
  3410                              <1> 	;	buffer - location of contiguous bytes to be writtten.
  3411                              <1> 	;	nchars - number of characters to be written.
  3412                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  3413                              <1> 	; Outputs: *u.r0 - number of bytes written.	
  3414                              <1> 	; ...............................................................
  3415                              <1> 	;				
  3416                              <1> 	; Retro UNIX 8086 v1 modification: 
  3417                              <1> 	;       'syswrite' system call has three arguments; so,
  3418                              <1> 	;	* 1st argument, file descriptor is in BX register
  3419                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  3420                              <1> 	;	* 3rd argument, number of bytes is in DX register
  3421                              <1> 	;
  3422                              <1> 	;	AX register (will be restored via 'u.r0') will return
  3423                              <1> 	;	to the user with number of bytes written. 
  3424                              <1> 	;
  3425                              <1> 
  3426 000034AF E824000000          <1> 	call	rw1
  3427                              <1> 	;jc	error ; 13/05/2015, ax < 1
  3428                              <1> 	;	; jsr r0,rw1 / get i-number in r1 of file to write
  3429                              <1>        	; 04/12/2021
  3430 000034B4 72F4                <1> 	jc	short syswrite_err
  3431 000034B6 7414                <1> 	jz	short rw3 ; error ! (permission denied)
  3432                              <1> 			; write to a file while it is open for read
  3433                              <1> 	; eax = inode number
  3434                              <1> 	
  3435                              <1> 	; 04/12/2021
  3436                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
  3437                              <1> 	;test	ah, 80h
  3438                              <1> 	;	; tst r1 / positive i-number ?
  3439                              <1>         ;jz	short rw3 ; 13/05/2015
  3440                              <1> 	;;jz	error
  3441                              <1> 	;	; bge error1 / yes, error 1 
  3442                              <1> 	;		   ; / negative i-number means write
  3443                              <1>         ;neg	ax
  3444                              <1> 	;	; neg r1 / make it positive
  3445                              <1> 	
  3446 000034B8 E81A1C0000          <1> 	call	writei
  3447                              <1>         	; jsr r0,writei / write data
  3448                              <1> rw0: ; 1:
  3449 000034BD A1[706C0000]        <1>         mov	eax, [u.nread]
  3450 000034C2 A3[446C0000]        <1> 	mov	[u.r0], eax
  3451                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
  3452                              <1> 				  ; / into (u.r0)
  3453 000034C7 E99BFCFFFF          <1> 	jmp	sysret
  3454                              <1>         	; br sysret1
  3455                              <1> rw3: 
  3456                              <1> 	; 13/05/2015
  3457 000034CC C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  3457 000034D4 0000                <1>
  3458                              <1> 	;stc
  3459                              <1> 	;retn
  3460                              <1> 	; 24/12/2021 - Retro UNIX 386 v1.2
  3461 000034D6 EBD2                <1> 	jmp	short syswrite_err
  3462                              <1> 
  3463                              <1> rw1:	
  3464                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
  3465                              <1> 	; 27/03/2020
  3466                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
  3467                              <1> 	; 14/05/2015
  3468                              <1> 	; 13/05/2015
  3469                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3470                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
  3471                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
  3472                              <1> 	;
  3473                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
  3474                              <1> 				;(in the user's virtual memory space)
  3475                              <1> 	;mov	[u.count], edx 
  3476                              <1> 		; jsr r0,arg; u.base / get buffer pointer
  3477                              <1>         	; jsr r0,arg; u.count / get no. of characters
  3478                              <1> 	;;mov	eax, ebx ; file descriptor
  3479                              <1> 		; mov *u.r0,r1 / put file descriptor 
  3480                              <1> 		             ; / (index to u.fp table) in r1
  3481                              <1> 	; 13/05/2015
  3482 000034D8 C705[446C0000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
  3482 000034E0 0000                <1>
  3483                              <1> 	;
  3484                              <1> 	;; call	getf
  3485                              <1>         ; ebx = File descriptor
  3486 000034E2 E8410B0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
  3487                              <1> 		; jsr r0,getf / get i-number of the file in r1
  3488                              <1> 	; AX = I-number of the file ; negative i-number means write
  3489                              <1> 
  3490                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
  3491                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
  3492                              <1> 	; BL = open mode & status flag (0 = read, 1 = write)
  3493                              <1> 	; eax = inode number (ax)
  3494                              <1> 	; 27/03/2020
  3495                              <1> 	; [cdev] = logical drive number 	
  3496                              <1> 
  3497                              <1> 	; 13/05/2015
  3498 000034E7 6683F801            <1> 	cmp 	ax, 1
  3499 000034EB 721A                <1> 	jb	short rw2
  3500                              <1> 	;
  3501 000034ED 890D[686C0000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
  3502                              <1> 				;(in the user's virtual memory space)
  3503 000034F3 8915[6C6C0000]      <1> 	mov	[u.count], edx 
  3504                              <1> 	; 14/05/2015
  3505 000034F9 C705[B86C0000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
  3505 00003501 0000                <1>
  3506                              <1> 
  3507                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
  3508                              <1> 	; 27/03/2020 - Retro UNIX 386 v2
  3509 00003503 80E301              <1> 	and	bl, 1
  3510                              <1> 		; zf = 0 -> open for write	
  3511                              <1> 		; zf = 1 -> open for read
  3512 00003506 C3                  <1> 	retn
  3513                              <1>         	; rts r0
  3514                              <1> rw2:
  3515                              <1> 	; 13/05/2015
  3516 00003507 C705[B86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  3516 0000350F 0000                <1>
  3517 00003511 C3                  <1> 	retn
  3518                              <1> 
  3519                              <1> 	; 18/04/2022
  3520                              <1> 	; 08/01/2022
  3521                              <1> 	; 02/01/2022
  3522                              <1> 	; 01/01/2022
  3523                              <1> 	; 27/12/2021
  3524                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility code
  3525                              <1> sysopen: ;<open file>
  3526                              <1> 	; 04/12/2021
  3527                              <1> 	; 07/08/2020 (Retro UNIX 386 v2)
  3528                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  3529                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
  3530                              <1> 	;
  3531                              <1> 	; 'sysopen' opens a file in following manner:
  3532                              <1> 	;    1) The second argument in a sysopen says whether to
  3533                              <1> 	;	open the file ro read (0) or write (>0).
  3534                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
  3535                              <1> 	;    3) The file is opened by 'iopen'.
  3536                              <1> 	;    4) Next housekeeping is performed on the fsp table
  3537                              <1> 	;	and the user's open file list - u.fp.
  3538                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
  3539                              <1> 	;	b) An entry for the file is created in the fsp table.
  3540                              <1> 	;	c) The number of this entry is put on u.fp list.
  3541                              <1> 	;	d) The file descriptor index to u.fp list is pointed
  3542                              <1> 	;	   to by u.r0.
  3543                              <1> 	;
  3544                              <1> 	; Calling sequence:
  3545                              <1> 	;	sysopen; name; mode
  3546                              <1> 	; Arguments:
  3547                              <1> 	;	name - file name or path name
  3548                              <1> 	;	mode - 0 to open for reading
  3549                              <1> 	;	       1 to open for writing
  3550                              <1> 	; Inputs: (arguments)
  3551                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
  3552                              <1> 	;		  is put into r0's location on the stack.	
  3553                              <1> 	; ...............................................................
  3554                              <1> 	;				
  3555                              <1> 	; Retro UNIX 8086 v1 modification: 
  3556                              <1> 	;       'sysopen' system call has two arguments; so,
  3557                              <1> 	;	* 1st argument, name is pointed to by BX register
  3558                              <1> 	;	* 2nd argument, mode is in CX register
  3559                              <1> 	;
  3560                              <1> 	;	AX register (will be restored via 'u.r0') will return
  3561                              <1> 	;	to the user with the file descriptor/number 
  3562                              <1> 	;	(index to u.fp list).
  3563                              <1> 	;
  3564                              <1> 	;call	arg2
  3565                              <1> 	; * name - 'u.namep' points to address of file/path name
  3566                              <1> 	;          in the user's program segment ('u.segmnt')
  3567                              <1> 	;          with offset in BX register (as sysopen argument 1).
  3568                              <1> 	; * mode - sysopen argument 2 is in CX register 
  3569                              <1> 	;          which is on top of stack.
  3570                              <1> 	;
  3571                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
  3572                              <1> 	;
  3573                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
  3574                              <1> 
  3575 00003512 891D[606C0000]      <1> 	mov	[u.namep], ebx
  3576 00003518 51                  <1> 	push	ecx ; * ; 04/12/2021 (cx -> ecx)
  3577 00003519 E8400B0000          <1> 	call	namei
  3578                              <1> 		; jsr r0,namei / i-number of file in r1
  3579                              <1>      	;and	ax, ax
  3580                              <1> 	;jz	error ; File not found
  3581 0000351E 722B                <1> 	jc	short fnotfound ; 14/05/2015
  3582                              <1> 	;jc	error ; 27/05/2013
  3583                              <1> 		; br  error2 / file not found
  3584                              <1>    	;pop	edx ; * ; mode ; 04/12/2021
  3585                              <1> 	;push	edx ; *
  3586                              <1> 	;;or	dx, dx
  3587                              <1> 	;or	dl, dl
  3588                              <1> 	;	; tst (sp) / is mode = 0 (2nd arg of call;
  3589                              <1> 	;	         ; / 0 means, open for read)
  3590                              <1> 	;;jz	short sysopen_0
  3591                              <1> 	;;	; beq 1f / yes, leave i-number positive
  3592                              <1> 	
  3593 00003520 8B1424              <1> 	mov	edx, [esp] ; *
  3594                              <1> 	; edx = open mode (0 or 1)
  3595                              <1> 
  3596                              <1> ;syscreat_0: ;op0: ; 27/12/2015
  3597                              <1> ;	neg	ax
  3598                              <1> ;        	; neg r1 / open for writing so make i-number negative
  3599                              <1> 
  3600                              <1> sysopen_0: ;1:
  3601 00003523 E8A0200000          <1> 	call	iopen
  3602                              <1> 		; jsr r0,iopen / open file whose i-number is in r1
  3603 00003528 5A                  <1> 	pop	edx ; * ; mode ; 04/12/2021
  3604                              <1> 	;;and	dx, dx
  3605                              <1> 	;and	dl, dl
  3606                              <1>         ;	; tst (sp)+ / pop the stack and test the mode
  3607                              <1> 	;jz	short sysopen_2
  3608                              <1>         ;	; beq op1 / is open for read op1
  3609                              <1> ;sysopen_1: ;op0:
  3610                              <1> 	;neg	ax
  3611                              <1>         ;	; neg r1 
  3612                              <1> 	;	     ;/ make i-number positive if open for writing [???]
  3613                              <1> 
  3614                              <1> 	;; NOTE: iopen always make i-number positive.
  3615                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
  3616                              <1> sysopen_1: ; 04/12/2021
  3617                              <1> sysopen_2: ;op1:
  3618 00003529 31F6                <1>         xor     esi, esi
  3619                              <1>         	; clr r2 / clear registers
  3620 0000352B 31DB                <1>         xor     ebx, ebx
  3621                              <1> 		; clr r3
  3622                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
  3623 0000352D 389E[4E6C0000]      <1>         cmp     [esi+u.fp], bl ; 0
  3624                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
  3625 00003533 7625                <1> 	jna	short sysopen_4
  3626                              <1> 		; beq 1f / if byte in list is 0 branch
  3627 00003535 46                  <1>         inc     esi
  3628                              <1> 		; inc r2 / bump r2 so next byte can be checked
  3629                              <1> 	; 02/01/2022
  3630                              <1> 	;cmp	si, OPENFILES ; 04/12/2021
  3631 00003536 6683FE0A            <1> 	cmp	si, 10
  3632                              <1> 		; cmp r2,$10. / reached end of list?
  3633 0000353A 72F1                <1> 	jb	short sysopen_3
  3634                              <1> 		; blt 1b / no, go back
  3635                              <1> toomanyf:
  3636                              <1> 	; 14/05/2015
  3637 0000353C C705[B86C0000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
  3637 00003544 0000                <1>
  3638 00003546 E9FCFBFFFF          <1> 	jmp	error
  3639                              <1>         	; br error2 / yes, error (no files open)
  3640                              <1> fnotfound: 
  3641                              <1> 	; 14/05/2015
  3642 0000354B C705[B86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
  3642 00003553 0000                <1>
  3643 00003555 E9EDFBFFFF          <1> 	jmp	error
  3644                              <1> 
  3645                              <1> sysopen_4: ; 1:
  3646 0000355A 6683BB[B4680000]00  <1>         cmp     word [ebx+fsp], 0
  3647                              <1> 		; tst fsp(r3) / scan fsp entries
  3648 00003562 760D                <1>         jna     short sysopen_5
  3649                              <1> 		; beq 1f / if 0 branch
  3650                              <1> 	;; 14/05/2015 - Retro UNIX 386 v1 modification !
  3651                              <1> 	;add	bx, 10 ; fsp structure size = 10 bytes/entry
  3652                              <1> 		; add $8.,r3 / add 8 to r3 
  3653                              <1> 			; / to bump it to next entry mfsp table
  3654                              <1> 	; 01/01/2022
  3655                              <1> 	; 07/08/2020 - Retro UNIX 386 v2
  3656 00003564 6683C310            <1> 	add	bx, 16 ; fsp structure size = 16 bytes/entry ; runix v2
  3657                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
  3658                              <1> 	;add	bx, fp.size
  3659                              <1> 
  3660                              <1> 	; 22/11/2021
  3661                              <1> 	;cmp	bx, NFILES*fp.size ; NFILES*16
  3662                              <1> 	; 02/01/2022
  3663 00003568 6681FB2003          <1> 	cmp	bx, nfiles*16
  3664                              <1> 	; 01/01/2022
  3665                              <1> 	;cmp	bx, NFILES*16 ; NFILES*fp.size
  3666                              <1> 	;;cmp	bx, nfiles*10
  3667                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
  3668 0000356D 72EB                <1> 	jb	short sysopen_4
  3669                              <1>        		; blt 1b / no, back
  3670                              <1> 	;jmp	error
  3671                              <1>         ;	; br error2 / yes, error
  3672                              <1> 	; 04/12/2021
  3673                              <1> 	; 07/08/2020
  3674 0000356F EBCB                <1> 	jmp	short toomanyf
  3675                              <1> 
  3676                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
  3677 00003571 668983[B4680000]    <1>         mov     [ebx+fsp], ax
  3678                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
  3679                              <1> 			; / into next available entry in fsp table,
  3680                              <1> 	;mov	di, [cdev] ; word ? byte ?
  3681                              <1>         ;mov	[ebx+fsp+2], di ; device number
  3682                              <1> 	;	; mov cdev,fsp+2(r3) / put # of device in next word
  3683                              <1> 
  3684                              <1> 	; 18/04/2022
  3685                              <1> 	; 04/12/2021        
  3686                              <1> 	;mov	al, [cdev]
  3687                              <1> 	;mov	ah, dl ; open mode, 0 = read, 1 = write
  3688                              <1> 	;mov	[ebx+fsp+4], ax ; device number & open mode
  3689                              <1> 
  3690                              <1> 	;xor	edi, edi
  3691                              <1>         ;mov	[ebx+fsp+4], edi ; offset pointer (0)
  3692                              <1> 	;	; clr fsp+4(r3)
  3693                              <1>         ;mov	[ebx+fsp+8], di ; open count (0), deleted flag (0)
  3694                              <1>        	;	; clr fsp+6(r3) / clear the next two words
  3695                              <1> 
  3696                              <1> 	; 04/12/2021 
  3697 00003578 31C0                <1> 	xor	eax, eax
  3698 0000357A 8983[BC680000]      <1>   	mov	[ebx+fsp+8], eax ; offset pointer = 0
  3699                              <1> 
  3700                              <1> 	;;inc	word [ebx+fsp+6]
  3701                              <1> 	;inc	byte [ebx+fsp+6] ; open count = open count + 1	
  3702                              <1> 	; 18/04/2022
  3703                              <1> 	;mov	word [ebx+fsp+6], ax ; open count = 0 
  3704                              <1> 				     ; (sysfork increases open count)
  3705                              <1> 	; 18/04/2022		     ; reserved (mnt) flag = 0
  3706 00003580 A0[216C0000]        <1> 	mov	al, [cdev]
  3707 00003585 88D4                <1> 	mov	ah, dl ; open mode, 0 = read, 1 = write
  3708 00003587 8983[B8680000]      <1> 	mov	[ebx+fsp+4], eax ; device number (al)
  3709                              <1> 				 ; & open mode (ah)
  3710                              <1> 				 ; (& open count = 0)
  3711                              <1>   	;mov	eax, ebx
  3712                              <1> 	;mov	bl, 10
  3713                              <1> 	;div	bl 
  3714                              <1> 	;	; asr r3
  3715                              <1> 	;	; asr r3 / divide by 8 
  3716                              <1> 	;	; asr r3 ; / to get number of the fsp entry-1
  3717                              <1> 	;inc	al
  3718                              <1>         ;	; inc r3 / add 1 to get fsp entry number
  3719                              <1>         ;mov	[esi+u.fp], al
  3720                              <1> 	;	; movb r3,u.fp(r2) / move entry number into 
  3721                              <1> 			; / next available slot in u.fp list
  3722                              <1> 	; 04/12/2021
  3723 0000358D C1EB04              <1> 	shr	ebx, 4	; / 16
  3724                              <1> 	;shr	bx, 4	; bx = fsp entry number (index)	
  3725                              <1> 			; bx <= 49 for current runix 386 version
  3726 00003590 FEC3                <1> 	inc 	bl	; bl = 1 to 50
  3727 00003592 889E[4E6C0000]      <1> 	mov	[esi+u.fp], bl 	
  3728                              <1> 
  3729 00003598 8935[446C0000]      <1>         mov     [u.r0], esi
  3730                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
  3731                              <1> 			     ; / into r0 loc on stack
  3732 0000359E E9C4FBFFFF          <1>         jmp	sysret
  3733                              <1> 		; br sysret2
  3734                              <1> 
  3735                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
  3736                              <1> ;
  3737                              <1> ;         15                    7                   0
  3738                              <1> ;  1     |-------------------------------------------|
  3739                              <1> ;        |   	     i-number of open file           |
  3740                              <1> ;        |-------------------------------------------| 
  3741                              <1> ;        |        high word of 32 bit i-number       |
  3742                              <1> ;        |-------------------------------------------|
  3743                              <1> ;        | open mode & status  |   device number     |
  3744                              <1> ;        |-------------------------------------------|			
  3745                              <1> ;        |    reserved byte    |     open count      |
  3746                              <1> ;        |-------------------------------------------| 
  3747                              <1> ;        | offset pointer, i.e., r/w pointer to file |
  3748                              <1> ;        |-------------------------------------------|
  3749                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
  3750                              <1> ;        |-------------------------------------------|
  3751                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
  3752                              <1> ;        |-------------------------------------------|
  3753                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
  3754                              <1> ;        |-------------------------------------------|
  3755                              <1> ;  2     |                                           |
  3756                              <1> ;        |-------------------------------------------| 
  3757                              <1> ;        |                                           |
  3758                              <1> ;        |-------------------------------------------|
  3759                              <1> ;        |                                           |
  3760                              <1> ;        |-------------------------------------------|
  3761                              <1> ;        |                                           |
  3762                              <1> ;        |-------------------------------------------| 
  3763                              <1> ;        |                                           | 
  3764                              <1> 
  3765                              <1> 	;
  3766                              <1> 	; 'fsp' table (10 bytes/entry)
  3767                              <1> 	; bit 15				   bit 0
  3768                              <1> 	; ---|-------------------------------------------
  3769                              <1> 	; r/w|		i-number of open file
  3770                              <1> 	; ---|-------------------------------------------
  3771                              <1> 	;		   device number
  3772                              <1> 	; -----------------------------------------------
  3773                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  3774                              <1> 	; -----------------------------------------------
  3775                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  3776                              <1> 	; ----------------------|------------------------
  3777                              <1> 	;  flag that says file 	| number of processes
  3778                              <1> 	;   has been deleted	| that have file open 
  3779                              <1> 	; ----------------------|------------------------
  3780                              <1> 	;
  3781                              <1> 
  3782                              <1> 	; 12/03/2022
  3783                              <1> 	; 11/02/2022
  3784                              <1> 	; 01/01/2022
  3785                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
  3786                              <1> syscreat: ; < create file >
  3787                              <1> 	; 12/03/2022
  3788                              <1> 	; 11/02/2022
  3789                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  3790                              <1> 	; 04/04/2021
  3791                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
  3792                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
  3793                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  3794                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
  3795                              <1> 	;
  3796                              <1> 	; 'syscreat' called with two arguments; name and mode.
  3797                              <1> 	; u.namep points to name of the file and mode is put
  3798                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
  3799                              <1> 	; If the file aready exists, it's mode and owner remain 
  3800                              <1> 	; unchanged, but it is truncated to zero length. If the file
  3801                              <1> 	; did not exist, an i-node is created with the new mode via
  3802                              <1> 	; 'maknod' whether or not the file already existed, it is
  3803                              <1> 	; open for writing. The fsp table is then searched for a free
  3804                              <1> 	; entry. When a free entry is found, proper data is placed
  3805                              <1> 	; in it and the number of this entry is put in the u.fp list.
  3806                              <1> 	; The index to the u.fp (also know as the file descriptor)
  3807                              <1> 	; is put in the user's r0. 			
  3808                              <1> 	;
  3809                              <1> 	; Calling sequence:
  3810                              <1> 	;	syscreate; name; mode
  3811                              <1> 	; Arguments:
  3812                              <1> 	;	name - name of the file to be created
  3813                              <1> 	;	mode - mode of the file to be created
  3814                              <1> 	; Inputs: (arguments)
  3815                              <1> 	; Outputs: *u.r0 - index to u.fp list 
  3816                              <1> 	;		   (the file descriptor of new file)
  3817                              <1> 	; ...............................................................
  3818                              <1> 	;				
  3819                              <1> 	; Retro UNIX 8086 v1 modification: 
  3820                              <1> 	;       'syscreate' system call has two arguments; so,
  3821                              <1> 	;	* 1st argument, name is pointed to by BX register
  3822                              <1> 	;	* 2nd argument, mode is in CX register
  3823                              <1> 	;
  3824                              <1> 	;	AX register (will be restored via 'u.r0') will return
  3825                              <1> 	;	to the user with the file descriptor/number 
  3826                              <1> 	;	(index to u.fp list).
  3827                              <1> 	;
  3828                              <1> 	;call	arg2
  3829                              <1> 	; * name - 'u.namep' points to address of file/path name
  3830                              <1> 	;          in the user's program segment ('u.segmnt')
  3831                              <1> 	;          with offset in BX register (as sysopen argument 1).
  3832                              <1> 	; * mode - sysopen argument 2 is in CX register 
  3833                              <1> 	;          which is on top of stack.
  3834                              <1> 	;
  3835                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
  3836                              <1> 			    ; / on stack
  3837 000035A3 891D[606C0000]      <1> 	mov	[u.namep], ebx ; file name address
  3838                              <1> 	;push	cx ; mode
  3839                              <1> 	; 04/12/2021
  3840 000035A9 51                  <1> 	push	ecx ; cx = mode (permission flags)
  3841 000035AA E8AF0A0000          <1> 	call 	namei        	
  3842                              <1> 		; jsr r0,namei / get the i-number
  3843                              <1>         ;and	ax, ax
  3844                              <1> 	;jz	short syscreat_1	       	
  3845 000035AF 7216                <1> 	jc	short syscreat_1
  3846                              <1> 		; br 2f / if file doesn't exist 2f
  3847                              <1> 	; 27/12/2015
  3848                              <1> 	;cmp	ax, 41 ; device inode ?
  3849                              <1>         ;jb	syscreat_0 ; yes
  3850                              <1> 	;
  3851                              <1> 	;neg 	ax
  3852                              <1>         ;	; neg r1 / if file already exists make i-number 
  3853                              <1> 		       ; / negative (open for writing)
  3854                              <1> 	; 11/02/2022
  3855                              <1> 	; Truncate existing file
  3856                              <1> ;syscreate_2:
  3857                              <1> 	;; 27/03/2021
  3858                              <1> 	;;xor	edx, edx ; 0
  3859                              <1> 	;;inc	dl ; DL = 1 ; create/truncate (open for write)
  3860                              <1> 	;mov	dl, 1
  3861                              <1> 	; 11/02/2022
  3862 000035B1 B202                <1> 	mov	dl, 2 ; create file (call from syscreat)
  3863 000035B3 E810200000          <1> 	call	iopen
  3864                              <1>          	; jsr r0,iopen
  3865                              <1> 	; 11/02/2022
  3866                              <1> 	; cpu will return here if inode in eax is regular file inode
  3867                              <1> 	; (if it is device or dir inode, cpu will jumpt to 'error')
  3868                              <1> 	;
  3869                              <1> 	; 12/03/2022
  3870 000035B8 50                  <1> 	push	eax ; * ; save inode number
  3871                              <1> 	; 
  3872                              <1> 	; truncate file to zero length
  3873                              <1> 	;call	itrunc
  3874                              <1>         	; jsr r0,itrunc / truncate to 0 length
  3875                              <1> 	; 11/02/2022
  3876                              <1> 	; (iget and regular file check -in 'itrunc'- is not needed) 
  3877 000035B9 E891170000          <1> 	call	itrunc_1
  3878                              <1> 	; 12/03/2022
  3879 000035BE 58                  <1> 	pop	eax ; * ; restore inode number in eax
  3880                              <1> 	;
  3881                              <1> 	;pop	cx ; pop mode (did not exist in original Unix v1 !?)
  3882                              <1> 	; 04/12/2021
  3883 000035BF 59                  <1> 	pop	ecx
  3884                              <1> syscreat_2:
  3885 000035C0 B201                <1> 	mov	dl, 1 ; open for writing
  3886 000035C2 E962FFFFFF          <1>         jmp     sysopen_1
  3887                              <1>         	; br op0
  3888                              <1> syscreat_1: ; 2: / file doesn't exist
  3889                              <1> 	;pop	ax
  3890                              <1>         ;	; mov (sp)+,r1 / put the mode in r1
  3891                              <1> 	; 27/03/2021
  3892 000035C7 58                  <1> 	pop	eax  ; ax = mode (permission flags)
  3893                              <1> 	;xor	ah, ah	
  3894                              <1>         ;	; bic $!377,r1 / clear upper byte
  3895                              <1> 	; 27/03/2021
  3896                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
  3897                              <1> 	; clear bits 15,14,13,12,9 of mode (input from user)
  3898 000035C8 80E40D              <1> 	and	ah, 0Dh ; ISUID (800h) & ISGID (400h) & IREAD (100h)
  3899                              <1> 	; 11/02/2022
  3900 000035CB 80CC80              <1> 	or	ah, 80h	; IFREG (8000h) ; Regular file
  3901 000035CE E8B40D0000          <1> 	call 	maknod
  3902                              <1>         	; jsr r0,maknod / make an i-node for this file
  3903                              <1> 	;sub	eax, eax ; 04/12/2021
  3904 000035D3 66A1[7C6C0000]      <1> 	mov	ax, [u.dirbuf]
  3905                              <1>         	; mov u.dirbuf,r1 / put i-number 
  3906                              <1> 			        ; / for this new file in r1
  3907                              <1> 	; 04/04/2021
  3908                              <1> 	;mov	dl, 1 ; open for writing
  3909                              <1>         ;
  3910                              <1> 	;jmp	sysopen_1
  3911                              <1>         ;	; br op0 / open the file
  3912                              <1> 	; 04/04/2021
  3913 000035D9 EBE5                <1> 	jmp	short syscreat_2
  3914                              <1> 
  3915                              <1> 	; 11/02/2022
  3916                              <1> 	; 04/12/2021
  3917                              <1> dir_access_err:	; 13/03/2022
  3918                              <1> ;	; 14/05/2015
  3919                              <1> ;	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
  3920                              <1> ;f_create_error:
  3921                              <1> 	; 27/03/2021
  3922 000035DB C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; permission denied !	
  3922 000035E3 0000                <1>
  3923 000035E5 E95DFBFFFF          <1> 	jmp	error
  3924                              <1> 
  3925                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
  3926                              <1> sysmkdir: ; < make directory >
  3927                              <1> 	; 13/03/2022
  3928                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  3929                              <1> 	; 02/04/2021
  3930                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
  3931                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  3932                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3933                              <1> 	;
  3934                              <1> 	; 'sysmkdir' creates an empty directory whose name is
  3935                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
  3936                              <1> 	; The special entries '.' and '..' are not present.
  3937                              <1> 	; Errors are indicated if the directory already exists or		
  3938                              <1> 	; user is not the super user. 
  3939                              <1> 	;
  3940                              <1> 	; Calling sequence:
  3941                              <1> 	;	sysmkdir; name; mode
  3942                              <1> 	; Arguments:
  3943                              <1> 	;	name - points to the name of the directory
  3944                              <1> 	;	mode - mode of the directory
  3945                              <1> 	; Inputs: (arguments)
  3946                              <1> 	; Outputs: -
  3947                              <1> 	;    (sets 'directory' flag to 1; 
  3948                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
  3949                              <1> 	; ...............................................................
  3950                              <1> 	;				
  3951                              <1> 	; Retro UNIX 8086 v1 modification: 
  3952                              <1> 	;       'sysmkdir' system call has two arguments; so,
  3953                              <1> 	;	* 1st argument, name is pointed to by BX register
  3954                              <1> 	;	* 2nd argument, mode is in CX register
  3955                              <1> 	;
  3956                              <1> 		
  3957                              <1> ; / make a directory
  3958                              <1> 
  3959                              <1> 	;call	arg2
  3960                              <1> 	; * name - 'u.namep' points to address of file/path name
  3961                              <1> 	;          in the user's program segment ('u.segmnt')
  3962                              <1> 	;          with offset in BX register (as sysopen argument 1).
  3963                              <1> 	; * mode - sysopen argument 2 is in CX register 
  3964                              <1> 	;          which is on top of stack.
  3965                              <1> 
  3966                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
  3967                              <1> 			    ; / on stack
  3968 000035EA 891D[606C0000]      <1> 	mov	[u.namep], ebx
  3969                              <1> 	;push	cx ; mode
  3970                              <1> 	; 27/03/2021
  3971 000035F0 51                  <1> 	push	ecx ; cx = mode
  3972 000035F1 E8680A0000          <1> 	call	namei
  3973                              <1>         	; jsr r0,namei / get the i-number
  3974                              <1>         	;     br .+4 / if file not found branch around error
  3975                              <1>         ;xor 	ax, ax
  3976                              <1> 	;jnz	error
  3977 000035F6 7334                <1> 	jnc	short dir_exists ; 14/05/2015
  3978                              <1> 	;jnc	error	
  3979                              <1> 		; br error2 / directory already exists (error)
  3980                              <1> 
  3981                              <1> 	;cmp	byte [u.uid], 0 ; 02/08/2013
  3982                              <1>         ;	;tstb u.uid / is user the super user
  3983                              <1> 	;jna	short dir_access_err ; 14/05/2015
  3984                              <1> 	;;jna	error
  3985                              <1>         ;	;bne error2 / no, not allowed
  3986                              <1> 	;pop	ax
  3987                              <1>         ;	;mov (sp)+,r1 / put the mode in r1
  3988                              <1> 	;and	ax, 0FFCFh ; 1111111111001111b
  3989                              <1>         ;	;bic $!317,r1 / all but su and ex
  3990                              <1> 	;;or	ax, 4000h ; 1011111111111111b
  3991                              <1> 	;or	ah, 40h ; Set bit 14 to 1
  3992                              <1>         ; 	;bis $40000,r1 / directory flag
  3993                              <1> 
  3994                              <1> 	; 02/04/2021
  3995                              <1> 	;cmp	word [u.uid], 0
  3996                              <1> 	;;ja	error
  3997                              <1> 	;ja	short dir_access_err
  3998                              <1> 
  3999                              <1> 	; 13/03/2022
  4000                              <1> 	; NOTE:
  4001                              <1> 	; Unix v5-v7 kernels do not allow (ordinary) users
  4002                              <1> 	; (except root/superuser) --if [u.uid] > 0--
  4003                              <1> 	; to make a sub directory. (ref: sys2.c, 'mknod')
  4004                              <1> 	;
  4005                              <1> 	; But, Retro UNIX 386 v1.2 will allow the owner of
  4006                              <1> 	; the parent directory to make a sub directory, here.
  4007                              <1> 
  4008                              <1> 	; 13/03/2022
  4009 000035F8 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0
  4010 00003600 7618                <1> 	jna	short sysmkdir1 ; root (superuser)
  4011                              <1> 
  4012                              <1> 	; Here..
  4013                              <1> 	; (current) inode buffer contains inode structure
  4014                              <1> 	; of the parent directory (at the return of 'namei').
  4015                              <1> 
  4016 00003602 66A1[C8670000]      <1> 	mov	ax, [i.uid] ; owner ID of the parent dir
  4017 00003608 663B05[966C0000]    <1> 	cmp	ax, [u.uid] ; user ID of current user/process
  4018 0000360F 75CA                <1> 	jne	short dir_access_err
  4019                              <1> 	; 13/03/2022
  4020                              <1> 	; additional checking (may or may not be necessary!?)
  4021 00003611 663B05[986C0000]    <1> 	cmp	ax, [u.ruid] 
  4022                              <1> 			; real (login) user ID must be same
  4023 00003618 75C1                <1> 	jne	short dir_access_err
  4024                              <1> 
  4025                              <1> 	; 02/04/2021
  4026                              <1> 	; ('mkdir' procedure will be called from 'maknod'
  4027                              <1> 	; and then 'mkdir' will check write access permission) 
  4028                              <1> 	; ((so, 'access_w' call is not needed here.))
  4029                              <1> 
  4030                              <1> 	;; 02/04/2021
  4031                              <1> 	;; ('make directory' user permission check)
  4032                              <1> 	;; ((current directory's write permission flags
  4033                              <1> 	;;  will be checked against user's 'uid' & gid'))
  4034                              <1> 	;mov	dx, 80h ; IWRITE
  4035                              <1> 	;call	access_w  ; (in 'access', 'u5.s')
  4036                              <1> 	;; (If cpu will return here, the user has write permission)
  4037                              <1> 
  4038                              <1> sysmkdir1:
  4039                              <1> 	; 27/03/2021
  4040 0000361A 58                  <1> 	pop	eax  ; ax = mode
  4041                              <1> 	; [ii] = current directory's inode number
  4042                              <1> 
  4043                              <1> 	; 27/03/2021
  4044                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
  4045                              <1> 	; clear bits 13,12,11,10,9,6,3,0 of mode (input from user)
  4046                              <1> 	;and	ax, 0C1B6h ; bits 15,14,8,7,5,4,2,1
  4047 0000361B 6625B601            <1> 	and	ax, 01B6h
  4048 0000361F 80CCC0              <1> 	or	ah, 0C0h ; IFREG (8000h) + IFDIR (4000h) 
  4049                              <1> 			 ; Directory
  4050 00003622 E8600D0000          <1> 	call	maknod
  4051                              <1>         	;jsr r0,maknod / make the i-node for the directory
  4052 00003627 E93BFBFFFF          <1> 	jmp	sysret
  4053                              <1>         	;br sysret2 /
  4054                              <1> dir_exists:
  4055                              <1> 	; 27/03/2021
  4056                              <1> 	; (same error number for files and directories)
  4057                              <1> 	; Error Number: 14 (ERR_DIR_EXISTS)
  4058 0000362C C705[B86C0000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS
  4058 00003634 0000                <1>
  4059                              <1> 				; 'file already exists !' error
  4060                              <1> 	; 04/12/2021
  4061 00003636 E90CFBFFFF          <1> 	jmp	error
  4062                              <1> ;dir_access_err:
  4063                              <1> ;	; 14/05/2015
  4064                              <1> ;	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
  4065                              <1> ;	jmp	error
  4066                              <1> 
  4067                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
  4068                              <1> sysclose: ;<close file>
  4069                              <1> 	; 02/03/2022
  4070                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  4071                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  4072                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
  4073                              <1> 	;
  4074                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
  4075                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
  4076                              <1> 	; is put in r1 and 'fclose' is called.
  4077                              <1> 	;
  4078                              <1> 	; Calling sequence:
  4079                              <1> 	;	sysclose
  4080                              <1> 	; Arguments:
  4081                              <1> 	;	-  
  4082                              <1> 	; Inputs: *u.r0 - file descriptor
  4083                              <1> 	; Outputs: -
  4084                              <1> 	; ...............................................................
  4085                              <1> 	;				
  4086                              <1> 	; Retro UNIX 8086 v1 modification:
  4087                              <1> 	;	 The user/application program puts file descriptor
  4088                              <1> 	;        in BX register as 'sysclose' system call argument.
  4089                              <1> 	; 	 (argument transfer method 1)
  4090                              <1> 
  4091                              <1> 	; / close the file
  4092                              <1> 	
  4093                              <1> 	;mov 	eax, ebx
  4094                              <1> 	; 04/12/2021
  4095                              <1> 	; ebx = file descriptor/number
  4096                              <1> 	;call 	fclose
  4097                              <1> 	; 02/03/2022
  4098 0000363B E8A2090000          <1> 	call	_fclose
  4099                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
  4100                              <1> 		; jsr r0,fclose / close the file
  4101                              <1>                	; br error2 / unknown file descriptor
  4102                              <1> 		; br sysret2
  4103                              <1> 	;; 14/05/2015
  4104                              <1> 	;jnc	sysret
  4105                              <1> 	; 04/12/2021
  4106 00003640 7205                <1> 	jc	short sysclose_err
  4107 00003642 E920FBFFFF          <1> 	jmp	sysret
  4108                              <1> sysclose_err:
  4109 00003647 C705[B86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  4109 0000364F 0000                <1>
  4110 00003651 E9F1FAFFFF          <1> 	jmp	error
  4111                              <1> 
  4112                              <1> 	; 23/02/2022
  4113                              <1> 	; 19/12/2021
  4114                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
  4115                              <1> sysemt:
  4116                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  4117                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  4118                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
  4119                              <1> 	;
  4120                              <1> 	; Retro UNIX 8086 v1 modification: 
  4121                              <1> 	;	'Enable Multi Tasking' system call instead 
  4122                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
  4123                              <1> 	;
  4124                              <1> 	; Retro UNIX 8086 v1 feature only!
  4125                              <1> 	;	Using purpose: Kernel will start without time-out
  4126                              <1> 	;	(internal clock/timer) functionality.
  4127                              <1> 	;	Then etc/init will enable clock/timer for
  4128                              <1> 	;	multi tasking. (Then it will not be disabled again
  4129                              <1> 	;	except hardware reset/restart.)
  4130                              <1> 	;
  4131                              <1> 	
  4132                              <1> 	;cmp	byte [u.uid], 0 ; root ?
  4133                              <1> 	;;ja	error
  4134                              <1> 	;ja	badsys ; 14/05/2015
  4135                              <1> 	; 04/12/2021
  4136 00003656 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0 ; root ?
  4137 0000365E 7605                <1> 	jna	short emt_0 
  4138 00003660 E994FBFFFF          <1> 	jmp	badsys
  4139                              <1> emt_0:
  4140 00003665 FA                  <1> 	cli	; 23/02/2022
  4141 00003666 21DB                <1> 	and	ebx, ebx
  4142 00003668 7429                <1> 	jz	short emt_2
  4143                              <1> 	; Enable multi tasking -time sharing-
  4144 0000366A B8[F8460000]        <1> 	mov	eax, clock ; enable multi tasking clock/timer
  4145                              <1> 	; 23/02/2022
  4146 0000366F BA[2A0A0000]        <1> 	mov	edx, rtci_default ; disable rtc (digital) printing
  4147                              <1> emt_1:
  4148 00003674 A3[EF060000]        <1> 	mov	[x_timer], eax
  4149                              <1> 	; 23/02/2022 (Temporary)
  4150 00003679 8915[F3060000]      <1> 	mov	[x_rtci], edx
  4151 0000367F B306                <1> 	mov	bl, 6  ; timer interrupt page, video page 6
  4152 00003681 E855020000          <1> 	call	wttyc  ; clear video page
  4153 00003686 B307                <1> 	mov	bl, 7  ; rtc interrupt page, video page 7
  4154 00003688 E84E020000          <1> 	call	wttyc  ; clear video page
  4155                              <1> 	;
  4156 0000368D FB                  <1> 	sti	; 23/02/2022
  4157 0000368E E9D4FAFFFF          <1> 	jmp	sysret
  4158                              <1> emt_2:
  4159                              <1> 	; Disable multi tasking -time sharing-
  4160 00003693 B8[FB060000]        <1> 	mov	eax, u_timer ; enable timer tick printing
  4161                              <1> 	; 23/02/2022
  4162 00003698 BA[310A0000]        <1> 	mov	edx, rtc_p   ; enable rtc (digital) printing
  4163                              <1> 	;
  4164 0000369D EBD5                <1> 	jmp	short emt_1
  4165                              <1> 
  4166                              <1> 	; Original UNIX v1 'sysemt' routine
  4167                              <1> ;sysemt:
  4168                              <1>         ;
  4169                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
  4170                              <1> 			 ; / in loc 30
  4171                              <1>         ;cmp    30,$core / was the argument a lower address 
  4172                              <1> 			; / than core
  4173                              <1>         ;blo    1f / yes, rtssym
  4174                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
  4175                              <1> 			; / and less than "ecore"
  4176                              <1>         ;blo    2f / yes, sysret2
  4177                              <1> ;1:
  4178                              <1>         ;mov    $rtssym,30
  4179                              <1> ;2:
  4180                              <1>         ;br     sysret2
  4181                              <1> 
  4182                              <1> sysilgins:
  4183                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  4184                              <1> 	; 03/06/2013
  4185                              <1> 	; Retro UNIX 8086 v1 modification: 
  4186                              <1> 	;	not a valid system call ! (not in use)
  4187                              <1> 	;
  4188 0000369F E955FBFFFF          <1> 	jmp	badsys
  4189                              <1> 	;jmp	error
  4190                              <1> 	;;jmp 	sysret
  4191                              <1> 
  4192                              <1> 	; Original UNIX v1 'sysemt' routine
  4193                              <1> ;sysilgins: / calculate proper illegal instruction trap address
  4194                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
  4195                              <1> 			  ;/ put it in loc 8.,
  4196                              <1>         ;cmp    10,$core / making it the illegal instruction 
  4197                              <1> 		       ; / trap address
  4198                              <1>         ;blo    1f / is the address a user core address?  
  4199                              <1> 		; / yes, go to 2f
  4200                              <1>         ;cmp    10,$ecore
  4201                              <1>         ;blo    2f
  4202                              <1> ;1:
  4203                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
  4204                              <1> 		    ; / instruction trap address for the system
  4205                              <1> ;2:
  4206                              <1>         ;br     sysret2 / return to the caller via 'sysret'
  4207                              <1> 
  4208                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
  4209                              <1> sysmdate: ; < change the modification time of a file >
  4210                              <1> 	; 23/02/2022 (Retro UNIX 386 v1 feature/modification)
  4211                              <1> 	;	(ECX input)
  4212                              <1> 	; 24/12/2021
  4213                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  4214                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4215                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4216                              <1> 	;
  4217                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
  4218                              <1> 	; file into core. The user is checked if he is the owner 
  4219                              <1> 	; or super user. If he is neither an error occurs.
  4220                              <1> 	; 'setimod' is then called to set the i-node modification
  4221                              <1> 	; byte and the modification time, but the modification time
  4222                              <1> 	; is overwritten by whatever get put on the stack during
  4223                              <1> 	; a 'systime' system call. This calls are restricted to
  4224                              <1> 	; the super user.		
  4225                              <1> 	;
  4226                              <1> 	; Calling sequence:
  4227                              <1> 	;	sysmdate; name
  4228                              <1> 	; Arguments:
  4229                              <1> 	;	name - points to the name of file
  4230                              <1> 	; Inputs: (arguments)
  4231                              <1> 	; Outputs: -
  4232                              <1> 	; ...............................................................
  4233                              <1> 	;				
  4234                              <1> 	; Retro UNIX 8086 v1 modification: 
  4235                              <1> 	;	 The user/application program puts address 
  4236                              <1> 	;	 of the file name in BX register 
  4237                              <1> 	;	 as 'sysmdate' system call argument.
  4238                              <1> 	;
  4239                              <1> ; / change the modification time of a file
  4240                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
  4241 000036A4 891D[606C0000]      <1>         mov	[u.namep], ebx
  4242                              <1> 	; 23/02/2022 - (Retro UNIX 386 v1 modification on unix v1 code)
  4243 000036AA 890D[50670000]      <1> 	mov	[p_time], ecx ; save new modification time to be set 
  4244 000036B0 E8A9090000          <1> 	call	namei
  4245                              <1> 		; jsr r0,namei / get its i-number
  4246                              <1> 	;;jc	error       
  4247                              <1> 	;	; br error2 / no, such file
  4248                              <1> 	;jc	fnotfound ; file not found !
  4249                              <1> 	; 24/12/2021
  4250 000036B5 7305                <1> 	jnc	short mdate_0
  4251 000036B7 E98FFEFFFF          <1> 	jmp	fnotfound
  4252                              <1> mdate_0: 
  4253 000036BC E896140000          <1> 	call	iget
  4254                              <1> 		; jsr r0,iget / get i-node into core
  4255                              <1> 	;mov	al, [u.uid]
  4256                              <1> 	;cmp	al, [i.uid]
  4257                              <1>         ;	; cmpb u.uid,i.uid / is user same as owner
  4258                              <1> 	;je	short mdate_1
  4259                              <1>         ;	; beq 1f / yes
  4260                              <1> 	;and	al, al
  4261                              <1> 	;	; tstb u.uid / no, is user the super user
  4262                              <1> 	;;jnz	error
  4263                              <1> 	;	; bne error2 / no, error
  4264                              <1> 	;jz	short mdate_1
  4265                              <1> 	; 04/12/2021
  4266 000036C1 66A1[966C0000]      <1> 	mov	ax, [u.uid]
  4267 000036C7 663B05[C8670000]    <1> 	cmp	ax, [i.uid]
  4268 000036CE 7414                <1> 	je	short mdate_1	
  4269 000036D0 6621C0              <1> 	and	ax, ax
  4270 000036D3 740F                <1> 	jz	short mdate_1
  4271                              <1> 
  4272 000036D5 C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  4272 000036DD 0000                <1>
  4273                              <1> sysstty_err:	; 06/02/2022
  4274 000036DF E963FAFFFF          <1> 	jmp	error
  4275                              <1> mdate_1: ;1:
  4276 000036E4 E8FF150000          <1> 	call	setimod
  4277                              <1>         	; jsr r0,setimod / fill in modification data,
  4278                              <1> 		               ; / time etc.
  4279 000036E9 BE[50670000]        <1> 	mov	esi, p_time
  4280 000036EE BF[FC670000]        <1> 	mov	edi, i.mtim
  4281 000036F3 A5                  <1> 	movsd
  4282                              <1> 		; mov 4(sp),i.mtim / move present time to
  4283                              <1>         	; mov 2(sp),i.mtim+2 / modification time
  4284 000036F4 E96EFAFFFF          <1>         jmp	sysret
  4285                              <1> 		; br sysret2
  4286                              <1> 
  4287                              <1> 	; 06/02/2022
  4288                              <1> sysstty_err_s:
  4289 000036F9 880D[446C0000]      <1> 	mov	byte [u.r0], cl ; serial port's tty number
  4290 000036FF EBDE                <1> 	jmp	short sysstty_err
  4291                              <1> 
  4292                              <1> sysstty: ; < set tty status and mode >
  4293                              <1> 	; 22/02/2022
  4294                              <1> 	; 21/02/2022
  4295                              <1> 	; 06/02/2022 (Retro UNIX 286 v1.2)
  4296                              <1> 	; 04/02/2022 (Retro UNIX 386 v1.1, Kernel v0.2.1.2)
  4297                              <1> 	; 02/02/2022 (Retro UNIX 386 v1, Kernel v0.2.0.18)
  4298                              <1> 	; 01/02/2022 (Retro UNIX 386 v1) -clear screen-
  4299                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
  4300                              <1> 	;	    ((32 bit reg push/pop))
  4301                              <1> 	; 17/11/2015
  4302                              <1> 	; 12/11/2015
  4303                              <1> 	; 29/10/2015
  4304                              <1> 	; 17/10/2015
  4305                              <1> 	; 13/10/2015
  4306                              <1> 	; 29/06/2015
  4307                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
  4308                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
  4309                              <1> 	;
  4310                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
  4311                              <1> 	; whose file descriptor is in (u.r0).
  4312                              <1> 	;
  4313                              <1> 	; Calling sequence:
  4314                              <1> 	;	sysstty; arg
  4315                              <1> 	; Arguments:
  4316                              <1> 	;	arg - address of 3 consequitive words that contain
  4317                              <1> 	;	      the source of status data	
  4318                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
  4319                              <1> 	; Outputs: ((status in address which is pointed to by arg))
  4320                              <1> 	; ...............................................................
  4321                              <1> 	;	
  4322                              <1> 	; Retro UNIX 8086 v1 modification: 
  4323                              <1> 	;	'sysstty' system call will set the tty
  4324                              <1> 	;	(clear keyboard buffer and set cursor position)
  4325                              <1> 	;	 in following manner:
  4326                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
  4327                              <1> 	;
  4328                              <1> 	; Inputs:
  4329                              <1> 	;	BX = 0 --> means
  4330                              <1> 	;	   If CL = FFh (& DX <> 0FFFFh) ; 01/02/2022
  4331                              <1> 	;	      set cursor position for console tty, only 
  4332                              <1> 	;	      CH will be ignored (char. will not be written)
  4333                              <1> 	;	   If CH = 0 (& DX <> 0FFFFh & CL < FFh) ; 01/02/20222
  4334                              <1> 	;	      set console tty for (current) process
  4335                              <1> 	;	      CL = tty number (0 to 9)
  4336                              <1> 	;	      (If CH = 0, character will not be written)
  4337                              <1> 	;          If CH > 0 (CL < FFh)	
  4338                              <1> 	;             CL = tty number (0 to 9)
  4339                              <1> 	;	      CH = character will be written
  4340                              <1> 	;	        at requested cursor position (in DX)
  4341                              <1> 	;	   DX = cursor position for tty number 0 to 7.
  4342                              <1>   	;		(only tty number 0 to 7) 
  4343                              <1> 	;          DL = communication parameters (for serial ports)
  4344                              <1> 	;	        (only for COM1 and COM2 serial ports)
  4345                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
  4346                              <1> 	;			or set cursor position	
  4347                              <1> 	;	   DH = 0FFh -> DL is not valid
  4348                              <1> 	;		do not set serial port parameters 
  4349                              <1> 	;		or do not set cursor position
  4350                              <1> 	;
  4351                              <1> 	;	BX > 0 --> points to name of tty
  4352                              <1> 	;    	   CH > 0 -->
  4353                              <1> 	;		CH = character will be written in current 
  4354                              <1> 	;            	cursor position (for tty number from 0 to 7)
  4355                              <1> 	;	     	or character will be sent to serial port
  4356                              <1> 	;	     	(for tty number 8 or 9)
  4357                              <1> 	;		CL = color of the character if tty number < 8.
  4358                              <1> 	;    	   CH = 0 --> Do not write a character, 
  4359                              <1> 	;		set mode (tty 8 to 9) or 
  4360                              <1> 	;		set current cursor positions (tty 0 to 7) only.
  4361                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
  4362                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
  4363                              <1> 	;		(DL is not valid)
  4364                              <1> 	;	   DL = communication parameters 
  4365                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
  4366                              <1> 	;
  4367                              <1> 	;	01/02/2022 - Retro UNIX 386 v1 - 2022 modification
  4368                              <1> 	;	(30/01/2022 - Retro UNIX 8086 - 2022 modification)
  4369                              <1> 	;	If CH = 0 & DX = 0FFFFh -> 
  4370                              <1> 	;	   clear screen (video page) & set cursor pos to 0,0.
  4371                              <1> 	;	   (for tty number 0 to 7, CL <= 7)
  4372                              <1> 	;	   (if CL = 0FFh -> clear console tty)	
  4373                              <1> 	;
  4374                              <1> 	; Outputs:
  4375                              <1> 	;	cf = 0 -> OK
  4376                              <1> 	;	     AL = tty number (0 to 9)
  4377                              <1> 	;	     AH = line status if tty number is 8 or 9
  4378                              <1> 	;	     AH = process number (of the caller)
  4379                              <1> 	;	cf = 1 means error (requested tty is not ready)
  4380                              <1> 	;	     AH = FFh if the tty is locked 
  4381                              <1> 	;		  (owned by another process)
  4382                              <1> 	;	        = process number (of the caller) 
  4383                              <1> 	;		  (if < FFh and tty number < 8)
  4384                              <1> 	;	     AL = tty number (0FFh if it does not exist)
  4385                              <1> 	;	     AH = line status if tty number is 8 or 9
  4386                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
  4387                              <1> 	;	
  4388                              <1> 
  4389                              <1> 	; 27/06/2015 (32 bit modifications)
  4390                              <1> 	; 14/01/2014
  4391 00003701 31C0                <1> 	xor 	eax, eax
  4392 00003703 6648                <1> 	dec	ax ; 17/10/2015
  4393 00003705 A3[446C0000]        <1> 	mov	[u.r0], eax ; 0FFFFh
  4394                              <1> 	;;;
  4395                              <1> 	; 01/02/2022
  4396 0000370A FEC1                <1> 	inc	cl  ; 0FFh -> 0, 7 -> 8
  4397 0000370C 39C2                <1> 	cmp	edx, eax
  4398                              <1> 	;cmp	dx, ax ; 0FFFFh
  4399 0000370E 7521                <1> 	jne	short sysstty_18
  4400                              <1> 	; clear video page
  4401                              <1> 	; (CH must be 0)
  4402 00003710 08ED                <1> 	or	ch, ch
  4403 00003712 75CB                <1> 	jnz	short sysstty_err ; invalid parameters
  4404 00003714 80F908              <1> 	cmp	cl, 8 ; > tty7 (serial port?)
  4405 00003717 77C6                <1> 	ja	short sysstty_err ; invalid parameters
  4406 00003719 20C9                <1> 	and	cl, cl
  4407 0000371B 7514                <1> 	jnz	short sysstty_18 ; actual tty (video page) num + 1
  4408 0000371D 0FB635[956C0000]    <1> 	movzx	esi, byte [u.uno]
  4409 00003724 8A8E[43680000]      <1> 	mov	cl, byte [esi+p.ttyc-1] ; current/console tty
  4410 0000372A 80F907              <1> 	cmp	cl, 7
  4411 0000372D 77CA                <1> 	ja	short sysstty_err_s ; serial port !	 
  4412                              <1> 	; here CL contains (actual) tty number (tty0 to tty7) 
  4413 0000372F FEC1                <1> 	inc	cl  ; 0 -> 1, 7 -> 8 
  4414                              <1> sysstty_18:
  4415 00003731 FEC9                <1> 	dec	cl  ; 8 -> 7, 1 -> 0
  4416                              <1> 	; cl = video page (tty) number
  4417                              <1> 	;;;
  4418 00003733 21DB                <1> 	and	ebx, ebx
  4419                              <1> 	;jnz	sysstty_6
  4420                              <1> 	; 01/02/2022
  4421 00003735 7405                <1> 	jz	short sysstty_19
  4422 00003737 E9C2000000          <1> 	jmp	sysstty_6
  4423                              <1> sysstty_19:
  4424                              <1> 	; set console tty
  4425                              <1> 	; 29/10/2015
  4426                              <1> 	; 17/01/2014 
  4427 0000373C 80F909              <1> 	cmp	cl, 9
  4428 0000373F 7613                <1> 	jna	short sysstty_0
  4429                              <1> 	; 17/11/2015
  4430 00003741 80F9FF              <1> 	cmp	cl, 0FFh
  4431 00003744 7202                <1> 	jb	short sysstty_13
  4432 00003746 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
  4433                              <1> sysstty_13:
  4434 00003748 8A1D[956C0000]      <1> 	mov	bl, [u.uno] ; process number
  4435 0000374E 8A8B[43680000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
  4436                              <1> sysstty_0:
  4437                              <1> 	; 29/06/2015
  4438 00003754 52                  <1> 	push	edx ; 24/12/2021
  4439 00003755 51                  <1> 	push	ecx
  4440 00003756 30D2                <1> 	xor 	dl, dl	; sysstty call sign
  4441 00003758 88C8                <1> 	mov	al, cl
  4442 0000375A A2[446C0000]        <1> 	mov	[u.r0], al ; tty number (0 to 9)
  4443 0000375F E8311F0000          <1> 	call	ottyp
  4444 00003764 59                  <1> 	pop	ecx
  4445 00003765 5A                  <1> 	pop	edx
  4446                              <1> 	;
  4447 00003766 7220                <1> 	jc	short sysstty_pd_err
  4448                              <1> 	;
  4449                              <1> 	; 22/02/2022 (Bug!, BugFix)
  4450                              <1> 	; (ebx = ?, modified in ottyp, it may be > 255)
  4451                              <1> 	;
  4452 00003768 80F908              <1> 	cmp	cl, 8
  4453 0000376B 720C                <1> 	jb	short sysstty_2
  4454                              <1> 	;
  4455 0000376D 80FEFF              <1> 	cmp	dh, 0FFh
  4456 00003770 7407                <1> 	je	short sysstty_2
  4457                              <1> 
  4458                              <1> ; 01/02/2022
  4459                              <1> ;	; 29/10/2015
  4460                              <1> ;	mov	ah, dl ; communication parameters
  4461                              <1> ;		; ah = 0E3h = 11100011b = 115200 baud,
  4462                              <1> ;		;			 THRE int + RDA int 
  4463                              <1> ;		; ah = 23h = 00100011b = 9600 baud,
  4464                              <1> ;		;			 THRE int + RDA int 
  4465                              <1> ;	sub	al, al ; 0
  4466                              <1> ;	; 12/07/2014
  4467                              <1> ;	cmp	cl, 9
  4468                              <1> ;	jb	short sysstty_1
  4469                              <1> ;	inc	al
  4470                              <1> ;sysstty_1:
  4471                              <1> ;	; 01/02/2022
  4472                              <1> ;	push	ecx
  4473                              <1> ;	; 29/06/2015	
  4474                              <1> ;	call 	sp_setp ; Set serial port communication parameters
  4475                              <1> ;	mov	[u.r0+1], cx ; Line status (ah)
  4476                              <1> ;			     ; Modem status (EAX bits 16 to 23)
  4477                              <1> ;	; 01/02/2022
  4478                              <1> ;	pop	ecx	
  4479                              <1> ;       jc      short sysstty_tmout_err ; 29/10/2015
  4480                              <1> 
  4481                              <1> 	; 01/02/2022
  4482 00003772 E831010000          <1> 	call	sysstty_scp
  4483 00003777 7276                <1>         jc      short sysstty_tmout_err ; 29/10/2015
  4484                              <1> 
  4485                              <1> sysstty_2:
  4486                              <1> 	; 17/01/2014
  4487 00003779 20ED                <1> 	and	ch, ch 	; set cursor position 
  4488                              <1> 			; or comm. parameters ONLY
  4489 0000377B 7527                <1> 	jnz	short sysstty_3
  4490                              <1> 	; 01/02/2022
  4491 0000377D 6683FAFF            <1> 	cmp	dx, 0FFFFh
  4492 00003781 7214                <1> 	jb	short sysstty_20
  4493                              <1> 	; clear screen (video page)
  4494 00003783 E93C010000          <1> 	jmp	sysstty_14
  4495                              <1> 
  4496                              <1> sysstty_pd_err: ; 29/06/2015
  4497                              <1> 	; 'permission denied !' error
  4498 00003788 C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
  4498 00003790 0000                <1>
  4499 00003792 E9B0F9FFFF          <1> 	jmp	error
  4500                              <1> 
  4501                              <1> sysstty_20:
  4502 00003797 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  4503 0000379E 888B[43680000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
  4504                              <1> sysstty_3:
  4505                              <1> 	; 16/01/2014
  4506 000037A4 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
  4507                              <1> 	; 17/11/2015
  4508 000037A6 B507                <1> 	mov 	ch, 7  ; Default color (light gray)
  4509 000037A8 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
  4510                              <1>         ;jna	sysstty_9
  4511                              <1> 	; 24/12/2021
  4512 000037AA 7705                <1> 	ja	short sysstty_12
  4513 000037AC E9C6000000          <1> 	jmp	sysstty_9
  4514                              <1> 
  4515                              <1> sysstty_12:
  4516                              <1> 	;; BX = 0, CL = 8 or CL = 9
  4517                              <1> 	; (Set specified serial port as console tty port)
  4518                              <1> 	; CH = character to be written
  4519                              <1> 	; 15/04/2014
  4520                              <1> 	; CH = 0 --> initialization only
  4521                              <1> 	; AL = character
  4522                              <1> 	; 26/06/2014
  4523 000037B1 880D[796C0000]      <1> 	mov	[u.ttyn], cl
  4524                              <1> 	; 12/07/2014
  4525 000037B7 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
  4526                              <1> 	; 02/02/2022
  4527 000037B9 FEC0                <1> 	inc	al  ; 0FFh -> 0, 0 -> 1
  4528 000037BB 740B                <1> 	jz	short sysstty_4 ; al = ch = 0
  4529 000037BD FEC8                <1> 	dec	al  ; 1 -> 0	
  4530                              <1> 	;and	al, al
  4531 000037BF 7407                <1> 	jz	short sysstty_4 ; al = ch = 0
  4532                              <1>  	; 04/07/2014
  4533 000037C1 E802240000          <1> 	call 	sndc
  4534                              <1> 	; 12/07/2014
  4535 000037C6 EB0C                <1> 	jmp	short sysstty_5
  4536                              <1> 
  4537                              <1> sysstty_4:
  4538                              <1> 	; 12/07/2014
  4539                              <1> 	;xchg 	ah, al ; al = 0 -> al = ah, ah = 0
  4540 000037C8 88E0                <1> 	mov	al, ah ; 29/06/2015
  4541 000037CA 2C08                <1> 	sub	al, 8
  4542                              <1> 	; 27/06/2015
  4543 000037CC E8B4F3FFFF          <1> 	call	sp_status ; get serial port status
  4544                              <1> 	; AL = Line status, AH = Modem status
  4545                              <1> 	; 12/11/2015
  4546 000037D1 3C80                <1> 	cmp	al, 80h
  4547 000037D3 F5                  <1> 	cmc
  4548                              <1> sysstty_5:
  4549 000037D4 66A3[456C0000]      <1> 	mov	[u.r0+1], ax ; ah = line status
  4550                              <1> 		; EAX bits 16-23 = modem status	
  4551 000037DA 9C                  <1> 	pushf
  4552 000037DB 30D2                <1> 	xor	dl, dl ; sysstty call sign
  4553 000037DD A0[796C0000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
  4554 000037E2 E8E11F0000          <1> 	call	cttyp
  4555 000037E7 9D                  <1> 	popf
  4556                              <1> 	;jnc	sysret ; time out error 
  4557                              <1> 	; 01/02/2022
  4558 000037E8 7205                <1> 	jc	short sysstty_tmout_err
  4559 000037EA E978F9FFFF          <1> 	jmp	sysret
  4560                              <1> 
  4561                              <1> 	; time out error 
  4562                              <1> sysstty_tmout_err:
  4563 000037EF C705[B86C0000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
  4563 000037F7 0000                <1>
  4564 000037F9 E949F9FFFF          <1> 	jmp	error
  4565                              <1> 
  4566                              <1> sysstty_6:
  4567 000037FE 52                  <1> 	push	edx ; 24/12/2021
  4568 000037FF 51                  <1> 	push	ecx
  4569 00003800 891D[606C0000]      <1> 	mov	[u.namep], ebx
  4570 00003806 E853080000          <1> 	call	namei
  4571 0000380B 59                  <1> 	pop	ecx
  4572 0000380C 5A                  <1> 	pop	edx
  4573 0000380D 7259                <1> 	jc	short sysstty_inv_dn
  4574                              <1> 	;
  4575                              <1> 	; 21/02/2022
  4576                              <1> 	;cmp	ax, 19  ; inode number of /dev/COM2
  4577                              <1> 	;ja	short sysstty_inv_dn ; 27/06/2015
  4578                              <1> 	;;
  4579                              <1> 	;cmp	al, 10 ; /dev/tty0 .. /dev/tty7
  4580                              <1> 	;	       ; /dev/COM1, /dev/COM2
  4581                              <1> 	;jb	short sysstty_7
  4582                              <1> 	;sub	al, 10
  4583                              <1> 	;jmp	short sysstty_8
  4584                              <1> 	;
  4585                              <1> 	; 21/02/2022
  4586                              <1> 	; (Retro UNIX 386 v2 file system inode numbers)
  4587 0000380F 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
  4588 00003812 7754                <1> 	ja	short sysstty_inv_dn
  4589                              <1> 	;cmp	al, 8	; /dev/tty inode number is 8
  4590                              <1> 	;jb	short sysstty_inv_dn
  4591 00003814 2C08                <1> 	sub	al, 8
  4592 00003816 7250                <1> 	jb	short sysstty_inv_dn
  4593 00003818 7408                <1> 	jz	short sysstty_7 ; /dev/tty inode number is 8
  4594                              <1> 	; convert inode number to tty number (tty0 to tty9)
  4595 0000381A 2C09                <1> 	sub	al, 9
  4596 0000381C 724A                <1> 	jb	short sysstty_inv_dn
  4597                              <1> 	; al = 0 to 9
  4598 0000381E 29DB                <1> 	sub	ebx, ebx ; 22/02/2022
  4599 00003820 EB0D                <1> 	jmp	short sysstty_8 
  4600                              <1> sysstty_7:
  4601                              <1> 	; 21/02/2022
  4602                              <1> 	;cmp	al, 1 ; /dev/tty
  4603                              <1> 	;jne	short sysstty_inv_dn ; 27/06/2015
  4604 00003822 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  4605 00003829 8A83[43680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
  4606                              <1> sysstty_8:
  4607                              <1> 	; 22/02/2022
  4608                              <1> 	; (ebx < 256)	
  4609 0000382F A2[446C0000]        <1> 	mov	[u.r0], al
  4610 00003834 52                  <1> 	push	edx ; 24/12/2021
  4611 00003835 50                  <1> 	push	eax
  4612 00003836 51                  <1> 	push	ecx	
  4613 00003837 E8591E0000          <1> 	call	ottyp
  4614 0000383C 59                  <1> 	pop	ecx
  4615 0000383D 58                  <1> 	pop	eax
  4616 0000383E 5A                  <1> 	pop	edx
  4617                              <1>         ;jc	sysstty_pd_err ; 'permission denied !'
  4618                              <1> 	; 06/02/2022
  4619 0000383F 7305                <1> 	jnc	short sysstty_21
  4620                              <1> 	; 'permission denied !'
  4621 00003841 E942FFFFFF          <1> 	jmp	sysstty_pd_err
  4622                              <1> sysstty_21:
  4623                              <1> 	; 29/10/2015
  4624 00003846 86E9                <1> 	xchg 	ch, cl
  4625                              <1> 		; cl = character, ch = color code
  4626 00003848 86C1                <1> 	xchg	al, cl
  4627                              <1> 		; al = character, cl = tty number
  4628 0000384A 80F907              <1> 	cmp	cl, 7
  4629                              <1> 	;ja	sysstty_12
  4630                              <1> 	; 06/02/2022
  4631 0000384D 7628                <1> 	jna	short sysstty_16
  4632                              <1> ;;
  4633 0000384F 80FEFF              <1> 	cmp	dh, 0FFh
  4634 00003852 740B                <1> 	je	short sysstty_22 ; do not set comm. parameters
  4635                              <1> 
  4636                              <1> ; 01/02/2022
  4637                              <1> ;	; 29/10/2015
  4638                              <1> ;	mov	ah, dl ; communication parameters
  4639                              <1> ;		; ah = 0E3h = 11100011b = 115200 baud,
  4640                              <1> ;		;			 THRE int + RDA int 
  4641                              <1> ;		; ah = 23h = 00100011b = 9600 baud,
  4642                              <1> ;		;			 THRE int + RDA int 
  4643                              <1> ;	sub	al, al ; 0
  4644                              <1> ;	; 12/07/2014
  4645                              <1> ;	cmp	cl, 9
  4646                              <1> ;	jb	short sysstty_1
  4647                              <1> ;	inc	al
  4648                              <1> ;sysstty_1:
  4649                              <1> ;	; 01/02/2022
  4650                              <1> ;	push	ecx
  4651                              <1> ;	; 29/06/2015	
  4652                              <1> ;	call 	sp_setp ; Set serial port communication parameters
  4653                              <1> ;	mov	[u.r0+1], cx ; Line status (ah)
  4654                              <1> ;			     ; Modem status (EAX bits 16 to 23)
  4655                              <1> ;	; 01/02/2022
  4656                              <1> ;	pop	ecx	
  4657                              <1> ;       jc      short sysstty_tmout_err ; 29/10/2015
  4658                              <1> 
  4659                              <1> 	; 02/02/2022
  4660 00003854 88C5                <1> 	mov	ch, al ; save char
  4661                              <1> 	; 01/02/2022
  4662 00003856 E84D000000          <1> 	call	sysstty_scp
  4663 0000385B 7292                <1>         jc      short sysstty_tmout_err ; 29/10/2015
  4664                              <1> 	; 02/02/2022
  4665 0000385D 88E8                <1> 	mov	al, ch ; restore char
  4666                              <1> sysstty_22:
  4667                              <1> 	; 01/02/2022
  4668 0000385F 08ED                <1> 	or	ch, ch
  4669 00003861 7437                <1> 	jz	short sysstty_11 ; do not send char to terminal
  4670                              <1> 	; send char to (serial port) terminal
  4671                              <1> 	; al = character
  4672                              <1> 	; cl = tty number (8 or 9)
  4673 00003863 E949FFFFFF          <1> 	jmp	sysstty_12 ; (tty8 or tty9)
  4674                              <1> 
  4675                              <1> sysstty_inv_dn: 
  4676                              <1> 	; 27/06/2015
  4677                              <1> 	; Invalid device name (not a tty) ! error
  4678                              <1> 	; (Device is not a tty or device name not found)
  4679 00003868 C705[B86C0000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
  4679 00003870 0000                <1>
  4680 00003872 E9D0F8FFFF          <1> 	jmp	error
  4681                              <1> 
  4682                              <1> sysstty_16:
  4683                              <1> 	; 22/02/2022
  4684                              <1> 	; 16/01/2014
  4685                              <1> 	;xor	bh, bh
  4686                              <1> sysstty_9: 	; tty 0 to tty 7
  4687                              <1> 	; al = character
  4688                              <1> 	; ch = color/attribute ; 01/02/2022
  4689                              <1> 	;
  4690                              <1>  	; 22/02/2022 (BugFix)
  4691                              <1> 	; (ebx may be > 255 here!? due to 'ottyp')
  4692 00003877 29DB                <1> 	sub	ebx, ebx ; *
  4693 00003879 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
  4694                              <1> 	;
  4695 0000387B 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
  4696 0000387E 7409                <1> 	je	short sysstty_10
  4697                              <1> 	; 24/12/2021
  4698 00003880 51                  <1> 	push	ecx
  4699 00003881 50                  <1> 	push	eax
  4700                              <1> 	; 22/02/2022	
  4701                              <1> 	;;movzx	ebx, cl ; *
  4702                              <1> 	;mov	bl, cl ; (tty number = video page number)
  4703 00003882 E81DDBFFFF          <1> 	call	set_cpos
  4704 00003887 58                  <1> 	pop	eax
  4705 00003888 59                  <1> 	pop	ecx
  4706                              <1> sysstty_10: 
  4707                              <1> 	; 22/02/2022
  4708                              <1> 	; bl = video page (tty) number 
  4709                              <1> 	;
  4710                              <1> 	; 29/10/2015
  4711 00003889 08C0                <1> 	or	al, al ; character
  4712 0000388B 740D                <1> 	jz      short sysstty_11 ; al = 0
  4713                              <1> 	; 17/11/2015
  4714 0000388D 3CFF                <1> 	cmp	al, 0FFh
  4715 0000388F 7309                <1> 	jnb	short sysstty_11
  4716                              <1> 		; ch > 0 and ch < FFh
  4717                              <1> 	; write a character at current cursor position
  4718 00003891 88EC                <1> 	mov	ah, ch ; color/attribute
  4719                              <1> 	; 12/07/2014
  4720 00003893 51                  <1> 	push	ecx ; 24/12/2021
  4721 00003894 E8F3DBFFFF          <1> 	call	write_c_current
  4722 00003899 59                  <1> 	pop	ecx
  4723                              <1> sysstty_11:
  4724                              <1> 	; 14/01/2014
  4725 0000389A 30D2                <1> 	xor	dl, dl ; sysstty call sign
  4726                              <1> 	; 18/01/2014
  4727                              <1> 	;movzx	eax, cl ; 27/06/2015
  4728 0000389C 88C8                <1> 	mov	al, cl
  4729 0000389E E8251F0000          <1> 	call	cttyp
  4730 000038A3 E9BFF8FFFF          <1> 	jmp	sysret
  4731                              <1> 
  4732                              <1> 	; 06/02/2022 (Retro UNIX 386 v1.2)
  4733                              <1> sysstty_scp:
  4734                              <1> 	; 02/02/2022
  4735                              <1> 	; set communication parameters (for COM1 or COM2)
  4736                              <1> 	; 01/02/2022
  4737                              <1> 	;
  4738                              <1> 	; 29/10/2015
  4739 000038A8 88D4                <1> 	mov	ah, dl ; communication parameters
  4740                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
  4741                              <1> 		;			 THRE int + RDA int 
  4742                              <1> 		; ah = 23h = 00100011b = 9600 baud,
  4743                              <1> 		;			 THRE int + RDA int 
  4744 000038AA 28C0                <1> 	sub	al, al ; 0
  4745                              <1> 	; 12/07/2014
  4746 000038AC 80F909              <1> 	cmp	cl, 9
  4747 000038AF 7202                <1> 	jb	short sysstty_1
  4748 000038B1 FEC0                <1> 	inc	al
  4749                              <1> sysstty_1:
  4750                              <1> 	; 02/02/2022
  4751 000038B3 52                  <1> 	push	edx
  4752                              <1> 	; 01/02/2022
  4753 000038B4 51                  <1> 	push	ecx
  4754                              <1> 	; 29/06/2015	
  4755 000038B5 E8D3F2FFFF          <1> 	call 	sp_setp ; Set serial port communication parameters
  4756 000038BA 66890D[456C0000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
  4757                              <1> 			     ; Modem status (EAX bits 16 to 23)
  4758                              <1> 	; 01/02/2022
  4759 000038C1 59                  <1> 	pop	ecx	
  4760 000038C2 5A                  <1> 	pop	edx ; 02/02/2022
  4761                              <1> 	; 01/02/2022
  4762                              <1> 	; if cf = 1 -> sysstty_tmout_err
  4763 000038C3 C3                  <1> 	retn
  4764                              <1> 
  4765                              <1> 	; 06/02/2022 (Retro UNIX 386 v1.2)
  4766                              <1> sysstty_14:
  4767                              <1> 	; 23/02/2022
  4768                              <1> 	; 02/02/2022
  4769                              <1> 	; ch = 0
  4770                              <1> 	; cl = video page
  4771                              <1> 	;
  4772                              <1> 	; dx = 0FFFFh
  4773                              <1> 	; clear screen (video page)
  4774                              <1> 	;
  4775                              <1> 
  4776                              <1> 	; 02/02/2022
  4777                              <1> 	; clear screen
  4778                              <1> 	;
  4779                              <1> 	; (modified registers: eax, ebx, ecx, edx, esi, edi)
  4780                              <1> 
  4781                              <1> 	; 23/02/2022
  4782 000038C4 88CB                <1> 	mov 	bl, cl ; CL = tty number (0 to 7)
  4783                              <1> 
  4784                              <1> 	; clear video page
  4785 000038C6 E810000000          <1> 	call	wttyc ; 23/02/2022
  4786                              <1> 
  4787                              <1> 	; 23/02/2022
  4788 000038CB 88D8                <1> 	mov	al, bl
  4789 000038CD 8A25[956C0000]      <1> 	mov	ah, [u.uno]
  4790 000038D3 66A3[446C0000]      <1> 	mov	[u.r0], ax
  4791 000038D9 EBBF                <1> 	jmp	short sysstty_11
  4792                              <1> 
  4793                              <1> wttyc:
  4794                              <1> 	; 23/02/2022
  4795                              <1> 	; (clear video page)
  4796                              <1> 	; INPUT:
  4797                              <1> 	;  bl = video page (0 to 7)
  4798                              <1> 	;
  4799                              <1> 	; Modified registers: eax, ecx, edx, esi, edi
  4800                              <1> 
  4801                              <1> 	;xor	dx, dx ; column 0, row 0
  4802                              <1> 	;;inc	dx ; 0 ; 23/02/2022
  4803                              <1> 	;
  4804                              <1> ;	movzx	ebx, cl
  4805                              <1> ;	mov 	bl, cl ; CL = tty number (0 to 7) ; 23/02/2022
  4806                              <1> 
  4807                              <1> ;	shl 	bl, 1 
  4808                              <1> ;	mov 	al, byte ptr [ebx+ttyl]
  4809                              <1> ;		; AL = lock value (0 or process number)
  4810                              <1> ;	or	al, al
  4811                              <1> ;	jz	short @f
  4812                              <1> ;	cmp	al, byte ptr [u.uno] ; process number
  4813                              <1> ;	jne	short sysstty_15
  4814                              <1> ;		; only the owner can clear its video page
  4815                              <1> ;	xor	al, al ; 0
  4816                              <1> ;@@:
  4817                              <1> ;	;mov	bl, cl		
  4818                              <1> ;	shr	bl, 1 
  4819                              <1> 
  4820 000038DB 30C0                <1> 	xor	al, al	; 0
  4821 000038DD B407                <1> 	mov 	ah, 07h	; attribute/color (default)
  4822                              <1> 
  4823                              <1> 	; scroll_up input:
  4824                              <1> 	;
  4825                              <1> 	; al = line count (0 or 1) ((0 == clear video page))
  4826                              <1> 	; 	((al = 1 for write_tty (putc) procedure))
  4827                              <1> 	; ah = attribute to be used on blanked line
  4828                              <1> 	; bl = video page number (0 to 7)
  4829                              <1> 
  4830 000038DF E846DBFFFF          <1> 	call	scroll_up ; clear video page (al=0)
  4831                              <1> 
  4832                              <1> 	; (modified registers: eax, ecx, edx, esi, edi)
  4833                              <1> 
  4834                              <1> 	; bl = video page number (0 to 7)
  4835                              <1> 	;xor	dx, dx ; column 0, row 0
  4836                              <1> 	; 02/02/2022
  4837 000038E4 31D2                <1> 	xor	edx, edx
  4838                              <1> 	; 23/02/2022
  4839                              <1> 	;call	set_cpos
  4840                              <1> 	;retn
  4841 000038E6 E9B9DAFFFF          <1> 	jmp	set_cpos
  4842                              <1> 
  4843                              <1> 	;mov	al, bl
  4844                              <1> 	;mov	ah, [u.uno]
  4845                              <1> 	;mov	[u.r0], ax
  4846                              <1> 	;jmp	short sysstty_11
  4847                              <1> 
  4848                              <1> ;sysstty_15:
  4849                              <1> ;	; 30/01/2022
  4850                              <1> ;	; permission (denied) error
  4851                              <1> ;	;xor	dl, dl ; sysstty call sign
  4852                              <1> ;	mov	al, cl
  4853                              <1> ;	sub	ah, ah ; 0
  4854                              <1> ;	call	cttyp
  4855                              <1> ;	jmp	error
  4856                              <1> 
  4857                              <1> ; Original UNIX v1 'sysstty' routine:
  4858                              <1> ; gtty:
  4859                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
  4860                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
  4861                              <1> 	; 		/ r2 has source
  4862                              <1>         ;mov    r2,-(sp)
  4863                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
  4864                              <1> ;1: / flush the clist wait till typewriter is quiescent
  4865                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
  4866                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
  4867                              <1>         ;mov    $240,*$ps / set processor priority to 5
  4868                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
  4869                              <1>         ;       br .+4 / list empty, skip branch
  4870                              <1>         ;br     1b / get another character until list is empty
  4871                              <1>         ;mov    0b,r1 / move cc offset to r1
  4872                              <1>         ;inc    r1 / bump it for output clist
  4873                              <1>         ;tstb   cc(r1) / is it 0
  4874                              <1>         ;beq    1f / yes, no characters to output
  4875                              <1>  	;mov    r1,0f / no, put offset in sleep arg
  4876                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
  4877                              <1>         ;br     1b / try to calm it down again
  4878                              <1> ;1:
  4879                              <1>         ;mov    (sp)+,r1
  4880                              <1>         ;mov    (sp)+,r2 / restore registers
  4881                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
  4882                              <1>         ;beq    1f / if 0, 1f
  4883                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
  4884                              <1>         ;                   / control status register
  4885                              <1> ;1:
  4886                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
  4887                              <1>         ;beq    1f / if 0 1f
  4888                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
  4889                              <1> 	;		    / control status reg
  4890                              <1> ;1:
  4891                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
  4892                              <1>         ;jmp     sysret2 / return to user
  4893                              <1> 
  4894                              <1> sysgtty: ; < get tty status >
  4895                              <1> 	; 22/02/2022
  4896                              <1> 	; 21/02/2022 
  4897                              <1> 	;	(Retro UNIX 386 v1.2, inode number modifications)
  4898                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
  4899                              <1> 	;	    ((32 bit reg push/pop))
  4900                              <1> 	; 23/11/2015
  4901                              <1> 	; 29/10/2015
  4902                              <1> 	; 17/10/2015
  4903                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
  4904                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
  4905                              <1> 	;
  4906                              <1> 	; 'sysgtty' gets the status of tty in question. 
  4907                              <1> 	; It stores in the three words addressed by it's argument
  4908                              <1> 	; the status of the typewriter whose file descriptor
  4909                              <1> 	; in (u.r0).
  4910                              <1> 	;
  4911                              <1> 	; Calling sequence:
  4912                              <1> 	;	sysgtty; arg
  4913                              <1> 	; Arguments:
  4914                              <1> 	;	arg - address of 3 words destination of the status
  4915                              <1> 	; Inputs: ((*u.r0 - file descriptor))
  4916                              <1> 	; Outputs: ((status in address which is pointed to by arg))
  4917                              <1> 	; ...............................................................
  4918                              <1> 	;	
  4919                              <1> 	; Retro UNIX 8086 v1 modification: 
  4920                              <1> 	;	'sysgtty' system call will return status of tty
  4921                              <1> 	;	(keyboard, serial port and video page status)
  4922                              <1> 	;	 in following manner:
  4923                              <1> 	;
  4924                              <1> 	; Inputs:
  4925                              <1> 	;	BX = 0 --> means 
  4926                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
  4927                              <1> 	;	                 for (current) process
  4928                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
  4929                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
  4930                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
  4931                              <1> 	;	     CH > 0 -->	tty number + 1
  4932                              <1> 	;
  4933                              <1> 	;	BX > 0 --> points to name of tty
  4934                              <1> 	;	     CL = 0 --> return keyboard status
  4935                              <1> 	;	     CL = 1 --> return video page status
  4936                              <1> 	;	     CH = undefined		 
  4937                              <1> 	;
  4938                              <1> 	; Outputs:
  4939                              <1> 	;	cf = 0 ->
  4940                              <1> 	;
  4941                              <1> 	;	     AL = tty number from 0 to 9
  4942                              <1> 	;		  (0 to 7 is also the video page of the tty)	
  4943                              <1> 	;	     AH = 0 if the tty is free/unused
  4944                              <1> 	;	     AH = the process number of the caller 
  4945                              <1>  	;	     AH = FFh if the tty is locked by another process
  4946                              <1> 	;
  4947                              <1> 	;	  (if calling is for serial port status)
  4948                              <1> 	;	     BX = serial port status if tty number is 8 or 9
  4949                              <1> 	;		  (BH = modem status, BL = Line status)
  4950                              <1> 	;	     CX = 0FFFFh (if data is ready)
  4951                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
  4952                              <1> 	;
  4953                              <1> 	;	  (if calling is for keyboard status)
  4954                              <1> 	;	     BX = current character in tty/keyboard buffer
  4955                              <1> 	;		  (BH = scan code, BL = ascii code)
  4956                              <1> 	;		  (BX=0 if there is not a waiting character)
  4957                              <1> 	;	     CX  is undefined
  4958                              <1> 	;
  4959                              <1> 	;	  (if calling is for video page status)	
  4960                              <1> 	;	     BX = cursor position on the video page
  4961                              <1> 	;		  if tty number < 8
  4962                              <1> 	;		  (BH = row, BL = column)
  4963                              <1> 	;	     CX = current character (in cursor position)
  4964                              <1> 	;		  on the video page of the tty 
  4965                              <1> 	;		  if tty number < 8
  4966                              <1> 	;		  (CH = color, CL = character)
  4967                              <1> 	;	
  4968                              <1> 	;	cf = 1 means error (requested tty is not ready)
  4969                              <1> 	;
  4970                              <1> 	;	     AH = FFh if the caller is not owner of
  4971                              <1> 	;		  specified tty or console tty
  4972                              <1> 	;	     AL = tty number (0FFh if it does not exist)
  4973                              <1> 	;	     BX, CX are undefined if cf = 1
  4974                              <1> 	;
  4975                              <1> 	;	  (If tty number is 8 or 9)
  4976                              <1> 	;	     AL = tty number 
  4977                              <1> 	;	     AH = the process number of the caller 
  4978                              <1> 	;	     BX = serial port status
  4979                              <1> 	;  		 (BH = modem status, BL = Line status)
  4980                              <1> 	;	     CX = 0
  4981                              <1> 	;
  4982                              <1> 		
  4983                              <1> gtty:   ; get (requested) tty number
  4984                              <1> 	; 22/02/2022
  4985                              <1> 	; 21/02/2022 (Retro UNIX 386 v1.2, inode number modifications)
  4986                              <1> 	; 17/10/2015
  4987                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
  4988                              <1> 	; 30/05/2013 - 12/07/2014
  4989                              <1> 	; Retro UNIX 8086 v1 modification ! 
  4990                              <1> 	;
  4991                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
  4992                              <1> 	;
  4993                              <1> 	; 28/06/2015 (32 bit modifications)
  4994                              <1> 	; 16/01/2014
  4995 000038EB 31C0                <1> 	xor 	eax, eax
  4996 000038ED 6648                <1> 	dec	ax ; 17/10/2015
  4997 000038EF A3[446C0000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
  4998 000038F4 80F901              <1> 	cmp	cl, 1
  4999 000038F7 760F                <1> 	jna	short sysgtty_0
  5000                              <1> sysgtty_invp:
  5001                              <1> 	; 28/06/2015
  5002 000038F9 C705[B86C0000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
  5002 00003901 0000                <1>
  5003 00003903 E93FF8FFFF          <1> 	jmp	error
  5004                              <1> sysgtty_0:	
  5005 00003908 21DB                <1> 	and	ebx, ebx
  5006 0000390A 7427                <1> 	jz	short sysgtty_1
  5007                              <1> 	;
  5008 0000390C 891D[606C0000]      <1> 	mov	[u.namep], ebx
  5009                              <1> 	;push	cx ; 23/11/2015
  5010 00003912 51                  <1> 	push	ecx ; 24/12/2021
  5011 00003913 E846070000          <1> 	call	namei
  5012 00003918 59                  <1> 	pop	ecx
  5013                              <1> 	;pop	cx ; 23/11/2015
  5014 00003919 7213                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
  5015                              <1> 	;
  5016                              <1> 	; 21/02/2022
  5017                              <1> 	;cmp	ax, 1
  5018                              <1> 	;jna	short sysgtty_2
  5019                              <1> 	;sub	ax, 10
  5020                              <1> 	;cmp	ax, 9
  5021                              <1> 	;;ja	short sysgtty_inv_dn
  5022                              <1> 	;;mov	ch, al
  5023                              <1> 	;;jmp	short sysgtty_4
  5024                              <1> 	;; 23/11/2015
  5025                              <1> 	;jna	short sysgtty_4
  5026                              <1> 	;
  5027                              <1> 	; 21/02/2022
  5028                              <1> 	; (Retro UNIX 386 v2 file system inode numbers)
  5029 0000391B 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
  5030 0000391E 770E                <1> 	ja	short sysgtty_inv_dn
  5031                              <1> 	;cmp	al, 8	; /dev/tty inode number is 8
  5032                              <1> 	;jb	short sysgtty_inv_dn
  5033 00003920 2C08                <1> 	sub	al, 8
  5034 00003922 720A                <1> 	jb	short sysgtty_inv_dn
  5035 00003924 7416                <1> 	jz	short sysgtty_2 ; /dev/tty inode number is 8
  5036                              <1> 	; convert inode number to tty number (tty0 to tty9)
  5037 00003926 2C09                <1> 	sub	al, 9
  5038 00003928 7204                <1> 	jb	short sysgtty_inv_dn
  5039                              <1> 	; al = 0 to 9
  5040 0000392A 29DB                <1> 	sub	ebx, ebx ; 22/02/2022
  5041 0000392C EB1F                <1> 	jmp	short sysgtty_4
  5042                              <1> 	
  5043                              <1> sysgtty_inv_dn: 
  5044                              <1> 	;; 28/06/2015
  5045                              <1> 	;; Invalid device name (not a tty) ! error
  5046                              <1> 	;; (Device is not a tty or device name not found)
  5047                              <1> 	;mov	dword [u.error], ERR_INV_DEV_NAME
  5048                              <1> 	;jmp	error
  5049                              <1> 	; 21/02/2022
  5050 0000392E E935FFFFFF          <1> 	jmp	sysstty_inv_dn
  5051                              <1> 
  5052                              <1> sysgtty_1:
  5053                              <1> 	; 16/01/2014
  5054 00003933 80FD0A              <1> 	cmp	ch, 10
  5055 00003936 77C1                <1> 	ja	short sysgtty_invp ; 28/06/2015
  5056 00003938 FECD                <1> 	dec	ch ; 0 -> FFh (negative)
  5057 0000393A 790F                <1> 	jns	short sysgtty_3 ; not negative
  5058                              <1> sysgtty_2:
  5059                              <1> 	; get tty number of console tty
  5060 0000393C 8A25[956C0000]      <1> 	mov	ah, [u.uno]
  5061                              <1>  	; 28/06/2015
  5062 00003942 0FB6DC              <1> 	movzx 	ebx, ah
  5063 00003945 8AAB[43680000]      <1> 	mov	ch, [ebx+p.ttyc-1]
  5064                              <1> sysgtty_3:
  5065 0000394B 88E8                <1> 	mov	al, ch
  5066                              <1> sysgtty_4:
  5067 0000394D A2[446C0000]        <1> 	mov	[u.r0], al
  5068                              <1>  	; 28/06/2015
  5069                              <1> 	;cmp	al, 9
  5070                              <1> 	;ja	short sysgtty_invp
  5071 00003952 8B2D[406C0000]      <1> 	mov	ebp, [u.usp]
  5072                              <1> 	; 23/11/2015
  5073 00003958 20C9                <1> 	and	cl, cl
  5074 0000395A 7432                <1> 	jz	short sysgtty_6 ; keyboard status
  5075 0000395C 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
  5076 0000395E 722E                <1> 	jb	short sysgtty_6 ; video page status
  5077                              <1> 	; serial port status
  5078                              <1> 	; 12/07/2014
  5079                              <1> 	;mov	dx, 0
  5080                              <1> 	;je	short sysgtty_5
  5081                              <1> 	;inc	dl
  5082                              <1> ;sysgtty_5:
  5083                              <1> 	; 28/06/2015
  5084 00003960 2C08                <1> 	sub	al, 8
  5085 00003962 E81EF2FFFF          <1> 	call	sp_status ; serial (COM) port (line) status
  5086                              <1> 	; AL = Line status, AH = Modem status
  5087 00003967 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
  5088 0000396B 8A25[956C0000]      <1> 	mov	ah, [u.uno]
  5089 00003971 8825[456C0000]      <1>         mov     [u.r0+1], ah
  5090                              <1> 	; 24/12/2021
  5091 00003977 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)
  5092                              <1> 				; (in ECX)
  5093 0000397D A880                <1> 	test	al, 80h
  5094 0000397F 7561                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
  5095 00003981 A801                <1> 	test	al, 1
  5096                              <1> 	;jz	sysret
  5097 00003983 7404                <1> 	jz	short sysgtty_10
  5098 00003985 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)
  5099                              <1> sysgtty_10:
  5100 00003989 E9D9F7FFFF          <1> 	jmp	sysret
  5101                              <1> sysgtty_6:
  5102 0000398E A2[796C0000]        <1> 	mov	[u.ttyn], al ; tty number
  5103                              <1> 	;movzx	ebx, al
  5104 00003993 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
  5105 00003995 D0E3                <1> 	shl 	bl, 1  ; aligned to word
  5106                              <1> 	; 22/04/2014 - 29/06/2015
  5107 00003997 81C3[54670000]      <1>         add     ebx, ttyl
  5108 0000399D 8A23                <1>  	mov	ah, [ebx]
  5109 0000399F 3A25[956C0000]      <1> 	cmp	ah, [u.uno]
  5110 000039A5 7404                <1> 	je	short sysgtty_7
  5111 000039A7 20E4                <1> 	and	ah, ah
  5112                              <1> 	;jz	short sysgtty_7
  5113 000039A9 7506                <1> 	jnz	short sysgtty_8
  5114                              <1> 	;mov	ah, 0FFh
  5115                              <1> sysgtty_7:
  5116 000039AB 8825[456C0000]      <1>         mov     [u.r0+1], ah
  5117                              <1> sysgtty_8:
  5118 000039B1 08C9                <1> 	or	cl, cl
  5119 000039B3 7510                <1> 	jnz	short sysgtty_9
  5120 000039B5 B001                <1> 	mov	al, 1  ; test a key is available
  5121 000039B7 E88F210000          <1> 	call	getc
  5122 000039BC 66894510            <1> 	mov	[ebp+16], ax ; bx, character
  5123 000039C0 E9A2F7FFFF          <1> 	jmp	sysret
  5124                              <1> sysgtty_9:
  5125 000039C5 8A1D[796C0000]      <1> 	mov	bl, [u.ttyn]
  5126                              <1> 	; bl = video page number
  5127 000039CB E8EC220000          <1> 	call 	get_cpos
  5128                              <1> 	; dx = cursor position
  5129 000039D0 66895510            <1> 	mov	[ebp+16], dx ; bx
  5130                              <1> 	;mov	bl, [u.ttyn]
  5131                              <1> 	; bl = video page number
  5132 000039D4 E8F4220000          <1> 	call	read_ac_current
  5133                              <1> 	; ax = character and attribute/color
  5134 000039D9 66894518            <1> 	mov	[ebp+24], ax ; cx
  5135 000039DD E985F7FFFF          <1> 	jmp	sysret
  5136                              <1> sysgtty_dnr_err:
  5137                              <1> 	; 'device not responding !' error	
  5138                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
  5139 000039E2 C705[B86C0000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ; 25
  5139 000039EA 0000                <1>
  5140 000039EC E956F7FFFF          <1> 	jmp	error	
  5141                              <1> 
  5142                              <1> ; Original UNIX v1 'sysgtty' routine:
  5143                              <1> ; sysgtty:
  5144                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
  5145                              <1> 	;	       / r2 has destination
  5146                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
  5147                              <1> 	;                     / in 1st word of dest
  5148                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
  5149                              <1> 	;                     / in 2nd word of dest
  5150                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
  5151                              <1>         ;jmp    sysret2 / return to user
  5152                              <1> 	
  5153                              <1> ; Original UNIX v1 'gtty' routine:
  5154                              <1> ; gtty:
  5155                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
  5156                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
  5157                              <1>         ;jsr    r0,getf / get the i-number of the file
  5158                              <1>         ;tst    r1 / is it open for reading
  5159                              <1>         ;bgt    1f / yes
  5160                              <1>         ;neg    r1 / no, i-number is negative, 
  5161                              <1> 	;          / so make it positive
  5162                              <1> ;1:
  5163                              <1>         ;sub    $14.,r1 / get i-number of tty0
  5164                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
  5165                              <1>         ;bhis   error9 / no, error
  5166                              <1>         ;asl    r1 / 0%2
  5167                              <1>         ;asl    r1 / 0%4 / yes
  5168                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
  5169                              <1> 	;	       ; / tty block
  5170                              <1>         ;mov    u.off,r2 / put argument in r2
  5171                              <1>         ;rts    r0 / return
  2090                                  %include 'u2.s'      ; 11/05/2015
  2091                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2092                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2093                              <1> ; ****************************************************************************
  2094                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS2.INC
  2095                              <1> ; Last Modification: 18/07/2022
  2096                              <1> ; ----------------------------------------------------------------------------
  2097                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2098                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2099                              <1> ;
  2100                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2101                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2102                              <1> ; <Bell Laboratories (17/3/1972)>
  2103                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2104                              <1> ;
  2105                              <1> ; Retro UNIX 8086 v1 - U2.ASM (24/03/2014) //// UNIX v1 -> u2.s
  2106                              <1> ;
  2107                              <1> ; ****************************************************************************
  2108                              <1> 
  2109                              <1> syslink:
  2110                              <1> 	; 12/01/2022
  2111                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
  2112                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2113                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2114                              <1> 	;
  2115                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
  2116                              <1> 	; name 1 is a file that already exists. name 2 is the name
  2117                              <1> 	; given to the entry that will go in the current directory.
  2118                              <1> 	; name2 will then be a link to the name 1 file. The i-number
  2119                              <1> 	; in the name 2 entry of current directory is the same
  2120                              <1> 	; i-number for the name 1 file.
  2121                              <1> 	;
  2122                              <1> 	; Calling sequence:
  2123                              <1> 	;	syslink; name 1; name 2
  2124                              <1> 	; Arguments:
  2125                              <1> 	;	name 1 - file name to which link will be created.
  2126                              <1> 	;	name 2 - name of entry in current directory that
  2127                              <1> 	;		 links to name 1.
  2128                              <1> 	; Inputs: -
  2129                              <1> 	; Outputs: -
  2130                              <1> 	; ...............................................................
  2131                              <1> 	;	
  2132                              <1> 	; Retro UNIX 8086 v1 modification: 
  2133                              <1> 	;       'syslink' system call has two arguments; so,
  2134                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
  2135                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
  2136                              <1> 	;
  2137                              <1> 		; / name1, name2
  2138                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
  2139 000039F1 891D[606C0000]      <1> 	mov	[u.namep], ebx
  2140 000039F7 51                  <1> 	push	ecx
  2141 000039F8 E861060000          <1> 	call	namei
  2142                              <1> 		; jsr r0,namei / find the i-number associated with
  2143                              <1> 			     ; / the 1st path name
  2144                              <1>      	;;and	ax, ax
  2145                              <1> 	;;jz	error ; File not found
  2146                              <1> 	;jc	error 
  2147                              <1> 		; br error9 / cannot be found
  2148 000039FD 730F                <1> 	jnc	short syslink0
  2149                              <1> 	;pop 	ecx
  2150                              <1> 	; 'file not found !' error
  2151 000039FF C705[B86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2151 00003A07 0000                <1>
  2152 00003A09 E939F7FFFF          <1> 	jmp	error
  2153                              <1> syslink0:
  2154 00003A0E E844110000          <1> 	call	iget
  2155                              <1> 		; jsr r0,iget / get the i-node into core
  2156 00003A13 8F05[606C0000]      <1> 	pop	dword [u.namep] ; ecx
  2157                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
  2158                              <1> 	; 24/12/2021
  2159 00003A19 50                  <1> 	push	eax ; *
  2160                              <1> 	;push	ax
  2161                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
  2162                              <1> 			    ; / (a link to this file is to be created)
  2163                              <1> 	; 24/12/2021
  2164 00003A1A 8A0D[216C0000]      <1> 	mov	cl, [cdev]
  2165 00003A20 51                  <1> 	push	ecx ; **
  2166                              <1> 	;push	word [cdev]
  2167                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
  2168 00003A21 E8AC000000          <1> 	call	isdir
  2169                              <1> 		; jsr r0,isdir / is it a directory
  2170 00003A26 E833060000          <1> 	call	namei
  2171                              <1> 		; jsr r0,namei / no, get i-number of name2
  2172                              <1> 	;jnc	error
  2173                              <1> 		; br .+4   / not found 
  2174                              <1> 			 ; / so r1 = i-number of current directory
  2175                              <1> 			 ; / ii = i-number of current directory
  2176                              <1> 		; br error9 / file already exists., error
  2177 00003A2B 720F                <1> 	jc	short syslink1
  2178                              <1> 	; pop eax ; 24/12/2021
  2179                              <1> 	; pop eax
  2180                              <1> 	; 'file exists !' error
  2181 00003A2D C705[B86C0000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
  2181 00003A35 0000                <1>
  2182 00003A37 E90BF7FFFF          <1> 	jmp	error
  2183                              <1> syslink1:
  2184                              <1> 	;pop	cx
  2185                              <1> 	; 24/12/2021
  2186 00003A3C 59                  <1> 	pop	ecx ; **
  2187                              <1> 	;cmp	cx, [cdev]
  2188 00003A3D 3A0D[216C0000]      <1> 	cmp	cl, [cdev]
  2189                              <1> 	;jne	error
  2190                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
  2191                              <1> 			       ; / end of current directory
  2192                              <1> 	        ; bne error9
  2193 00003A43 740F                <1> 	je	short syslink2
  2194                              <1> 	; 'not same drive !' error
  2195 00003A45 C705[B86C0000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
  2195 00003A4D 0000                <1>
  2196 00003A4F E9F3F6FFFF          <1> 	jmp	error
  2197                              <1> syslink2:
  2198                              <1> 	;pop	eax ; 24/12/2021
  2199                              <1> 	;push	eax
  2200                              <1> 	; 24/12/2021
  2201 00003A54 8B0424              <1> 	mov	eax, [esp] ; *
  2202 00003A57 66A3[7C6C0000]      <1> 	mov	[u.dirbuf], ax
  2203                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
  2204 00003A5D E8C5000000          <1> 	call	mkdir
  2205                              <1> 		; jsr r0,mkdir / make directory entry for name2 
  2206                              <1> 		 	     ; / in current directory
  2207                              <1> 	; 24/12/2021
  2208 00003A62 58                  <1> 	pop	eax ; *
  2209                              <1> 	;pop	ax
  2210                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
  2211 00003A63 E8EF100000          <1> 	call	iget
  2212                              <1> 		; jsr r0,iget / get i-node into core
  2213 00003A68 FE05[C6670000]      <1> 	inc	byte [i.nlks]
  2214                              <1> 		; incb i.nlks / add 1 to its number of links
  2215                              <1> sysunlink_2:
  2216                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
  2217 00003A6E C605[356C0000]01    <1> 	mov	byte [imodx], 1	; (flag means file data is same
  2218                              <1> 				;  but inode's itself has been modified)
  2219 00003A75 E86E120000          <1> 	call	setimod
  2220                              <1> 		; jsr r0,setimod / set the i-node modified flag
  2221 00003A7A E9E8F6FFFF          <1> 	jmp	sysret
  2222                              <1> 
  2223                              <1> sysunlink:
  2224                              <1> 	; 12/01/2022
  2225                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
  2226                              <1> 	; 04/12/2015 (14 byte file names)
  2227                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2228                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2229                              <1> 	;
  2230                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
  2231                              <1> 	; name from its directory. If this entry was the last link
  2232                              <1> 	; to the file, the contents of the file are freed and the
  2233                              <1> 	; file is destroyed. If, however, the file was open in any
  2234                              <1> 	; process, the actual destruction is delayed until it is 
  2235                              <1> 	; closed, even though the directory entry has disappeared.
  2236                              <1> 	; 
  2237                              <1> 	; The error bit (e-bit) is set to indicate that the file	
  2238                              <1> 	; does not exist or that its directory can not be written.
  2239                              <1> 	; Write permission is not required on the file itself.
  2240                              <1> 	; It is also illegal to unlink a directory (except for
  2241                              <1> 	; the superuser).
  2242                              <1> 	;
  2243                              <1> 	; Calling sequence:
  2244                              <1> 	;	sysunlink; name
  2245                              <1> 	; Arguments:
  2246                              <1> 	;	name - name of directory entry to be removed 
  2247                              <1> 	; Inputs: -
  2248                              <1> 	; Outputs: -
  2249                              <1> 	; ...............................................................
  2250                              <1> 	;				
  2251                              <1> 	; Retro UNIX 8086 v1 modification:
  2252                              <1> 	;	 The user/application program puts address of the name
  2253                              <1> 	;        in BX register as 'sysunlink' system call argument.
  2254                              <1> 
  2255                              <1> 	; / name - remove link name
  2256 00003A7F 891D[606C0000]      <1> 	mov	[u.namep], ebx
  2257                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
  2258 00003A85 E8D4050000          <1> 	call	namei
  2259                              <1> 		; jsr r0,namei / find the i-number associated 
  2260                              <1> 			     ; / with the path name
  2261                              <1> 	;jc	error
  2262                              <1> 		; br error9 / not found
  2263 00003A8A 730F                <1> 	jnc	short sysunlink1
  2264                              <1> 	; 'file not found !' error
  2265 00003A8C C705[B86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2265 00003A94 0000                <1>
  2266 00003A96 E9ACF6FFFF          <1> 	jmp	error
  2267                              <1> sysunlink1:
  2268 00003A9B 50                  <1> 	push	eax ; 24/12/2021
  2269                              <1> 	;push	ax
  2270                              <1> 		; mov r1,-(sp) / put its i-number on the stack
  2271 00003A9C E831000000          <1> 	call	isdir
  2272                              <1> 		; jsr r0,isdir / is it a directory
  2273                              <1> 	;xor 	ax, ax
  2274                              <1> 	; 24/12/2021
  2275 00003AA1 31C0                <1> 	xor	eax, eax
  2276 00003AA3 66A3[7C6C0000]      <1> 	mov	[u.dirbuf], ax ; 0
  2277                              <1> 		; clr u.dirbuf / no, clear the location that will
  2278                              <1> 			   ; / get written into the i-number portion
  2279                              <1> 			 ; / of the entry
  2280 00003AA9 832D[646C0000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
  2281                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
  2282 00003AB0 E8BD000000          <1> 	call	wdir
  2283                              <1> 		; jsr r0,wdir / free the directory entry
  2284 00003AB5 58                  <1> 	pop	eax ; 24/12/2021
  2285                              <1> 	;pop	ax
  2286                              <1> 		; mov (sp)+,r1 / get i-number back
  2287 00003AB6 E89C100000          <1> 	call	iget
  2288                              <1> 		; jsr r0,iget / get i-node
  2289                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
  2290                              <1> 	;call	setimod
  2291                              <1> 	;	; jsr r0,setimod / set modified flag
  2292                              <1> 	;	
  2293 00003ABB FE0D[C6670000]      <1> 	dec	byte [i.nlks]
  2294                              <1> 		; decb i.nlks / decrement the number of links
  2295                              <1> 	; 24/12/2021
  2296 00003AC1 75AB                <1> 	jnz	short sysunlink_2
  2297                              <1> 	;jnz	sysret
  2298                              <1> 		; bgt sysret9 / if this was not the last link
  2299                              <1> 			    ; / to file return
  2300                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
  2301 00003AC3 E820120000          <1> 	call	setimod
  2302                              <1> 		; jsr r0,setimod / set modified flag
  2303                              <1> 	; AX = r1 = i-number
  2304 00003AC8 E89B0A0000          <1> 	call	anyi
  2305                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
  2306                              <1> 			 ; / Then free contents of file and destroy it.
  2307 00003ACD E995F6FFFF          <1> 	jmp	sysret
  2308                              <1> 		; br sysret9
  2309                              <1> ;sysunlink_2:
  2310                              <1> 	;; 12/01/2022 - Retro UNIX 386 v1.2
  2311                              <1> 	;mov	byte [imodx], 1	; (flag means file data is same
  2312                              <1> 	;			;  but inode's itself has been modified)
  2313                              <1> 	;call	setimod
  2314                              <1> 	;	; jsr r0,setimod / set the i-node modified flag
  2315                              <1> 	;jmp	sysret
  2316                              <1> 
  2317                              <1> isdir:
  2318                              <1> 	; 13/03/2022
  2319                              <1> 	; 08/01/2022
  2320                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode)
  2321                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  2322                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  2323                              <1> 	;
  2324                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
  2325                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
  2326                              <1> 	;  called by syslink and sysunlink to make sure directories
  2327                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
  2328                              <1> 	; 'isdir' does not bother checking. The current i-node
  2329                              <1> 	;  is not disturbed.			
  2330                              <1> 	;		
  2331                              <1> 	; INPUTS ->
  2332                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
  2333                              <1> 	;    u.uid - user id
  2334                              <1> 	; OUTPUTS ->
  2335                              <1> 	;    r1 - contains current i-number upon exit
  2336                              <1> 	;    	 (current i-node back in core) 
  2337                              <1> 	;	
  2338                              <1> 	; ((AX = R1))
  2339                              <1> 	;
  2340                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2341                              <1> 	;
  2342                              <1> 
  2343                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
  2344                              <1> 	; / there is an error unless super user made the call
  2345                              <1> 	
  2346                              <1> 	; 01/01/2022
  2347 00003AD2 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0 ; 16 bit uid (runix v2 fs inode)
  2348                              <1> 	;cmp	byte [u.uid], 0 
  2349                              <1> 		; tstb u.uid / super user
  2350 00003ADA 764A                <1> 	jna	short isdir1
  2351                              <1> 		; beq 1f / yes, don't care
  2352                              <1> 	; 08/01/2022
  2353 00003ADC FF35[1C6C0000]      <1> 	push	dword [ii]
  2354                              <1> 	;push	word [ii]
  2355                              <1> 		; mov ii,-(sp) / put current i-number on stack
  2356 00003AE2 E870100000          <1> 	call	iget
  2357                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
  2358                              <1> 	; 01/01/2022 (runix v2 fs inode flags)
  2359 00003AE7 F605[C5670000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file ?
  2360 00003AEE 7421                <1> 	jz	short isdir2 ; no, error!
  2361 00003AF0 F605[C5670000]40    <1> 	test	byte [i.flgs+1], 40h ; directory flag
  2362                              <1> 	;test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
  2363                              <1> 		; bit $40000,i.flgs / is it a directory
  2364                              <1> 	;jnz	error
  2365                              <1> 		; bne error9 / yes, error
  2366 00003AF7 7427                <1> 	jz	short isdir0
  2367                              <1> 
  2368                              <1> 	; 13/03/2022
  2369                              <1> 	; NOTE:
  2370                              <1> 	; Unix v5-v7 kernels do not allow (ordinary) users
  2371                              <1> 	; (except root/superuser) --if [u.uid] > 0--
  2372                              <1> 	; to link a directory. (ref: sys2.c, 'link')
  2373                              <1> 	;
  2374                              <1> 	; But, Retro UNIX 386 v1.2 will allow the owner of
  2375                              <1> 	; the directory to link it.
  2376                              <1> 
  2377 00003AF9 66A1[C8670000]      <1> 	mov	ax, [i.uid] ; owner ID of the parent dir
  2378 00003AFF 663B05[966C0000]    <1> 	cmp	ax, [u.uid] ; user ID of current user/process
  2379 00003B06 7509                <1> 	jne	short isdir2
  2380                              <1> 	; 13/03/2022
  2381                              <1> 	; additional checking (may or may not be necessary!?)
  2382 00003B08 663B05[986C0000]    <1> 	cmp	ax, [u.ruid] 
  2383                              <1> 			; real (login) user ID must be same
  2384 00003B0F 740F                <1> 	je	short isdir0
  2385                              <1> 
  2386                              <1> isdir2:
  2387 00003B11 C705[B86C0000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
  2387 00003B19 0000                <1>
  2388                              <1> 				; 'permission denied !' error
  2389                              <1> 	;pop	ax
  2390 00003B1B E927F6FFFF          <1> 	jmp	error	
  2391                              <1> isdir0:	
  2392                              <1> 	; 08/01/2022
  2393 00003B20 58                  <1> 	pop	eax
  2394                              <1> 	;pop	ax
  2395                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
  2396 00003B21 E831100000          <1> 	call	iget
  2397                              <1> 		; jsr r0,iget / get it back in
  2398                              <1> isdir1: ; 1:
  2399 00003B26 C3                  <1> 	retn
  2400                              <1> 		; rts r0
  2401                              <1> 
  2402                              <1> mkdir:
  2403                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
  2404                              <1> 	; 04/12/2015 (14 byte directory names)
  2405                              <1> 	; 12/10/2015
  2406                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
  2407                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  2408                              <1> 	;
  2409                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
  2410                              <1> 	; by u.namep into the current directory.
  2411                              <1> 	;
  2412                              <1> 	; INPUTS ->
  2413                              <1> 	;    u.namep - points to a file name 
  2414                              <1> 	;	           that is about to be a directory entry.
  2415                              <1> 	;    ii - current directory's i-number.	
  2416                              <1> 	; OUTPUTS ->
  2417                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
  2418                              <1> 	;    u.off - points to entry to be filled 
  2419                              <1> 	;	     in the current directory		
  2420                              <1> 	;    u.base - points to start of u.dirbuf.
  2421                              <1> 	;    r1 - contains i-number of current directory 
  2422                              <1> 	;	
  2423                              <1> 	; ((AX = R1)) output
  2424                              <1> 	;
  2425                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
  2426                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2427                              <1> 	;
  2428                              <1> 
  2429                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  2430 00003B27 31C0                <1> 	xor 	eax, eax
  2431 00003B29 BF[7E6C0000]        <1> 	mov     edi, u.dirbuf+2
  2432 00003B2E 89FE                <1> 	mov	esi, edi
  2433 00003B30 AB                  <1> 	stosd
  2434 00003B31 AB                  <1> 	stosd
  2435                              <1> 	; 04/12/2015 (14 byte directory names)
  2436 00003B32 AB                  <1> 	stosd
  2437 00003B33 66AB                <1> 	stosw
  2438                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
  2439 00003B35 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
  2440                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2441                              <1> 	;mov 	ebp, [u.namep]
  2442 00003B37 E881060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  2443                              <1> 		; esi = physical address (page start + offset)
  2444                              <1> 		; ecx = byte count in the page (1 - 4096)
  2445                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2446                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
  2447                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
  2448                              <1> mkdir_1: ; 1: 
  2449 00003B3C 45                  <1> 	inc	ebp ; 12/10/2015
  2450                              <1> 	;
  2451                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
  2452                              <1> 	; 01/08/2013
  2453 00003B3D AC                  <1> 	lodsb
  2454                              <1> 		; movb (r2)+,r1 / move character in name to r1
  2455 00003B3E 20C0                <1> 	and 	al, al
  2456 00003B40 7426                <1> 	jz 	short mkdir_3 	  
  2457                              <1> 		; beq 1f / if null, done
  2458 00003B42 3C2F                <1> 	cmp	al, '/'
  2459                              <1> 		; cmp r1,$'/ / is it a "/"?
  2460 00003B44 7413                <1> 	je	short mkdir_err
  2461                              <1> 	;je	error
  2462                              <1> 		; beq error9 / yes, error
  2463                              <1> 	; 12/10/2015
  2464                              <1> 	;dec	cx
  2465 00003B46 49                  <1> 	dec	ecx ; 24/12/2021
  2466 00003B47 7505                <1> 	jnz	short mkdir_2
  2467                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2468 00003B49 E875060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  2469                              <1> 		; esi = physical address (page start + offset)
  2470                              <1> 		; ecx = byte count in the page
  2471                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2472                              <1> mkdir_2:
  2473 00003B4E 81FF[8C6C0000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
  2474                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
  2475                              <1> 				     ; / a char?
  2476 00003B54 74E6                <1> 	je	short mkdir_1
  2477                              <1> 		; beq 1b / yes, go back
  2478 00003B56 AA                  <1> 	stosb
  2479                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
  2480 00003B57 EBE3                <1> 	jmp 	short mkdir_1
  2481                              <1> 		; br 1b / get next char
  2482                              <1> mkdir_err:
  2483                              <1> 	; 17/06/2015
  2484 00003B59 C705[B86C0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  2484 00003B61 0000                <1>
  2485 00003B63 E9DFF5FFFF          <1> 	jmp	error
  2486                              <1> 
  2487                              <1> mkdir_3: ; 1:
  2488 00003B68 A1[5C6C0000]        <1> 	mov	eax, [u.dirp]
  2489 00003B6D A3[646C0000]        <1> 	mov	[u.off], eax
  2490                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
  2491                              <1> 				 ; / slot to u.off
  2492                              <1> 	; 08/01/2022
  2493                              <1> wdir:	; 24/12/2021 (Retro UNIX 386 v1.2)
  2494                              <1> 	; 29/04/2013
  2495 00003B72 C705[686C0000]-     <1>         mov     dword [u.base], u.dirbuf
  2495 00003B78 [7C6C0000]          <1>
  2496                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
  2497 00003B7C C705[6C6C0000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
  2497 00003B84 0000                <1>
  2498                              <1> 		; mov $10.,u.count / u.count = 10
  2499                              <1> 	; 08/01/2022
  2500 00003B86 A1[1C6C0000]        <1> 	mov	eax, [ii]
  2501                              <1> 	;mov	ax, [ii] 
  2502                              <1> 		; mov ii,r1 / r1 has i-number of current directory
  2503                              <1> 	;mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
  2504                              <1> 	; 08/01/2022 (Retro UNIX 386 v2 file system inode)
  2505 00003B8B 66BA8000            <1> 	mov	dx, 80h	; mov dx, IWRITE
  2506 00003B8F E8AD100000          <1> 	call 	access
  2507                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
  2508                              <1> 				 ; / for writing
  2509                              <1> 	; AX = i-number of current directory
  2510                              <1> 	; 01/08/2013
  2511 00003B94 FE05[B66C0000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
  2512                              <1> 	;call	writei
  2513                              <1> 	;	; jsr r0,writei / write into directory
  2514                              <1> 	;retn	
  2515                              <1> 	;	; rts r0
  2516                              <1> 	; 24/12/2021
  2517 00003B9A E938150000          <1> 	jmp	writei
  2518                              <1> 
  2519                              <1> 
  2520                              <1> 	; 09/05/2022 
  2521                              <1> 	;	(Retro UNIX 386 v1.2, Kernel v0.2.2.1)
  2522                              <1> 	; 06/02/2022
  2523                              <1> 	; 12/01/2022
  2524                              <1> 	; 01/01/2022
  2525                              <1> 	; 24/12/2021
  2526                              <1> 	; 11/12/2021
  2527                              <1> 	; 04/12/2021
  2528                              <1> 	; 30/11/2021
  2529                              <1> 	; 28/11/2021 - Retro UNIX 386 v1.2
  2530                              <1> 	;	(Retro UNIX 386 v2 fs compatibility modification)
  2531                              <1> sysexec:
  2532                              <1> 	; 02/05/2021
  2533                              <1> 	; 27/03/2021
  2534                              <1> 	; 26/03/2021
  2535                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
  2536                              <1> 	; 23/10/2015
  2537                              <1> 	; 10/10/2015, 18/10/2015, 19/10/2015
  2538                              <1> 	; 29/07/2015, 05/08/2015, 05/08/2015
  2539                              <1> 	; 21/07/2015, 24/07/2015, 25/07/2015
  2540                              <1> 	; 01/07/2015, 02/07/2015, 20/07,2015
  2541                              <1> 	; 24/06/2015, 25/06/2021
  2542                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2543                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  2544                              <1> 	;
  2545                              <1> 	; 'sysexec' initiates execution of a file whose path name if
  2546                              <1> 	; pointed to by 'name' in the sysexec call. 
  2547                              <1> 	; 'sysexec' performs the following operations:
  2548                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
  2549                              <1> 	;    2. obtains i-node of file to be executed via 'iget'.
  2550                              <1> 	;    3. sets trap vectors to system routines.
  2551                              <1> 	;    4. loads arguments to be passed to executing file into
  2552                              <1> 	;	highest locations of user's core
  2553                              <1> 	;    5. puts pointers to arguments in locations immediately
  2554                              <1> 	;	following arguments.
  2555                              <1> 	;    6.	saves number of arguments in next location.
  2556                              <1> 	;    7. initializes user's stack area so that all registers
  2557                              <1> 	;	will be zeroed and the PS is cleared and the PC set
  2558                              <1> 	;	to core when 'sysret' restores registers 
  2559                              <1> 	;	and does an rti.
  2560                              <1> 	;    8. inializes u.r0 and u.sp
  2561                              <1> 	;    9. zeros user's core down to u.r0
  2562                              <1> 	;   10.	reads executable file from storage device into core
  2563                              <1> 	;	starting at location 'core'.
  2564                              <1> 	;   11.	sets u.break to point to end of user's code with
  2565                              <1> 	;	data area appended.
  2566                              <1> 	;   12.	calls 'sysret' which returns control at location
  2567                              <1> 	;	'core' via 'rti' instruction.
  2568                              <1> 	;
  2569                              <1> 	; Calling sequence:
  2570                              <1> 	;	sysexec; namep; argp
  2571                              <1> 	; Arguments:
  2572                              <1> 	;	namep - points to pathname of file to be executed
  2573                              <1> 	;	argp  - address of table of argument pointers
  2574                              <1> 	;	argp1... argpn - table of argument pointers
  2575                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
  2576                              <1> 	; Inputs: (arguments)
  2577                              <1> 	; Outputs: -	
  2578                              <1> 	; ...............................................................
  2579                              <1> 	;
  2580                              <1> 	; Retro UNIX 386 v1 modification: 
  2581                              <1> 	;	User application runs in it's own virtual space 
  2582                              <1> 	;	which is izolated from kernel memory (and other
  2583                              <1> 	;	memory pages) via 80386	paging in ring 3 
  2584                              <1> 	;	privilige mode. Virtual start address is always 0.
  2585                              <1> 	;	User's core memory starts at linear address 400000h
  2586                              <1> 	;	(the end of the 1st 4MB).
  2587                              <1> 	;
  2588                              <1> 	; Retro UNIX 8086 v1 modification: 
  2589                              <1> 	;	user/application segment and system/kernel segment
  2590                              <1> 	;	are different and sysenter/sysret/sysrele routines
  2591                              <1> 	;	are different (user's registers are saved to 
  2592                              <1> 	;	and then restored from system's stack.)
  2593                              <1> 	;
  2594                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  2595                              <1> 	;	      arguments which were in these registers;
  2596                              <1> 	;	      but, it returns by putting the 1st argument
  2597                              <1> 	;	      in 'u.namep' and the 2nd argument
  2598                              <1> 	;	      on top of stack. (1st argument is offset of the
  2599                              <1> 	;	      file/path name in the user's program segment.)
  2600                              <1> 	
  2601                              <1> 	;call	arg2
  2602                              <1> 	; * name - 'u.namep' points to address of file/path name
  2603                              <1> 	;          in the user's program segment ('u.segmnt')
  2604                              <1> 	;          with offset in BX register (as sysopen argument 1).
  2605                              <1> 	; * argp - sysexec argument 2 is in CX register 
  2606                              <1> 	;          which is on top of stack.
  2607                              <1> 	;
  2608                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
  2609                              <1> 
  2610                              <1> 	; 23/06/2015 (32 bit modifications)
  2611                              <1> 
  2612 00003B9F 891D[606C0000]      <1> 	mov	[u.namep], ebx ; argument 1
  2613                              <1>         ; 18/10/2015
  2614 00003BA5 890D[D46C0000]      <1> 	mov     [argv], ecx  ; * ; argument 2
  2615 00003BAB E8AE040000          <1> 	call	namei
  2616                              <1> 		; jsr r0,namei / namei returns i-number of file 
  2617                              <1> 			     ; / named in sysexec call in r1
  2618                              <1> 	;jc	error
  2619                              <1> 		; br error9
  2620 00003BB0 730F                <1> 	jnc	short sysexec_0
  2621                              <1> 	;
  2622                              <1> 	; 'file not found !' error
  2623 00003BB2 C705[B86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
  2623 00003BBA 0000                <1>
  2624 00003BBC E986F5FFFF          <1> 	jmp	error
  2625                              <1> 
  2626                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
  2627                              <1> 	; (executable file flag is checked in 'access')
  2628                              <1> 	; (following error message is in 'access' subroutine)
  2629                              <1> ;sysexec_not_exf:
  2630                              <1> 	;; 'not executable file !' error
  2631                              <1> 	;mov	dword [u.error], ERR_NOT_EXECUTABLE
  2632                              <1> 	;jmp	error 
  2633                              <1> sysexec_0:
  2634                              <1> 	; 26/03/2021 ('iget' will be called in 'access')
  2635                              <1> 	;call	iget
  2636                              <1> 	;	; jsr r0,iget / get i-node for file to be executed
  2637                              <1> 	;
  2638                              <1> 	;test	byte [i.flgs], 10h
  2639                              <1> 	;;test	word [i.flgs], 10h
  2640                              <1> 	;	; bit $20,i.flgs / is file executable
  2641                              <1> 	;jz	short sysexec_not_exf
  2642                              <1> 	;;jz	error
  2643                              <1> 	;	; beq error9
  2644                              <1> 	; 26/03/2021
  2645 00003BC1 66BA4000            <1> 	mov	dx, 40h ; IEXEC - execute, owner
  2646 00003BC5 E877100000          <1> 	call	access
  2647                              <1> 	; ! we are here because there is execute permission !
  2648                              <1> 	; ('iopen' is not needed for regular files, from now on)
  2649                              <1> 
  2650                              <1> 	; 26/03/2021
  2651                              <1> 	;; 25/03/2021
  2652                              <1> 	;; (ref: Retro UNIX 386 v2, 'ux.s')
  2653                              <1> 	;mov	dx, 40h ; IEXEC - execute, owner
  2654                              <1> 	;;
  2655                              <1> 	;call	iopen
  2656                              <1> 	;	; jsr r0,iopen / gets i-node for file with i-number
  2657                              <1> 	;		     ; / given in r1 (opens file)
  2658                              <1> 	
  2659                              <1> 	; 26/03/2021
  2660                              <1> 	; AX = i-number of the file
  2661                              <1> 	;test	byte [i.flgs], 20h
  2662                              <1> 	;;test	word [i.flgs], 20h
  2663                              <1> 	;	; bit $40,i.flgs / test user id on execution bit
  2664                              <1> 	;jz	short sysexec_1
  2665                              <1> 	;	; beq 1f
  2666                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013
  2667                              <1> 	;	; tstb u.uid / test user id
  2668                              <1> 	;jna	short sysexec_1
  2669                              <1> 	;	; beq 1f / super user
  2670                              <1> 
  2671                              <1> 	;mov	cl, [i.uid]
  2672                              <1> 	;mov	[u.uid], cl ; 02/08/2013
  2673                              <1> 	;	; movb i.uid,u.uid / put user id of owner of file
  2674                              <1> 				 ; / as process user id
  2675                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
  2676                              <1> 	;mov	al, [i.flgs+1]
  2677 00003BCA 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0	; super user (root) ?
  2678                              <1> 	;jna	short sysexec_19 ; yes, super user
  2679                              <1> 	;; 02/05/2021
  2680 00003BD2 7625                <1> 	jna	short sysexec_1	; don't set UID or GID
  2681                              <1> 
  2682                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2
  2683 00003BD4 A0[C5670000]        <1> 	mov	al, [i.flgs+1]
  2684                              <1> 
  2685                              <1> 	; test set user id on execution bit 
  2686 00003BD9 A808                <1> 	test	al, 08h ; ISUID flag (800h)
  2687                              <1> 	;jz	short sysexec_19
  2688                              <1> 	; 02/05/2021
  2689 00003BDB 741C                <1> 	jz	short sysexec_1 ; do not set group ID
  2690                              <1> 				; (if user ID will not be set)
  2691                              <1> 				; (02/05/2021)	
  2692                              <1> 	; set user id on exec (800h)
  2693                              <1> 	; 26/03/2021
  2694                              <1> sysexec_setuid:
  2695                              <1> 	;; 27/03/2021
  2696                              <1> 	;cmp	word [u.uid], 0
  2697                              <1> 	;;jna	short sysexec_19 ; super user
  2698                              <1> 	;; 02/05/2021
  2699                              <1> 	;jna	short sysexec_1 ; do not set group ID
  2700                              <1> 	;			; (if user ID will not be set)
  2701                              <1> 	;			; (02/05/2021)
  2702 00003BDD 668B0D[C8670000]    <1> 	mov	cx, [i.uid]
  2703 00003BE4 66890D[966C0000]    <1> 	mov	[u.uid], cx
  2704                              <1> sysexec_19:
  2705                              <1> 	; test set group id on execution bit 
  2706 00003BEB A804                <1> 	test	al, 04h ; ISGID flag (400h)
  2707 00003BED 740A                <1> 	jz	short sysexec_1
  2708                              <1> sysexec_setgid:
  2709                              <1> 	; set group id on exec (400h)
  2710 00003BEF A0[CA670000]        <1> 	mov	al, [i.gid]
  2711 00003BF4 A2[9A6C0000]        <1> 	mov	[u.gid], al
  2712                              <1> 	;
  2713                              <1> sysexec_1:
  2714                              <1> 	; 06/02/2022
  2715                              <1> 	; 12/01/2022
  2716                              <1> 	; 24/12/2021
  2717                              <1> 	; 11/12/2021
  2718                              <1> 	; 04/12/2021
  2719                              <1> 	; 10/10/2015, 18/10/2015
  2720                              <1> 	; 21/07/2015, 24/07/2015
  2721                              <1> 	; 24/06/2015, 25/06/2015
  2722                              <1>         ; Moving arguments to the end of [u.upage]
  2723                              <1> 	; (by regarding page borders in user's memory space)
  2724                              <1> 	;
  2725                              <1> 	; 10/10/2015
  2726                              <1> 	; 21/07/2015
  2727 00003BF9 89E5                <1> 	mov	ebp, esp ; (**)
  2728                              <1> 	; 18/10/2015
  2729 00003BFB 89EF                <1> 	mov 	edi, ebp
  2730 00003BFD B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
  2731                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
  2732 00003C02 29CF                <1> 	sub	edi, ecx
  2733 00003C04 89FC                <1> 	mov	esp, edi
  2734 00003C06 31C0                <1> 	xor	eax, eax
  2735 00003C08 A3[706C0000]        <1> 	mov 	[u.nread], eax ; 0
  2736                              <1> 	; 12/01/2022
  2737                              <1> 	; ([argc] must be cleared because previous 'sysexec'
  2738                              <1> 	; may leave it with any value after an error))
  2739 00003C0D A3[D06C0000]        <1> 	mov	[argc], eax ; 0
  2740                              <1> 	;
  2741 00003C12 49                  <1> 	dec	ecx ; 256 - 1
  2742 00003C13 890D[6C6C0000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
  2743                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
  2744                              <1> 	; 24/12/2021
  2745                              <1> sysexec_2:
  2746 00003C19 8B35[D46C0000]      <1> 	mov	esi, [argv] ; 18/10/2015
  2747 00003C1F E85C020000          <1> 	call	get_argp
  2748                              <1> 	;mov	ecx, 4 
  2749                              <1> 	; 06/02/2022
  2750 00003C24 31C9                <1> 	xor	ecx, ecx
  2751 00003C26 B104                <1> 	mov	cl, 4
  2752                              <1> sysexec_3:
  2753 00003C28 21C0                <1> 	and	eax, eax
  2754 00003C2A 7454                <1> 	jz	short sysexec_6
  2755                              <1> 	; 18/10/2015
  2756 00003C2C 010D[D46C0000]      <1> 	add	[argv], ecx ; 4
  2757                              <1> 	;;inc	word [argc]
  2758                              <1> 	; 11/12/2021
  2759                              <1> 	;inc	dword [argc]
  2760                              <1> 	; 12/01/2022
  2761 00003C32 FE05[D06C0000]      <1> 	inc	byte [argc]
  2762                              <1> 	;
  2763 00003C38 A3[686C0000]        <1> 	mov	[u.base], eax
  2764                              <1>  	; 23/10/2015
  2765 00003C3D 66C705[B06C0000]00- <1> 	mov	word [u.pcount], 0
  2765 00003C45 00                  <1>
  2766                              <1> sysexec_4:
  2767 00003C46 E8C4160000          <1> 	call	cpass ; get a character from user's core memory
  2768 00003C4B 750B                <1>         jnz	short sysexec_5
  2769                              <1> 		; (max. 255 chars + null)
  2770                              <1> 	; 18/10/2015
  2771 00003C4D 28C0                <1> 	sub 	al, al
  2772 00003C4F AA                  <1> 	stosb
  2773 00003C50 FF05[706C0000]      <1> 	inc	dword [u.nread]
  2774 00003C56 EB28                <1> 	jmp	short sysexec_6
  2775                              <1> sysexec_5:
  2776 00003C58 AA                  <1> 	stosb
  2777 00003C59 20C0                <1> 	and 	al, al
  2778 00003C5B 75E9                <1> 	jnz	short sysexec_4
  2779 00003C5D B904000000          <1> 	mov	ecx, 4
  2780 00003C62 390D[CC6C0000]      <1> 	cmp	[ncount], ecx ; 4
  2781 00003C68 72AF                <1> 	jb	short sysexec_2
  2782 00003C6A 8B35[C86C0000]      <1> 	mov	esi, [nbase]
  2783 00003C70 010D[C86C0000]      <1> 	add	[nbase], ecx ; 4	
  2784                              <1> 	;sub	[ncount], cx 
  2785                              <1> 	; 11/12/2021
  2786 00003C76 290D[CC6C0000]      <1> 	sub	[ncount], ecx
  2787 00003C7C 8B06                <1> 	mov	eax, [esi]
  2788 00003C7E EBA8                <1> 	jmp	short sysexec_3
  2789                              <1> sysexec_6:
  2790                              <1> 	; 24/12/2021
  2791                              <1> 	; 18/10/2015
  2792                              <1> 	; argument list transfer from user's core memory to
  2793                              <1> 	; kernel stack frame is OK here.
  2794                              <1> 	; [u.nread] = argument list length
  2795                              <1> 	;mov	[argv], esp ; start address of argument list
  2796                              <1> 	;
  2797                              <1> 	; 18/10/2015
  2798                              <1> 	; 24/07/2015
  2799                              <1>         ; 21/07/2015
  2800                              <1> 	; 02/07/2015
  2801                              <1> 	; 25/06/2015
  2802                              <1> 	; 24/06/2015
  2803                              <1> 	; 23/06/2015
  2804                              <1> 	;
  2805 00003C80 8B1D[A86C0000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
  2806 00003C86 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
  2807 00003C88 740A                <1> 	jz	short sysexec_7
  2808 00003C8A A1[A46C0000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
  2809 00003C8F E861E8FFFF          <1> 	call	deallocate_page_dir
  2810                              <1> sysexec_7:
  2811 00003C94 E891E7FFFF          <1> 	call	make_page_dir
  2812                              <1> 	;jc	short sysexec_14
  2813                              <1> 	;jc	panic  ; allocation error 
  2814                              <1> 	;	       ; after a deallocation would be nonsence !?
  2815                              <1> 	; 26/03/2021
  2816 00003C99 7243                <1> 	jc	short sysexec_panic
  2817                              <1> 	
  2818                              <1> 	; 24/07/2015
  2819                              <1> 	; map kernel pages (1st 4MB) to PDE 0
  2820                              <1> 	;     of the user's page directory
  2821                              <1> 	;     (It is needed for interrupts!)
  2822                              <1> 	; 18/10/2015
  2823 00003C9B 8B15[08670000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
  2824 00003CA1 8B02                <1> 	mov	eax, [edx] ; physical address of
  2825                              <1> 			   ; kernel's first page table (1st 4 MB)
  2826                              <1> 			   ; (PDE 0 of kernel's page directory)
  2827 00003CA3 8B15[A46C0000]      <1> 	mov 	edx, [u.pgdir]
  2828 00003CA9 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
  2829                              <1> 	;
  2830                              <1> 	; 20/07/2015
  2831 00003CAB BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
  2832                              <1> 	; 18/10/2015
  2833 00003CB0 BE[C06C0000]        <1> 	mov	esi, pcore ; physical start address
  2834                              <1> sysexec_8:	
  2835 00003CB5 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
  2836 00003CBA E889E7FFFF          <1> 	call	make_page_table
  2837                              <1> 	;jc	panic
  2838                              <1> 	; 26/03/2021
  2839 00003CBF 721D                <1> 	jc	short sysexec_panic
  2840                              <1> 	;
  2841                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
  2842 00003CC1 E890E7FFFF          <1> 	call	make_page ; make new page, clear and set the pte
  2843                              <1> 	;jc	panic
  2844                              <1> 	; 26/03/2021
  2845 00003CC6 7216                <1> 	jc	short sysexec_panic
  2846                              <1> 	;
  2847 00003CC8 8906                <1> 	mov	[esi], eax ; 24/06/2015
  2848                              <1> 	; ebx = virtual address (24/07/2015)
  2849                              <1> 	; 30/11/2021
  2850                              <1> 	;call 	add_to_swap_queue
  2851                              <1> 	; 18/10/2015
  2852 00003CCA 81FE[C46C0000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
  2853 00003CD0 7411                <1> 	je	short sysexec_9 ; yes
  2854 00003CD2 BE[C46C0000]        <1> 	mov	esi, ecore  ; physical address of the last page
  2855                              <1> 	; 20/07/2015
  2856 00003CD7 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
  2857                              <1> 	; ebx = virtual end address + segment base address - 4K
  2858 00003CDC EBD7                <1>         jmp     short sysexec_8
  2859                              <1> sysexec_panic:
  2860                              <1> 	; 26/03/2021
  2861 00003CDE E9AEECFFFF          <1> 	jmp	panic
  2862                              <1> 
  2863                              <1> sysexec_9:
  2864                              <1> 	; 12/01/2022
  2865                              <1> 	; 11/12/2021
  2866                              <1> 	; 18/10/2015
  2867                              <1> 	; 26/08/2015
  2868                              <1> 	; 25/06/2015
  2869                              <1> 	; move arguments from kernel stack to [ecore]
  2870                              <1> 	; (argument list/line will be copied from kernel stack
  2871                              <1> 	; frame to the last (stack) page of user's core memory)
  2872                              <1> 	; 18/10/2015
  2873 00003CE3 8B3D[C46C0000]      <1> 	mov	edi, [ecore]
  2874 00003CE9 81C700100000        <1> 	add	edi, PAGE_SIZE
  2875                              <1> 	;movzx	eax, word [argc]
  2876                              <1> 	; 12/01/2022
  2877                              <1> 	;xor	eax, eax
  2878                              <1> 	;mov	al, [argc]
  2879                              <1> 	; [argc] < 32
  2880                              <1> 	; 11/12/2021
  2881 00003CEF A1[D06C0000]        <1> 	mov	eax, [argc]
  2882 00003CF4 09C0                <1> 	or	eax, eax
  2883 00003CF6 7509                <1> 	jnz	short sysexec_10
  2884 00003CF8 89FB                <1> 	mov 	ebx, edi
  2885 00003CFA 83EB04              <1> 	sub	ebx, 4 
  2886 00003CFD 8903                <1> 	mov	[ebx], eax ; 0
  2887 00003CFF EB43                <1> 	jmp 	short sysexec_13
  2888                              <1> sysexec_10:
  2889 00003D01 8B0D[706C0000]      <1> 	mov	ecx, [u.nread]
  2890                              <1> 	;mov 	esi, [argv]
  2891 00003D07 89E6                <1> 	mov	esi, esp ; start address of argument list
  2892 00003D09 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
  2893                              <1> 
  2894                              <1> 	;;;;
  2895                              <1> 	; 09/05/2022
  2896                              <1> 	; (move edi -backward- to dword boundary)
  2897                              <1> 	; ((this will prevent 'general protection fault' error
  2898                              <1> 	;  as result of a lodsd or dword move instruction
  2899                              <1> 	;  at the end of argument list))
  2900 00003D0B 83EF03              <1> 	sub	edi, 3
  2901 00003D0E 83E7FC              <1> 	and	edi, ~3 ; (*)
  2902                              <1> 	;;;
  2903                              <1> 
  2904 00003D11 89C2                <1> 	mov	edx, eax
  2905                              <1> 	; 03/02/2022 ; ([argc] < 32)
  2906 00003D13 FEC2                <1> 	inc	dl ; argument count + 1 for argc value
  2907 00003D15 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
  2908                              <1> 	; edx <= 128
  2909 00003D18 89FB                <1> 	mov	ebx, edi
  2910                              <1> 	; 09/05/2022 (*) - edi is already dword aligned -
  2911                              <1> 	;and	bl, 0FCh ; 32 bit (dword) alignment
  2912 00003D1A 29D3                <1> 	sub 	ebx, edx
  2913 00003D1C 89FA                <1> 	mov	edx, edi
  2914 00003D1E F3A4                <1> 	rep	movsb
  2915 00003D20 89D6                <1> 	mov 	esi, edx
  2916 00003D22 89DF                <1> 	mov 	edi, ebx
  2917 00003D24 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
  2918 00003D29 2B15[C46C0000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
  2919 00003D2F AB                  <1> 	stosd	; eax = argument count
  2920                              <1> sysexec_11:
  2921 00003D30 89F0                <1> 	mov	eax, esi
  2922 00003D32 01D0                <1> 	add	eax, edx
  2923 00003D34 AB                  <1> 	stosd  ; eax = virtual address
  2924 00003D35 FE0D[D06C0000]      <1> 	dec	byte [argc]
  2925 00003D3B 7407                <1> 	jz	short sysexec_13
  2926                              <1> sysexec_12:
  2927 00003D3D AC                  <1> 	lodsb
  2928 00003D3E 20C0                <1> 	and	al, al
  2929 00003D40 75FB                <1> 	jnz	short sysexec_12
  2930 00003D42 EBEC                <1> 	jmp	short sysexec_11
  2931                              <1> 	;
  2932                              <1> 	; 1:
  2933                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
  2934                              <1> 			     ; / pointers to arguments to be passed
  2935                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
  2936                              <1> 			      ; / u.quit = 1 take quit
  2937                              <1> 		; mov $1,u.intr / u.intr determines handling of 
  2938                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
  2939                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
  2940                              <1> 			       ; / system routine
  2941                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector
  2942                              <1> 			       ; / set to take system routine
  2943                              <1> 		; mov $sstack,sp / stack space used during swapping
  2944                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
  2945                              <1> 		; mov $ecore,r5 / r5 has end of core
  2946                              <1> 		; mov $core,r4 / r4 has start of users core
  2947                              <1> 		; mov r4,u.base / u.base has start of users core
  2948                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
  2949                              <1> 	; 1:
  2950                              <1> 		; tst (r2)+ / argument char = "nul"
  2951                              <1> 		; bne 1b
  2952                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of
  2953                              <1> 			  ; / end of argument pointer list
  2954                              <1> 	; 1:
  2955                              <1> 	     ; / move arguments to bottom of users core
  2956                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
  2957                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
  2958                              <1> 			    ; / ptr list
  2959                              <1> 		; blo 1f / branch to 1f when all arguments
  2960                              <1> 		       ; / are moved
  2961                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
  2962                              <1> 	; 2:
  2963                              <1> 		; tstb (r3)+
  2964                              <1> 		; bne 2b / scan argument for \0 (nul)
  2965                              <1> 
  2966                              <1> 	; 2:
  2967                              <1> 		; movb -(r3),-(r5) / move argument char 
  2968                              <1> 				 ; / by char starting at "ecore"
  2969                              <1> 		; cmp r3,(r2) / moved all characters in 
  2970                              <1> 			    ; / this argument
  2971                              <1> 		; bhi 2b / branch 2b if not
  2972                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
  2973                              <1> 			     ; / r5 has pointer to nth arg
  2974                              <1> 		; br 1b / string
  2975                              <1> 	; 1:
  2976                              <1> 		; clrb -(r5)
  2977                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
  2978                              <1> 			; / last word of argument strings
  2979                              <1> 		; mov $core,r2
  2980                              <1> 	
  2981                              <1> 	; 1: / move argument pointers into core following 
  2982                              <1> 	      ; / argument strings
  2983                              <1> 		; cmp r2,r4
  2984                              <1> 		; bhis 1f / branch to 1f when all pointers
  2985                              <1> 			; / are moved
  2986                              <1> 		; mov (r2)+,-(r5)
  2987                              <1> 		; br 1b
  2988                              <1> 	; 1:
  2989                              <1> 		; sub $core,r4 / gives number of arguments *2
  2990                              <1> 		; asr r4 / divide r4 by 2 to calculate 
  2991                              <1> 		       ; / the number of args stored
  2992                              <1> 		; mov r4,-(r5) / save number of arguments ahead
  2993                              <1> 			     ; / of the argument pointers
  2994                              <1> sysexec_13:
  2995                              <1> 	; 30/11/2021
  2996                              <1> 	; 28/11/2021
  2997                              <1> 	; 19/10/2015
  2998                              <1> 	; 18/10/2015
  2999                              <1> 	; 29/07/2015
  3000                              <1> 	; 25/07/2015
  3001                              <1> 	; 24/07/2015
  3002                              <1> 	; 20/07/2015
  3003                              <1> 	; 25/06/2015
  3004                              <1> 	; 24/06/2015
  3005                              <1> 	; 23/06/2015
  3006                              <1> 	;
  3007                              <1> 	; moving arguments to [ecore] is OK here..
  3008                              <1> 	; 18/10/2015
  3009 00003D44 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
  3010                              <1> 	; ebx = beginning address of argument list pointers
  3011                              <1> 	;	in user's stack
  3012                              <1> 	; 19/10/2015
  3013 00003D46 2B1D[C46C0000]      <1> 	sub 	ebx, [ecore]
  3014 00003D4C 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
  3015                              <1> 			; end of core - 4096 (last page)
  3016                              <1> 			; (virtual address)
  3017 00003D52 891D[D46C0000]      <1> 	mov	[argv], ebx
  3018 00003D58 891D[746C0000]      <1> 	mov	[u.break], ebx ; available user memory
  3019                              <1> 	;
  3020 00003D5E 29C0                <1> 	sub	eax, eax
  3021 00003D60 C705[6C6C0000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
  3021 00003D68 0000                <1>
  3022                              <1> 		; mov $14,u.count
  3023 00003D6A C705[586C0000]-     <1> 	mov	dword [u.fofp], u.off
  3023 00003D70 [646C0000]          <1>
  3024                              <1> 		; mov $u.off,u.fofp
  3025 00003D74 A3[646C0000]        <1> 	mov	[u.off], eax ; 0
  3026                              <1> 		; clr u.off / set offset in file to be read to zero
  3027                              <1> 	; 25/07/2015
  3028 00003D79 A3[686C0000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
  3029                              <1> 	; 25/06/2015 
  3030 00003D7E A1[1C6C0000]        <1> 	mov	eax, [ii] ; 28/11/2021 (32 bit inode number)
  3031                              <1> 	; AX = i-number of the executable file
  3032 00003D83 E83B110000          <1> 	call	readi
  3033                              <1> 		; jsr r0,readi / read in first six words of 
  3034                              <1> 			; / user's file, starting at $core
  3035                              <1> 		; mov sp,r5 / put users stack address in r5
  3036                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
  3037                              <1> 				; / from r5 (leaves number of words
  3038                              <1> 				; / less 26 available for
  3039                              <1> 			     	; / program in user core
  3040                              <1> 		; mov r5,u.count /
  3041                              <1> 	; 25/06/2015
  3042 00003D88 8B0D[746C0000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
  3043 00003D8E 890D[6C6C0000]      <1> 	mov	[u.count], ecx ; save for overrun check
  3044                              <1> 	;
  3045 00003D94 8B0D[706C0000]      <1> 	mov	ecx, [u.nread]
  3046 00003D9A 890D[746C0000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
  3047 00003DA0 80F920              <1> 	cmp	cl, 32
  3048 00003DA3 7540                <1>         jne     short sysexec_15
  3049                              <1> 	;:
  3050                              <1> 	; 25/06/2015
  3051                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
  3052                              <1> 	; 18/10/2015
  3053 00003DA5 8B35[C06C0000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
  3054                              <1> 		             ; (phys. start addr. of the exec. file)
  3055 00003DAB AD                  <1> 	lodsd
  3056 00003DAC 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBh, 1Eh -> jump to +32
  3057 00003DB0 7533                <1> 	jne	short sysexec_15
  3058                              <1> 		; cmp core,$405 / br .+14 is first instruction 
  3059                              <1> 			      ; / if file is standard a.out format
  3060                              <1> 		; bne 1f / branch, if not standard format
  3061 00003DB2 AD                  <1> 	lodsd
  3062 00003DB3 89C1                <1> 	mov	ecx, eax ; text (code) section size
  3063 00003DB5 AD                  <1> 	lodsd
  3064 00003DB6 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
  3065                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
  3066                              <1> 		              ; / number of bytes in program text
  3067                              <1> 		; sub $14,r5 / subtract 12
  3068 00003DB8 89CB                <1> 	mov	ebx, ecx
  3069                              <1> 	;
  3070                              <1> 	; 25/06/2015
  3071                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
  3072                              <1> 	;	and SINGLIX operating systems (as code template).
  3073                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
  3074                              <1> 	;	due to RUFS (floppy disk file system) restriction...
  3075                              <1> 	;	Overrun is not possible for current version.
  3076                              <1> 	;
  3077 00003DBA AD                  <1> 	lodsd	
  3078 00003DBB 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
  3079 00003DBD 3B1D[6C6C0000]      <1> 	cmp	ebx, [u.count]
  3080 00003DC3 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
  3081                              <1> 	;
  3082                              <1> 	; 24/07/2015
  3083                              <1> 	; add bss section size to [u.break]
  3084 00003DC5 0105[746C0000]      <1> 	add 	[u.break], eax
  3085                              <1> 	;
  3086 00003DCB 83E920              <1> 	sub	ecx, 32 ; header size (already loaded)
  3087                              <1> 	;cmp	ecx, [u.count]
  3088                              <1> 	;jnb	short sysexec_16
  3089                              <1> 		; cmp r5,u.count /
  3090                              <1> 		; bgt 1f / branch if r5 greater than u.count
  3091 00003DCE 890D[6C6C0000]      <1> 	mov	[u.count], ecx ; required read count
  3092                              <1> 		; mov r5,u.count
  3093                              <1> 	;
  3094 00003DD4 EB29                <1> 	jmp	short sysexec_16
  3095                              <1> 	;
  3096                              <1> sysexec_14:
  3097                              <1> 	; 23/06/2015
  3098                              <1> 	; insufficient (out of) memory
  3099 00003DD6 C705[B86C0000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
  3099 00003DDE 0000                <1>
  3100 00003DE0 E962F3FFFF          <1> 	jmp	error
  3101                              <1> 	;
  3102                              <1> sysexec_15:
  3103                              <1> 	; 25/06/2015
  3104                              <1>         ;movzx   edx, word [i.size] ; file size
  3105                              <1> 	; 30/11/2021
  3106 00003DE5 8B15[CC670000]      <1> 	mov	edx, [i.size] ; file size
  3107 00003DEB 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
  3108 00003DED 7626                <1> 	jna	short sysexec_17 ; no need to next read
  3109 00003DEF 01D1                <1> 	add	ecx, edx ; [i.size]
  3110 00003DF1 3B0D[6C6C0000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
  3111 00003DF7 77DD                <1> 	ja	short sysexec_14
  3112 00003DF9 8915[6C6C0000]      <1> 	mov	[u.count], edx
  3113                              <1> sysexec_16:
  3114                              <1> 	;mov	ax, [ii] ; i-number
  3115                              <1> 	; 28/11/2021
  3116 00003DFF A1[1C6C0000]        <1> 	mov	eax, [ii] ; 32 bit inode number
  3117 00003E04 E8BA100000          <1> 	call	readi
  3118                              <1> 		; add core+10,u.nread / add size of user data area
  3119                              <1> 		                    ; / to u.nread
  3120                              <1> 		; br 2f
  3121                              <1> 	; 1:
  3122                              <1> 		; jsr r0,readi / read in rest of file
  3123                              <1> 	; 2:
  3124 00003E09 8B0D[706C0000]      <1> 	mov	ecx, [u.nread]
  3125 00003E0F 010D[746C0000]      <1> 	add	[u.break], ecx
  3126                              <1> 		; mov u.nread,u.break / set users program break to end of
  3127                              <1> 				    ; / user code
  3128                              <1> 		; add $core+14,u.break / plus data area
  3129                              <1> 	; 20/07/2015
  3130                              <1> sysexec_17:
  3131                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
  3132                              <1> 	; ('iclose' is not needed for regular files, from now on)
  3133                              <1> 	;;mov	ax, [ii] ; i-number
  3134                              <1> 	;call	iclose
  3135                              <1> 	;	; jsr r0,iclose / does nothing
  3136 00003E15 31C0                <1>         xor     eax, eax
  3137 00003E17 FEC0                <1> 	inc	al
  3138 00003E19 66A3[906C0000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
  3139 00003E1F 66A3[926C0000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
  3140                              <1> 	; 30/11/2021
  3141 00003E25 FEC8                <1> 	dec	al  ; eax = 0
  3142                              <1> 	; 02/07/2015
  3143                              <1>         ;cmp	dword [u.ppgdir], 0 ; is the caller sys_init (kernel) ?
  3144 00003E27 3905[A86C0000]      <1> 	cmp	[u.ppgdir], eax ; 0 ; is the caller sys_init (kernel) ?
  3145 00003E2D 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
  3146                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
  3147 00003E2F 8B15[08670000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
  3148 00003E35 8915[A86C0000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here
  3149                              <1> sysexec_18:
  3150                              <1> 	; 18/10/2015
  3151                              <1> 	; 05/08/2015
  3152                              <1> 	; 29/07/2015
  3153 00003E3B 8B2D[D46C0000]      <1> 	mov	ebp, [argv] ; user's stack pointer must points to argument
  3154                              <1> 			    ; list pointers (argument count)
  3155 00003E41 FA                  <1> 	cli
  3156 00003E42 8B25[A4660000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
  3157                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
  3158                              <1> 			    ; for this process	 
  3159                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
  3160                              <1> 	;;xor	eax, eax ; 0
  3161                              <1> 	;dec	al ; eax = 0
  3162                              <1> 	; eax = 0 ; 30/11/2021 
  3163 00003E48 66BA2300            <1> 	mov	dx, UDATA
  3164 00003E4C 6652                <1> 	push	dx  ; user's stack segment
  3165 00003E4E 55                  <1> 	push	ebp ; user's stack pointer
  3166                              <1> 		    ; (points to number of arguments)
  3167 00003E4F FB                  <1> 	sti
  3168 00003E50 9C                  <1> 	pushfd	; EFLAGS
  3169                              <1> 		; Set IF for enabling interrupts in user mode
  3170                              <1> 	;or	dword [esp], 200h 
  3171                              <1> 	;
  3172                              <1> 	;mov	bx, UCODE
  3173                              <1> 	;push	bx ; user's code segment
  3174 00003E51 6A1B                <1> 	push	UCODE
  3175                              <1> 	;push	0
  3176 00003E53 50                  <1> 	push	eax ; EIP (=0) - start address -
  3177                              <1> 		; clr -(r5) / popped into ps when rti in 
  3178                              <1> 			  ; / sysrele is executed
  3179                              <1> 		; mov $core,-(r5) / popped into pc when rti 
  3180                              <1> 		                ; / in sysrele is executed
  3181                              <1> 		;mov r5,0f / load second copyz argument
  3182                              <1> 		;tst -(r5) / decrement r5
  3183 00003E54 8925[3C6C0000]      <1> 	mov	[u.sp], esp ; 29/07/2015
  3184                              <1> 	; 05/08/2015
  3185                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
  3186                              <1> 	; ('push dx' would cause to general protection fault, 
  3187                              <1> 	; after 'pop ds' etc.)
  3188                              <1> 	;
  3189                              <1> 	;; push dx ; ds (UDATA)
  3190                              <1> 	;; push dx ; es (UDATA)
  3191                              <1> 	;; push dx ; fs (UDATA)
  3192                              <1> 	;; push dx ; gs (UDATA)
  3193                              <1> 	;
  3194                              <1> 	; This is a trick to prevent general protection fault
  3195                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
  3196 00003E5A 8EC2                <1> 	mov 	es, dx ; UDATA
  3197 00003E5C 06                  <1> 	push 	es ; ds (UDATA)
  3198 00003E5D 06                  <1> 	push 	es ; es (UDATA)
  3199 00003E5E 06                  <1> 	push 	es ; fs (UDATA)
  3200 00003E5F 06                  <1> 	push	es ; gs (UDATA)
  3201 00003E60 66BA1000            <1> 	mov	dx, KDATA
  3202 00003E64 8EC2                <1> 	mov	es, dx
  3203                              <1> 	;
  3204                              <1> 	;; pushad simulation
  3205 00003E66 89E5                <1> 	mov	ebp, esp ; esp before pushad
  3206 00003E68 50                  <1> 	push	eax ; eax (0)
  3207 00003E69 50                  <1> 	push	eax ; ecx (0)
  3208 00003E6A 50                  <1> 	push	eax ; edx (0)
  3209 00003E6B 50                  <1> 	push	eax ; ebx (0)
  3210 00003E6C 55                  <1> 	push	ebp ; esp before pushad
  3211 00003E6D 50                  <1> 	push	eax ; ebp (0)
  3212 00003E6E 50                  <1> 	push	eax ; esi (0)		
  3213 00003E6F 50                  <1> 	push	eax ; edi (0)	
  3214                              <1> 	;
  3215 00003E70 A3[446C0000]        <1> 	mov	[u.r0], eax ; eax = 0
  3216 00003E75 8925[406C0000]      <1> 	mov	[u.usp], esp
  3217                              <1> 		; mov r5,u.r0 /
  3218                              <1> 		; sub $16.,r5 / skip 8 words
  3219                              <1> 		; mov r5,u.sp / assign user stack pointer value,
  3220                              <1> 		;             / effectively zeroes all regs
  3221                              <1> 			    ; / when sysrele is executed
  3222                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
  3223                              <1> 		; clr u.break
  3224                              <1> 		; mov r5,sp / point sp to user's stack
  3225                              <1> 	;
  3226 00003E7B E9E9F2FFFF          <1> 	jmp	sysret0
  3227                              <1> 	;jmp	sysret
  3228                              <1> 		; br sysret3 / return to core image at $core
  3229                              <1> 
  3230                              <1> get_argp:
  3231                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
  3232                              <1> 	; 18/10/2015 (nbase, ncount)
  3233                              <1> 	; 21/07/2015
  3234                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
  3235                              <1> 	; Get (virtual) address of argument from user's core memory
  3236                              <1> 	;
  3237                              <1> 	; INPUT:
  3238                              <1> 	;	esi = virtual address of argument pointer
  3239                              <1> 	; OUTPUT:
  3240                              <1> 	;	eax = virtual address of argument
  3241                              <1> 	;
  3242                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
  3243                              <1> 	;
  3244 00003E80 833D[A86C0000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
  3245                              <1> 				    ; (the caller is kernel)
  3246 00003E87 767C                <1>         jna     short get_argpk 
  3247                              <1> 	;
  3248 00003E89 89F3                <1>      	mov	ebx, esi
  3249 00003E8B E81DE9FFFF          <1> 	call	get_physical_addr ; get physical address
  3250 00003E90 7254                <1>         jc	short get_argp_err ; 11/12/2021
  3251 00003E92 A3[C86C0000]        <1> 	mov 	[nbase], eax ; physical address	
  3252                              <1> 	;mov	[ncount], cx ; remain byte count in page (1-4096)
  3253                              <1> 	; 11/12/2021
  3254 00003E97 890D[CC6C0000]      <1> 	mov	[ncount], ecx
  3255 00003E9D B804000000          <1> 	mov	eax, 4 ; 21/07/2015
  3256                              <1> 	;cmp	cx, ax ; 4
  3257                              <1> 	; 11/12/2021
  3258 00003EA2 39C1                <1> 	cmp	ecx, eax ; 4
  3259 00003EA4 734A                <1> 	jnb	short get_argp2
  3260 00003EA6 89F3                <1> 	mov	ebx, esi
  3261 00003EA8 01CB                <1> 	add	ebx, ecx
  3262 00003EAA E8FEE8FFFF          <1> 	call	get_physical_addr ; get physical address
  3263 00003EAF 7235                <1> 	jc	short get_argp_err
  3264                              <1> 	;push	esi
  3265 00003EB1 89C6                <1> 	mov	esi, eax
  3266                              <1> 	;xchg	cx, [ncount]
  3267                              <1> 	; 11/12/2021
  3268 00003EB3 870D[CC6C0000]      <1> 	xchg	ecx, [ncount]
  3269 00003EB9 8735[C86C0000]      <1> 	xchg	esi, [nbase]
  3270 00003EBF B504                <1> 	mov	ch, 4
  3271 00003EC1 28CD                <1> 	sub	ch, cl
  3272                              <1> get_argp0:
  3273 00003EC3 AC                  <1> 	lodsb
  3274                              <1> 	;push	ax
  3275                              <1> 	; 11/12/2021
  3276 00003EC4 50                  <1> 	push	eax
  3277 00003EC5 FEC9                <1> 	dec	cl
  3278 00003EC7 75FA                <1>         jnz     short get_argp0
  3279 00003EC9 8B35[C86C0000]      <1> 	mov	esi, [nbase]
  3280                              <1> 	; 21/07/2015
  3281 00003ECF 0FB6C5              <1> 	movzx	eax, ch
  3282 00003ED2 0105[C86C0000]      <1> 	add	[nbase], eax
  3283                              <1> 	;sub	[ncount], ax
  3284                              <1> 	; 11/12/2021
  3285 00003ED8 2905[CC6C0000]      <1> 	sub	[ncount], eax
  3286                              <1> get_argp1:
  3287 00003EDE AC                  <1> 	lodsb
  3288 00003EDF FECD                <1> 	dec	ch
  3289 00003EE1 743B                <1>         jz      short get_argp3
  3290                              <1>         ;push	ax
  3291                              <1> 	; 11/12/2021
  3292 00003EE3 50                  <1> 	push	eax
  3293 00003EE4 EBF8                <1> 	jmp     short get_argp1
  3294                              <1> get_argp_err:
  3295 00003EE6 A3[B86C0000]        <1> 	mov	[u.error], eax
  3296 00003EEB E957F2FFFF          <1> 	jmp	error
  3297                              <1> get_argp2:
  3298                              <1> 	; 21/07/2015
  3299                              <1> 	;mov	eax, 4
  3300 00003EF0 8B15[C86C0000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
  3301 00003EF6 0105[C86C0000]      <1> 	add	[nbase], eax
  3302                              <1> 	;sub	[ncount], ax
  3303                              <1> 	; 11/12/2021
  3304 00003EFC 2905[CC6C0000]      <1> 	sub	[ncount], eax
  3305                              <1> 	;
  3306 00003F02 8B02                <1> 	mov	eax, [edx]
  3307 00003F04 C3                  <1> 	retn
  3308                              <1> get_argpk:
  3309                              <1> 	; Argument is in kernel's memory space
  3310 00003F05 66C705[CC6C0000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
  3310 00003F0D 10                  <1>
  3311 00003F0E 8935[C86C0000]      <1> 	mov	[nbase], esi
  3312 00003F14 8305[C86C0000]04    <1> 	add	dword [nbase], 4
  3313 00003F1B 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physical addr.
  3314 00003F1D C3                  <1> 	retn
  3315                              <1> get_argp3:
  3316 00003F1E B103                <1> 	mov	cl, 3
  3317                              <1> get_argp4:
  3318 00003F20 C1E008              <1> 	shl	eax, 8
  3319                              <1> 	;pop	dx
  3320                              <1> 	; 11/12/2021
  3321 00003F23 5A                  <1> 	pop	edx
  3322 00003F24 88D0                <1> 	mov 	al, dl
  3323 00003F26 E2F8                <1>         loop    get_argp4
  3324                              <1> 	;pop	esi
  3325 00003F28 C3                  <1> 	retn	
  3326                              <1> 
  3327                              <1> sysfstat:
  3328                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
  3329                              <1> 	;	([idev] return in eax)
  3330                              <1> 	;	0 = root device
  3331                              <1> 	;	1 = mounted device (>0)
  3332                              <1> 	; 06/02/2022 
  3333                              <1> 	; 08/01/2022
  3334                              <1> 	; 26/12/2021 (Retro UNIX 386 v1.2) 
  3335                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3336                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3337                              <1> 	;
  3338                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
  3339                              <1> 	; on open files instead of files given by name. It puts the
  3340                              <1> 	; buffer address on the stack, gets the i-number and
  3341                              <1> 	; checks to see if the file is open for reading or writing.
  3342                              <1> 	; If the file is open for writing (i-number is negative)
  3343                              <1> 	; the i-number is set positive and a branch into 'sysstat'
  3344                              <1> 	; is made.	
  3345                              <1> 	;
  3346                              <1> 	; Calling sequence:
  3347                              <1> 	;	sysfstat; buf
  3348                              <1> 	; Arguments:
  3349                              <1> 	;	buf - buffer address
  3350                              <1> 	;
  3351                              <1> 	; Inputs: *u.r0 - file descriptor
  3352                              <1> 	; Outputs: buffer is loaded with file information
  3353                              <1> 	; ...............................................................
  3354                              <1> 	;				
  3355                              <1> 	; Retro UNIX 8086 v1 modification:
  3356                              <1> 	;       'sysfstat' system call has two arguments; so,
  3357                              <1> 	;	* 1st argument, file descriptor is in BX register
  3358                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  3359                              <1> 
  3360                              <1> 	; / set status of open file
  3361                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
  3362 00003F29 51                  <1> 	push	ecx ; *
  3363                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
  3364                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
  3365                              <1> 		; jsr r0,getf / get the files i-number
  3366                              <1> 	; BX = file descriptor (file number)
  3367 00003F2A E8F9000000          <1> 	call	getf1
  3368                              <1> 	; 06/02/2022
  3369 00003F2F 21C0                <1> 	and	eax, eax
  3370                              <1> 	;and	ax, ax ; i-number of the file
  3371                              <1> 		; tst	r1 / is it 0?
  3372                              <1> 	;jz	error
  3373                              <1> 		; beq error3 / yes, error
  3374                              <1> 	;jnz	short sysfstat1
  3375                              <1> 	; 26/12/2021 - Retro UNIX 386 v1.2 (runix v2 file system)
  3376 00003F31 752C                <1> 	jnz	short sysstat1
  3377 00003F33 C705[B86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  3377 00003F3B 0000                <1>
  3378 00003F3D E905F2FFFF          <1> 	jmp	error
  3379                              <1> 	; 26/12/2021
  3380                              <1> ;sysfstat1:
  3381                              <1> 	;cmp	ah, 80h
  3382                              <1>         ;jb      short sysstat1
  3383                              <1> 	;	; bgt 1f / if i-number is negative (open for writing)
  3384                              <1> 	;neg	ax
  3385                              <1> 	;	; neg r1 / make it positive, then branch
  3386                              <1> 	; 08/01/2022
  3387                              <1> 	;jmp	short sysstat1
  3388                              <1> 		; br 1f / to 1f
  3389                              <1> sysstat:
  3390                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.1, Kernel v0.2.1.3)
  3391                              <1> 	;	([idev] return in eax)
  3392                              <1> 	;	0 = root device
  3393                              <1> 	;	1 = mounted device (>0)
  3394                              <1> 	; 26/12/2021 (Retro UNIX 386 v1.2) 
  3395                              <1> 	; 18/10/2015
  3396                              <1> 	; 07/10/2015
  3397                              <1> 	; 02/09/2015
  3398                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3399                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3400                              <1> 	;
  3401                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
  3402                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
  3403                              <1> 	; long and information about the file placed in it.	
  3404                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
  3405                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
  3406                              <1> 	; is then loaded and the results are given in the UNIX
  3407                              <1> 	; Programmers Manual sysstat (II).	
  3408                              <1> 	;
  3409                              <1> 	; Calling sequence:
  3410                              <1> 	;	sysstat; name; buf
  3411                              <1> 	; Arguments:
  3412                              <1> 	;	name - points to the name of the file
  3413                              <1> 	;	buf - address of a 34 bytes buffer
  3414                              <1> 	; Inputs: -
  3415                              <1> 	; Outputs: buffer is loaded with file information
  3416                              <1> 	; ...............................................................
  3417                              <1> 	;				
  3418                              <1> 	; Retro UNIX 8086 v1 modification: 
  3419                              <1> 	;       'sysstat' system call has two arguments; so,
  3420                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  3421                              <1> 	;	to get sysstat system call arguments from the user;
  3422                              <1> 	;	* 1st argument, name is pointed to by BX register
  3423                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  3424                              <1> 	;
  3425                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  3426                              <1> 	;	      arguments which were in these registers;
  3427                              <1> 	;	      but, it returns by putting the 1st argument
  3428                              <1> 	;	      in 'u.namep' and the 2nd argument
  3429                              <1> 	;	      on top of stack. (1st argument is offset of the
  3430                              <1> 	;	      file/path name in the user's program segment.)		 	
  3431                              <1> 	
  3432                              <1> 	; / ; name of file; buffer - get files status
  3433                              <1> 		; jsr r0,arg2 / get the 2 arguments
  3434 00003F42 891D[606C0000]      <1> 	mov	[u.namep], ebx
  3435 00003F48 51                  <1> 	push	ecx ; *
  3436 00003F49 E810010000          <1> 	call	namei
  3437                              <1> 		; jsr r0,namei / get the i-number for the file
  3438                              <1> 	;jc	error
  3439                              <1> 		; br error3 / no such file, error
  3440 00003F4E 730F                <1> 	jnc	short sysstat1
  3441                              <1> 	; pop 	ecx
  3442                              <1> sysstat_err0:
  3443                              <1> 	; 'file not found !' error
  3444 00003F50 C705[B86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  3444 00003F58 0000                <1>
  3445 00003F5A E9E8F1FFFF          <1> 	jmp	error
  3446                              <1> 
  3447                              <1> sysstat1: ; 1:
  3448 00003F5F E8F30B0000          <1> 	call	iget
  3449                              <1> 		; jsr r0,iget / get the i-node into core
  3450                              <1> 	; 07/10/2015 (ax = [ii], inode number)
  3451                              <1> 	; 02/09/2015
  3452 00003F64 8F05[686C0000]      <1> 	pop	dword [u.base] ; *
  3453                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
  3454 00003F6A E861000000          <1> 	call	sysstat_gpa ; get physical address
  3455 00003F6F 730A                <1> 	jnc 	short sysstat2
  3456                              <1> sysstat_err1:
  3457 00003F71 A3[B86C0000]        <1> 	mov	dword [u.error], eax ; error code
  3458 00003F76 E9CCF1FFFF          <1> 	jmp	error
  3459                              <1> sysstat2:
  3460 00003F7B A0[1C6C0000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
  3461 00003F80 AA                  <1> 	stosb
  3462 00003F81 FF05[686C0000]      <1> 	inc 	dword [u.base]
  3463                              <1> 	;dec 	cx
  3464 00003F87 49                  <1> 	dec	ecx ; 26/12/2021
  3465 00003F88 7505                <1> 	jnz	short sysstat3
  3466 00003F8A E841000000          <1> 	call	sysstat_gpa
  3467                              <1> 	;jc	short sysstat_err1
  3468                              <1> sysstat3:
  3469 00003F8F A0[1D6C0000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
  3470 00003F94 AA                  <1> 	stosb
  3471                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
  3472 00003F95 FF05[686C0000]      <1> 	inc 	dword [u.base]
  3473                              <1> 	;;dec 	word [u.pcount]
  3474                              <1> 	;dec	cx
  3475 00003F9B 49                  <1> 	dec	ecx ; 26/12/2021
  3476 00003F9C 7505                <1> 	jnz	short sysstat4
  3477 00003F9E E82D000000          <1> 	call	sysstat_gpa
  3478                              <1> 	;jc	short sysstat_err1	
  3479                              <1> sysstat4:
  3480 00003FA3 BE[C4670000]        <1> 	mov	esi, inode
  3481                              <1> 		; mov $inode,r2 / r2 points to i-node
  3482                              <1> sysstat5: ; 1:
  3483 00003FA8 A4                  <1> 	movsb
  3484                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
  3485 00003FA9 FF05[686C0000]      <1> 	inc 	dword [u.base]
  3486                              <1> 	;;dec 	word [u.pcount]
  3487                              <1> 	;dec	cx
  3488 00003FAF 49                  <1> 	dec	ecx ; 26/12/2021
  3489 00003FB0 7505                <1> 	jnz	short sysstat6
  3490 00003FB2 E819000000          <1> 	call	sysstat_gpa
  3491                              <1> 	;jc	short sysstat_err1
  3492                              <1> sysstat6:
  3493                              <1> 	; 26/12/2021 - Retro UNIX 386 v1.2
  3494 00003FB7 81FE[04680000]      <1> 	cmp	esi, inode + 64 ; Retro UNIX v2 inode		
  3495                              <1> 	;cmp	esi, inode + 32
  3496                              <1> 		; cmp r2,$inode+32 / done?
  3497 00003FBD 75E9                <1> 	jne	short sysstat5
  3498                              <1> 		; bne 1b / no, go back
  3499                              <1> 
  3500                              <1> 	;;;
  3501                              <1> 	; 09/05/2022
  3502                              <1> 	;*** additional feature *** -retro unix only- 
  3503                              <1> 	;
  3504                              <1> 	; !! return device number -of current inode- in eax !!
  3505                              <1> 	;
  3506                              <1> 	; (modification reason/purpose:
  3507                              <1> 	; to improve 'pwd' command's pathname output/result
  3508                              <1> 	; and to correct 'cp' command's 'can not copy file itself'
  3509                              <1> 	; error due to same inode numbers in root file system
  3510                              <1> 	; and mounted file system.)
  3511                              <1> 	;
  3512 00003FBF 29C0                <1> 	sub	eax, eax
  3513 00003FC1 A0[206C0000]        <1> 	mov	al, [idev] ; [cdev]
  3514 00003FC6 A3[446C0000]        <1> 	mov	[u.r0], eax
  3515                              <1> 	;;;  
  3516                              <1> 
  3517 00003FCB E997F1FFFF          <1> 	jmp	sysret
  3518                              <1> 		; br sysret3 / return through sysret
  3519                              <1> 	;
  3520                              <1> sysstat_gpa: ; get physical address of file status buffer
  3521                              <1> 	; 02/09/2015
  3522 00003FD0 8B1D[686C0000]      <1> 	mov 	ebx, [u.base]
  3523                              <1> 	; 07/10/2015
  3524 00003FD6 E8D2E7FFFF          <1> 	call	get_physical_addr ; get physical address
  3525                              <1> 	;jc	short sysstat_gpa1
  3526 00003FDB 7294                <1> 	jc	short sysstat_err1
  3527                              <1> 	; 18/10/2015
  3528 00003FDD 89C7                <1> 	mov	edi, eax ; physical address
  3529                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
  3530                              <1> ;sysstat_gpa1:
  3531 00003FDF C3                  <1> 	retn
  3532                              <1> 
  3533                              <1> fclose:
  3534                              <1> 	; 12/03/2022
  3535                              <1> 	; 11/02/2022
  3536                              <1> 	; 08/01/2022
  3537                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
  3538                              <1> 	; 08/04/2021
  3539                              <1> 	; 04/04/2021
  3540                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
  3541                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
  3542                              <1> 	;            (32 bit offset pointer modification)
  3543                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
  3544                              <1> 	;
  3545                              <1> 	; Given the file descriptor (index to the u.fp list)
  3546                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
  3547                              <1> 	; If i-node is active (i-number > 0) the entry in 
  3548                              <1> 	; u.fp list is cleared. If all the processes that opened
  3549                              <1> 	; that file close it, then fsp etry is freed and the file
  3550                              <1> 	; is closed. If not a return is taken. 
  3551                              <1> 	; If the file has been deleted while open, 'anyi' is called
  3552                              <1> 	; to see anyone else has it open, i.e., see if it is appears
  3553                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
  3554                              <1> 	; a check is made to see if the file is special.	
  3555                              <1> 	;
  3556                              <1> 	; INPUTS ->
  3557                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
  3558                              <1> 	;    u.fp - list of entries in the fsp table
  3559                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
  3560                              <1> 	; OUTPUTS ->
  3561                              <1> 	;    r1 - contains the same file descriptor
  3562                              <1> 	;    r2 - contains i-number
  3563                              <1> 	;
  3564                              <1> 	; ((AX = R1))
  3565                              <1> 	; ((Modified registers: edx, ebx, ecx, esi, edi, ebp))
  3566                              <1> 	;
  3567                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
  3568                              <1> 	;              if i-number of the file is 0. (error)
  3569                              <1> 
  3570                              <1> 	; 08/04/2021
  3571                              <1> 	; INPUT:
  3572                              <1> 	;	eax = file descriptor
  3573                              <1> 	; OUTPUT:
  3574                              <1> 	;	cf = 0 -> eax = file descriptor
  3575                              <1> 	;	cf = 1 -> file not open ; 11/02/2022
  3576                              <1> 
  3577                              <1> 	; 18/08/2020
  3578                              <1> 	;movzx	edx, ax ; **
  3579 00003FE0 89C3                <1> 	mov	ebx, eax
  3580                              <1> 
  3581                              <1> 	; 18/08/2020
  3582                              <1> _fclose:
  3583 00003FE2 53                  <1> 	push	ebx ; ***  ; file descriptor (index to u.fp)
  3584                              <1> 
  3585                              <1> 	;push	ax ; ***
  3586                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
  3587                              <1> 			     ; / the index to u.fp list)
  3588                              <1> 	; ebx = file descriptor/number
  3589 00003FE3 E840000000          <1> 	call	getf
  3590                              <1> 		; jsr r0,getf / r1 contains i-number, 
  3591                              <1> 			    ; / cdev has device =, u.fofp 
  3592                              <1> 			    ; / points to 3rd word of fsp entry
  3593                              <1> 	;cmp	eax, 1 ; 18/08/2020
  3594 00003FE8 6683F801            <1> 	cmp	ax, 1 ; r1
  3595                              <1> 		; tst r1 / is i-number 0?
  3596 00003FEC 7238                <1> 	jb	short fclose_2
  3597                              <1> 		; beq 1f / yes, i-node not active so return
  3598                              <1> 		; tst (r0)+ / no, jump over error return
  3599                              <1> 	
  3600                              <1> 	;mov	ebx, edx ; **
  3601                              <1>  	; 18/08/2020
  3602 00003FEE 8B1C24              <1> 	mov	ebx, [esp]
  3603                              <1> 	;mov	edx, eax 
  3604                              <1> 	;;mov 	dx, ax ; *
  3605                              <1> 		; mov r1,r2 / move i-number to r2 ;*
  3606                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
  3607                              <1> 			    ; / which is index to u.fp ; **
  3608 00003FF1 C683[4E6C0000]00    <1> 	mov	byte [ebx+u.fp], 0
  3609                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
  3610 00003FF8 8B1D[586C0000]      <1> 	mov	ebx, [u.fofp]
  3611                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
  3612                              <1> 
  3613                              <1> 	; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
  3614                              <1> 	; ebx = 5th word of fsp entry (64 bit file offset)
  3615                              <1> fclose_0:
  3616                              <1> 	; 08/01/2022
  3617 00003FFE FE4BFE              <1> 	dec	byte [ebx-2] ; 18/08/2020 - Retro UNIX 386 v2
  3618                              <1> 	;dec	byte [ebx+4] ; 18/06/2015
  3619                              <1> 		; decb 2(r1) / decrement the number of processes 
  3620                              <1> 			   ; / that have opened the file
  3621 00004001 7923                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
  3622                              <1> 		; bge 1f / if all processes haven't closed the file, return
  3623                              <1> 	;
  3624                              <1> 	;push	dx ; *
  3625                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
  3626                              <1> 	;;xor	ax, ax ; 0
  3627                              <1> 	;xor	eax, eax ; 18/08/2020
  3628                              <1> 		; clear 1st word of fsp entry
  3629                              <1> 	;mov	[ebx-8], ax ; 0 ; 18/08/2020
  3630                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
  3631 00004003 66C743F80000        <1> 	mov	word [ebx-8], 0 ; clear 1st word of fsp entry ; i-number
  3632                              <1> 			; Note: 32 bit i-node number field is ready but
  3633                              <1> 			;	it is not used in current runix version.	
  3634                              <1> 
  3635                              <1> 	;;mov	[ebx-4], ax ; 0
  3636                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
  3637                              <1> 	;mov	al, [ebx+5] ; 18/06/2015
  3638                              <1> 	;	; tstb	3(r1) / has this file been deleted
  3639                              <1> 	;and	al, al
  3640                              <1> 	;jz	short fclose_1
  3641                              <1> 	;	; beq 2f / no, branch
  3642                              <1> 
  3643                              <1> 	;push	edx ; * ; 18/08/2020
  3644                              <1> 	;mov	eax, edx ; * ; 18/08/2020
  3645                              <1> 
  3646                              <1> 	;; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
  3647                              <1> 	;;test	byte [ebx-3], 80h ; open mode & status flags
  3648                              <1> 	; 04/04/2021 - Retro UNIX 386 v2 (new fsp structure)
  3649                              <1> 	;test	byte [ebx-4], 80h ; open mode & status flags 
  3650                              <1> 	;jz	short fclose_1	; deleted file flag (bit 7)
  3651                              <1> 
  3652                              <1> 	; 04/04/2021
  3653 00004009 31D2                <1> 	xor	edx, edx
  3654                              <1> 	; 08/01/2022
  3655 0000400B 8A53FD              <1> 	mov	dl, [ebx-3] ; open mode & status flags
  3656 0000400E F6C280              <1> 	test	dl, 80h	    ; deleted file flag (bit 7)
  3657 00004011 7409                <1> 	jz	short fclose_1 ; (not deleted -while open-)
  3658 00004013 52                  <1> 	push	edx
  3659                              <1> 	; 12/03/2022
  3660 00004014 50                  <1> 	push	eax ; inode number 
  3661                              <1> 
  3662                              <1> 	; deleted file !
  3663                              <1> 
  3664                              <1> 	;mov	ax, dx ; *
  3665                              <1> 		; mov r2,r1 / yes, put i-number back into r1
  3666                              <1> 	; AX = inode number
  3667 00004015 E84E050000          <1> 	call	anyi
  3668                              <1> 		; jsr r0,anyi / free all blocks related to i-number
  3669                              <1> 			    ; / check if file appears in fsp again
  3670                              <1> 	; 12/03/2022
  3671 0000401A 58                  <1> 	pop	eax ; inode number
  3672                              <1> 	; 04/04/2021
  3673 0000401B 5A                  <1> 	pop	edx
  3674                              <1> 	; 11/02/2022
  3675                              <1> 	;(cpu will come here if anyi returns -without error-)
  3676                              <1> 	;; 08/04/2021
  3677                              <1> 	;jc	short fclose_3 ; error code in eax	
  3678                              <1> 	;; 18/08/2020
  3679                              <1> 	;;jmp	short fclose_2
  3680                              <1> 
  3681                              <1> 	; ax = inode number
  3682                              <1> fclose_1: ; 2:
  3683                              <1> 	; 04/04/2021
  3684 0000401C 80E201              <1> 	and	dl, 1
  3685 0000401F FEC2                <1> 	inc	dl ; 0 -> 1 (open for read), 1 -> 2 (open for write)
  3686                              <1> 	
  3687                              <1> 	;pop	eax ; * ; 18/08/2020 
  3688                              <1> 	;;pop	ax ; *
  3689                              <1> 		; mov (sp)+,r1 / put i-number back into r1
  3690 00004021 E814170000          <1> 	call	iclose ; close if it is special file 
  3691                              <1> 		; jsr r0,iclose / check to see if it is a special file
  3692                              <1> 	; 11/02/2022
  3693                              <1> 	;(cpu will come here if iclose returns -without error-)
  3694                              <1> 	;; 08/04/2021
  3695                              <1> 	;jnc	short fclose_2
  3696                              <1> ;fclose_3:
  3697                              <1> ;	pop	ebx ; ***  ; file descriptor
  3698                              <1> ;	; eax = error code
  3699                              <1> ;	retn
  3700                              <1> fclose_2: ; 1:
  3701 00004026 58                  <1> 	pop	eax ; *** ; 18/08/2020
  3702                              <1> 	;pop	ax ; ***
  3703                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
  3704 00004027 C3                  <1> 	retn
  3705                              <1> 		; rts r0
  3706                              <1> 
  3707                              <1> 	; 08/01/2022
  3708                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
  3709                              <1> getf:	; / get the device number and the i-number of an open file
  3710                              <1> 	; 13/05/2015
  3711                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3712                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
  3713                              <1> 
  3714                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
  3715                              <1> 	;
  3716                              <1> 	; 16/05/2021
  3717                              <1> 	; 27/03/2020 - Retro UNIX 386 v2 
  3718                              <1> 	;	(new open files -fsp- structure)
  3719                              <1> 	; 13/05/2015
  3720                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3721                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
  3722                              <1> 	
  3723                              <1> 	; INPUT: 
  3724                              <1> 	;    ;eax = file descriptor/number
  3725                              <1> 	;     ebx = file descriptor/number ; 18/08/2020 	
  3726                              <1> 	; OUTPUT:
  3727                              <1> 	;     bl = open mode & status flag ; 27/03/2020
  3728                              <1> 	;        (bit 0 open mode flag, 0 = read, 1 = write)  
  3729                              <1> 	;    eax = inode number (in AX)
  3730                              <1> 	;          If eax = 0 -> file not open
  3731                              <1> 	;   byte [cdev] = logical drive number (of inode in eax)
  3732                              <1> 	;	
  3733                              <1> 	; Modified registers: eax, ebx
  3734                              <1> 
  3735                              <1> 	; 16/05/2021 ('getf' procedure, unix v7 x86 'fio.c')
  3736                              <1> 	; /*
  3737                              <1> 	;  * Convert a user supplied
  3738                              <1> 	;  * file descriptor into a pointer
  3739                              <1> 	;  * to a file structure.
  3740                              <1> 	;  * Only task is to check range
  3741                              <1> 	;  * of the descriptor.
  3742                              <1> 	;  */
  3743                              <1> 	; struct file *
  3744                              <1> 	; getf(f)
  3745                              <1> 	;
  3746                              <1> 	; 18/08/2020
  3747                              <1> 	; 	ebx = file descriptor/number
  3748                              <1> 
  3749                              <1> 	; 16/05/2021
  3750                              <1> 	;NOFILE	equ 10 ; 08/01/2022
  3751                              <1> 
  3752                              <1> 	; 18/08/2020
  3753                              <1> 	;mov	ebx, eax
  3754                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
  3755                              <1> 
  3756                              <1> 	; ebx = file descriptor/number
  3757                              <1> 
  3758                              <1> 	; 18/08/2020
  3759 00004028 29C0                <1> 	sub	eax, eax ; eax = 0
  3760                              <1>  
  3761 0000402A 83FB0A              <1> 	cmp	ebx, 10 ; cmp ebx, NOFILE ; 16/05/2021
  3762                              <1> 		; cmp r1,$10. / user limited to 10 open files
  3763 0000402D 732E                <1>         jnb	short getf2 ; 13/05/2015
  3764                              <1> 	;jnb	error
  3765                              <1> 		; bhis error3 / u.fp is table of users open files,
  3766                              <1> 			    ; / index in fsp table
  3767                              <1> 	; 08/01/2022
  3768 0000402F 8A83[4E6C0000]      <1> 	mov	al, [ebx+u.fp]
  3769                              <1> 	;mov	bl, [ebx+u.fp]
  3770                              <1> 		; movb u.fp(r1),r1 / r1 contains number of entry 
  3771                              <1> 		                 ; / in fsp table
  3772 00004035 08C0                <1> 	or	al, al ; 08/01/2022
  3773                              <1> 	;or	bl, bl
  3774                              <1> 	;jnz	short getf3
  3775 00004037 7424                <1> 	jz	short getf2 ; 18/08/2020
  3776                              <1> 	;;jz	short getf4
  3777                              <1> 		; beq 1f / if its zero return
  3778                              <1> ;getf2:
  3779                              <1> ;	; 'File not open !' error (ax=0)
  3780                              <1> ;	;sub	eax, eax ; 18/08/2020
  3781                              <1> ;	retn
  3782                              <1> ;getf3:	
  3783                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
  3784                              <1> 	;
  3785                              <1> 	; 'fsp' table (10 bytes/entry)
  3786                              <1> 	; bit 15				   bit 0
  3787                              <1> 	; ---|-------------------------------------------
  3788                              <1> 	; r/w|		i-number of open file
  3789                              <1> 	; ---|-------------------------------------------
  3790                              <1> 	;		   device number
  3791                              <1> 	; -----------------------------------------------
  3792                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  3793                              <1> 	; -----------------------------------------------
  3794                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  3795                              <1> 	; ----------------------|------------------------
  3796                              <1> 	;  flag that says file 	| number of processes
  3797                              <1> 	;   has been deleted	| that have file open 
  3798                              <1> 	; ----------------------|------------------------
  3799                              <1> 
  3800                              <1> 	; Retro UNIX 386 v2 modification ! (27/03/2020)
  3801                              <1> 
  3802                              <1> 	; bit 15 				    bit 0
  3803                              <1> 	; ----------------------------------------------- byte 0
  3804                              <1> 	;    	       i-number of open file           
  3805                              <1> 	; ----------------------------------------------- byte 2
  3806                              <1> 	;          high word of 32 bit i-number       
  3807                              <1> 	; ----------------------------------------------- byte 4
  3808                              <1> 	;    open mode & status  |   device number     
  3809                              <1> 	; ----------------------------------------------- byte 6
  3810                              <1> 	;       reserved byte    |    open count  
  3811                              <1> 	; ----------------------------------------------- byte 8
  3812                              <1> 	;   offset pointer, i.e., r/w pointer to file 
  3813                              <1> 	; ----------------------------------------------- byte 10
  3814                              <1> 	;     64 bit file offset pointer (bit 16-31)  
  3815                              <1> 	; ----------------------------------------------- byte 12
  3816                              <1> 	;     64 bit file offset pointer (bit 32-47)   
  3817                              <1> 	; ----------------------------------------------- byte 14
  3818                              <1> 	;     64 bit file offset pointer (bit 48-63)  
  3819                              <1> 	; ----------------------------------------------- byte 16
  3820                              <1> 	
  3821                              <1> 	; 11/05/2015 - Retro UNIX 386 v1
  3822                              <1> 	;mov	eax, 10
  3823                              <1> 
  3824                              <1> 	; 27/03/2020 - Retro UNIX 386 v2	
  3825                              <1> 	;mov	eax, opfls.size ; mov eax, 16
  3826                              <1> 	
  3827                              <1> 	;sub	eax, eax ; 18/08/2020 ; eax = 0
  3828                              <1> 
  3829                              <1> 	;mov	al, opfls.size  ; mov al, 16
  3830                              <1> 	;
  3831                              <1> 	;mul	bl
  3832                              <1> 	;;mov	ebx, fsp-6 ; the 3rd word in the fsp entry
  3833                              <1> 	;; 27/03/2020
  3834                              <1> 	;mov	ebx, fsp-(opfls.size-opfls.offset) ; fsp-8
  3835                              <1> 	
  3836                              <1> 	;add	ebx, eax
  3837                              <1> 		; asl r1
  3838                              <1> 		; asl r1 / multiply by 8 to get index into 
  3839                              <1> 		       ; / fsp table entry
  3840                              <1> 		; asl r1
  3841                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
  3842                              <1> 			      ; / in the fsp entry
  3843                              <1> 	; 08/01/2022
  3844 00004039 88C3                <1> 	mov	bl, al
  3845                              <1> 	; 18/08/2020
  3846 0000403B FECB                <1> 	dec	bl ; zero based fsp table entry number
  3847                              <1> 	;shl	bl, 4 ; * 16 ; opfls.size
  3848                              <1> 	; 08/01/2022
  3849 0000403D C1E304              <1> 	shl	ebx, 4 ; * 16 ; opfls.size
  3850 00004040 81C3[BC680000]      <1> 	add	ebx, fsp+8 ; opfls.offset	
  3851                              <1> 	; ebx = address of the file offset pointer 
  3852                              <1> 	;	(not file offset! not fsp entry address !)
  3853                              <1> 
  3854 00004046 891D[586C0000]      <1> 	mov	[u.fofp], ebx
  3855                              <1> 		; mov r1,u.fofp / save address of 3rd word 
  3856                              <1> 			     ; / in fsp entry in u.fofp
  3857                              <1> 	; 18/08/2020
  3858 0000404C 8A43FD              <1> 	mov	al, [ebx-3]  ; open mode & status flags
  3859                              <1> 
  3860 0000404F 50                  <1> 	push	eax
  3861                              <1> 
  3862                              <1> 	;mov	ax, [ebx]
  3863                              <1> 	;;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
  3864                              <1> 	;mov	[cdev], ax ; ;;in fact (!) 
  3865                              <1> 			     ;;dev number is in 1 byte
  3866                              <1> 		; mov -(r1),cdev / remove the device number cdev
  3867                              <1> 
  3868                              <1> 	; 18/08/2020
  3869 00004050 8A43FC              <1> 	mov	al, [ebx-4]  ; logical drive number
  3870                              <1> 
  3871 00004053 A2[216C0000]        <1> 	mov	[cdev], al
  3872                              <1> 
  3873                              <1> 	;dec	ebx
  3874                              <1> 	;dec	ebx
  3875                              <1> 	; 18/08/2020
  3876 00004058 668B43F8            <1> 	mov	ax, [ebx-8]
  3877                              <1> 		; mov -(r1),r1 / and the i-number r1
  3878                              <1> 
  3879 0000405C 5B                  <1> 	pop	ebx ; ebx = bl = open mode and status flag
  3880                              <1> 		; (bit 0 is open mode flag, 0 = read, 1 = write)
  3881                              <1> 	; eax = inode number (in ax)	
  3882                              <1> 
  3883                              <1> getf2:	; 18/08/2020
  3884                              <1> getf4:	; 1: ; 08/01/2022
  3885 0000405D C3                  <1> 	retn
  3886                              <1> 		; rts r0
  3887                              <1> 
  3888                              <1> 	; 15/05/2022
  3889                              <1> 	; 08/01/2022
  3890                              <1> 	; 19/12/2021
  3891                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  3892                              <1> namei:
  3893                              <1> 	; 18/10/2021
  3894                              <1> 	; 12/06/2021
  3895                              <1> 	; 01/05/2021
  3896                              <1> 	; 26/03/2021
  3897                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
  3898                              <1> 	; 04/12/2015 (14 byte file names)
  3899                              <1> 	; 18/10/2015 (nbase, ncount)
  3900                              <1> 	; 12/10/2015
  3901                              <1> 	; 21/08/2015
  3902                              <1> 	; 18/07/2015
  3903                              <1> 	; 02/07/2015
  3904                              <1> 	; 17/06/2015
  3905                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
  3906                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3907                              <1> 	;
  3908                              <1> 	; 'namei' takes a file path name and returns i-number of
  3909                              <1> 	; the file in the current directory or the root directory
  3910                              <1> 	; (if the first character of the pathname is '/').	
  3911                              <1> 	;
  3912                              <1> 	; INPUTS ->
  3913                              <1> 	;    u.namep - points to a file path name
  3914                              <1> 	;    u.cdir - i-number of users directory
  3915                              <1> 	;    u.cdev - device number on which user directory resides	
  3916                              <1> 	; OUTPUTS ->
  3917                              <1> 	;    r1 - i-number of file
  3918                              <1> 	;    cdev
  3919                              <1> 	;    u.dirbuf - points to directory entry where a match 
  3920                              <1> 	;               occurs in the search for file path name.
  3921                              <1> 	;	        If no match u.dirp points to the end of 
  3922                              <1> 	;               the directory and r1 = i-number of the current
  3923                              <1> 	;	        directory.	
  3924                              <1> 	; ((AX = R1))
  3925                              <1> 	;
  3926                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
  3927                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
  3928                              <1> 	;
  3929                              <1> 
  3930                              <1> 	;mov	ax, [u.cdir]
  3931                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
  3932                              <1> 			      ; / in r1
  3933                              <1> 	; 01/05/2021
  3934 0000405E A1[486C0000]        <1> 	mov	eax, [u.cdir]	
  3935 00004063 8A15[4C6C0000]      <1> 	mov	dl, [u.cdrv]
  3936 00004069 8815[216C0000]      <1> 	mov	[cdev], dl
  3937                              <1> 	;mov	dx, [u.cdrv]
  3938                              <1> 	;mov	[cdev], dx	; NOTE: Retro UNIX 8086 v1 
  3939                              <1> 				; device/drive number is in 1 byte, 
  3940                              <1> 				; not in 1 word!
  3941                              <1> 		; mov u.cdev,cdev / device number for users directory 
  3942                              <1> 				; / into cdev
  3943                              <1> 	; 12/10/2015
  3944                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3945                              <1>       	; convert virtual (pathname) addr to physical address
  3946 0000406F E849010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
  3947                              <1> 		; esi = physical address of [u.namep]
  3948                              <1> 		; ecx = byte count in the page
  3949 00004074 803E2F              <1> 	cmp	byte [esi], '/'
  3950                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
  3951 00004077 751C                <1> 	jne	short namei_1
  3952                              <1> 		; bne 1f
  3953 00004079 FF05[606C0000]      <1> 	inc	dword [u.namep]
  3954                              <1> 		; inc u.namep / go to next char
  3955                              <1> 	;dec	cx ; remain byte count in the page
  3956 0000407F 49                  <1> 	dec	ecx ; 18/10/2021
  3957 00004080 7506                <1> 	jnz	short namei_0
  3958                              <1> 	; 12/10/2015
  3959 00004082 E836010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  3960                              <1> 		; esi = physical address (page start + offset)
  3961                              <1> 		; ecx = byte count in the page
  3962 00004087 4E                  <1> 	dec	esi
  3963                              <1> namei_0:
  3964 00004088 46                  <1> 	inc 	esi  ; go to next char
  3965                              <1> 	;mov	ax, [rootdir] ; 09/07/2013
  3966                              <1> 	; 18/10/2021
  3967 00004089 A1[266C0000]        <1> 	mov	eax, [rootdir]
  3968                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
  3969 0000408E C605[216C0000]00    <1> 	mov	byte [cdev], 0
  3970                              <1> 		; clr cdev / clear device number
  3971                              <1> namei_1: ; 1:
  3972 00004095 F606FF              <1> 	test	byte [esi], 0FFh
  3973                              <1> 	;jz	short getf4
  3974                              <1> 	; 26/03/2021
  3975                              <1> 	;jz	short getf2 ; retn
  3976                              <1> 	;;jz	nig
  3977                              <1> 		; tstb *u.namep / is the character in file name a nul
  3978                              <1> 		; beq nig / yes, end of file name reached; 
  3979                              <1> 			; / branch to "nig"
  3980                              <1> 	; 19/12/2021
  3981                              <1> namei_9:
  3982                              <1> 	; 12/06/2021
  3983                              <1> 	;jnz	short namei_2
  3984                              <1> 	;retn
  3985                              <1> 	; 08/01/2022
  3986 00004098 74C3                <1> 	jz	short getf4
  3987                              <1> namei_2: ; 1:
  3988                              <1> 	; 18/10/2015
  3989 0000409A 8935[C86C0000]      <1> 	mov 	[nbase], esi
  3990                              <1> 	;mov 	[ncount], cx
  3991                              <1> 	; 18/10/2021
  3992 000040A0 890D[CC6C0000]      <1> 	mov	[ncount], ecx
  3993                              <1> 	;
  3994                              <1> 	;;mov	dx, 2
  3995                              <1> 	;mov	dl, 2 ; user flag (read, non-owner)
  3996                              <1> 	; 25/03/2021
  3997                              <1> 	;mov	dx, 100h ; IREAD - read, owner 
  3998                              <1> 	; 18/10/2021
  3999 000040A6 29D2                <1> 	sub	edx, edx
  4000 000040A8 FEC6                <1> 	inc	dh ; dx = 100h ; IREAD - read, owner 
  4001 000040AA E8920B0000          <1> 	call	access
  4002                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
  4003                              <1> 	; 'access' will not return here if user has not "r" permission !
  4004                              <1> 
  4005                              <1> 	;test 	word [i.flgs], 4000h
  4006                              <1> 	;	; bit $40000,i.flgs / directory i-node?
  4007                              <1>         ;jz	short namei_err
  4008                              <1> 		; beq error3 / no, got an error
  4009                              <1> 	; 26/03/2021 
  4010                              <1> ;	mov	al, [i.flgs+1]
  4011                              <1> ;	;test	al, 80h ; IFREG ; 80h
  4012                              <1> ;	;jz	short namei_err ; not a regular file ! (device!?)
  4013                              <1> ;	;and	al, 40h ; IFDIR ; 40h
  4014                              <1> ;	;jz	short namei_err ; not a sub directory !
  4015                              <1> ;	shl	al, 1 ; 80h (IFREG flag) -> cf = 1
  4016                              <1> ;	jnc	short namei_err ; not a regular file ! (device!?)
  4017                              <1> ;	shl	al, 1 ; 80h (IFDIR flag) -> cf = 1
  4018                              <1> ;	jnc	short namei_err ; not a sub directory !
  4019                              <1> 
  4020                              <1> 	; 27/03/2021
  4021 000040AF E83A010000          <1> 	call	chk_dir ; check for directory, jump to 'error' if not
  4022                              <1> 	; CPU will be here if the inode is a (valid) directory inode
  4023                              <1> 
  4024                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  4025                              <1> 	;xor	eax, eax
  4026                              <1> 	;mov	[u.off], eax ; 0
  4027                              <1> 	; 01/05/2021 - Retro UNIX 386 v2 inode structure
  4028 000040B4 A1[CC670000]        <1> 	mov	eax, [i.size]
  4029                              <1> 	;mov	ax, [i.size]
  4030 000040B9 A3[5C6C0000]        <1> 	mov	[u.dirp], eax
  4031                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
  4032                              <1> 		; clr u.off / u.off is file offset used by user
  4033                              <1> 	; 18/10/2021
  4034 000040BE 31C0                <1> 	xor	eax, eax
  4035                              <1> 	;mov	[u.off], eax ; 0
  4036 000040C0 BB[646C0000]        <1> 	mov	ebx, u.off
  4037 000040C5 8903                <1> 	mov	[ebx], eax ; mov dword [u.off], 0
  4038                              <1> 	;
  4039 000040C7 891D[586C0000]      <1> 	mov	[u.fofp], ebx ; u.off ; 18/10/2021
  4040                              <1> 	;mov	dword [u.fofp], u.off
  4041                              <1> 			; mov $u.off,u.fofp / u.fofp is a pointer to 
  4042                              <1> 				  ; / the offset portion of fsp entry
  4043                              <1> namei_3: ; 2:
  4044 000040CD C705[686C0000]-     <1> 	mov	dword [u.base], u.dirbuf
  4044 000040D3 [7C6C0000]          <1>
  4045                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
  4046                              <1> 				    ; / copied from a directory
  4047 000040D7 C705[6C6C0000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
  4047 000040DF 0000                <1>
  4048                              <1>  		; mov $10.,u.count / u.count is byte count 
  4049                              <1> 				 ; / for reads and writes
  4050                              <1> 	;mov 	ax, [ii]
  4051                              <1> 	; 18/10/2021
  4052 000040E1 A1[1C6C0000]        <1> 	mov	eax, [ii] ; (32 bit inode number)
  4053                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
  4054 000040E6 FE05[B66C0000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
  4055 000040EC E8D20D0000          <1>     	call	readi
  4056                              <1> 		; jsr r0,readi / read 10. bytes of file 
  4057                              <1> 		      ; with i-number (r1); i.e. read a directory entry
  4058                              <1> 
  4059 000040F1 8B0D[706C0000]      <1> 	mov 	ecx, [u.nread]
  4060 000040F7 09C9                <1> 	or 	ecx, ecx
  4061                              <1> 		; tst u.nread
  4062 000040F9 741A                <1> 	jz	short nib
  4063                              <1> 		; ble nib / gives error return
  4064                              <1> 	;
  4065                              <1> 	;mov 	bx, [u.dirbuf]
  4066                              <1> 	;and 	bx, bx       
  4067                              <1> 	; 18/10/2021
  4068 000040FB 66F705[7C6C0000]FF- <1> 	test	word [u.dirbuf], 0FFFFh
  4068 00004103 FF                  <1>
  4069                              <1> 		; tst u.dirbuf /
  4070 00004104 7513                <1> 	jnz	short namei_4
  4071                              <1> 		; bne 3f / branch when active directory entry 
  4072                              <1> 		       ; / (i-node word in entry non zero)
  4073 00004106 A1[646C0000]        <1> 	mov	eax, [u.off]
  4074 0000410B 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
  4075 0000410E A3[5C6C0000]        <1> 	mov	[u.dirp], eax
  4076                              <1> 		; mov u.off,u.dirp
  4077                              <1> 		; sub $10.,u.dirp
  4078 00004113 EBB8                <1> 	jmp	short namei_3
  4079                              <1> 		; br 2b
  4080                              <1> 
  4081                              <1> 	; 18/07/2013
  4082                              <1> nib: 
  4083 00004115 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
  4084 00004117 F9                  <1> 	stc
  4085                              <1> nig:
  4086 00004118 C3                  <1> 	retn
  4087                              <1> 
  4088                              <1> 	; 27/03/2021
  4089                              <1> ;namei_err:
  4090                              <1> 	; 16/06/2015
  4091                              <1> ;	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
  4092                              <1> ;	jmp	error
  4093                              <1> 
  4094                              <1> namei_4: ; 3:
  4095                              <1> 	; 18/10/2015
  4096                              <1> 	; 12/10/2015
  4097                              <1> 	; 21/08/2015
  4098                              <1> 	; 18/07/2015
  4099 00004119 8B2D[606C0000]      <1> 	mov	ebp, [u.namep]
  4100                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
  4101 0000411F BF[7E6C0000]        <1> 	mov 	edi, u.dirbuf + 2
  4102                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
  4103                              <1> 	; 18/10/2015
  4104 00004124 8B35[C86C0000]      <1> 	mov	esi, [nbase]
  4105                              <1> 	;mov	cx, [ncount]
  4106                              <1> 	;and	cx, cx
  4107                              <1> 	; 18/10/2021
  4108 0000412A 8B0D[CC6C0000]      <1> 	mov	ecx, [ncount]
  4109 00004130 21C9                <1> 	and	ecx, ecx
  4110 00004132 7505                <1> 	jnz	short namei_5	
  4111                              <1> 	;
  4112 00004134 E88A000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  4113                              <1> 		; esi = physical address (page start + offset)
  4114                              <1> 		; ecx = byte count in the page
  4115                              <1> namei_5: ; 3:
  4116 00004139 45                  <1> 	inc	ebp ; 18/07/2015
  4117 0000413A AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
  4118                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
  4119 0000413B 08C0                <1> 	or 	al, al
  4120 0000413D 741C                <1> 	jz 	short namei_7
  4121                              <1> 		; beq 3f / if char is nul, then the last char in string
  4122                              <1> 			; / has been moved
  4123 0000413F 3C2F                <1> 	cmp	al, '/'
  4124                              <1> 		; cmp r4,$'/ / is char a </>
  4125 00004141 7418                <1> 	je 	short namei_7
  4126                              <1> 		; beq 3f	
  4127                              <1> 	; 12/10/2015
  4128                              <1> 	;dec	cx ; remain byte count in the page
  4129 00004143 49                  <1> 	dec	ecx ; 18/10/2021
  4130 00004144 7505                <1> 	jnz	short namei_6
  4131 00004146 E878000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  4132                              <1> 		; esi = physical address (page start + offset)
  4133                              <1> 		; ecx = byte count in the page
  4134                              <1> namei_6:
  4135 0000414B 81FF[8C6C0000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  4136                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
  4137                              <1> 				     ; / all 8 bytes of file name
  4138 00004151 74E6                <1> 	je	short namei_5
  4139                              <1> 		; beq 3b
  4140 00004153 AE                  <1> 	scasb	
  4141                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
  4142                              <1> 			      ; / char read from directory
  4143 00004154 74E3                <1> 	je 	short namei_5
  4144                              <1> 		; beq 3b / branch if chars match
  4145                              <1> namei_10:
  4146 00004156 E972FFFFFF          <1>         jmp	namei_3 ; 2b
  4147                              <1> 		; br 2b / file names do not match go to next directory entry
  4148                              <1> namei_7: ; 3:
  4149 0000415B 81FF[8C6C0000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  4150                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
  4151 00004161 7405                <1> 	je	short namei_8
  4152                              <1> 		; beq 3f
  4153                              <1> 	;mov 	ah, [edi]
  4154                              <1> 	;;inc 	edi 
  4155                              <1> 	;and 	ah, ah
  4156                              <1> 	;	; tstb (r3)+ /
  4157                              <1>         ; 18/10/2021
  4158 00004163 F607FF              <1> 	test	byte [edi], 0FFh
  4159                              <1> 	; 08/01/2021
  4160 00004166 75EE                <1> 	jnz	short namei_10 
  4161                              <1> 	;jnz	namei_3
  4162                              <1> 		; bne 2b
  4163                              <1> namei_8: ; 3
  4164 00004168 892D[606C0000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
  4165                              <1> 		; mov r2,u.namep / u.namep points to char 
  4166                              <1> 			       ; / following a / or nul
  4167                              <1> 	;mov	bx, [u.dirbuf]
  4168                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
  4169                              <1> 				; / entry to r1
  4170                              <1> 
  4171                              <1> 	;;;;
  4172                              <1> 	; 15/05/2022 - Retro UNIX (8086/386) feature only !
  4173                              <1> 	; ! 'pwd' utility modification !
  4174                              <1> 	; ((if directory entry name is a dotdot)))
  4175                              <1> 	;; check if it is mounted device's root directory inode
  4176                              <1> 	; and if so, replace it with parent dir inode number
  4177                              <1> 	;  of mounting directory in [mntp].
  4178                              <1> 
  4179 0000416E 0FB71D[7C6C0000]    <1> 	movzx	ebx, word [u.dirbuf]
  4180                              <1> 
  4181 00004175 6683FB01            <1> 	cmp	bx, 1 ; root directory inode number
  4182 00004179 7539                <1> 	jne	short namei_11
  4183                              <1> 
  4184 0000417B 3B1D[1C6C0000]      <1> 	cmp	ebx, [ii] ; for root dir, '.' & '..' is 1
  4185 00004181 7531                <1> 	jne	short namei_11 ; not root dir (of mounted dev)
  4186                              <1> 
  4187                              <1> 	;cmp	[idev], bh ; 0
  4188 00004183 383D[216C0000]      <1> 	cmp	[cdev], bh ; 0
  4189                              <1> 			; 0 = root fs, dev num in [rdev]
  4190                              <1> 			; 1 = mounted, dev num in [mdev]
  4191 00004189 7629                <1> 	jna	short namei_11
  4192                              <1> 
  4193                              <1> 	; dotdot (parent directory link) check
  4194 0000418B 66813D[7E6C0000]2E- <1> 	cmp	word [u.dirbuf+2], '..'
  4194 00004193 2E                  <1>
  4195 00004194 751E                <1> 	jne	short namei_11
  4196 00004196 803D[806C0000]00    <1> 	cmp	byte [u.dirbuf+4], 0
  4197 0000419D 7515                <1> 	jne	short namei_11
  4198                              <1> 	
  4199                              <1> 	; (This may not be necessary because [idev] = 1
  4200                              <1> 	; and [mnti] is expected as a sub dir inode number)
  4201 0000419F 391D[2A6C0000]      <1> 	cmp	[mnti], ebx ; 1
  4202 000041A5 760D                <1> 	jna	short namei_11
  4203                              <1> 	
  4204                              <1> 	; change inumber to parent dir inum of mount directory
  4205 000041A7 8B1D[2E6C0000]      <1> 	mov	ebx, [mntp]
  4206 000041AD C605[216C0000]00    <1> 	mov	byte [cdev], 0 ; root fs
  4207                              <1> namei_11:
  4208                              <1> 	;;;;
  4209                              <1> 
  4210 000041B4 20C0                <1> 	and 	al, al
  4211                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
  4212                              <1> 		      ;  / if r4 = </> then go to next directory
  4213                              <1> 	; 15/05/2022
  4214 000041B6 89D8                <1> 	mov	eax, ebx
  4215                              <1> 	;;mov	ax, bx
  4216                              <1> 	;;mov 	ax, [u.dirbuf] ; 17/06/2015
  4217                              <1>         ;; 18/10/2021 (16 bit inode number in 32 bit register)
  4218                              <1> 	;movzx	eax, word [u.dirbuf] 
  4219                              <1> 	; 19/12/2021
  4220 000041B8 E9DBFEFFFF          <1> 	jmp	namei_9 ; eax = inode number
  4221                              <1> ;	jnz	namei_2 
  4222                              <1> ;		; bne 1b
  4223                              <1> ;	; AX = i-number of the file
  4224                              <1> ;;;nig:
  4225                              <1> ;	retn
  4226                              <1> 		; tst (r0)+ / gives non-error return
  4227                              <1> ;;nib:
  4228                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
  4229                              <1> 		       ; ax = 0 -> file not found 
  4230                              <1> ;;	stc	; 27/05/2013
  4231                              <1> ;;	retn
  4232                              <1> 		; rts r0
  4233                              <1> 
  4234                              <1> trans_addr_nmbp:
  4235                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
  4236                              <1> 	; 18/10/2015
  4237                              <1> 	; 12/10/2015
  4238 000041BD 8B2D[606C0000]      <1> 	mov 	ebp, [u.namep]
  4239                              <1> trans_addr_nm: 
  4240                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
  4241                              <1> 	; Convert virtual (pathname) address to physical address
  4242                              <1> 	; (Retro UNIX 386 v1 feature only !)
  4243                              <1> 	; 18/10/2015
  4244                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
  4245                              <1> 	; 02/07/2015
  4246                              <1> 	; 17/06/2015
  4247                              <1> 	; 16/06/2015
  4248                              <1> 	;
  4249                              <1> 	; INPUTS: 
  4250                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
  4251                              <1> 	;	[u.pgdir] = user's page directory
  4252                              <1> 	; OUTPUT:
  4253                              <1> 	;       esi = physical address of the pathname
  4254                              <1> 	;	ecx = remain byte count in the page
  4255                              <1> 	;
  4256                              <1> 	; (Modified registers: EBX, ECX, EDX, ESI) ; 18/10/2021
  4257                              <1> 	;
  4258                              <1> 
  4259                              <1> 	; 18/10/2021
  4260 000041C3 29C9                <1> 	sub	ecx, ecx
  4261                              <1> 	;
  4262                              <1>         ;cmp	dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
  4263 000041C5 390D[A86C0000]      <1> 	cmp	[u.ppgdir], ecx ; 0 ; 18/10/2021
  4264 000041CB 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
  4265                              <1> 				     ; it is already physical address
  4266 000041CD 50                  <1>    	push	eax	
  4267 000041CE 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
  4268 000041D0 E8D8E5FFFF          <1>        	call	get_physical_addr ; get physical address
  4269 000041D5 7204                <1> 	jc	short tr_addr_nm_err
  4270                              <1> 	; 18/10/2015
  4271                              <1> 	; eax = physical address 
  4272                              <1> 	; ecx = remain byte count in page (1-4096) ; 18/10/2021
  4273                              <1> 		; 12/10/2015 (cx = [u.pncount])
  4274 000041D7 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
  4275 000041D9 58                  <1> 	pop	eax 
  4276 000041DA C3                  <1> 	retn
  4277                              <1> 
  4278                              <1> tr_addr_nm_err:
  4279 000041DB A3[B86C0000]        <1> 	mov	[u.error], eax
  4280                              <1> 	;pop 	eax
  4281 000041E0 E962EFFFFF          <1> 	jmp	error
  4282                              <1> 
  4283                              <1> trans_addr_nmk:
  4284                              <1> 	; 12/10/2015
  4285                              <1> 	; 02/07/2015
  4286 000041E5 8B35[606C0000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
  4287                              <1> 	;mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
  4288                              <1> 	; 18/10/2021
  4289 000041EB B510                <1> 	mov	ch, PAGE_SIZE/256
  4290 000041ED C3                  <1> 	retn
  4291                              <1> 
  4292                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  4293                              <1> chk_dir:
  4294                              <1> 	; 12/06/2021
  4295                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
  4296                              <1> 	; Check for directory inode
  4297                              <1> 
  4298 000041EE 8A0D[C5670000]      <1> 	mov	cl, [i.flgs+1]
  4299                              <1> 	;test	cl, 80h ; IFREG ; 80h
  4300                              <1> 	;jz	short chk_dir_err ; not a regular file ! (device!?)
  4301                              <1> 	;and	cl, 40h ; IFDIR ; 40h
  4302                              <1> 	;jz	short chk_dir_err ; not a sub directory !
  4303 000041F4 D0E1                <1> 	shl	cl, 1 ; 80h (IFREG flag) -> cf = 1
  4304 000041F6 7305                <1> 	jnc	short chk_dir_err ; not a regular file ! (device!?)
  4305 000041F8 D0E1                <1> 	shl	cl, 1 ; 40h (IFDIR flag) -> cf = 1
  4306 000041FA 7301                <1> 	jnc	short chk_dir_err ; not a sub directory !
  4307                              <1> 	; 12/06/2021
  4308 000041FC C3                  <1> 	retn
  4309                              <1> chk_dir_err:
  4310 000041FD C705[B86C0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  4310 00004205 0000                <1>
  4311 00004207 E93BEFFFFF          <1> 	jmp	error
  4312                              <1> 
  4313                              <1> 	; 06/02/2022
  4314                              <1> 	; 08/01/2022
  4315                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode)
  4316                              <1> syschdir:
  4317                              <1> 	; / makes the directory specified in the argument
  4318                              <1> 	; / the current directory
  4319                              <1> 	;
  4320                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
  4321                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4322                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  4323                              <1> 	;
  4324                              <1> 	; 'syschdir' makes the directory specified in its argument
  4325                              <1> 	; the current working directory.
  4326                              <1> 	;
  4327                              <1> 	; Calling sequence:
  4328                              <1> 	;	syschdir; name
  4329                              <1> 	; Arguments:
  4330                              <1> 	;	name - address of the path name of a directory
  4331                              <1> 	;	       terminated by nul byte.	
  4332                              <1> 	; Inputs: -
  4333                              <1> 	; Outputs: -
  4334                              <1> 	; ...............................................................
  4335                              <1> 	;				
  4336                              <1> 	; Retro UNIX 8086 v1 modification:
  4337                              <1> 	;	 The user/application program puts address of 
  4338                              <1> 	;	 the path name in BX register as 'syschdir' 
  4339                              <1> 	; 	 system call argument.
  4340                              <1> 
  4341 0000420C 891D[606C0000]      <1> 	mov	[u.namep], ebx
  4342                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
  4343 00004212 E847FEFFFF          <1> 	call	namei
  4344                              <1> 		; jsr r0,namei / find its i-number
  4345                              <1> 	;jc	error
  4346                              <1> 		; br error3
  4347 00004217 730F                <1> 	jnc	short syschdir0
  4348                              <1> 	; 'directory not found !' error
  4349 00004219 C705[B86C0000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
  4349 00004221 0000                <1>
  4350 00004223 E91FEFFFFF          <1> 	jmp	error
  4351                              <1> syschdir0:
  4352                              <1> 	; 08/01/2022
  4353 00004228 66BA0001            <1> 	mov	dx, 100h  ; read access ; IREAD (100h)
  4354 0000422C E8100A0000          <1> 	call	access
  4355                              <1> 		; jsr r0,access; 2 / get i-node into core
  4356                              <1> 	
  4357                              <1> 	; 06/02/2022
  4358                              <1> 	;; 01/01/2022 (runix v2 fs inode flag)
  4359                              <1> 	;test	byte [i.flgs+1], 80h ; regular file ?
  4360                              <1> 	;jz	short syschdir2 ; no, error!
  4361                              <1> 	;test	byte [i.flgs+1], 40h ; directory flag ?
  4362                              <1> 	;;test	word [i.flgs], 4000h
  4363                              <1> 	;	; bit $40000,i.flgs / is it a directory?
  4364                              <1> 	;;jz	error 
  4365                              <1> 	;	; beq error3 / no error
  4366                              <1> 	;jnz	short syschdir1
  4367                              <1> ;syschdir2:
  4368                              <1> 	;mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  4369                              <1> 	;jmp	error
  4370                              <1> 
  4371                              <1> 	; 06/02/2022
  4372                              <1> 	; check for directory, jump to 'error' if not
  4373 00004231 E8B8FFFFFF          <1> 	call	chk_dir
  4374                              <1> 	; (cpu will not return here
  4375                              <1> 	;  if the inode it is not a valid dir inode)
  4376                              <1> 
  4377                              <1> syschdir1:
  4378 00004236 66A3[486C0000]      <1> 	mov	[u.cdir], ax
  4379                              <1> 		; mov r1,u.cdir / move i-number to users 
  4380                              <1> 			      ; / current directory
  4381                              <1> 	;mov	ax, [cdev]
  4382                              <1> 	;mov	[u.cdrv], ax
  4383                              <1> 	; 08/01/2022
  4384 0000423C A0[216C0000]        <1> 	mov	al, [cdev]
  4385 00004241 A2[4C6C0000]        <1> 	mov	[u.cdrv], al
  4386                              <1> 		; mov cdev,u.cdev / move its device to users 
  4387                              <1> 			        ; / current device
  4388 00004246 E91CEFFFFF          <1> 	jmp	sysret
  4389                              <1> 		; br sysret3
  4390                              <1> 
  4391                              <1> syschmod: ; < change mode of file >
  4392                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  4393                              <1> 	; 01/05/2021
  4394                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
  4395                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4396                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  4397                              <1> 	;
  4398                              <1> 	; 'syschmod' changes mode of the file whose name is given as
  4399                              <1> 	; null terminated string pointed to by 'name' has it's mode 
  4400                              <1> 	; changed to 'mode'.
  4401                              <1> 	;
  4402                              <1> 	; Calling sequence:
  4403                              <1> 	;	syschmod; name; mode
  4404                              <1> 	; Arguments:
  4405                              <1> 	;	name - address of the file name
  4406                              <1> 	;	       terminated by null byte.
  4407                              <1> 	;	mode - (new) mode/flags < attributes >
  4408                              <1> 	;	
  4409                              <1> 	; Inputs: -
  4410                              <1> 	; Outputs: -
  4411                              <1> 	; ...............................................................
  4412                              <1> 	;				
  4413                              <1> 	; Retro UNIX 8086 v1 modification: 
  4414                              <1> 	;       'syschmod' system call has two arguments; so,
  4415                              <1> 	;	* 1st argument, name is pointed to by BX register
  4416                              <1> 	;	* 2nd argument, mode is in CX register
  4417                              <1> 	;
  4418                              <1> 	; Mode bits (Flags):
  4419                              <1> 	;	bit 15 - 'i-node is allocated' flag (8000h)
  4420                              <1> 	;	bit 14 - directory flag (4000h)
  4421                              <1> 	;	bit 13 - file has modified flag (always on) (2000h)
  4422                              <1> 	;	bit 12 - large file flag (1000h)
  4423                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
  4424                              <1> 	;	bit 5 - set user ID on execution flag (20h) 
  4425                              <1> 	;	bit 4 - executable flag (10h)
  4426                              <1> 	;	bit 3 - read permission for owner (08h)
  4427                              <1> 	;	bit 2 - write permission for owner (04h)
  4428                              <1> 	;	bit 1 - read permission for non-owner (02h)
  4429                              <1> 	;	bit 0 - write permission for non-owner (01h)
  4430                              <1> 
  4431                              <1> 	; 01/05/2021 (07/02/2020)
  4432                              <1> 	; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
  4433                              <1> 	; 	bit 15 - IFREG - regular file (8000h)
  4434                              <1> 	;	bit 14 - IFDIR - directory (4000h)
  4435                              <1> 	;	bit 13 - IRSVD - 0 - reserved/mounted bit (2000h)
  4436                              <1> 	; 	bit 12 - ILARG - large file addressing bit (1000h)
  4437                              <1> 	; 	bit 11 - ISUID - set user id on exec (800h)
  4438                              <1> 	;	bit 10 - ISGID - set group id on exec (400h)
  4439                              <1> 	; 	bit  9 - IEXTT - 0 - use extents (200h)
  4440                              <1> 	;	bit  8 - IREAD - read, owner (100h)
  4441                              <1> 	;	bit  7 - IWRITE - write, owner (80h)
  4442                              <1> 	;	bit  6 - IEXEC - execute, owner (40h)
  4443                              <1> 	; 	bit  5 - read, group (20h)
  4444                              <1> 	; 	bit  4 - write, group (10h)
  4445                              <1> 	; 	bit  3 - execute, group (08h)
  4446                              <1> 	;	bit  2 - read, others (04h)
  4447                              <1> 	; 	bit  1 - write, others (02h)
  4448                              <1> 	; 	bit  0 - execute, others (01h)
  4449                              <1> 	;
  4450                              <1> 	; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
  4451                              <1> 	;	bit 15 - IFREG - 0 - device file (8000h)
  4452                              <1> 	; 	bit 14 - IFBLK - block device (4000h)
  4453                              <1> 	; 	bit 13 - IFCHR - 1 - character special (2000h)
  4454                              <1> 	;	bit 12 - IFIFO - fifo special (1000h)
  4455                              <1> 	; 	bit 11 - IPIPE - pipe special (800h)
  4456                              <1> 	;	bit 10 - IREDIR - redirected (400h)
  4457                              <1> 	;	bit  9 - IEXTR - external device driver (200h)
  4458                              <1> 	;	bit  8 - IREAD - read, owner (100h)
  4459                              <1> 	;	bit  7 - IWRITE - write, owner (80h)
  4460                              <1> 	;	bit  6 - IEXEC - execute, owner (40h)
  4461                              <1> 	; 	bit  5 - read, group (20h)
  4462                              <1> 	; 	bit  4 - write, group (10h)
  4463                              <1> 	; 	bit  3 - execute, group (08h)
  4464                              <1> 	;	bit  2 - read, others (04h)
  4465                              <1> 	; 	bit  1 - write, others (02h)
  4466                              <1> 	; 	bit  0 - execute, others (01h)
  4467                              <1> 
  4468                              <1> 	; / name; mode
  4469 0000424B E877000000          <1> 	call	isown
  4470                              <1> 		; jsr r0,isown / get the i-node and check user status
  4471                              <1> 
  4472                              <1> 	; 25/05/2020
  4473                              <1> 	; AL = new mode (return form 'isown', ecx -> eax)
  4474                              <1> 
  4475                              <1> 	;test	word [i.flgs], 4000h
  4476                              <1> 	;	; bit $40000,i.flgs / directory?
  4477                              <1> 	;jz	short syschmod1
  4478                              <1> 	;	; beq 2f / no
  4479                              <1> 	;; AL = (new) mode
  4480                              <1> 	;and	al, 0CFh ; 11001111b (clears bit 4 & 5)
  4481                              <1> 	;	; bic $60,r2 / su & ex / yes, clear set user id and 
  4482                              <1> 	;		   ; / executable modes
  4483                              <1> 
  4484                              <1> 	; 01/05/2021
  4485                              <1> 	; AX = new mode (9 bits for devices or 12 bits files)
  4486 00004250 8A15[C5670000]      <1> 	mov	dl, [i.flgs+1]
  4487                              <1> 	; 09/01/2022
  4488 00004256 F6C280              <1> 	test	dl, 80h ; regular file
  4489 00004259 7416                <1> 	jz	short syschmod1 ; device file
  4490 0000425B F6C240              <1> 	test	dl, 40h ; directory
  4491 0000425E 7511                <1> 	jnz	short syschmod1
  4492                              <1> 	; regular file
  4493 00004260 6625FF0D            <1> 	and	ax, 0DFFh ; clear bit 9, 12-15 (of new mode)
  4494                              <1> 	; clear bit 8,10,11 of current mode/flags
  4495 00004264 80E2F2              <1> 	and	dl, 0F2h ; and dl, 11110010b
  4496                              <1> syschmod0:
  4497 00004267 08D4                <1> 	or	ah, dl
  4498 00004269 66A3[C4670000]      <1> 	mov	[i.flgs], ax	
  4499 0000426F EB45                <1> 	jmp	short syschmod2
  4500                              <1> syschmod1: 
  4501                              <1> 	; device or directory	
  4502 00004271 6625B601            <1> 	and	ax, 1B6h ; clear bit 9-15 & bit 0,3,6 (EXEC bits)
  4503                              <1> 	; clear bit 8 (IREAD) of current mode/flags
  4504                              <1> 	;	 (dl contains flag bits 8-15)
  4505 00004275 80E2FE              <1> 	and	dl, ~1 ; and dl, 11111110b 
  4506 00004278 EBED                <1> 	jmp	short syschmod0
  4507                              <1> 
  4508                              <1> ;syschmod1: ; 2:
  4509                              <1> 	;mov	[i.flgs], al	
  4510                              <1> 	;	; movb r2,i.flgs / move remaining mode to i.flgs
  4511                              <1> 
  4512                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
  4513                              <1> 	;mov	byte [imodx], 1 ; (flag means file data is same
  4514                              <1> 	;			;  but inode's itself has been modified)
  4515                              <1> 	;call	setimod
  4516                              <1> 	;jmp	sysret
  4517                              <1> 
  4518                              <1> 	; 25/05/2020
  4519                              <1> 	;jmp	short syschmod2
  4520                              <1> 
  4521                              <1> syschown: ; < change owner of file >
  4522                              <1> 	; 13/03/2022
  4523                              <1> 	; 11/03/2022
  4524                              <1> 	; 14/02/2022
  4525                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  4526                              <1> 	; 01/05/2021
  4527                              <1> 	;	(change owner and group ID of file)
  4528                              <1> 	; 02/04/2021
  4529                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
  4530                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4531                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4532                              <1> 	;
  4533                              <1> 	; 'syschown' changes the owner of the file whose name is given
  4534                              <1> 	; as null terminated string pointed to by 'name' has it's owner
  4535                              <1> 	; changed to 'owner'
  4536                              <1> 	;
  4537                              <1> 	; Calling sequence:
  4538                              <1> 	;	syschown; name; owner
  4539                              <1> 	; Arguments:
  4540                              <1> 	;	name - address of the file name
  4541                              <1> 	;	       terminated by null byte.
  4542                              <1> 	;	owner - (new) owner (number/ID)
  4543                              <1> 	;	
  4544                              <1> 	; Inputs: -
  4545                              <1> 	; Outputs: -
  4546                              <1> 	; ...............................................................
  4547                              <1> 	;				
  4548                              <1> 	; Retro UNIX 8086 v1 modification: 
  4549                              <1> 	;       'syschown' system call has two arguments; so,
  4550                              <1> 	;	* 1st argument, name is pointed to by BX register
  4551                              <1> 	;	* 2nd argument, owner number is in CX register
  4552                              <1> 	;
  4553                              <1> 	; / name; owner
  4554 0000427A E848000000          <1> 	call	isown
  4555                              <1> 		; jsr r0,isown / get the i-node and check user status
  4556                              <1> 	
  4557                              <1> 	; 25/05/2020
  4558                              <1> 	; AL = owner number (return form 'isown', ecx -> eax)
  4559                              <1> 	; 02/04/2021
  4560                              <1> 	; AX = owner number
  4561                              <1> 	; 01/05/2021
  4562                              <1> 	; byte 2 of EAX is group number
  4563                              <1> 
  4564                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013 
  4565                              <1> 	;	; tstb u.uid / super user
  4566                              <1> 	;jz	short syschown1
  4567                              <1> 	;	; beq 2f / yes, 2f
  4568 0000427F 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0
  4569 00004287 741F                <1> 	jz	short syschown1
  4570                              <1> 
  4571                              <1> 	;test	byte [i.flgs], 20h ; 32
  4572                              <1> 	;	; bit $40,i.flgs / no, set userid on execution?
  4573                              <1> 	;;jnz	error
  4574                              <1> 	;	; bne 3f / yes error, could create Trojan Horses
  4575                              <1> 	;jz	short syschown1
  4576                              <1> 	; 01/05/2021
  4577                              <1> 	; check set user id on execution flag
  4578                              <1> 	; (protection against Trojan Horses)
  4579                              <1> 
  4580                              <1> 	; ((Note: UNIX v7 x86 'chown' source code in 'sys4.c'
  4581                              <1> 	;        does not contain this protection)) 
  4582                              <1> 
  4583                              <1> 	; 14/02/2022
  4584 00004289 8A15[C5670000]      <1> 	mov	dl, [i.flgs+1]
  4585 0000428F F6C280              <1> 	test	dl, 80h ; IFREG ; RUNIX v2 inode flags  	
  4586 00004292 7405                <1> 	jz	short syschown_err ; device file !
  4587                              <1> 	; 09/01/2022
  4588                              <1> 	;test	byte [i.flgs+1], 08h ; ISUID ; RUNIX v2 inode flags  	
  4589                              <1> 	; 14/02/2022
  4590 00004294 F6C208              <1> 	test	dl, 08h	; set user id on execution
  4591 00004297 740F                <1> 	jz	short syschown1 ; 11/03/2022
  4592                              <1> 		; 11/03/2022
  4593                              <1> 		; bit $40,i.flgs / no, set userid on execution?
  4594                              <1> 		; bne 3f / yes error, could create Trojan Horses
  4595                              <1> syschown_err:
  4596                              <1> 	; 'permission denied !'
  4597 00004299 C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
  4597 000042A1 0000                <1>
  4598 000042A3 E99FEEFFFF          <1> 	jmp	error
  4599                              <1> syschown1: ; 2:
  4600                              <1> 	;; AL = owner (number/ID)
  4601                              <1> 	;mov	[i.uid], al ; 23/06/2015
  4602                              <1> 	;	; movb r2,i.uid / no, put the new owners id 
  4603                              <1> 	;		      ; / in the i-node
  4604                              <1> 	; 02/04/2021 (Retro UNIX 386 v2)
  4605                              <1> 	; AX = owner number
  4606 000042A8 66A3[C8670000]      <1> 	mov	[i.uid], ax ; owner
  4607                              <1> 	; 13/03/2022
  4608                              <1> 	;; 14/02/2022 (Retro UNIX 386 v1.2)
  4609                              <1> 	;test	dl, 04h ; ISGID ; set grup id on execution
  4610                              <1> 	;jz	short syschown2
  4611                              <1> 	; 01/05/2021 (Retro UNIX 386 v2)
  4612 000042AE C1E810              <1> 	shr	eax, 16
  4613 000042B1 A2[CA670000]        <1> 	mov	[i.gid], al ; group
  4614                              <1> syschown2:
  4615                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
  4616                              <1> syschmod2:
  4617                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  4618 000042B6 C605[356C0000]01    <1> 	mov	byte [imodx], 1	; (flag means file data is same
  4619                              <1> 			      ;  but inode's itself has been modified)
  4620 000042BD E8260A0000          <1> 	call	setimod ; 25/05/2020
  4621                              <1> 	
  4622 000042C2 E9A0EEFFFF          <1> 	jmp	sysret
  4623                              <1> 
  4624                              <1> 	; 1: 
  4625                              <1> 		; jmp sysret4
  4626                              <1> 	; 3:
  4627                              <1> 		; jmp	error
  4628                              <1> 
  4629                              <1> isown:
  4630                              <1> 	; 11/03/2022
  4631                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  4632                              <1> 	; 06/11/2021
  4633                              <1> 	; 12/06/2021
  4634                              <1> 	; 01/05/2021
  4635                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
  4636                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4637                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  4638                              <1> 	;
  4639                              <1> 	; 'isown' is given a file name (the 1st argument).
  4640                              <1> 	;  It find the i-number of that file via 'namei' 
  4641                              <1> 	;  then gets the i-node into core via 'iget'.
  4642                              <1> 	;  It then tests to see if the user is super user. 
  4643                              <1> 	;  If not, it checks to see if the user is owner of 
  4644                              <1> 	;  the file. If he is not an error occurs.
  4645                              <1> 	;  If user is the owner 'setimod' is called to indicate
  4646                              <1> 	;  the inode has been modified and the 2nd argument of
  4647                              <1> 	;  the call is put in r2.
  4648                              <1> 	;
  4649                              <1> 	; INPUTS ->
  4650                              <1> 	;    arguments of syschmod and syschown calls
  4651                              <1> 	; OUTPUTS ->
  4652                              <1> 	;    u.uid - id of user
  4653                              <1> 	;    imod - set to a 1
  4654                              <1> 	;    r2 - contains second argument of the system call
  4655                              <1> 	;
  4656                              <1> 	;   ((AX=R2) output as 2nd argument)
  4657                              <1> 	;
  4658                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))
  4659                              <1> 	;
  4660                              <1> 		; jsr r0,arg2 / u.namep points to file name
  4661                              <1> 	;; ! 2nd argument on top of stack !
  4662                              <1> 	;; 22/06/2015 - 32 bit modifications
  4663                              <1> 	;; 07/07/2013
  4664 000042C7 891D[606C0000]      <1> 	mov	[u.namep], ebx ;; 1st argument
  4665 000042CD 51                  <1> 	push 	ecx ;* ; 2nd argument
  4666                              <1> 	;;
  4667 000042CE E88BFDFFFF          <1> 	call	namei
  4668                              <1> 		; jsr r0,namei / get its i-number
  4669                              <1>        ; Retro UNIX 8086 v1 modification !
  4670                              <1>        ; ax = 0 -> file not found 
  4671                              <1> 	;and	ax, ax
  4672                              <1> 	;jz	error
  4673                              <1> 	;jc	error ; 27/05/2013
  4674                              <1> 		; br error3
  4675 000042D3 730F                <1> 	jnc	short isown1  ; 25/05/2020 (isown0 -> isown1)
  4676                              <1> 	; 'file not found !' error
  4677 000042D5 C705[B86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  4677 000042DD 0000                <1>
  4678 000042DF E963EEFFFF          <1> 	jmp	error
  4679                              <1> isown1:
  4680 000042E4 E86E080000          <1> 	call	iget
  4681                              <1> 		; jsr r0,iget / get i-node into core
  4682                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
  4683                              <1> 	;; 06/11/2021
  4684                              <1> 	;jnc	short isown3
  4685                              <1> 	;mov	[u.error], eax
  4686                              <1> 	;jmp	error
  4687                              <1> ;isown3:
  4688                              <1> 	; check if it is super user ID
  4689                              <1> 	; 09/01/2022 (Retro UNIX 386 v2 fs inode structure)
  4690 000042E9 66A1[966C0000]      <1> 	mov	ax, [u.uid]
  4691 000042EF 6609C0              <1> 	or	ax, ax
  4692                              <1> 	;mov	al, [u.uid] ; 02/08/2013
  4693                              <1> 	;or	al, al
  4694                              <1> 		; tstb u.uid / super user?
  4695                              <1> 	; 12/06/2021
  4696 000042F2 7418                <1> 	jz	short isown2 ; 25/05/2020 (isown1 -> isown2)
  4697                              <1> 		; beq 1f / yes, branch
  4698                              <1> 	
  4699                              <1> 	; check user ID	(if same with file's owner)
  4700 000042F4 663B05[C8670000]    <1> 	cmp	ax, [i.uid] ; 09/01/2022
  4701                              <1> 	;cmp	al, [i.uid]
  4702                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
  4703                              <1> 				 ; / the file
  4704                              <1> 	;jne	error
  4705                              <1> 		; beq 1f / yes
  4706                              <1> 		; jmp error3 / no, error
  4707                              <1> 	; 11/03/2022
  4708 000042FB 740F                <1> 	je	short isown2 ; 25/05/2020
  4709                              <1> 	;; 01/05/2021
  4710                              <1> 	;jne	short isown_err
  4711                              <1> 
  4712                              <1> 	; 11/03/2022 (*)
  4713                              <1> 	; Note: It is seen as original unix (v5-v7) kernel
  4714                              <1> 	;	source handles 'u.gid' for group permissions
  4715                              <1> 	;	but kernel uses 'u.uid' as primary and unic
  4716                              <1> 	;	(singular) user id/number; a user group
  4717                              <1> 	;	does/can not contain same user id/number
  4718                              <1> 	;	with anotner group. So, if active/current
  4719                              <1> 	;	user ID is same with file's owner id,
  4720                              <1> 	;	group id check is not needed.
  4721                              <1> 	;	([u.uid] = [i.uid] is enough to confirm)	
  4722                              <1> 
  4723                              <1> 	; 01/05/2021
  4724                              <1> 	;mov	ax, [u.uid]
  4725                              <1> 	;or	ax, ax
  4726                              <1> 	;jz	short isown2 
  4727                              <1> 	;cmp	ax, [i.uid]
  4728                              <1> 	;;je	short isown2
  4729                              <1> 	;jne	short isown_err
  4730                              <1> 
  4731                              <1> 	; 01/05/2021
  4732                              <1> 	; ((Note: UNIX v7 x86 'chown', 'chmod' procedures
  4733                              <1> 	;    and their sub procedures do not check group ID))
  4734                              <1> 	; (('sys4.c', 'fio.c'))
  4735                              <1> 
  4736                              <1> 	; 11/03/2022 (*)
  4737                              <1> 	; 01/05/2021
  4738                              <1> 	; check group ID (if same with group of file's owner)
  4739                              <1> 	;mov	al, [u.gid]
  4740                              <1> 	;cmp	al, [i.gid]
  4741                              <1> 	;je	short isown2
  4742                              <1> isown_err:
  4743 000042FD C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER ; 11
  4743 00004305 0000                <1>
  4744                              <1> 			; 'permission denied !' error
  4745 00004307 E93BEEFFFF          <1> 	jmp	error
  4746                              <1> 
  4747                              <1> 	; 25/05/2020
  4748                              <1> ;isown2: ; 1:
  4749                              <1> ;	call	setimod
  4750                              <1> ;		; jsr r0,setimod / indicates 
  4751                              <1> ;		;	       ; / i-node has been modified
  4752                              <1> isown2: 
  4753                              <1> 	; 25/05/2020
  4754 0000430C 58                  <1> 	pop	eax ;* ; 2nd argument
  4755                              <1> 		; mov (sp)+,r2 / mode is put in r2 
  4756                              <1> 		       ; / (u.off put on stack with 2nd arg)
  4757 0000430D C3                  <1> 	retn
  4758                              <1> 
  4759                              <1> ;;arg:  ; < get system call arguments >
  4760                              <1> 	; 'arg' extracts an argument for a routine whose call is 
  4761                              <1> 	; of form:
  4762                              <1> 	;	sys 'routine' ; arg1
  4763                              <1> 	;		or
  4764                              <1> 	;	sys 'routine' ; arg1 ; arg2
  4765                              <1> 	;		or
  4766                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
  4767                              <1> 	;	
  4768                              <1> 	; INPUTS ->
  4769                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
  4770                              <1> 	;	This pointers's value is actually the value of
  4771                              <1> 	;	update pc at the the trap to sysent (unkni) is
  4772                              <1> 	;	made to process the sys instruction
  4773                              <1> 	;    r0 - contains the return address for the routine
  4774                              <1> 	;	that called arg. The data in the word pointer 
  4775                              <1> 	;	to by the return address is used as address
  4776                              <1> 	;	in which the extracted argument is stored
  4777                              <1> 	;    	
  4778                              <1> 	; OUTPUTS ->
  4779                              <1> 	;    'address' - contains the extracted argument 
  4780                              <1> 	;    u.sp+18 - is incremented by 2 
  4781                              <1> 	;    r1 - contains the extracted argument
  4782                              <1> 	;    r0 - points to the next instruction to be
  4783                              <1> 	;	 executed in the calling routine.
  4784                              <1> 	;
  4785                              <1>   
  4786                              <1> 	; mov u.sp,r1
  4787                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
  4788                              <1> 			; / into argument of arg2
  4789                              <1> 	; add $2,18.(r1) / point pc on stack 
  4790                              <1> 			      ; / to next system argument
  4791                              <1> 	; rts r0
  4792                              <1> 
  4793                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
  4794                              <1> 	; 'arg2' takes first argument in system call
  4795                              <1> 	;  (pointer to name of the file) and puts it in location
  4796                              <1> 	;  u.namep; takes second argument and puts it in u.off
  4797                              <1> 	;  and on top of the stack
  4798                              <1> 	;	
  4799                              <1> 	; INPUTS ->
  4800                              <1> 	;    u.sp, r0
  4801                              <1> 	;    	
  4802                              <1> 	; OUTPUTS ->
  4803                              <1> 	;    u.namep
  4804                              <1> 	;    u.off 
  4805                              <1> 	;    u.off pushed on stack
  4806                              <1> 	;    r1
  4807                              <1> 	;
  4808                              <1> 
  4809                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
  4810                              <1> 				; / first arg in sys call
  4811                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
  4812                              <1> 				; / second arg in sys call
  4813                              <1> 	; mov r0,r1 / r0 points to calling routine
  4814                              <1> 	; mov (sp),r0 / put operation code back in r0
  4815                              <1> 	; mov u.off,(sp) / put pointer to second argument 
  4816                              <1> 			; / on stack
  4817                              <1> 	; jmp (r1) / return to calling routine
  4818                              <1> 
  4819                              <1> systime: ; / get time of year
  4820                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4821                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
  4822                              <1> 	;
  4823                              <1> 	; 20/06/2013
  4824                              <1> 	; 'systime' gets the time of the year.
  4825                              <1> 	; The present time is put on the stack.
  4826                              <1> 	;
  4827                              <1> 	; Calling sequence:
  4828                              <1> 	;	systime
  4829                              <1> 	; Arguments: -
  4830                              <1> 	;	
  4831                              <1> 	; Inputs: -
  4832                              <1> 	; Outputs: sp+2, sp+4 - present time
  4833                              <1> 	; ...............................................................
  4834                              <1> 	;	
  4835                              <1> 	; Retro UNIX 8086 v1 modification: 
  4836                              <1> 	;       'systime' system call will return to the user
  4837                              <1> 	;	with unix time (epoch) in DX:AX register pair
  4838                              <1> 	;
  4839                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
  4840                              <1> 	;	system call for PC compatibility !!		 	
  4841                              <1> 
  4842 0000430E E80DE9FFFF          <1> 	call 	epoch
  4843 00004313 A3[446C0000]        <1> 	mov 	[u.r0], eax
  4844                              <1> 		; mov s.time,4(sp)
  4845                              <1> 		; mov s.time+2,2(sp) / put the present time 
  4846                              <1> 				   ; / on the stack
  4847                              <1> 		; br sysret4
  4848 00004318 E94AEEFFFF          <1> 	jmp	sysret 
  4849                              <1> 
  4850                              <1> sysstime: ; / set time
  4851                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  4852                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4853                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4854                              <1> 	;
  4855                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
  4856                              <1> 	;
  4857                              <1> 	; Calling sequence:
  4858                              <1> 	;	sysstime
  4859                              <1> 	; Arguments: -
  4860                              <1> 	;	
  4861                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
  4862                              <1> 	; Outputs: -
  4863                              <1> 	; ...............................................................
  4864                              <1> 	;	
  4865                              <1> 	; Retro UNIX 8086 v1 modification: 
  4866                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
  4867                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
  4868                              <1> 	; 
  4869                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  4870                              <1> 	;	to get sysstime system call arguments from the user;
  4871                              <1> 	;	* 1st argument, lowword of unix time is in BX register
  4872                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
  4873                              <1> 	;
  4874                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
  4875                              <1> 	;	system call for PC compatibility !!	
  4876                              <1> 
  4877                              <1> 	; 09/01/2022 (Retro UNIX 386 v2 fs inode structure)
  4878 0000431D 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0 ; 16 bit user ID
  4879                              <1> 	;cmp	byte [u.uid], 0
  4880                              <1> 		; tstb u.uid / is user the super user
  4881                              <1> 	;ja	error
  4882                              <1> 		; bne error4 / no, error
  4883 00004325 760F                <1> 	jna	short systime1
  4884                              <1> 	; 'permission denied !'
  4885 00004327 C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
  4885 0000432F 0000                <1>
  4886 00004331 E911EEFFFF          <1> 	jmp	error
  4887                              <1> systime1:
  4888                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
  4889                              <1> 	; EBX = unix (epoch) time (from user)
  4890 00004336 89D8                <1> 	mov	eax, ebx
  4891 00004338 E860EAFFFF          <1> 	call 	set_date_time
  4892                              <1> 		; mov 4(sp),s.time
  4893                              <1> 		; mov 2(sp),s.time+2 / set the system time
  4894 0000433D E925EEFFFF          <1> 	jmp	sysret
  4895                              <1> 		; br sysret4
  4896                              <1> 
  4897                              <1> sysbreak:
  4898                              <1> 	; 18/10/2015
  4899                              <1> 	; 07/10/2015
  4900                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4901                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
  4902                              <1> 	;
  4903                              <1> 	; 'sysbreak' sets the programs break points. 
  4904                              <1> 	; It checks the current break point (u.break) to see if it is
  4905                              <1> 	; between "core" and the stack (sp). If it is, it is made an
  4906                              <1> 	; even address (if it was odd) and the area between u.break
  4907                              <1> 	; and the stack is cleared. The new breakpoint is then put
  4908                              <1> 	; in u.break and control is passed to 'sysret'.
  4909                              <1> 	;
  4910                              <1> 	; Calling sequence:
  4911                              <1> 	;	sysbreak; addr
  4912                              <1> 	; Arguments: -
  4913                              <1> 	;	
  4914                              <1> 	; Inputs: u.break - current breakpoint
  4915                              <1> 	; Outputs: u.break - new breakpoint 
  4916                              <1> 	;	area between old u.break and the stack (sp) is cleared.
  4917                              <1> 	; ...............................................................
  4918                              <1> 	;	
  4919                              <1> 	; Retro UNIX 8086 v1 modification:
  4920                              <1> 	;	The user/application program puts breakpoint address
  4921                              <1> 	;       in BX register as 'sysbreak' system call argument.
  4922                              <1> 	; 	(argument transfer method 1)
  4923                              <1> 	;
  4924                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
  4925                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
  4926                              <1> 	;  NOTE:
  4927                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
  4928                              <1> 	;	'u.break' address) of user's memory for original unix's
  4929                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
  4930                              <1> 
  4931                              <1> 		; mov u.break,r1 / move users break point to r1
  4932                              <1> 		; cmp r1,$core / is it the same or lower than core?
  4933                              <1> 		; blos 1f / yes, 1f
  4934                              <1> 	; 23/06/2015
  4935 00004342 8B2D[746C0000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
  4936                              <1> 	;and	ebp, ebp
  4937                              <1> 	;jz	short sysbreak_3 
  4938                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
  4939                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
  4940 00004348 8B15[3C6C0000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
  4941 0000434E 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
  4942                              <1> 	; 07/10/2015
  4943 00004351 891D[746C0000]      <1> 	mov	[u.break], ebx ; virtual address !!!
  4944                              <1> 	;
  4945 00004357 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
  4946                              <1> 			   ; with top of user's stack (virtual!)
  4947 00004359 7327                <1> 	jnb	short sysbreak_3
  4948                              <1> 		; cmp r1,sp / is it the same or higher 
  4949                              <1> 			  ; / than the stack?
  4950                              <1> 		; bhis 1f / yes, 1f
  4951 0000435B 89DE                <1> 	mov	esi, ebx
  4952 0000435D 29EE                <1> 	sub	esi, ebp ; new break point - old break point
  4953 0000435F 7621                <1> 	jna	short sysbreak_3 
  4954                              <1> 	;push	ebx
  4955                              <1> sysbreak_1:
  4956 00004361 89EB                <1> 	mov	ebx, ebp  
  4957 00004363 E845E4FFFF          <1> 	call	get_physical_addr ; get physical address
  4958 00004368 0F826DFEFFFF        <1> 	jc	tr_addr_nm_err
  4959                              <1> 	; 18/10/2015
  4960 0000436E 89C7                <1> 	mov	edi, eax 
  4961 00004370 29C0                <1> 	sub	eax, eax ; 0
  4962                              <1> 		 ; ECX = remain byte count in page (1-4096)
  4963 00004372 39CE                <1> 	cmp	esi, ecx
  4964 00004374 7302                <1> 	jnb	short sysbreak_2
  4965 00004376 89F1                <1> 	mov	ecx, esi
  4966                              <1> sysbreak_2:
  4967 00004378 29CE                <1> 	sub	esi, ecx
  4968 0000437A 01CD                <1> 	add	ebp, ecx
  4969 0000437C F3AA                <1> 	rep 	stosb
  4970 0000437E 09F6                <1> 	or	esi, esi
  4971 00004380 75DF                <1> 	jnz	short sysbreak_1
  4972                              <1> 	;
  4973                              <1> 		; bit $1,r1 / is it an odd address
  4974                              <1> 		; beq 2f / no, its even
  4975                              <1> 		; clrb (r1)+ / yes, make it even
  4976                              <1> 	; 2: / clear area between the break point and the stack
  4977                              <1> 		; cmp r1,sp / is it higher or same than the stack
  4978                              <1> 		; bhis 1f / yes, quit
  4979                              <1> 		; clr (r1)+ / clear word
  4980                              <1> 		; br 2b / go back
  4981                              <1> 	;pop	ebx
  4982                              <1> sysbreak_3: ; 1:
  4983                              <1> 	;mov	[u.break], ebx ; virtual address !!!
  4984                              <1> 		; jsr r0,arg; u.break / put the "address" 
  4985                              <1> 			; / in u.break (set new break point)
  4986                              <1> 		; br sysret4 / br sysret
  4987 00004382 E9E0EDFFFF          <1> 	jmp	sysret
  4988                              <1> 
  4989                              <1> maknod: 
  4990                              <1> 	; 18/07/2022
  4991                              <1> 	; 12/03/2022
  4992                              <1> 	; 11/03/2022
  4993                              <1> 	; 14/02/2022
  4994                              <1> 	; 10/01/2022
  4995                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  4996                              <1> 	; 06/11/2021 (Retro UNIX 386 v2)
  4997                              <1> 	; 15/08/2021
  4998                              <1> 	; 06/05/2021
  4999                              <1> 	; 02/05/2021
  5000                              <1> 	; 01/04/2021
  5001                              <1> 	; 27/03/2021
  5002                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
  5003                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5004                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  5005                              <1> 	;
  5006                              <1> 	; 'maknod' creates an i-node and makes a directory entry
  5007                              <1> 	; for this i-node in the current directory.
  5008                              <1> 	;
  5009                              <1> 	; INPUTS ->
  5010                              <1> 	;    r1 - contains mode
  5011                              <1> 	;    ii - current directory's i-number	
  5012                              <1> 	;    	
  5013                              <1> 	; OUTPUTS ->
  5014                              <1> 	;    u.dirbuf - contains i-number of free i-node 
  5015                              <1> 	;    i.flgs - flags in new i-node 
  5016                              <1> 	;    i.uid - filled with u.uid
  5017                              <1> 	;    i.nlks - 1 is put in the number of links
  5018                              <1> 	;    i.ctim - creation time
  5019                              <1> 	;    i.ctim+2 - modification time
  5020                              <1> 	;    imod - set via call to setimod
  5021                              <1> 	;	
  5022                              <1> 	; ((AX = R1)) input
  5023                              <1> 	;
  5024                              <1> 	; (Retro UNIX Prototype : 
  5025                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
  5026                              <1>         ; ((Modified registers: eax, edx, ebx, ecx, esi, edi, ebp))
  5027                              <1> 
  5028                              <1> 	; 27/03/2021
  5029                              <1> 	; INPUT:
  5030                              <1>  	;	AX = mode
  5031                              <1> 	;
  5032                              <1> 	; ('maknod' is called by 'syscreat' and 'sysmkdir')
  5033                              <1> 	; (('syscreat' and 'sysmkdir' will set AX input))
  5034                              <1> 
  5035                              <1> 	; 27/03/2021
  5036                              <1> 	; Retro UNIX 386 v2 inode mode flags (ref: 'ux.s')
  5037                              <1> 	; for File Inode: (high byte)
  5038                              <1> 	;   IFREG - 1 = regular file (8000h)
  5039                              <1> 	;   IFDIR - 1 = directory (4000h)
  5040                              <1> 	;   IRSVD - 0 = reserved bit (2000h) ; Mounted flag for dirs
  5041                              <1> 	;   ILARG - large file addressing bit (1000h)
  5042                              <1> 	;   ISUID - set user id on exec (800h)
  5043                              <1> 	;   ISGID - set group id on exec (400h)
  5044                              <1> 	;   IEXTT - 1 = use extents (200h)
  5045                              <1> 	;   IREAD - read, owner (100h)
  5046                              <1> 	; for Device Inode: (high byte)
  5047                              <1> 	;   IFREG - 0 = device file (8000h)
  5048                              <1> 	;   IFBLK - 1 = block device (4000h)
  5049                              <1> 	;   IFCHR - character special (2000h) -always 1-
  5050                              <1> 	;   IFIFO - fifo special (1000h)
  5051                              <1> 	;   IPIPE - pipe special (800h) ; 07/02/2020
  5052                              <1> 	;   IREDIR - redirected (400h)  ; 07/02/2020
  5053                              <1> 	;   IEXTR - 1 = external device driver (200h)
  5054                              <1> 	;   IREAD - read, owner (100h)
  5055                              <1> 
  5056                              <1> 	;; / r1 contains the mode
  5057                              <1> 	;or 	ah, 80h	; 10000000b
  5058                              <1> 	;	; bis $100000,r1 / allocate flag set
  5059                              <1> 
  5060                              <1> 	; 14/02/2022
  5061                              <1> 	; input ->
  5062                              <1> 	;   [u.namep] points to the file name address
  5063                              <1> 	;	     (in the user's memory space)
  5064                              <1> 	;   [u.dirp] points to empty slot in the directory
  5065                              <1> 
  5066                              <1> 	; high 3 bit will be checked here
  5067                              <1> 	; 	(ref: unix v7 x86 source, iget.c)
  5068                              <1> 
  5069                              <1> ;	; 27/03/2021
  5070                              <1> ;	test	ah, 0E0h ; 80h+40h+20h
  5071                              <1> ;	jnz	short maknod0	
  5072                              <1> ;
  5073                              <1> ;	; ('syscreat' clears ILARG & IEXTT bits)
  5074                              <1> ;	;and	ah, ~0Ch ; clear ILARG & IEXTT bits
  5075                              <1> ;	;	; user can set ISUID & ISGID bits
  5076                              <1> ;
  5077                              <1> ;	or	ah, 80h ; IFREG
  5078                              <1> ;maknod0:
  5079 00004387 50                  <1> 	push	eax ; ***** ; 27/03/2021 (32 bit push, pop)
  5080                              <1> 		; mov r1,-(sp) / put mode on stack
  5081                              <1> 	; 31/07/2013
  5082                              <1> 	;mov	ax, [ii] ; move current i-number to AX/r1
  5083                              <1> 	;	; mov ii,r1 / move current i-number to r1
  5084                              <1> 	;mov	dl, 1 ; owner flag mask
  5085                              <1> 	; 15/08/2021
  5086                              <1> 	;movzx	eax, word [ii] ; move current i-number to EAX
  5087                              <1> 	; 09/01/2022
  5088 00004388 A1[1C6C0000]        <1> 	mov	eax, [ii] ; move current i-number to EAX
  5089                              <1> 	; 25/03/2021
  5090 0000438D 66BA8000            <1> 	mov	dx, 80h	; IWRITE - write,owner
  5091 00004391 E8AB080000          <1> 	call	access	
  5092                              <1> 		; jsr r0,access; 1 / get its i-node into core
  5093                              <1> 	; 15/08/2021
  5094                              <1> 	; NOTE: cpu will not return here if there is a permission error
  5095                              <1> 	;	(it will jump to 'error' address from/in 'access')
  5096                              <1> 	
  5097 00004396 50                  <1> 	push	eax ; **** (parent) ; 27/03/2021 (32 bit push, pop)
  5098                              <1> 		; mov r1,-(sp) / put i-number on stack
  5099                              <1> 	;mov	ax, 40
  5100                              <1> 	;	; mov $40.,r1 / r1 = 40
  5101                              <1> 	; 27/03/2021
  5102 00004397 31C0                <1> 	xor	eax, eax
  5103                              <1> 	;;dec	ax ; 0FFFFh
  5104                              <1> 	; 15/08/2021
  5105                              <1> 	;dec	eax ; 0FFFFFFFFh
  5106                              <1> 	; 01/04/2021
  5107                              <1> ;maknod1: ; 1: / scan for a free i-node (next 4 instructions)
  5108                              <1> 	;;inc	ax
  5109                              <1> 	;	; inc r1 / r1 = r1 + 1
  5110                              <1> 	; 15/08/2021
  5111                              <1> 	;inc	eax
  5112                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
  5113                              <1> 	; eax = 0 -> start from first free inode
  5114                              <1> 	; eax > 0 -> locate this inode on the inode map buffer
  5115                              <1> 	; NOTE:
  5116                              <1> 	; Retro UNIX 386 v2 'imap' is mostly different than v1 'imap'
  5117                              <1> 	; ('imap' will not check inode table)
  5118 00004399 E8980A0000          <1> 	call	imap
  5119                              <1> 		; jsr r0,imap / get byte address and bit position in 
  5120                              <1> 			    ; /	inode map in r2 & m
  5121                              <1> 	; 09/01/2022
  5122                              <1> 	; (cpu will not return here if there would be an eror in imap)
  5123                              <1> 	; 15/08/2021
  5124                              <1> 	;jc	short maknod_err
  5125                              <1> 
  5126                              <1> 	; DX (MQ) has a 1 in the calculated bit position
  5127                              <1>         ; eBX (R2) has byte address of the byte with allocation bit
  5128                              <1> 
  5129                              <1> 	; 06/11/2021
  5130                              <1> 	; ebp = superblock buffer address
  5131                              <1> 	; eax = inode number
  5132                              <1> 	; 10/01/2022
  5133                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
  5134                              <1> 	;		of current IMAP sector	
  5135                              <1> 
  5136                              <1> 	; 27/03/2021
  5137                              <1> 	; If cpu is here, there is not an error
  5138                              <1> 	; and EBX points to inode map buffer
  5139                              <1> 	; DL has 1 at bit position which is for free inode
  5140                              <1> 	; (E)AX = inode number
  5141                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
  5142                              <1> 	; ECX = byte offset from the (start of) inode map buffer
  5143                              <1> 
  5144                              <1> 	; 15/08/2021
  5145                              <1> maknod1:
  5146                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
  5147                              <1> 	;	       Inode count must be checked here
  5148                              <1> 	; (Original UNIX v1 did not check inode count here !?)
  5149 0000439E 8413                <1> 	test	[ebx], dl
  5150                              <1> 		; bitb mq,(r2) / is the i-node active
  5151                              <1> 	;jnz	short maknod1
  5152                              <1> 	;	; bne 1b / yes, try the next one
  5153                              <1> 	; 15/08/2021
  5154 000043A0 7408                <1> 	jz	short maknod3 ; free inode (inactive inode)
  5155                              <1> maknod2:
  5156 000043A2 40                  <1> 	inc	eax
  5157 000043A3 E8B20A0000          <1> 	call	imap_x ; next call to imap (bypass 1st call code)
  5158                              <1> 	; 10/01/2022
  5159                              <1> 	; (cpu will/would not return here 
  5160                              <1> 	;  if there is/was an error in 'imap_x')
  5161                              <1> 	;jnc	short maknod1
  5162 000043A8 EBF4                <1> 	jmp	short maknod1
  5163                              <1> 
  5164                              <1> 	; 14/02/2022
  5165                              <1> ;maknod_err:
  5166                              <1> ;	; 15/08/2021
  5167                              <1> ;	;pop	edx  ; two pops for stack alignment
  5168                              <1> ;	;pop	edx  ; (may not be needed while jumping to 'error')
  5169                              <1> ;	mov	[u.error], eax
  5170                              <1> ;	jmp	error
  5171                              <1> maknod3:
  5172                              <1> 	; 10/01/2022
  5173                              <1> 	; ebp = superblock buffer address
  5174                              <1> 	; eax = (free) inode number
  5175                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
  5176                              <1> 	;			of current IMAP sector
  5177                              <1> 	; EBX = buffer address/offset for relevant alloc byte
  5178                              <1> 	;  DL has 1 at bit position which is for free inode
  5179                              <1> 	;
  5180                              <1> 	; ECX = byte offset from the (start of) inode map buffer
  5181                              <1> 
  5182                              <1> 	;mov	[ebp+SB.LastInode], eax ; (free) inode number
  5183                              <1> 
  5184 000043AA 50                  <1> 	push	eax ; ***
  5185 000043AB 51                  <1> 	push	ecx ; **
  5186 000043AC 52                  <1> 	push	edx ; *
  5187                              <1> 	; 18/07/2022
  5188                              <1> 	;push	ebp ; @ ; 11/03/2022
  5189                              <1> 
  5190 000043AD 8B457C              <1> 	mov	eax, [ebp+SB.ImapBuffer]
  5191                              <1> 
  5192 000043B0 E821160000          <1> 	call	wslot
  5193                              <1> 	; ebx = buffer data address (write operation bit is set)
  5194                              <1> 	; eax = physical sector number
  5195                              <1> 	; Note: ebx contains addr of the 1st buffer in the buf chain
  5196                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
  5197                              <1> 
  5198                              <1> 	; 18/07/2022
  5199                              <1> 	;pop	ebp ; @ ; 11/03/2022
  5200                              <1> 
  5201                              <1> 	;mov	[ebp+SB.ImapBuffer], ebx
  5202                              <1> 			; save inode map buffer address
  5203 000043B5 5A                  <1> 	pop	edx ; *
  5204 000043B6 59                  <1> 	pop	ecx ; **
  5205 000043B7 01CB                <1> 	add	ebx, ecx ; + byte offset (for allocation bit pos)	
  5206                              <1> 
  5207                              <1> 	; set allocation bit (for this new inode) ; 10/01/2022 
  5208 000043B9 0813                <1> 	or	[ebx], dl
  5209                              <1> 		; bisb mq,(r2) / no, make it active 
  5210                              <1> 			     ; / (put a 1 in the bit map)
  5211                              <1> 	;push	ebp ; @
  5212 000043BB E823160000          <1> 	call	dskwr ; writes the 1st buffer to sector
  5213                              <1> 		      ; (at the beginning/head of the buffer chain)
  5214                              <1> 	;pop	ebp ; @
  5215                              <1> 
  5216                              <1> 	; if we are here, buffer has been written to disk successfully 
  5217                              <1> 	; (otherwise cpu would jump to 'error' address)
  5218                              <1> 
  5219                              <1> 	; set superblock modified flag
  5220 000043C0 BA[366C0000]        <1> 	mov	edx, smod
  5221 000043C5 F605[216C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
  5222 000043CC 7401                <1> 	jz	short maknod4 ; no, root device
  5223                              <1> 	; yes, mounted device
  5224                              <1> 	;mov	edx, mmod
  5225 000043CE 42                  <1> 	inc	edx ; edx = offset mmod
  5226                              <1> maknod4: 
  5227 000043CF FE02                <1> 	inc	byte [edx] ; superblock modified !
  5228                              <1> 
  5229                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  5230                              <1> 	;;
  5231                              <1> 	;; 27/03/2021
  5232                              <1> 	;; (ref: 'UNIXHDCP.ASM', 'mak_nod', 18/01/2020)
  5233                              <1> 	;or	byte [smod], 2 ; inode map modified
  5234                              <1> 	;; 01/04/2021
  5235                              <1> 	;;or	byte [imapbuf_hdr+bufhdr.status], 2
  5236                              <1> 	;or	byte [imapbuf_hdr], 2 ; set modified flag bit
  5237                              <1> 	; 02/05/2021
  5238                              <1> 	;or	byte [esi+ldrv.b_status], 2 ; inode map modified
  5239                              <1> 	; 15/08/2021
  5240                              <1> 	; 06/05/2021
  5241                              <1> 	;or	byte [esi+ldrv.status], 2 ; inode map modified
  5242                              <1> 	;;or	byte [sysbuf_hdr], 2 ; set modified flag bit
  5243                              <1> 	
  5244                              <1> 	;mov	eax, [ebp+SB.LastInode] ; (free) inode number
  5245                              <1> 	;push	eax ; ***
  5246                              <1> 
  5247                              <1> 	; 12/03/2022
  5248                              <1> 	; increase first free inode number
  5249 000043D1 8B0424              <1> 	mov	eax, [esp] ; ***
  5250 000043D4 40                  <1> 	inc	eax ; next inode number 
  5251                              <1> 		    ; (free inode search start value)
  5252 000043D5 894534              <1> 	mov	[ebp+SB.FirstFreeIno], eax
  5253                              <1> 
  5254                              <1> 	; 12/03/2022
  5255                              <1> 	; decrease free inode count
  5256 000043D8 8B5530              <1> 	mov	edx, [ebp+SB.FreeInodes]
  5257                              <1> 	;cmp	edx, 0FFFFFFFFh
  5258                              <1> 	;je	short maknod5 ; invalid
  5259 000043DB 42                  <1> 	inc	edx ; 0FFFFFFFFh -> 0
  5260 000043DC 7405                <1> 	jz	short maknod5 ; invalid
  5261 000043DE 4A                  <1> 	dec	edx
  5262 000043DF 4A                  <1> 	dec	edx
  5263 000043E0 895530              <1> 	mov	[ebp+SB.FreeInodes], edx ; -1
  5264                              <1> maknod5:
  5265 000043E3 E851170000          <1> 	call	get_system_time
  5266                              <1> 		; eax = current time (as unix epoch time)
  5267 000043E8 89455C              <1> 	mov	[ebp+SB.ModifTime], eax
  5268                              <1> 
  5269 000043EB 58                  <1> 	pop	eax ; *** ; inode number
  5270                              <1> 	;;
  5271 000043EC E866070000          <1> 	call	iget
  5272                              <1> 		; jsr r0,iget / get i-node into core
  5273                              <1> 	; 09/01/2022
  5274                              <1> 	;  (If cpu is here, there was/is not an error!)
  5275                              <1> 	; 06/11/2021
  5276                              <1> 	;jc	short maknod_err
  5277                              <1> 	
  5278                              <1> 	;test	word [i.flgs], 8000h 
  5279                              <1> 	;	; tst i.flgs / is i-node already allocated
  5280                              <1> 	;jnz	short maknod1	
  5281                              <1> 	;	; blt 1b / yes, look for another one
  5282                              <1> 	; 27/03/2021
  5283                              <1> 	; (Retro UNIX 386 v2 inode flags) 
  5284 000043F1 F605[C5670000]E0    <1> 	test	byte [i.flgs+1], 0E0h ; 80h+40h+20h
  5285                              <1> 	;jnz	short maknod1 ; i-node already allocated
  5286                              <1> 	;		      ; (as it is in inode table)
  5287                              <1> 	; 15/08/2021
  5288 000043F8 75A8                <1> 	jnz	short maknod2 ; defective inode map !?
  5289                              <1> 
  5290                              <1> 	; AX = free inode number
  5291 000043FA 66A3[7C6C0000]      <1> 	mov	[u.dirbuf], ax
  5292                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
  5293 00004400 58                  <1> 	pop	eax ; **** (parent) ; 27/03/2021 (32 bit push, pop)
  5294                              <1> 		; mov (sp)+,r1 / get current i-number back
  5295 00004401 E851070000          <1> 	call	iget
  5296                              <1> 		; jsr r0,iget / get i-node in core
  5297                              <1> 	; 09/01/2022
  5298                              <1> 	; 06/11/2021
  5299                              <1> 	;jc	short maknod_err
  5300                              <1> 
  5301                              <1> 	; 14/02/2022
  5302                              <1> 	; here..
  5303                              <1> 	;  [u.namep] points to the file name address
  5304                              <1> 	;	     (in the user's memory space)
  5305                              <1> 	;  [u.dirp] points to empty slot in the directory
  5306                              <1> 
  5307 00004406 E81CF7FFFF          <1> 	call	mkdir
  5308                              <1> 		; jsr r0,mkdir / make a directory entry 
  5309                              <1> 			     ; / in current directory
  5310                              <1> 	; 09/01/2022
  5311                              <1> 	;  (If cpu is here, there was/is not an error in 'mkdir'!)
  5312                              <1> 	; 06/11/2021
  5313                              <1> 	;jc	short maknod_err
  5314                              <1> 	
  5315                              <1> 	; (eax = 0)
  5316                              <1> 	;movzx	eax, [u.difbuf] ; 06/11/2021
  5317 0000440B 66A1[7C6C0000]      <1> 	mov	ax, [u.dirbuf]
  5318                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
  5319 00004411 E841070000          <1> 	call	iget
  5320                              <1> 		; jsr r0,iget / get it into core
  5321                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
  5322                              <1> 	; 09/01/2022
  5323                              <1> 	; 06/11/2021
  5324                              <1> 	;jc	short maknod_err
  5325                              <1> 
  5326                              <1> 	;mov	ecx, 8
  5327                              <1> 	; 27/03/2021
  5328 00004416 31C9                <1> 	xor	ecx, ecx 
  5329 00004418 B110                <1> 	mov	cl, 16 ; 64 bit inodes
  5330 0000441A 31C0                <1> 	xor	eax, eax ; 0
  5331 0000441C BF[C4670000]        <1> 	mov	edi, inode 
  5332 00004421 F3AB                <1> 	rep	stosd
  5333                              <1> 	;
  5334                              <1> 	;pop	word [i.flgs]
  5335                              <1> 	;	; mov (sp)+,i.flgs / fill flags
  5336                              <1> 	; 27/03/2021 (32 bit push, pop)
  5337 00004423 58                  <1> 	pop	eax ; *****
  5338 00004424 66A3[C4670000]      <1> 	mov	[i.flgs], ax
  5339                              <1> 
  5340                              <1> 	;mov 	cl, [u.uid] ; 02/08/2013
  5341                              <1> 	;mov 	[i.uid], cl
  5342                              <1> 	;	; movb u.uid,i.uid / user id
  5343                              <1> 	; 15/08/2021
  5344                              <1> 	; 27/03/2021
  5345 0000442A 8A0D[9A6C0000]      <1> 	mov	cl, [u.gid] ; 8 bit group ID ; 15/08/2021
  5346 00004430 880D[CA670000]      <1> 	mov	[i.gid], cl 	
  5347 00004436 668B0D[966C0000]    <1> 	mov	cx, [u.uid] ; 16 bit user ID
  5348 0000443D 66890D[C8670000]    <1> 	mov	[i.uid], cx	
  5349                              <1> 
  5350 00004444 C605[C6670000]01    <1> 	mov     byte [i.nlks], 1
  5351                              <1> 		; movb $1,i.nlks / 1 link
  5352                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
  5353                              <1> 	;mov	eax, [s.time]
  5354                              <1> 	;mov 	[i.ctim], eax
  5355                              <1> 	 	; mov s.time,i.ctim / time created
  5356                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
  5357                              <1> 	; Retro UNIX 8086 v1 modification !
  5358                              <1> 	; i.ctime=0, i.ctime+2=0 and
  5359                              <1>         ; 'setimod' will set ctime of file via 'epoch'
  5360                              <1> 	;call	setimod
  5361                              <1> 	;	; jsr r0,setimod / set modified flag
  5362                              <1> 	;retn
  5363                              <1> 	;	; rts r0 / return
  5364                              <1> 	; 27/03/2021
  5365 0000444B E998080000          <1> 	jmp	setimod
  5366                              <1> 
  5367                              <1> sysseek: ; / moves read write pointer in an fsp entry
  5368                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5369                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  5370                              <1> 	;
  5371                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
  5372                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
  5373                              <1> 	; The file descriptor refers to a file open for reading or
  5374                              <1> 	; writing. The read (or write) pointer is set as follows:
  5375                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
  5376                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
  5377                              <1> 	;	  current location plus offset.
  5378                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
  5379                              <1> 	;	  size of file plus offset.
  5380                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
  5381                              <1> 	;
  5382                              <1> 	; Calling sequence:
  5383                              <1> 	;	sysseek; offset; ptrname
  5384                              <1> 	; Arguments:
  5385                              <1> 	;	offset - number of bytes desired to move 
  5386                              <1> 	;		 the r/w pointer
  5387                              <1> 	;	ptrname - a switch indicated above
  5388                              <1> 	;
  5389                              <1> 	; Inputs: r0 - file descriptor 
  5390                              <1> 	; Outputs: -
  5391                              <1> 	; ...............................................................
  5392                              <1> 	;	
  5393                              <1> 	; Retro UNIX 8086 v1 modification: 
  5394                              <1> 	;       'sysseek' system call has three arguments; so,
  5395                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
  5396                              <1> 	;	* 2nd argument, offset is in CX register
  5397                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
  5398                              <1> 	;	
  5399                              <1> 
  5400 00004450 E820000000          <1> 	call	seektell
  5401                              <1> 	; AX = u.count
  5402                              <1> 	; BX = *u.fofp
  5403                              <1> 		; jsr r0,seektell / get proper value in u.count
  5404                              <1> 		; add u.base,u.count / add u.base to it
  5405 00004455 0305[686C0000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
  5406 0000445B 8903                <1> 	mov	[ebx], eax
  5407                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
  5408 0000445D E905EDFFFF          <1> 	jmp	sysret
  5409                              <1> 		; br sysret4
  5410                              <1> 
  5411                              <1> systell: ; / get the r/w pointer
  5412                              <1> 	; 01/03/2022
  5413                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  5414                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5415                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  5416                              <1> 	;
  5417                              <1> 	; Retro UNIX 8086 v1 modification:
  5418                              <1> 	; ! 'systell' does not work in original UNIX v1,
  5419                              <1> 	; 	    it returns with error !
  5420                              <1> 	; Inputs: r0 - file descriptor 
  5421                              <1> 	; Outputs: r0 - file r/w pointer
  5422                              <1> 
  5423                              <1> 	;xor	ecx, ecx ; 0
  5424                              <1> 	;mov	edx, 1 ; 05/08/2013
  5425                              <1> 	; 09/01/2022
  5426 00004462 29D2                <1> 	sub	edx, edx
  5427 00004464 FEC2                <1> 	inc	dl
  5428                              <1> 	; edx = 1
  5429                              <1> 	;call 	seektell
  5430 00004466 E810000000          <1> 	call 	seektell0 ; 05/08/2013
  5431                              <1> 	;mov	ebx, [u.fofp]
  5432                              <1> 	; 01/03/2022
  5433                              <1> 	;mov	eax, [ebx]
  5434 0000446B A3[446C0000]        <1> 	mov	[u.r0], eax
  5435 00004470 E9F2ECFFFF          <1> 	jmp	sysret
  5436                              <1> 
  5437                              <1> ; Original unix v1 'systell' system call:
  5438                              <1> 		; jsr r0,seektell
  5439                              <1> 		; br error4
  5440                              <1> 
  5441                              <1> seektell:
  5442                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  5443                              <1> 	; 06/11/2021
  5444                              <1> 	; 12/06/2021
  5445                              <1> 	; 06/05/2021 (Retro UNIX 386 v2)
  5446                              <1> 	; 03/01/2016
  5447                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5448                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  5449                              <1> 	;
  5450                              <1> 	; 'seektell' puts the arguments from sysseek and systell
  5451                              <1> 	; call in u.base and u.count. It then gets the i-number of
  5452                              <1> 	; the file from the file descriptor in u.r0 and by calling
  5453                              <1> 	; getf. The i-node is brought into core and then u.count
  5454                              <1> 	; is checked to see it is a 0, 1, or 2.
  5455                              <1> 	; If it is 0 - u.count stays the same
  5456                              <1> 	;          1 - u.count = offset (u.fofp)
  5457                              <1> 	;	   2 - u.count = i.size (size of file)
  5458                              <1> 	; 	 		
  5459                              <1> 	; !! Retro UNIX 8086 v1 modification:
  5460                              <1> 	;	Argument 1, file descriptor is in BX;
  5461                              <1> 	;	Argument 2, offset is in CX;
  5462                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
  5463                              <1> 	;
  5464                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
  5465                              <1> 	; call 	arg
  5466                              <1> 	;
  5467                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
  5468                              <1> 	;
  5469 00004475 890D[686C0000]      <1> 	mov 	[u.base], ecx ; offset
  5470                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
  5471                              <1> 	; 09/01/2022
  5472                              <1> 	; ebx = file descriptor (0 to 9)
  5473                              <1> seektell0:
  5474 0000447B 8915[6C6C0000]      <1> 	mov 	[u.count], edx
  5475                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
  5476                              <1> 	;mov	ax, bx
  5477                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
  5478                              <1> 			     ; / (index in u.fp list)
  5479                              <1> 	; 12/06/2021
  5480                              <1> 	; BX = file descriptor (file number)
  5481 00004481 E8A2FBFFFF          <1> 	call	getf
  5482                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
  5483                              <1> 	; 09/01/2022
  5484 00004486 09C0                <1> 	or	eax, eax
  5485                              <1> 	;or	ax, ax ; i-number of the file
  5486                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
  5487                              <1> 		             ; / put it on the stack
  5488                              <1> 	;jz	error
  5489                              <1> 		; beq error4 / if i-number is 0, not active so error
  5490 00004488 750F                <1> 	jnz	short seektell1
  5491 0000448A C705[B86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  5491 00004492 0000                <1>
  5492 00004494 E9AEECFFFF          <1> 	jmp	error
  5493                              <1> seektell1:
  5494                              <1> 	; 06/05/2021
  5495                              <1> 	;push	eax
  5496                              <1> 	;cmp	ah, 80h
  5497                              <1> 	;jb	short seektell2
  5498                              <1> 	;	; bgt .+4 / if its positive jump
  5499                              <1> 	;neg	ax
  5500                              <1> 	;	; neg r1 / if not make it positive
  5501                              <1> seektell2:
  5502 00004499 E8B9060000          <1> 	call	iget
  5503                              <1> 		; jsr r0,iget / get its i-node into core
  5504                              <1> 	; 09/01/2022
  5505                              <1> 	; (if there is/was an error in 'iget', cpu will not come here)
  5506                              <1> 	;; 06/11/2021
  5507                              <1> 	;jnc	short seektell6
  5508                              <1> 	;mov	[u.error], eax
  5509                              <1> 	;jmp	error
  5510                              <1> seektell6:
  5511 0000449E 8B1D[586C0000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
  5512 000044A4 803D[6C6C0000]01    <1> 	cmp	byte [u.count], 1
  5513                              <1> 		; cmp u.count,$1 / is ptr name =1
  5514 000044AB 7705                <1> 	ja	short seektell3
  5515                              <1> 		; blt 2f / no its zero
  5516 000044AD 7409                <1> 	je	short seektell4
  5517                              <1> 		; beq 1f / yes its 1
  5518 000044AF 31C0                <1> 	xor	eax, eax
  5519                              <1> 	;jmp	short seektell5
  5520 000044B1 C3                  <1> 	retn
  5521                              <1> seektell3:
  5522                              <1> 	; 03/01/2016
  5523                              <1> 	;;movzx	eax, word [i.size]
  5524                              <1> 	;mov   	ax, [i.size]
  5525                              <1> 	;	; mov i.size,u.count /  put number of bytes 
  5526                              <1> 	;			; / in file in u.count
  5527                              <1> 	;;jmp	short seektell5
  5528                              <1> 	;	; br 2f
  5529                              <1> 	; 06/05/2021 - Retro UNIX 386 v2
  5530 000044B2 A1[CC670000]        <1> 	mov	eax, [i.size]
  5531 000044B7 C3                  <1> 	retn
  5532                              <1> seektell4: ; 1: / ptrname =1
  5533                              <1> 	;mov	ebx, [u.fofp]
  5534 000044B8 8B03                <1> 	mov	eax, [ebx]
  5535                              <1> 		; mov *u.fofp,u.count / put offset in u.count
  5536                              <1> ;seektell5: ; 2: / ptrname =0
  5537                              <1> 	;mov	[u.count], eax
  5538                              <1> 	;pop	eax 
  5539                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
  5540 000044BA C3                  <1> 	retn
  5541                              <1> 		; rts r0
  5542                              <1> 
  5543                              <1> sysintr: ; / set interrupt handling
  5544                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5545                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  5546                              <1> 	;
  5547                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
  5548                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
  5549                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
  5550                              <1> 	; If one does the interrupt character in the tty buffer is
  5551                              <1> 	; cleared and 'sysret'is called. If one does not exits
  5552                              <1> 	; 'sysret' is just called.	
  5553                              <1> 	;
  5554                              <1> 	; Calling sequence:
  5555                              <1> 	;	sysintr; arg
  5556                              <1> 	; Argument:
  5557                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
  5558                              <1> 	;	    - if 1, intterupts cause their normal result
  5559                              <1> 	;		 i.e force an exit.
  5560                              <1> 	;	    - if arg is a location within the program,
  5561                              <1> 	;		control is passed to that location when
  5562                              <1> 	;		an interrupt occurs.	
  5563                              <1> 	; Inputs: -
  5564                              <1> 	; Outputs: -
  5565                              <1> 	; ...............................................................
  5566                              <1> 	;	
  5567                              <1> 	; Retro UNIX 8086 v1 modification: 
  5568                              <1> 	;       'sysintr' system call sets u.intr to value of BX
  5569                              <1> 	;	then branches into sysquit.
  5570                              <1> 	;
  5571 000044BB 66891D[906C0000]    <1> 	mov	[u.intr], bx
  5572                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
  5573                              <1> 		; br 1f / go into quit routine
  5574 000044C2 E9A0ECFFFF          <1> 	jmp	sysret
  5575                              <1> 
  5576                              <1> sysquit:
  5577                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5578                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  5579                              <1> 	;
  5580                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
  5581                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
  5582                              <1> 	; tty exists. If one does the interrupt character in the tty
  5583                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
  5584                              <1> 	; 'sysret' is just called.	
  5585                              <1> 	;
  5586                              <1> 	; Calling sequence:
  5587                              <1> 	;	sysquit; arg
  5588                              <1> 	; Argument:
  5589                              <1> 	;	arg - if 0, this call disables quit signals from the
  5590                              <1> 	;		typewriter (ASCII FS)
  5591                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
  5592                              <1> 	;		cease and a core image to be produced.
  5593                              <1> 	;		 i.e force an exit.
  5594                              <1> 	;	    - if arg is an address in the program,
  5595                              <1> 	;		a quit causes control to sent to that
  5596                              <1> 	;		location.	
  5597                              <1> 	; Inputs: -
  5598                              <1> 	; Outputs: -
  5599                              <1> 	; ...............................................................
  5600                              <1> 	;	
  5601                              <1> 	; Retro UNIX 8086 v1 modification: 
  5602                              <1> 	;       'sysquit' system call sets u.quit to value of BX
  5603                              <1> 	;	then branches into 'sysret'.
  5604                              <1> 	;
  5605 000044C7 66891D[926C0000]    <1> 	mov	[u.quit], bx
  5606 000044CE E994ECFFFF          <1> 	jmp	sysret
  5607                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
  5608                              <1> 	;1:
  5609                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
  5610                              <1> 			      ; / to r1
  5611                              <1> 		; beq sysret4 / return to user
  5612                              <1> 		; clrb 6(r1) / clear the interrupt character 
  5613                              <1> 			   ; / in the tty buffer
  5614                              <1> 		; br sysret4 / return to user
  5615                              <1> 
  5616                              <1> syssetuid: ; / set process id
  5617                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
  5618                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
  5619                              <1> 	;		(16 bit uid)
  5620                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5621                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  5622                              <1> 	;
  5623                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
  5624                              <1> 	; to the process id in (u.r0). Both the effective user u.uid
  5625                              <1> 	; and the real user u.ruid are set to this. 
  5626                              <1> 	; Only the super user can make this call.	
  5627                              <1> 	;
  5628                              <1> 	; Calling sequence:
  5629                              <1> 	;	syssetuid
  5630                              <1> 	; Arguments: -
  5631                              <1> 	;
  5632                              <1> 	; Inputs: (u.r0) - contains the process id.
  5633                              <1> 	; Outputs: -
  5634                              <1> 	; ...............................................................
  5635                              <1> 	;	
  5636                              <1> 	; Retro UNIX 8086 v1 modification: 
  5637                              <1> 	;       BL contains the (new) user ID of the current process
  5638                              <1> 
  5639                              <1> 	; 27/03/2021
  5640                              <1> 	; INPUT:
  5641                              <1> 	;    BX = (new) user ID
  5642                              <1> 
  5643                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
  5644                              <1> 	;cmp	bl, [u.ruid] 
  5645                              <1> 	;	; cmpb r1,u.ruid / is it equal to the real user 
  5646                              <1> 			       ; / id number
  5647                              <1> 	; 27/03/2021
  5648 000044D3 663B1D[986C0000]    <1> 	cmp	bx, [u.ruid]
  5649 000044DA 7420                <1> 	je	short setuid1
  5650                              <1> 		; beq 1f / yes
  5651                              <1> 	;cmp	byte [u.uid], 0 ; 02/08/2013
  5652                              <1> 	;	; tstb u.uid / no, is current user the super user?
  5653                              <1> 	;;ja	error
  5654                              <1> 	;	; bne error4 / no, error
  5655                              <1> 	; 27/03/2021
  5656 000044DC 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0 
  5657 000044E4 760F                <1> 	jna	short setuid0
  5658                              <1> setuid_err:
  5659                              <1> setgid_err:
  5660 000044E6 C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
  5660 000044EE 0000                <1>
  5661                              <1> 				; 'permission denied !' error
  5662 000044F0 E952ECFFFF          <1> 	jmp	error
  5663                              <1> setuid0:
  5664                              <1> 	;mov	[u.ruid], bl
  5665                              <1> 	; 27/03/2021
  5666 000044F5 66891D[986C0000]    <1> 	mov	[u.ruid], bx
  5667                              <1> setuid1: ; 1:
  5668                              <1> 	;mov	[u.uid], bl ; 02/08/2013
  5669                              <1> 	;	; movb r1,u.uid / put process id in u.uid
  5670                              <1> 	;	; movb r1,u.ruid / put process id in u.ruid
  5671                              <1> 	; 27/03/2021
  5672 000044FC 66891D[966C0000]    <1> 	mov	[u.uid], bx
  5673 00004503 E95FECFFFF          <1> 	jmp	sysret
  5674                              <1> 		; br sysret4 / system return
  5675                              <1> 
  5676                              <1> sysgetuid: ; < get user id >
  5677                              <1> 	; 11/03/2022
  5678                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
  5679                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
  5680                              <1> 	;		(16 bit uid)
  5681                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5682                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  5683                              <1> 	;
  5684                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
  5685                              <1> 	; The real user ID identifies the person who is logged in,
  5686                              <1> 	; in contradistinction to the effective user ID, which
  5687                              <1> 	; determines his access permission at each moment. It is thus
  5688                              <1> 	; useful to programs which operate using the 'set user ID'
  5689                              <1> 	; mode, to find out who invoked them.	
  5690                              <1> 	;
  5691                              <1> 	; Calling sequence:
  5692                              <1> 	;	syssetuid
  5693                              <1> 	; Arguments: -
  5694                              <1> 	;
  5695                              <1> 	; Inputs: -
  5696                              <1> 	; Outputs: (u.r0) - contains the real user's id.
  5697                              <1> 	; ...............................................................
  5698                              <1> 	;	
  5699                              <1> 	; Retro UNIX 8086 v1 modification: 
  5700                              <1> 	;       AL contains the real user ID at return.
  5701                              <1> 	;
  5702                              <1> 	; 11/03/2022 - Retro UNIX 386 v1.2
  5703                              <1> 	; Input:
  5704                              <1> 	;	none
  5705                              <1> 	; Output/Return:
  5706                              <1> 	;	AX = real user ID
  5707                              <1> 	;	Hig Word of EAX = effective user ID
  5708                              <1> 
  5709                              <1> 	;;movzx eax, byte [u.ruid]
  5710                              <1> 	; 27/03/2021
  5711                              <1> 	;movzx	eax, word [u.ruid]
  5712                              <1> 	; 11/03/2022
  5713                              <1> 	; (return u.uid & u.ruid numbers as it is in unix v5-v7)
  5714 00004508 66A1[966C0000]      <1> 	mov	ax, [u.uid]
  5715 0000450E C1E010              <1> 	shl	eax, 16	; efective user ID in high word of eax
  5716                              <1> 	; 09/01/2022
  5717 00004511 66A1[986C0000]      <1> 	mov	ax, [u.ruid] ; real user ID in low word of eax
  5718 00004517 A3[446C0000]        <1> 	mov	[u.r0], eax 
  5719                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
  5720 0000451C E946ECFFFF          <1> 	jmp	sysret
  5721                              <1> 		; br sysret4 / systerm return, sysret
  5722                              <1> 
  5723                              <1> syssetgid: ; set group id
  5724                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
  5725                              <1> 	; 02/04/2021
  5726                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
  5727                              <1> 	;
  5728                              <1> 	; 'syssetgid' sets the user's group id (u.gid) 
  5729                              <1> 	;  of the current process to the process id in (u.r0).
  5730                              <1> 	;  Both the effective user u.gid and the real user
  5731                              <1> 	;  u.rgid are set to this. 
  5732                              <1> 	;  Only the super user can make this call.	
  5733                              <1> 	
  5734                              <1> 	; INPUT:
  5735                              <1> 	;	BL = (new) group ID
  5736                              <1> 	; OUTPUT:
  5737                              <1> 	;	-
  5738                              <1> 
  5739 00004521 3A1D[9B6C0000]      <1> 	cmp	bl, [u.rgid] 
  5740 00004527 7410                <1> 	je	short setgid1
  5741                              <1> 
  5742                              <1> 	;cmp	byte [u.uid], 0
  5743                              <1> 	; 02/04/2021
  5744 00004529 66833D[966C0000]00  <1> 	cmp	word [u.uid], 0
  5745 00004531 77B3                <1> 	ja	short setgid_err
  5746                              <1> setgid0:
  5747 00004533 881D[9B6C0000]      <1> 	mov	[u.rgid], bl
  5748                              <1> setgid1: ; 1:
  5749 00004539 881D[9A6C0000]      <1> 	mov	[u.gid], bl
  5750 0000453F E923ECFFFF          <1> 	jmp	sysret
  5751                              <1> 
  5752                              <1> sysgetgid: ; < get group id >
  5753                              <1> 	; 11/03/2022
  5754                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
  5755                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
  5756                              <1> 	;
  5757                              <1> 	; 'sysgetgid' returns the real group ID of the current process.
  5758                              <1> 	; The real group ID identifies the group of the person
  5759                              <1> 	; who is logged in, in contradistinction to the effective
  5760                              <1> 	; group ID, which determines his access permission at each moment.
  5761                              <1> 	; It is thus useful to programs which operate using
  5762                              <1> 	; the 'set group ID' mode, to find out the group of the user
  5763                              <1> 	; who invoked them.
  5764                              <1> 
  5765                              <1> 	; 11/03/2022 - Retro UNIX 386 v1.2
  5766                              <1> 	; Input:
  5767                              <1> 	;	none
  5768                              <1> 	; Output/Return:
  5769                              <1> 	;	AL = real group ID
  5770                              <1> 	;	AH = effective group ID
  5771                              <1> 
  5772                              <1> 	;movzx	eax, word [u.ruid]
  5773                              <1> 	;; 09/01/2022
  5774                              <1> 	;mov	ax, [u.ruid]
  5775                              <1> 	; 11/03/2022
  5776                              <1> 	; (return u.gid & u.rgid numbers as it is in unix v5-v7)
  5777 00004544 8A25[9A6C0000]      <1> 	mov	ah, [u.gid] ; efective group ID in byte 1
  5778 0000454A A0[9B6C0000]        <1> 	mov	al, [u.rgid] ; real group ID in byte 0
  5779 0000454F A3[446C0000]        <1> 	mov	[u.r0], eax
  5780 00004554 E90EECFFFF          <1> 	jmp	sysret
  5781                              <1> 
  5782                              <1> sysver: ; get operating system version
  5783                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
  5784                              <1> 	; 18/06/2021 - Retro UNIX 386 v2
  5785                              <1> 
  5786                              <1> 	;VMAJOR equ 2 ; Retro UNIX 386 v2
  5787                              <1> 	;VMINOR equ 0 ; Retro UNIX 386 v2.0 (v2.0.0)
  5788                              <1> 	;CURRENT_VERSION equ (VMAJOR*256)+VMINOR
  5789                              <1> 
  5790                              <1> 	; 09/01/2022
  5791                              <1> 	VMAJOR equ 1 ; Retro UNIX 386 v1
  5792                              <1> 	VMINOR equ 2 ; Retro UNIX 386 v1.2 (v1.2.0)
  5793                              <1> 	CURRENT_VERSION equ (VMAJOR*256)+VMINOR 		  
  5794                              <1> 
  5795                              <1> 	; 29/04/2016 - TRDOS 386 v2.0
  5796                              <1> 	;mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
  5797                              <1> 	; 18/06/2021
  5798 00004559 C705[446C0000]0201- <1> 	mov	dword [u.r0], CURRENT_VERSION ;	(ah = 2, al = 0)
  5798 00004561 0000                <1>
  5799 00004563 E9FFEBFFFF          <1> 	jmp	sysret
  5800                              <1> 
  5801                              <1> anyi: 
  5802                              <1> 	; 18/07/2022
  5803                              <1> 	; 26/03/2022
  5804                              <1> 	; 13/03/2022
  5805                              <1> 	; 12/03/2022
  5806                              <1> 	; 09/01/2022
  5807                              <1> 	; 02/01/2022
  5808                              <1> 	; 01/01/2022
  5809                              <1> 	; 27/12/2021 (Retro UNIX 386 v1.2)
  5810                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  5811                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5812                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
  5813                              <1> 	;
  5814                              <1> 	; 'anyi' is called if a file deleted while open.
  5815                              <1> 	; "anyi" checks to see if someone else has opened this file.
  5816                              <1> 	;
  5817                              <1> 	; INPUTS ->
  5818                              <1> 	;    r1 - contains an i-number
  5819                              <1> 	;    fsp - start of table containing open files
  5820                              <1> 	;
  5821                              <1> 	; OUTPUTS ->
  5822                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
  5823                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
  5824                              <1> 	;    if file not found - bit in i-node map is cleared
  5825                              <1> 	;    			 (i-node is freed)
  5826                              <1> 	;               all blocks related to i-node are freed
  5827                              <1> 	;	        all flags in i-node are cleared
  5828                              <1> 	; ((AX = R1)) input
  5829                              <1> 	;
  5830                              <1> 	;    (Retro UNIX Prototype: 02/12/2012, UNIXCOPY.ASM)
  5831                              <1> 	;	12/03/2022
  5832                              <1>         ;    ((Modified registers: eax, edx, ecx, ebx, esi, edi, ebp))  
  5833                              <1> 	;
  5834                              <1> 		; / r1 contains an i-number
  5835 00004568 BB[B4680000]        <1> 	mov	ebx, fsp
  5836                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
  5837                              <1> anyi_1: ; 1:
  5838                              <1> 	;cmp	eax, [ebx] ; 09/01/2022 (32 bit inode number)
  5839 0000456D 663B03              <1> 	cmp	ax, [ebx]
  5840                              <1> 		; cmp r1,(r2) / do i-numbers match?
  5841                              <1> 	;je	short anyi_3
  5842                              <1> 		; beq 1f / yes, 1f
  5843                              <1> 	; 12/03/2022
  5844 00004570 7505                <1> 	jne	short anyi_0		
  5845                              <1> 
  5846                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
  5847                              <1> 	;neg	ax
  5848                              <1> 	;	; neg r1 / no complement r1
  5849                              <1> 	;cmp	ax, [ebx]
  5850                              <1> 	;	; cmp r1,(r2) / do they match now?
  5851                              <1> 	;;je	short anyi_3
  5852                              <1> 		; beq 1f / yes, transfer
  5853                              <1> 		; / i-numbers do not match
  5854                              <1> 	; 12/03/2022
  5855                              <1> 	;jne	short ayni_0
  5856                              <1> 
  5857                              <1> anyi_3: ; 1: / i-numbers match
  5858                              <1> 	; 13/03/2022 (BugFix)
  5859                              <1> 	;; 09/01/2022
  5860                              <1> 	;test	byte [ebx+5], 1 ; open for writing flag
  5861                              <1> 	;jz	short anyi_0	
  5862                              <1> 
  5863                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
  5864 00004572 804B0580            <1> 	or	byte [ebx+5], 80h ; set deleted file flag (bit 7)
  5865                              <1> 	; 22/06/2015
  5866                              <1> 	;inc 	byte [ebx+9]
  5867                              <1> 		; incb 7(r2) / increment upper byte of the 4th word
  5868                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
  5869 00004576 C3                  <1> 	retn
  5870                              <1> 		; rts r0
  5871                              <1> anyi_0:
  5872                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
  5873                              <1> 	;add	ebx, fp.size ; runix v2 fsp table size is 16 bytes
  5874                              <1> 	; 01/01/2022
  5875 00004577 83C310              <1> 	add	ebx, 16 ; runix v2 fsp table size is 16 bytes
  5876                              <1> 	;;add	ebx, 10 ; fsp table size is 10 bytes
  5877                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
  5878                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
  5879                              <1> 	; 22/11/2021
  5880                              <1> 	;cmp	ebx, fsp + (NFILES*fp.size) ; fsp+(NFILES*16)
  5881                              <1> 	; 02/01/2022
  5882 0000457A 81FB[D46B0000]      <1> 	cmp	ebx, fsp + (nfiles*16)
  5883                              <1> 	; 01/01/2022
  5884                              <1> 	;cmp	ebx, fsp + (NFILES*16) ; fsp+(NFILES*fp.size)
  5885                              <1> 	;;cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
  5886                              <1> 		; cmp r2,$fsp+[nfiles*8] 
  5887                              <1> 			; / are we at last entry in the table
  5888 00004580 72EB                <1> 	jb	short anyi_1
  5889                              <1> 		; blt 1b / no, check next entries i-number
  5890                              <1> 
  5891                              <1> 	; 27/12/2021
  5892                              <1> 	;;cmp	ax, 32768
  5893                              <1> 	;cmp	ah, 80h ; negative number check
  5894                              <1> 	;	; tst r1 / yes, no match
  5895                              <1> 	;	; bge .+4
  5896                              <1> 	;jb	short anyi_2
  5897                              <1> 	;neg	ax
  5898                              <1> 	;	; neg r1 / make i-number positive
  5899                              <1> ;anyi_2:	
  5900                              <1> 	; 12/03/2022
  5901                              <1> 	;push	eax ; **** ; inode number
  5902                              <1> 	;
  5903 00004582 E8AF080000          <1> 	call	imap
  5904                              <1> 		; jsr r0,imap / get address of allocation bit 
  5905                              <1> 			    ; / in the i-map in r2
  5906                              <1> 
  5907                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
  5908                              <1>         ;; EBX (R2) has address of the byte with allocation bit
  5909                              <1> 
  5910                              <1> 	; 12/03/2022
  5911                              <1> 	; (at return of imap)
  5912                              <1> 	; ebp = superblock buffer address
  5913                              <1> 	; eax = inode number
  5914                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
  5915                              <1> 	;			of current IMAP sector
  5916                              <1> 	; EBX = buffer address/offset for relevant alloc byte
  5917                              <1> 	;  DL has 1 at bit position which is for free inode
  5918                              <1> 	;
  5919                              <1> 	; ECX = byte offset from the (start of) inode map buffer
  5920                              <1> 
  5921                              <1>  	;;not	dx
  5922                              <1> 	;not 	dl ; 0 at calculated bit position, other bits are 1
  5923                              <1>         ;;and	[ebx], dx
  5924                              <1> 	;and 	[ebx], dl 
  5925                              <1> 	;	; bicb mq,(r2) / clear bit for i-node in the imap
  5926                              <1> 
  5927                              <1> 	; 12/03/2022 ; (*)
  5928                              <1> 
  5929                              <1> 	;mov	[ebp+SB.LastInode], eax ; (free) inode number
  5930                              <1> 
  5931 00004587 50                  <1> 	push	eax ; ***
  5932 00004588 51                  <1> 	push	ecx ; **
  5933 00004589 52                  <1> 	push	edx ; *
  5934                              <1> 
  5935                              <1> 	; 18/07/2022
  5936                              <1> 	;push	ebp ; @ ; 11/03/2022
  5937                              <1> 
  5938 0000458A 8B457C              <1> 	mov	eax, [ebp+SB.ImapBuffer]
  5939                              <1> 
  5940 0000458D E844140000          <1> 	call	wslot
  5941                              <1> 	; ebx = buffer data address (write operation bit is set)
  5942                              <1> 	; eax = physical sector number
  5943                              <1> 	; Note: ebx contains addr of the 1st buffer in the buf chain
  5944                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
  5945                              <1> 
  5946                              <1> 	; 18/07/2022
  5947                              <1> 	;pop	ebp ; @ ; 11/03/2022
  5948                              <1> 
  5949                              <1> 	;mov	[ebp+SB.ImapBuffer], ebx
  5950                              <1> 			; save inode map buffer address
  5951 00004592 5A                  <1> 	pop	edx ; *
  5952 00004593 59                  <1> 	pop	ecx ; **
  5953 00004594 01CB                <1> 	add	ebx, ecx ; + byte offset (for allocation bit pos)	
  5954                              <1> 
  5955                              <1> 	;not	dx
  5956 00004596 F6D2                <1> 	not 	dl ; 0 at calculated bit position, other bits are 1
  5957                              <1>         ;and	[ebx], dx
  5958 00004598 2013                <1> 	and 	[ebx], dl 
  5959                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
  5960                              <1> 
  5961                              <1> 	;push	ebp ; @
  5962 0000459A E844140000          <1> 	call	dskwr ; writes the 1st buffer to sector
  5963                              <1> 		      ; (at the beginning/head of the buffer chain)
  5964                              <1> 	;pop	ebp ; @
  5965                              <1> 
  5966                              <1> 	; if we are here, buffer has been written to disk successfully 
  5967                              <1> 	; (otherwise cpu would jump to 'error' address)
  5968                              <1> 
  5969                              <1> 	; 12/03/2022 ; (*)
  5970                              <1> 	; set superblock modified flag
  5971 0000459F BA[366C0000]        <1> 	mov	edx, smod
  5972 000045A4 F605[216C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
  5973 000045AB 7401                <1> 	jz	short anyi_2 ; no, root device
  5974                              <1> 	; yes, mounted device
  5975 000045AD 42                  <1> 	inc	edx ; edx = offset mmod
  5976                              <1> anyi_2:
  5977 000045AE FE02                <1> 	inc	byte [edx] ; superblock modified !
  5978                              <1> 
  5979                              <1> 	; 12/03/2022
  5980                              <1> 	; decrease first free inode number (if it is required)
  5981 000045B0 8B0424              <1> 	mov	eax, [esp] ; ***
  5982                              <1> 	; eax = released/freed inode number 
  5983 000045B3 394534              <1> 	cmp	[ebp+SB.FirstFreeIno], eax
  5984 000045B6 7603                <1> 	jna	short anyi_4
  5985 000045B8 894534              <1> 	mov	[ebp+SB.FirstFreeIno], eax
  5986                              <1> 		    ; (free inode search start value)
  5987                              <1> anyi_4:
  5988                              <1> 	; 12/03/2022
  5989                              <1> 	; increase free inode count
  5990 000045BB 8B5530              <1> 	mov	edx, [ebp+SB.FreeInodes]
  5991                              <1> 	;cmp	edx, 0FFFFFFFFh
  5992                              <1> 	;je	short anyi_5 ; invalid
  5993 000045BE 42                  <1> 	inc	edx ; 0FFFFFFFFh -> 0
  5994 000045BF 7403                <1> 	jz	short anyi_5 ; invalid
  5995 000045C1 895530              <1> 	mov	[ebp+SB.FreeInodes], edx ; +1
  5996                              <1> anyi_5:
  5997 000045C4 E870150000          <1> 	call	get_system_time
  5998                              <1> 		; eax = current time (as unix epoch time)
  5999 000045C9 89455C              <1> 	mov	[ebp+SB.ModifTime], eax
  6000                              <1> 
  6001 000045CC 58                  <1> 	pop	eax ; *** ; inode number
  6002                              <1> 
  6003 000045CD E860070000          <1> 	call	itrunc
  6004                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
  6005                              <1> 
  6006                              <1> 	; 26/03/2022
  6007                              <1> 	; eax = 0 ; (itrunc clears eax at return)
  6008                              <1> 
  6009                              <1> 	; 12/03/2022
  6010                              <1> 	;pop	eax ; **** ; inode number
  6011                              <1> 
  6012                              <1> 	; 26/03/2022
  6013 000045D2 66A3[C4670000]      <1> 	mov	[i.flgs], ax ; (eax should be 0 here)
  6014                              <1> 	;mov 	word [i.flgs], 0
  6015                              <1> 		; clr i.flgs / clear all flags in the i-node
  6016 000045D8 C3                  <1> 	retn
  6017                              <1> 		; rts r0 / return
  6018                              <1> 
  6019                              <1> ;anyi_3: ; 1: / i-numbers match
  6020                              <1> ;	; 09/01/2022
  6021                              <1> ;	test	byte [ebx+5], 1 ; open for writing flag
  6022                              <1> ;	jz	short anyi_0	
  6023                              <1> ;
  6024                              <1> ;	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
  6025                              <1> ;	or	byte [ebx+5], 80h ; set deleted file flag (bit 7)
  6026                              <1> ;	; 22/06/2015
  6027                              <1> ;	;inc 	byte [ebx+9]
  6028                              <1> ;		; incb 7(r2) / increment upper byte of the 4th word
  6029                              <1> ;		   ; / in that fsp entry (deleted flag of fsp entry)
  6030                              <1> ;	retn
  6031                              <1> ;		; rts r0
  2091                                  %include 'u3.s'      ; 10/05/2015
  2092                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2093                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2094                              <1> ; ****************************************************************************
  2095                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS3.INC
  2096                              <1> ; Last Modification: 24/12/2021
  2097                              <1> ; ----------------------------------------------------------------------------
  2098                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2099                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2100                              <1> ;
  2101                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2102                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2103                              <1> ; <Bell Laboratories (17/3/1972)>
  2104                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2105                              <1> ;
  2106                              <1> ; Retro UNIX 8086 v1 - U3.ASM (08/03/2014) //// UNIX v1 -> u3.s
  2107                              <1> ;
  2108                              <1> ; ****************************************************************************
  2109                              <1> 
  2110                              <1> tswitch: ; Retro UNIX 386 v1
  2111                              <1> tswap:
  2112                              <1> 	; 01/09/2015
  2113                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
  2114                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
  2115                              <1> 	; time out swap, called when a user times out.
  2116                              <1> 	; the user is put on the low priority queue.
  2117                              <1> 	; This is done by making a link from the last user
  2118                              <1> 	; on the low priority queue to him via a call to 'putlu'.
  2119                              <1> 	; then he is swapped out.
  2120                              <1> 	;
  2121                              <1> 	; Retro UNIX 386 v1 modification ->
  2122                              <1> 	;       swap (software task switch) is performed by changing
  2123                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  2124                              <1> 	;	as in Retro UNIX 8086 v1.
  2125                              <1> 	;
  2126                              <1> 	; RETRO UNIX 8086 v1 modification ->
  2127                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  2128                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  2129                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  2130                              <1> 	;	compatibles was using 1MB segmented memory 
  2131                              <1> 	;	in 8086/8088 times.
  2132                              <1> 	;
  2133                              <1> 	; INPUTS ->
  2134                              <1> 	;    u.uno - users process number
  2135                              <1> 	;    runq+4 - lowest priority queue
  2136                              <1> 	; OUTPUTS ->
  2137                              <1> 	;    r0 - users process number
  2138                              <1> 	;    r2 - lowest priority queue address
  2139                              <1> 	;
  2140                              <1> 	; ((AX = R0, BX = R2)) output
  2141                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
  2142                              <1> 	;
  2143 000045D9 A0[956C0000]        <1> 	mov 	al, [u.uno]
  2144                              <1> 	       	; movb u.uno,r1 / move users process number to r1
  2145                              <1> 		; mov  $runq+4,r2 
  2146                              <1> 			; / move lowest priority queue address to r2
  2147 000045DE E8CD000000          <1>         call 	putlu
  2148                              <1> 		; jsr r0,putlu / create link from last user on Q to 
  2149                              <1> 		             ; / u.uno's user
  2150                              <1> 
  2151                              <1> switch: ; Retro UNIX 386 v1
  2152                              <1> swap:
  2153                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
  2154                              <1> 	; 02/09/2015
  2155                              <1> 	; 01/09/2015
  2156                              <1> 	; 31/08/2015
  2157                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
  2158                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  2159                              <1> 	; 'swap' is routine that controls the swapping of processes
  2160                              <1> 	; in and out of core.
  2161                              <1> 	;
  2162                              <1> 	; Retro UNIX 386 v1 modification ->
  2163                              <1> 	;       swap (software task switch) is performed by changing
  2164                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  2165                              <1> 	;	as in Retro UNIX 8086 v1.
  2166                              <1> 	;
  2167                              <1> 	; RETRO UNIX 8086 v1 modification ->
  2168                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  2169                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  2170                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  2171                              <1> 	;	compatibles was using 1MB segmented memory 
  2172                              <1> 	;	in 8086/8088 times.
  2173                              <1> 	;
  2174                              <1> 	; INPUTS ->
  2175                              <1> 	;    runq table - contains processes to run.
  2176                              <1> 	;    p.link - contains next process in line to be run.
  2177                              <1> 	;    u.uno - process number of process in core	
  2178                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
  2179                              <1> 	; OUTPUTS ->
  2180                              <1> 	;    (original unix v1 -> present process to its disk block)
  2181                              <1> 	;    (original unix v1 -> new process into core -> 
  2182                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
  2183                              <1> 	;	   for new process)
  2184                              <1> 	;    u.quant = 3 (Time quantum for a process)
  2185                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
  2186                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
  2187                              <1> 	;	 for now, it will swap the process if there is not
  2188                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
  2189                              <1> 	;	 or will count down from 3 to 0 even if there is a
  2190                              <1> 	;        keyboard event locking due to repetitive key strokes.
  2191                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
  2192                              <1> 	;
  2193                              <1> 	;    u.pri -points to highest priority run Q.
  2194                              <1> 	;    r2 - points to the run queue.
  2195                              <1> 	;    r1 - contains new process number
  2196                              <1> 	;    r0 - points to place in routine or process that called
  2197                              <1> 	;	  swap all user parameters
  2198                              <1> 	;				
  2199                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
  2200                              <1> 	;
  2201                              <1> swap_0:
  2202                              <1> 		;mov $300,*$ps / processor priority = 6
  2203 000045E3 BE[326C0000]        <1> 	mov	esi, runq
  2204                              <1> 		; mov $runq,r2 / r2 points to runq table
  2205                              <1> swap_1: ; 1: / search runq table for highest priority process
  2206 000045E8 668B06              <1> 	mov	ax, [esi]
  2207 000045EB 6621C0              <1> 	and 	ax, ax
  2208                              <1>        		; tst (r2)+ / are there any processes to run 
  2209                              <1> 			  ; / in this Q entry
  2210 000045EE 7507                <1> 	jnz	short swap_2
  2211                              <1>        		; bne 1f / yes, process 1f
  2212                              <1> 		; cmp r2,$runq+6 / if zero compare address 
  2213                              <1> 			       ; / to end of table
  2214                              <1> 		; bne 1b / if not at end, go back
  2215 000045F0 E8E0000000          <1> 	call	idle
  2216                              <1> 		; jsr r0,idle; s.idlet+2 / wait for interrupt; 
  2217                              <1> 				       ; / all queues are empty
  2218 000045F5 EBF1                <1> 	jmp	short swap_1
  2219                              <1> 		; br swap
  2220                              <1> swap_2: ; 1:
  2221 000045F7 0FB6D8              <1> 	movzx	ebx, al ; 02/09/2015
  2222                              <1> 		; tst -(r2) / restore pointer to right Q entry
  2223                              <1>  		; mov r2,u.pri / set present user to this run queue
  2224                              <1> 	        ; movb (r2)+,r1 / move 1st process in queue to r1
  2225 000045FA 38E0                <1> 	cmp	al, ah
  2226                              <1> 		; cmpb r1,(r2)+ / is there only 1 process 
  2227                              <1> 			      ; / in this Q to be run
  2228 000045FC 740A                <1> 	je	short swap_3
  2229                              <1>        		; beq 1f / yes
  2230                              <1> 		; tst -(r2) / no, pt r2 back to this Q entry
  2231                              <1> 	;movzx	ebx, al
  2232 000045FE 8AA3[53680000]      <1> 	mov	ah, [ebx+p.link-1] 
  2233 00004604 8826                <1>        	mov	[esi], ah
  2234                              <1> 		; movb p.link-1(r1),(r2) / move next process 
  2235                              <1> 				       ; / in line into run queue
  2236 00004606 EB05                <1> 	jmp	short swap_4
  2237                              <1>        		; br 2f
  2238                              <1> swap_3: ; 1:
  2239                              <1> 	;xor	dx, dx
  2240                              <1> 	; 24/12/2021
  2241 00004608 31D2                <1> 	xor	edx, edx
  2242 0000460A 668916              <1> 	mov	[esi], dx
  2243                              <1> 		; clr -(r2) / zero the entry; no processes on the Q
  2244                              <1> swap_4: ; / write out core to appropriate disk area and read 
  2245                              <1>       ; / in new process if required
  2246                              <1>        		; clr *$ps / clear processor status
  2247 0000460D 8A25[956C0000]      <1> 	mov 	ah, [u.uno]
  2248 00004613 38C4                <1> 	cmp	ah, al
  2249                              <1> 		; cmpb r1,u.uno / is this process the same as 
  2250                              <1> 			      ; / the process in core?
  2251 00004615 743B                <1>        	je	short swap_8
  2252                              <1>        		; beq 2f / yes, don't have to swap
  2253                              <1>        		; mov r0,-(sp) / no, write out core; save r0 
  2254                              <1> 			   ; / (address in routine that called swap)
  2255                              <1> 		; mov r1,-(sp) / put r1 (new process #) on the stack
  2256                              <1> 	; 01/09/2015
  2257                              <1> 	;mov	[u.usp], esp
  2258                              <1>        		; mov sp,u.usp / save stack pointer
  2259                              <1> 		; mov $sstack,sp / move swap stack pointer 
  2260                              <1> 			       ; / to the stack pointer
  2261 00004617 08E4                <1> 	or	ah, ah
  2262                              <1>        		; tstb u.uno / is the process # = 0
  2263 00004619 740D                <1>        	jz	short swap_6 ; 'sysexit'
  2264                              <1> 		; beq  1f / yes, kill process by overwriting
  2265                              <1> 	; 02/09/2015
  2266 0000461B 8925[406C0000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
  2267                              <1> 	;
  2268 00004621 E834000000          <1> 	call	wswap
  2269                              <1> 		;jsr r0,wswap / write out core to disk
  2270                              <1> 	 ; 31/08/2015
  2271                              <1> 	;movzx	ebx, al ; New (running) process number
  2272 00004626 EB1C                <1> 	jmp 	short swap_7
  2273                              <1> swap_6:
  2274                              <1> 	; 31/08/2015
  2275                              <1> 	; Deallocate memory pages belong to the process
  2276                              <1> 	; which is being terminated
  2277                              <1> 	; 14/05/2015 ('sysexit')
  2278                              <1>  	; Deallocate memory pages of the process
  2279                              <1> 	; (Retro UNIX 386 v1 modification !)
  2280                              <1> 	;
  2281                              <1> 	; movzx ebx, al
  2282 00004628 53                  <1> 	push	ebx
  2283 00004629 A1[A46C0000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
  2284 0000462E 8B1D[A86C0000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  2285 00004634 E8BCDEFFFF          <1> 	call	deallocate_page_dir
  2286 00004639 A1[A06C0000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
  2287 0000463E E848DFFFFF          <1> 	call	deallocate_page
  2288 00004643 5B                  <1> 	pop	ebx
  2289                              <1> swap_7: ;1: 
  2290                              <1> 	; 02/09/2015
  2291                              <1> 	; 31/08/2015
  2292                              <1> 	; 14/05/2015
  2293 00004644 C0E302              <1> 	shl	bl, 2 ; * 4 
  2294 00004647 8B83[70680000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
  2295                              <1> 	;cli
  2296 0000464D E831000000          <1> 	call	rswap
  2297                              <1>  		; mov (sp)+,r1 / restore r1 to new process number
  2298                              <1> 		; jsr r0,rswap / read new process into core
  2299                              <1>        		; jsr r0,unpack / unpack the users stack from next
  2300                              <1> 			      ; / to his program to its normal
  2301                              <1> 	; 01/09/2015
  2302                              <1> 	;mov	esp, [u.usp]	
  2303                              <1> 		; mov u.usp,sp / location; restore stack pointer to
  2304                              <1> 			     ; / new process stack
  2305                              <1> 		; mov (sp)+,r0 / put address of where the process 
  2306                              <1> 			     ; / that just got swapped in, left off.,
  2307                              <1> 			     ; / i.e., transfer control to new process
  2308                              <1> 	;sti
  2309                              <1> swap_8: ;2:
  2310                              <1> 	; RETRO UNIX 8086 v1 modification !
  2311 00004652 C605[8C6C0000]04    <1> 	mov	byte [u.quant], time_count 
  2312                              <1> 		; movb $30.,uquant / initialize process time quantum
  2313 00004659 C3                  <1> 	retn
  2314                              <1> 		; rts r0 / return
  2315                              <1> 
  2316                              <1> wswap:  ; < swap out, swap to disk >
  2317                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
  2318                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  2319                              <1> 	; 'wswap' writes out the process that is in core onto its 
  2320                              <1> 	; appropriate disk area.
  2321                              <1> 	;
  2322                              <1> 	; Retro UNIX 386 v1 modification ->
  2323                              <1> 	;       User (u) structure content and the user's register content
  2324                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
  2325                              <1> 	;	saving 'u' structure and user registers for task switching).
  2326                              <1> 	;	u.usp - points to kernel stack address which contains
  2327                              <1> 	;		user's registers while entering system call.  
  2328                              <1> 	;	u.sp  - points to kernel stack address 
  2329                              <1> 	;		to return from system call -for IRET-.
  2330                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  2331                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  2332                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  2333                              <1> 	;
  2334                              <1> 	; Retro UNIX 8086 v1 modification ->
  2335                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  2336                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  2337                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  2338                              <1> 	;	compatibles was using 1MB segmented memory 
  2339                              <1> 	;	in 8086/8088 times.
  2340                              <1> 	;
  2341                              <1> 	; INPUTS ->
  2342                              <1> 	;    u.break - points to end of program
  2343                              <1> 	;    u.usp - stack pointer at the moment of swap
  2344                              <1> 	;    core - beginning of process program		
  2345                              <1> 	;    ecore - end of core 	
  2346                              <1> 	;    user - start of user parameter area		
  2347                              <1> 	;    u.uno - user process number	
  2348                              <1> 	;    p.dska - holds block number of process	
  2349                              <1> 	; OUTPUTS ->
  2350                              <1> 	;    swp I/O queue
  2351                              <1> 	;    p.break - negative word count of process 
  2352                              <1> 	;    r1 - process disk address	
  2353                              <1> 	;    r2 - negative word count
  2354                              <1> 	;
  2355                              <1> 	; RETRO UNIX 8086 v1 input/output:
  2356                              <1> 	;
  2357                              <1> 	; INPUTS ->
  2358                              <1> 	;    u.uno - process number (to be swapped out)
  2359                              <1> 	; OUTPUTS ->
  2360                              <1> 	;    none
  2361                              <1> 	;
  2362                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
  2363                              <1> 	;
  2364 0000465A 8B3D[A06C0000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
  2365 00004660 B921000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  2366 00004665 BE[3C6C0000]        <1> 	mov	esi, user ; active user (u) structure	
  2367 0000466A F3A5                <1> 	rep	movsd
  2368                              <1> 	;
  2369 0000466C 8B35[406C0000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
  2370                              <1> 			     ;      points to user registers)
  2371 00004672 8B0D[3C6C0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  2372                              <1> 			     ; (for IRET)
  2373                              <1> 			     ; [u.sp] -> EIP (user)
  2374                              <1> 			     ; [u.sp+4]-> CS (user)
  2375                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  2376                              <1> 			     ; [u.sp+12] -> ESP (user)
  2377                              <1> 			     ; [u.sp+16] -> SS (user)	
  2378 00004678 29F1                <1> 	sub	ecx, esi     ; required space for user registers
  2379 0000467A 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  2380                              <1> 			     ; (for IRET) 	
  2381 0000467D C1E902              <1> 	shr	ecx, 2	     		
  2382 00004680 F3A5                <1> 	rep	movsd
  2383 00004682 C3                  <1> 	retn
  2384                              <1> 
  2385                              <1> 	; Original UNIX v1 'wswap' routine:
  2386                              <1> 	; wswap:
  2387                              <1> 		; mov *$30,u.emt / determines handling of emts
  2388                              <1>         	; mov *$10,u.ilgins / determines handling of 
  2389                              <1> 				; / illegal instructions
  2390                              <1> 		; mov u.break,r2 / put process program break address in r2
  2391                              <1> 		; inc r2 / add 1 to it 
  2392                              <1> 		; bic $1,r2 / make it even
  2393                              <1> 		; mov r2,u.break / set break to an even location
  2394                              <1> 		; mov u.usp,r3 / put users stack pointer 
  2395                              <1> 			     ; / at moment of swap in r3
  2396                              <1> 		; cmp r2,$core / is u.break less than $core
  2397                              <1> 		; blos 2f / yes
  2398                              <1> 		; cmp r2,r3 / no, is (u.break) greater than stack ptr.
  2399                              <1>        		; bhis 2f / yes
  2400                              <1> 	; 1:
  2401                              <1>        		; mov (r3)+,(r2)+ / no, pack stack next to users program
  2402                              <1> 		; cmp r3,$ecore / has stack reached end of core
  2403                              <1> 		; bne 1b / no, keep packing
  2404                              <1> 	 	; br 1f / yes
  2405                              <1> 	; 2:
  2406                              <1>        		; mov $ecore,r2 / put end of core in r2 
  2407                              <1> 	; 1:
  2408                              <1>        		; sub  $user,r2 / get number of bytes to write out 
  2409                              <1> 			   ; / (user up to end of stack gets written out)
  2410                              <1> 		; neg r2 / make it negative
  2411                              <1> 		; asr r2 / change bytes to words (divide by 2)
  2412                              <1> 		; mov r2,swp+4 / word count
  2413                              <1> 		; movb u.uno,r1 / move user process number to r1
  2414                              <1> 		; asl r1 / x2 for index
  2415                              <1>       		; mov r2,p.break-2(r1) / put negative of word count 
  2416                              <1> 				     ; / into the p.break table
  2417                              <1>        		; mov p.dska-2(r1),r1 / move disk address of swap area 
  2418                              <1> 				    ; /	for process to r1
  2419                              <1>        		; mov r1,swp+2 / put processes dska address in swp+2 
  2420                              <1> 			     ; / (block number)
  2421                              <1> 		; bis $1000,swp / set it up to write (set bit 9)
  2422                              <1>        		; jsr r0,ppoke / write process out on swap area of disk
  2423                              <1> 	; 1:
  2424                              <1>        		; tstb swp+1 / is lt done writing?
  2425                              <1>        		; bne 1b / no, wait
  2426                              <1> 		; rts r0 / yes, return to swap
  2427                              <1> 
  2428                              <1> rswap:  ; < swap in, swap from disk >
  2429                              <1> 	; 15/09/2015
  2430                              <1> 	; 28/08/2015
  2431                              <1> 	; 14/05/2015
  2432                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
  2433                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  2434                              <1> 	; 'rswap' reads a process whose number is in r1, 
  2435                              <1> 	; from disk into core.
  2436                              <1> 	;
  2437                              <1> 	; Retro UNIX 386 v1 modification ->
  2438                              <1> 	;       User (u) structure content and the user's register content
  2439                              <1> 	;	will be restored from process's/user's UPAGE (a page for
  2440                              <1> 	;	saving 'u' structure and user registers for task switching).
  2441                              <1> 	;	u.usp - points to kernel stack address which contains
  2442                              <1> 	;		user's registers while entering system call.  
  2443                              <1> 	;	u.sp  - points to kernel stack address 
  2444                              <1> 	;		to return from system call -for IRET-.
  2445                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  2446                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  2447                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  2448                              <1> 	;
  2449                              <1> 	; RETRO UNIX 8086 v1 modification ->
  2450                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  2451                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  2452                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  2453                              <1> 	;	compatibles was using 1MB segmented memory 
  2454                              <1> 	;	in 8086/8088 times.
  2455                              <1> 	;
  2456                              <1> 	; INPUTS ->
  2457                              <1> 	;    r1 - process number of process to be read in
  2458                              <1> 	;    p.break - negative of word count of process 
  2459                              <1> 	;    p.dska - disk address of the process		
  2460                              <1> 	;    u.emt - determines handling of emt's 	
  2461                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  2462                              <1> 	; OUTPUTS ->
  2463                              <1> 	;    8 = (u.ilgins)
  2464                              <1> 	;    24 = (u.emt)
  2465                              <1> 	;    swp - bit 10 is set to indicate read 
  2466                              <1> 	;		(bit 15=0 when reading is done)	
  2467                              <1> 	;    swp+2 - disk block address
  2468                              <1> 	;    swp+4 - negative word count 	
  2469                              <1> 	;      ((swp+6 - address of user structure)) 
  2470                              <1> 	;
  2471                              <1> 	; RETRO UNIX 8086 v1 input/output:
  2472                              <1> 	;
  2473                              <1> 	; INPUTS ->
  2474                              <1> 	;    AL	- new process number (to be swapped in)	 
  2475                              <1> 	; OUTPUTS ->
  2476                              <1> 	;    none
  2477                              <1> 	;
  2478                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
  2479                              <1> 	;
  2480                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
  2481 00004683 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
  2482 00004685 B921000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  2483 0000468A BF[3C6C0000]        <1> 	mov	edi, user ; active user (u) structure	
  2484 0000468F F3A5                <1> 	rep	movsd
  2485 00004691 58                  <1> 	pop	eax ; 15/09/2015, 'rswap' return address 
  2486 00004692 8B3D[406C0000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
  2487                              <1> 			     ;      points to user registers)
  2488 00004698 8B0D[3C6C0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  2489                              <1> 			     ; (for IRET)
  2490                              <1> 			     ; [u.sp] -> EIP (user)
  2491                              <1> 			     ; [u.sp+4]-> CS (user)
  2492                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  2493                              <1> 			     ; [u.sp+12] -> ESP (user)
  2494                              <1> 			     ; [u.sp+16] -> SS (user)		
  2495                              <1> 	; 28/08/2015
  2496 0000469E 29F9                <1> 	sub	ecx, edi     ; required space for user registers
  2497 000046A0 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  2498                              <1> 			     ; (for IRET) 	
  2499 000046A3 C1E902              <1> 	shr	ecx, 2	       		
  2500 000046A6 F3A5                <1> 	rep	movsd
  2501 000046A8 8B25[406C0000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
  2502 000046AE 50                  <1> 	push	eax ; 15/09/2015 'rswap' return address
  2503 000046AF C3                  <1> 	retn
  2504                              <1> 
  2505                              <1> 	; Original UNIX v1 'rswap'  and 'unpack' routines:
  2506                              <1> 	;rswap:
  2507                              <1>        		; asl r1 / process number x2 for index
  2508                              <1>        		; mov p.break-2(r1), swp+4 / word count
  2509                              <1>        		; mov p.dska-2(r1),swp+2 / disk address
  2510                              <1>        		; bis $2000,swp / read
  2511                              <1>        		; jsr r0,ppoke / read it in 
  2512                              <1> 	; 1:
  2513                              <1>        		; tstb swp+1 / done
  2514                              <1>        		; bne 1b / no, wait for bit 15 to clear (inhibit bit)
  2515                              <1>        		; mov u.emt,*$30 / yes move these
  2516                              <1>        		; mov u.ilgins,*$10 / back
  2517                              <1>        		; rts r0 / return
  2518                              <1> 
  2519                              <1> 	;unpack: ; / move stack back to its normal place
  2520                              <1> 		; mov u.break,r2 / r2 points to end of user program
  2521                              <1>        		; cmp r2,$core / at beginning of user program yet?
  2522                              <1> 		; blos 2f / yes, return
  2523                              <1> 		; cmp r2,u.usp / is break_above the stack pointer 
  2524                              <1> 			     ; / before swapping
  2525                              <1> 		; bhis 2f / yes, return
  2526                              <1> 		; mov $ecore,r3 / r3 points to end of core
  2527                              <1> 		; add r3,r2
  2528                              <1> 		; sub u.usp,r2 / end of users stack is in r2
  2529                              <1> 	; 1:
  2530                              <1> 		; mov -(r2),-(r3) / move stack back to its normal place
  2531                              <1> 		; cmp r2,u.break / in core
  2532                              <1> 		; bne 1b
  2533                              <1> 	; 2:
  2534                              <1>        		; rts r0
  2535                              <1> 
  2536                              <1> putlu: 
  2537                              <1> 	; 12/09/2015
  2538                              <1> 	; 02/09/2015
  2539                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
  2540                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
  2541                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
  2542                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
  2543                              <1> 	; the last process on the queue to process in r1 by putting
  2544                              <1> 	; the process number in r1 into the last process's link.
  2545                              <1> 	;
  2546                              <1> 	; INPUTS ->
  2547                              <1> 	;    r1 - user process number
  2548                              <1> 	;    r2 - points to lowest priority queue 
  2549                              <1> 	;    p.dska - disk address of the process		
  2550                              <1> 	;    u.emt - determines handling of emt's 	
  2551                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  2552                              <1> 	; OUTPUTS ->
  2553                              <1> 	;    r3 - process number of last process on the queue upon
  2554                              <1> 	;	  entering putlu
  2555                              <1> 	;    p.link-1 + r3 - process number in r1
  2556                              <1> 	;    r2 - points to lowest priority queue
  2557                              <1> 	;
  2558                              <1> 	; ((Modified registers: EDX, EBX)) 
  2559                              <1> 	;
  2560                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
  2561                              <1> 
  2562                              <1> 	; eBX = r2
  2563                              <1> 	; eAX = r1 (AL=r1b)
  2564                              <1> 
  2565 000046B0 BB[326C0000]        <1> 	mov	ebx, runq
  2566 000046B5 0FB613              <1> 	movzx  	edx, byte [ebx]
  2567 000046B8 43                  <1> 	inc	ebx
  2568 000046B9 20D2                <1> 	and	dl, dl
  2569                              <1> 		; tstb (r2)+ / is queue empty?
  2570 000046BB 740A                <1>        	jz	short putlu_1
  2571                              <1> 		; beq 1f / yes, branch
  2572 000046BD 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
  2573                              <1> 		; movb (r2),r3 / no, save the "last user" process number
  2574                              <1> 			     ; / in r3
  2575 000046BF 8882[53680000]      <1>        	mov	[edx+p.link-1], al
  2576                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
  2577                              <1> 			     ; / "last users" link
  2578 000046C5 EB03                <1> 	jmp	short putlu_2
  2579                              <1> 		; br 2f /
  2580                              <1> putlu_1: ; 1:
  2581 000046C7 8843FF              <1> 	mov	[ebx-1], al
  2582                              <1>        		; movb r1,-1(r2) / user is only user; 
  2583                              <1> 			    ; / put process no. at beginning and at end
  2584                              <1> putlu_2: ; 2: 
  2585 000046CA 8803                <1> 	mov	[ebx], al
  2586                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
  2587                              <1> 			     ; / on the queue
  2588 000046CC 88C2                <1> 	mov	dl, al
  2589 000046CE 88B2[53680000]      <1>         mov     [edx+p.link-1], dh ; 0
  2590                              <1> 		; dec r2 / restore r2
  2591 000046D4 C3                  <1>         retn
  2592                              <1> 		; rts r0
  2593                              <1> 
  2594                              <1> ;copyz:
  2595                              <1> ;       mov     r1,-(sp) / put r1 on stack
  2596                              <1> ;       mov     r2,-(sp) / put r2 on stack
  2597                              <1> ;       mov     (r0)+,r1
  2598                              <1> ;       mov     (r0)+,r2
  2599                              <1> ;1:
  2600                              <1> ;       clr     (r1)+ / clear all locations between r1 and r2
  2601                              <1> ;       cmp     r1,r2 
  2602                              <1> ;       blo     1b
  2603                              <1> ;       mov     (sp)+,r2 / restore r2
  2604                              <1> ;       mov     (sp)+,r1 / restore r1
  2605                              <1> ;       rts     r0 
  2606                              <1> 
  2607                              <1> idle:
  2608                              <1> 	; 01/09/2015
  2609                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
  2610                              <1> 	; 10/04/2013 - 23/10/2013 (Retro UNIX 8086 v1)
  2611                              <1> 	; (idle & wait loop)
  2612                              <1> 	; Retro Unix 8086 v1 modification on original UNIX v1
  2613                              <1> 	; idle procedure!
  2614                              <1>       	;
  2615                              <1>   	; 01/09/2015
  2616 000046D5 FB                  <1> 	sti
  2617                              <1>       	; 29/07/2013
  2618 000046D6 F4                  <1>       	hlt
  2619 000046D7 90                  <1>       	nop ; 10/10/2013
  2620 000046D8 90                  <1>       	nop
  2621 000046D9 90                  <1>       	nop
  2622                              <1>       	; 23/10/2013
  2623 000046DA 90                  <1>       	nop
  2624 000046DB 90                  <1>       	nop
  2625 000046DC 90                  <1>       	nop
  2626 000046DD 90                  <1>       	nop
  2627 000046DE C3                  <1>       	retn      
  2628                              <1> 
  2629                              <1> 	;mov *$ps,-(sp) / save ps on stack
  2630                              <1> 	;clr *$ps / clear ps
  2631                              <1> 	;mov clockp,-(sp) / save clockp on stack
  2632                              <1> 	;mov (r0)+,clockp / arg to idle in clockp
  2633                              <1> 	;1 / wait for interrupt
  2634                              <1> 	;mov (sp)+,clockp / restore clockp, ps
  2635                              <1> 	;mov (sp)+,*$ps
  2636                              <1> 	;rts r0
  2637                              <1> 
  2638                              <1> clear:
  2639                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
  2640                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
  2641                              <1> 	; 09/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
  2642                              <1> 	; 'clear' zero's out of a block (whose block number is in r1)
  2643                              <1> 	; on the current device (cdev)
  2644                              <1> 	;	
  2645                              <1> 	; INPUTS ->
  2646                              <1> 	;    r1 - block number of block to be zeroed
  2647                              <1> 	;    cdev - current device number 
  2648                              <1> 	; OUTPUTS ->
  2649                              <1> 	;    a zeroed I/O buffer onto the current device
  2650                              <1> 	;    r1 - points to last entry in the I/O buffer
  2651                              <1> 	;
  2652                              <1> 	; ((AX = R1)) input/output
  2653                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 14/11/2012, UNIXCOPY.ASM)
  2654                              <1>         ;    ((Modified registers: EDX, ECX, EBX, ESI, EDI, EBP))  
  2655                              <1> 
  2656 000046DF E8F2120000          <1> 	call 	wslot
  2657                              <1> 		; jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
  2658                              <1>                    ; / word of I/O queue r5 points to first data word in buffer
  2659 000046E4 89DF                <1> 	mov	edi, ebx ; r5
  2660 000046E6 89C2                <1> 	mov	edx, eax
  2661 000046E8 B980000000          <1> 	mov	ecx, 128
  2662                              <1> 		; mov $256.,r3
  2663 000046ED 31C0                <1> 	xor	eax, eax
  2664 000046EF F3AB                <1> 	rep	stosd
  2665 000046F1 89D0                <1> 	mov	eax, edx
  2666                              <1> ; 1: 
  2667                              <1>        		; clr (r5)+ / zero data word in buffer
  2668                              <1>        		; dec r3
  2669                              <1>        		; bgt 1b / branch until all data words in buffer are zero
  2670                              <1> 	;call	dskwr
  2671                              <1> 		; jsr r0,dskwr / write zeroed buffer area out onto physical
  2672                              <1>                              ; / block specified in r1
  2673                              <1> 	; eAX (r1) = block number
  2674                              <1> 	;retn
  2675                              <1> 		; rts r0
  2676                              <1> 	; 24/12/2021
  2677 000046F3 E9EB120000          <1> 	jmp	dskwr
  2092                                  %include 'u4.s'      ; 15/04/2015
  2093                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2094                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2095                              <1> ; ****************************************************************************
  2096                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS4.INC
  2097                              <1> ; Last Modification: 27/02/2022 (Retro UNIX 386 v1.2)
  2098                              <1> ; ----------------------------------------------------------------------------
  2099                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2100                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2101                              <1> ;
  2102                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2103                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2104                              <1> ; <Bell Laboratories (17/3/1972)>
  2105                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2106                              <1> ;
  2107                              <1> ; Retro UNIX 8086 v1 - U4.ASM (04/07/2014) //// UNIX v1 -> u4.s
  2108                              <1> ;
  2109                              <1> ; ****************************************************************************
  2110                              <1> 
  2111                              <1> ;setisp:
  2112                              <1>        ;mov     r1,-(sp)
  2113                              <1>        ;mov     r2,-(sp)
  2114                              <1>        ;mov     r3,-(sp)
  2115                              <1>        ;mov     clockp,-(sp)
  2116                              <1>        ;mov     $s.syst+2,clockp
  2117                              <1>        ;jmp     (r0)
  2118                              <1> 
  2119                              <1> clock: ; / interrupt from 60 cycle clock
  2120                              <1> 	
  2121                              <1> 	; 14/10/2015
  2122                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  2123                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
  2124                              <1> 
  2125                              <1>        ;mov     r0,-(sp) / save r0
  2126                              <1>        ;tst     *$lks / restart clock?
  2127                              <1>        ;mov     $s.time+2,r0 / increment the time of day
  2128                              <1>        ;inc     (r0)
  2129                              <1>        ;bne     1f
  2130                              <1>        ;inc     -(r0)
  2131                              <1> ;1:
  2132                              <1>        ;mov     clockp,r0 / increment appropriate time category
  2133                              <1>        ;inc     (r0)
  2134                              <1>        ;bne     1f
  2135                              <1>        ;inc     -(r0)
  2136                              <1> ;1:
  2137                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2138                              <1> 
  2139 000046F8 803D[8C6C0000]00    <1> 	cmp	byte [u.quant], 0
  2140 000046FF 772C                <1> 	ja	short clk_1
  2141                              <1> 	;
  2142 00004701 803D[386C0000]FF    <1>         cmp     byte [sysflg], 0FFh ; user or system space ?
  2143 00004708 7529                <1> 	jne	short clk_2 ; system space (sysflg <> 0FFh)
  2144 0000470A 803D[956C0000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ?
  2145 00004711 761A                <1> 	jna	short clk_1 ; yes, do not swap out
  2146 00004713 66833D[906C0000]00  <1> 	cmp	word [u.intr], 0
  2147 0000471B 7616                <1> 	jna	short clk_2
  2148                              <1> clk_0:
  2149                              <1> 	; 14/10/2015
  2150 0000471D FE05[386C0000]      <1> 	inc	byte [sysflg] ; Now, we are in system space
  2151 00004723 58                  <1> 	pop	eax ; return address to the timer interrupt
  2152                              <1> 	;
  2153 00004724 B020                <1> 	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  2154                              <1> 	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  2155 00004726 E620                <1> 	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  2156                              <1> 	;
  2157 00004728 E99FEAFFFF          <1> 	jmp     sysrelease ; 'sys release' by clock/timer
  2158                              <1> clk_1:
  2159 0000472D FE0D[8C6C0000]      <1> 	dec	byte [u.quant]
  2160                              <1> clk_2:
  2161 00004733 C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
  2162                              <1> 
  2163                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
  2164                              <1> 
  2165                              <1>        ;mov     $uquant,r0 / decrement user time quantum
  2166                              <1>        ;decb    (r0)
  2167                              <1>        ;bge     1f / if less than 0
  2168                              <1>        ;clrb    (r0) / make it 0
  2169                              <1> ;1: / decrement time out counts return now if priority was not 0
  2170                              <1>        ;cmp     4(sp),$200 / ps greater than or equal to 200
  2171                              <1>        ;bge     2f / yes, check time outs
  2172                              <1>        ;tstb    (r0) / no, user timed out?
  2173                              <1>        ;bne     1f / no
  2174                              <1>        ;cmpb    sysflg,$-1 / yes, are we outside the system?
  2175                              <1>        ;bne     1f / no, 1f
  2176                              <1>        ;mov     (sp)+,r0 / yes, put users r0 in r0
  2177                              <1>        ;sys     0 / sysrele
  2178                              <1>        ;rti
  2179                              <1> ;2: / priority is high so just decrement time out counts
  2180                              <1>        ;mov     $toutt,r0 / r0 points to beginning of time out table
  2181                              <1> ;2:
  2182                              <1>        ;tstb    (r0) / is the time out?
  2183                              <1>        ;beq     3f / yes, 3f (get next entry)
  2184                              <1>        ;decb    (r0) / no, decrement the time
  2185                              <1>        ;bne     3f / isit zero now?
  2186                              <1>        ;incb    (r0) / yes, increment the time
  2187                              <1> ;3:
  2188                              <1>        ;inc     r0 / next entry
  2189                              <1>        ;cmp     r0,$touts / end of toutt table?
  2190                              <1>        ;blo     2b / no, check this entry
  2191                              <1>        ;mov     (sp)+,r0 / yes, restore r0
  2192                              <1>        ;rti / return from interrupt
  2193                              <1> ;1: / decrement time out counts; if 0 call subroutine
  2194                              <1>        ;mov     (sp)+,r0 / restore r0
  2195                              <1>        ;mov     $240,*$ps / set processor priority to 5
  2196                              <1>        ;jsr     r0,setisp / save registers
  2197                              <1>        ;mov     $touts-toutt-1,r0 / set up r0 as index to decrement thru
  2198                              <1>                                ;  / the table
  2199                              <1> ;1:
  2200                              <1>        ;tstb    toutt(r0) / is the time out for this entry
  2201                              <1>        ;beq     2f / yes
  2202                              <1>        ;decb    toutt(r0) / no, decrement the time
  2203                              <1>        ;bne     2f / is the time 0, now
  2204                              <1>        ;asl     r0 / yes, 2 x r0 to get word index for tout entry
  2205                              <1>        ;jsr     r0,*touts(r0) / go to appropriate routine specified in this
  2206                              <1>        ;asr     r0 / touts entry; set r0 back to toutt index
  2207                              <1> ;2:
  2208                              <1>        ;dec     r0 / set up r0 for next entry
  2209                              <1>        ;bge     1b / finished? , no, go back
  2210                              <1>        ;br      retisp / yes, restore registers and do a rti
  2211                              <1> 
  2212                              <1> ;retisp:
  2213                              <1>        ;mov     (sp)+,clockp / pop values before interrupt off the stack
  2214                              <1>        ;mov     (sp)+,r3
  2215                              <1>        ;mov     (sp)+,r2
  2216                              <1>        ;mov     (sp)+,r1
  2217                              <1>        ;mov     (sp)+,r0
  2218                              <1>        ;rti     / return from interrupt
  2219                              <1> 
  2220                              <1> 
  2221                              <1> wakeup: ; / wakeup processes waiting for an event 
  2222                              <1> 	; / by linking them to the queue
  2223                              <1> 	;
  2224                              <1> 	; 27/02/2022
  2225                              <1> 	; 15/09/2015
  2226                              <1> 	; 29/06/2015
  2227                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
  2228                              <1> 	;
  2229                              <1> 	; 15/05/2013 - 02/06/2014
  2230                              <1> 	; Retro UNIX 8086 v1 modification !
  2231                              <1> 	; (Process/task switching routine by using
  2232                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.)
  2233                              <1> 	;
  2234                              <1> 	; In original UNIX v1, 'wakeup' is called to wake the process
  2235                              <1> 	; sleeping in the specified wait channel by creating a link 
  2236                              <1> 	; to it from the last user process on the run queue.
  2237                              <1> 	; If there is no process to wake up, nothing happens.
  2238                              <1> 	;
  2239                              <1> 	; In Retro UNIX 8086 v1, Int 09h keyboard interrupt will set
  2240                              <1> 	; 'switching' status of the current process (owns current tty)
  2241                              <1> 	; (via alt + function keys) to a process which has highest
  2242                              <1> 	; priority (on run queue) on the requested tty (0 to 7, except
  2243                              <1> 	; 8 and 9 which are tty identifiers of COM1, COM2 serial ports)
  2244                              <1> 	; as it's console tty. (NOTE: 'p.ttyc' is used to set console
  2245                              <1> 	; tty for tty switching by keyboard.)	 
  2246                              <1> 	; 
  2247                              <1> 	; INPUT -> 
  2248                              <1> 	;	   AL = wait channel (r3) ('tty number' for now)
  2249                              <1> 	;	   ;;EBX = Run queue (r2) offset
  2250                              <1> 	;
  2251                              <1> 	; ((modified registers: EAX, EBX))
  2252                              <1> 	;
  2253 00004734 0FB6D8              <1> 	movzx	ebx, al ; 29/06/2015
  2254 00004737 81C3[68670000]      <1> 	add	ebx, wlist
  2255 0000473D 8A03                <1> 	mov	al, [ebx] ; waiting list (waiting process number)
  2256 0000473F 20C0                <1> 	and	al, al
  2257 00004741 741E                <1> 	jz	short wa0 ; nothing to wakeup
  2258                              <1> 	;
  2259 00004743 30E4                <1> 	xor	ah, ah
  2260 00004745 8825[8C6C0000]      <1> 	mov 	[u.quant], ah ; 0 ; time quantum = 0	
  2261 0000474B 8823                <1> 	mov	[ebx], ah ; 0 ; zero wait channel entry
  2262                              <1> 	; 15/09/2015
  2263 0000474D 0FB6D8              <1> 	movzx	ebx, al
  2264                              <1> 	; 27/02/2022 (p.waitc is not used)
  2265                              <1> 	;mov	[ebx+p.waitc-1], ah ; 0
  2266 00004750 FEC4                <1> 	inc	ah
  2267 00004752 88A3[63680000]      <1> 	mov	byte [ebx+p.stat-1], ah ; 1 ; SRUN
  2268                              <1> 	;
  2269 00004758 57                  <1> 	push	edi
  2270 00004759 52                  <1> 	push	edx
  2271 0000475A E851FFFFFF          <1> 	call	putlu
  2272 0000475F 5A                  <1> 	pop	edx
  2273 00004760 5F                  <1> 	pop	edi
  2274                              <1> wa0:
  2275 00004761 C3                  <1> 	retn
  2276                              <1> 
  2277                              <1> 	; 27/02/2022
  2278                              <1> 	; 05/12/2021
  2279                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
  2280                              <1> sleep: 
  2281                              <1> 	; 15/09/2015
  2282                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
  2283                              <1> 	;
  2284                              <1> 	; 09/05/2013 - 20/03/2014
  2285                              <1> 	;
  2286                              <1> 	; Retro UNIX 8086 v1 modification !
  2287                              <1> 	; (Process/task switching and quit routine by using
  2288                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
  2289                              <1> 	;
  2290                              <1> 	; In original UNIX v1, 'sleep' is called to wait for
  2291                              <1> 	; tty and tape output or input becomes available
  2292                              <1> 	; and process is put on waiting channel and swapped out,
  2293                              <1> 	; then -when the tty or tape is ready to write or read-
  2294                              <1> 	; 'wakeup' gets process back to active swapped-in status.)
  2295                              <1> 	;
  2296                              <1> 	; In Retro UNIX 8086 v1, Int 1Bh ctrl+brk interrupt and
  2297                              <1> 	; Int 09h keyboard interrupt will set 'quit' or 'switching'		
  2298                              <1> 	; status of the current process also INT 1Ch will count down
  2299                              <1> 	; 'uquant' value and INT 09h will redirect scancode of keystroke
  2300                              <1> 	; to tty buffer of the current process and kernel will get
  2301                              <1> 	; user input by using tty buffer of the current process
  2302                              <1> 	; (instead of standard INT 16h interrupt).
  2303                              <1> 	; TTY output will be redirected to related video page of text mode
  2304                              <1> 	; (INT 10h will be called with different video page depending
  2305                              <1> 	; on tty assignment of the active process: 0 to 7 for
  2306                              <1> 	; pseudo screens.)
  2307                              <1> 	;
  2308                              <1> 	; In Retro UNIX 8086 v1, 'sleep' will be called to wait for
  2309                              <1> 	; a keystroke from keyboard or wait for reading or writing
  2310                              <1> 	; characters/data on serial port(s).
  2311                              <1> 	;
  2312                              <1> 	; Character/Terminal input/output through COM1 and COM2 will be
  2313                              <1> 	; performed by related routines in addition to pseudo TTY routines.
  2314                              <1> 	; 
  2315                              <1> 	; R1 = AH = wait channel (0-9 for TTYs) ; 05/10/2013 (22/09/2013)
  2316                              <1> 	;
  2317                              <1> 	;; 05/10/2013
  2318                              <1>         ;10/12/2013
  2319                              <1> 	;cmp   byte [u.uno], 1
  2320                              <1>         ;ja    short sleep0
  2321                              <1> 	;retn
  2322                              <1> 
  2323                              <1> 	; 20/03/2014
  2324                              <1> 	;mov	bx, [runq]
  2325                              <1> 	;cmp	bl, bh
  2326                              <1> 	;jne	short sleep0	
  2327                              <1> 	; 25/02/2014
  2328                              <1> 	;cmp	word ptr [runq], 0
  2329                              <1> 	;ja	short sleep0	
  2330                              <1> 	;retn
  2331                              <1> sleep0:
  2332                              <1> 	;
  2333 00004762 E849000000          <1> 	call	isintr
  2334                              <1> 	;jnz	sysret
  2335                              <1> 		; / wait for event
  2336                              <1>        		; jsr r0,isintr / check to see if interrupt 
  2337                              <1> 			      ; / or quit from user
  2338                              <1>                		; br 2f / something happened
  2339                              <1> 			      ; / yes, his interrupt so return
  2340                              <1>                      	      ;	/ to user
  2341                              <1> 	; 05/12/2021
  2342 00004767 7405                <1> 	jz	short sleep_2
  2343                              <1> sleep_3:
  2344 00004769 E9F9E9FFFF          <1> 	jmp	sysret
  2345                              <1> sleep_2:
  2346                              <1> 	; 30/06/2015
  2347 0000476E 0FB6DC              <1>     	movzx	ebx, ah ; 30/06/2015
  2348 00004771 81C3[68670000]      <1> 	add	ebx, wlist
  2349 00004777 8A03                <1> 	mov	al, [ebx]
  2350 00004779 20C0                <1> 	and	al, al
  2351 0000477B 7407                <1> 	jz	short sleep1
  2352 0000477D 53                  <1> 	push	ebx
  2353 0000477E E82DFFFFFF          <1> 	call	putlu
  2354 00004783 5B                  <1> 	pop	ebx
  2355                              <1> sleep1:
  2356 00004784 A0[956C0000]        <1> 	mov	al, [u.uno]    
  2357 00004789 8803                <1>   	mov	[ebx], al 	; put the process number
  2358                              <1> 				; in the wait channel
  2359                              <1> 		; mov (r0)+,r1 / put number of wait channel in r1
  2360                              <1> 		; movb wlist(r1),-(sp) / put old process number in there,
  2361                              <1> 				     ; / on the stack
  2362                              <1>        		; movb u.uno,wlist(r1) / put process number of process
  2363                              <1> 				     ; / to put to sleep in there
  2364                              <1> 	; 30/11/2021
  2365 0000478B 31DB                <1> 	xor	ebx, ebx
  2366 0000478D 8A1D[216C0000]      <1> 	mov	bl, [cdev]
  2367 00004793 53                  <1> 	push	ebx
  2368                              <1>         ; 15/09/2015
  2369                              <1> 	;movzx	ebx, al
  2370 00004794 88C3                <1> 	mov	bl, al
  2371 00004796 C683[63680000]04    <1>         mov     byte [ebx+p.stat-1], 4 ; SSLEEP
  2372                              <1> 	; 27/02/2022 (p.waitc is not used)
  2373                              <1> 	;inc	ah
  2374                              <1> 	;mov	[ebx+p.waitc-1], ah ; wait channel + 1
  2375                              <1> 	;
  2376                              <1> 	;
  2377                              <1> 	;push	word [cdev]
  2378                              <1> 	;	; mov cdev,-(sp) / nothing happened in isintr so
  2379 0000479D E841FEFFFF          <1> 	call	swap
  2380                              <1>        		; jsr r0,swap / swap out process that needs to sleep
  2381                              <1>         ;pop	word [cdev]
  2382                              <1> 	;	; mov (sp)+,cdev / restore device
  2383                              <1> 	; 30/11/2021
  2384 000047A2 58                  <1> 	pop	eax
  2385 000047A3 A2[216C0000]        <1> 	mov	[cdev], al
  2386 000047A8 E803000000          <1> 	call	isintr
  2387                              <1> 	; 22/09/2013
  2388                              <1> 	;jnz	sysret         
  2389                              <1> 		; jsr r0,isintr / check for interrupt of new process
  2390                              <1>                		; br 2f / yes, return to new user
  2391                              <1> 		; movb (sp)+,r1 / no, r1 = old process number that was 
  2392                              <1> 				; / originally on the wait channel
  2393                              <1>        		; beq 1f / if 0 branch
  2394                              <1>   		; mov $runq+4,r2 / r2 points to lowest priority queue
  2395                              <1>        		; mov $300,*$ps / processor priority = 6
  2396                              <1> 		; jsr r0,putlu / create link to old process number
  2397                              <1>        		; clr *$ps / clear the status; process priority = 0
  2398                              <1> 	; 05/12/2021
  2399 000047AD 75BA                <1> 	jnz	short sleep_3 ; jump to sysret
  2400                              <1>      ;1:
  2401 000047AF C3                  <1> 	retn
  2402                              <1> 		; rts r0 / return
  2403                              <1>      ;2:
  2404                              <1>         ;;jmp	sysret
  2405                              <1> 		; jmp sysret / return to user
  2406                              <1> 
  2407                              <1> isintr:
  2408                              <1> 	; 30/11/2021	
  2409                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
  2410                              <1> 	;
  2411                              <1> 	; 09/05/2013 - 30/05/2014
  2412                              <1> 	;
  2413                              <1> 	; Retro UNIX 8086 v1 modification !
  2414                              <1> 	; (Process/task switching and quit routine by using
  2415                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
  2416                              <1> 	;
  2417                              <1> 	; Retro UNIX 8086 v1 modification:
  2418                              <1> 	; 'isintr' checks if user interrupt request is enabled
  2419                              <1> 	;  and there is a 'quit' request by user;
  2420                              <1> 	;  otherwise, 'isintr' will return with zf=1 that means
  2421                              <1> 	;  "nothing to do". (20/10/2013)
  2422                              <1> 	;
  2423                              <1> 	; 20/10/2013
  2424 000047B0 66833D[7A6C0000]00  <1> 	cmp 	word [u.ttyp], 0 ; has process got a tty ?
  2425 000047B8 761F                <1> 	jna	short isintr2 ; retn
  2426                              <1> 	; 03/09/2013
  2427                              <1> 	; (nothing to do)
  2428                              <1> 	;retn
  2429                              <1> 	; 22/09/2013
  2430 000047BA 66833D[906C0000]00  <1> 	cmp	word [u.intr], 0
  2431 000047C2 7615                <1> 	jna	short isintr2 ; retn
  2432                              <1> 	; 30/05/2014
  2433                              <1> 	;push	ax
  2434 000047C4 50                  <1> 	push	eax ; 30/11/2021 
  2435 000047C5 66A1[926C0000]      <1> 	mov	ax, [u.quit]
  2436 000047CB 6609C0              <1> 	or	ax, ax ; 0 ?
  2437 000047CE 7408                <1> 	jz	short isintr1 ; zf = 1
  2438 000047D0 6683F8FE            <1> 	cmp	ax, 0FFFEh  ; 'ctrl + brk' check
  2439 000047D4 7702                <1> 	ja	short isintr1 ; 0FFFFh, zf = 0
  2440                              <1> 	;xor	ax, ax ; zf = 1
  2441                              <1> 	; 30/11/2021
  2442 000047D6 31C0                <1> 	xor	eax, eax
  2443                              <1> isintr1:
  2444                              <1> 	;pop	ax
  2445                              <1> 	; 30/11/2021
  2446 000047D8 58                  <1> 	pop	eax
  2447                              <1> isintr2: ; 22/09/2013
  2448                              <1> 	; zf=1 -> nothing to do
  2449 000047D9 C3                  <1> 	retn
  2450                              <1> 
  2451                              <1> 	; UNIX v1 original 'isintr' routine... 
  2452                              <1>        	;mov     r1,-(sp) / put number of wait channel on the stack
  2453                              <1>        	;mov     r2,-(sp) / save r2
  2454                              <1>        	;mov     u.ttyp,r1 / r1 = pointer to buffer of process control
  2455                              <1>         ;                 / typewriter
  2456                              <1>        	;beq     1f / if 0, do nothing except skip return
  2457                              <1>        	;movb    6(r1),r1 / put interrupt char in the tty buffer in r1
  2458                              <1>        	;beq     1f / if its 0 do nothing except skip return
  2459                              <1>        	;cmp     r1,$177 / is interrupt char = delete?
  2460                              <1>        	;bne     3f / no, so it must be a quit (fs)
  2461                              <1>        	;tst     u.intr / yes, value of u.intr determines handling
  2462                              <1>         ;              / of interrupts
  2463                              <1>        	;bne     2f / if not 0, 2f. If zero do nothing.
  2464                              <1>      ;1:
  2465                              <1>        	;tst     (r0)+ / bump r0 past system return (skip)
  2466                              <1>      ;4:
  2467                              <1>        	;mov     (sp)+,r2 / restore r1 and r2
  2468                              <1>        	;mov     (sp)+,r1
  2469                              <1>        	;rts     r0
  2470                              <1>      ;3: / interrupt char = quit (fs)
  2471                              <1>        	;tst     u.quit / value of u.quit determines handling of quits
  2472                              <1>        	;beq     1b / u.quit = 0 means do nothing
  2473                              <1>      ;2: / get here because either u.intr <> 0 or u.qult <> O
  2474                              <1>        	;mov     $tty+6,r1 / move pointer to tty block into r1
  2475                              <1>      ;1: / find process control tty entry in tty block
  2476                              <1>        	;cmp     (r1),u.ttyp / is this the process control tty buffer?
  2477                              <1>        	;beq     1f / block found go to 1f
  2478                              <1>        	;add     $8,r1 / look at next tty block
  2479                              <1>        	;cmp     r1,$tty+[ntty*8]+6 / are we at end of tty blocks
  2480                              <1>        	;blo     1b / no
  2481                              <1>        	;br      4b / no process control tty found so go to 4b
  2482                              <1>      ;1:
  2483                              <1>        	;mov     $240,*$ps / set processor priority to 5
  2484                              <1>        	;movb    -3(r1),0f / load getc call argument; character llst
  2485                              <1>         ;                  / identifier
  2486                              <1>        	;inc     0f / increment
  2487                              <1>      ;1:
  2488                              <1>        	;jsr     r0,getc; 0:.. / erase output char list for control
  2489                              <1>         ;        br 4b / process tty. This prevents a line of stuff
  2490                              <1>         ;             / being typed out after you hit the interrupt
  2491                              <1>         ;             / key
  2492                              <1>        	;br      1b
  2093                                  %include 'u5.s'      ; 03/06/2015
  2094                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2095                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2096                              <1> ; ****************************************************************************
  2097                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS5.INC
  2098                              <1> ; Last Modification: 17/07/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.3)
  2099                              <1> ; ----------------------------------------------------------------------------
  2100                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2101                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2102                              <1> ;
  2103                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2104                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2105                              <1> ; <Bell Laboratories (17/3/1972)>
  2106                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2107                              <1> ;
  2108                              <1> ; Retro UNIX 8086 v1 - U5.AS M (07/08/2013) //// UNIX v1 -> u5.s
  2109                              <1> ;
  2110                              <1> ; ****************************************************************************
  2111                              <1> 
  2112                              <1> 	; 09/03/2022
  2113                              <1> 	; 09/01/2022
  2114                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2115                              <1> mget_w:
  2116                              <1> 	; 28/10/2021
  2117                              <1> 	; 22/08/2021
  2118                              <1> 	; 20/08/2021
  2119                              <1> 	; 25/05/2020
  2120                              <1> 	; 24/05/2020 - Retro UNIX 386 v2	
  2121 000047DA C605[DA6C0000]01    <1> 	mov	byte [mget_rw], 1 ; write access
  2122 000047E1 EB07                <1> 	jmp	short mget
  2123                              <1> mget_r:
  2124                              <1> 	; 28/10/2021
  2125                              <1> 	; 22/08/2021
  2126                              <1> 	; 25/05/2020
  2127                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
  2128 000047E3 C605[DA6C0000]00    <1> 	mov	byte [mget_rw], 0 ; read access	
  2129                              <1> mget:
  2130                              <1> 	; 17/07/2022
  2131                              <1> 	; 09/03/2022
  2132                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  2133                              <1> 	; 28/11/2021
  2134                              <1> 	; 22/11/2021
  2135                              <1> 	; 28/10/2021 - temporary (simplified code)
  2136                              <1> 	; 22/08/2021
  2137                              <1> 	; 20/08/2021
  2138                              <1> 	; 25/05/2020
  2139                              <1> 	; 24/05/2020
  2140                              <1> 	; 05/05/2020
  2141                              <1> 	; 02/05/2020, 03/05/2020
  2142                              <1> 	; 29/04/2020 - Retro UNIX 386 v2
  2143                              <1> 	; New inode model/format (Modified UNIX v7 inode model)
  2144                              <1> 	;	
  2145                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  2146                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  2147                              <1> 	;
  2148                              <1> 	; Get existing or (allocate) a new disk block for file
  2149                              <1> 	; 
  2150                              <1> 	; INPUTS ->
  2151                              <1> 	;    u.fofp (file offset pointer)
  2152                              <1> 	;    inode 
  2153                              <1> 	;    u.off (file offset)
  2154                              <1> 	; OUTPUTS ->
  2155                              <1> 	;    r1 (physical block number)
  2156                              <1> 	;    r2, r3, r5 (internal)
  2157                              <1> 	;
  2158                              <1> 	; ((AX = R1)) output
  2159                              <1> 	;    (Retro UNIX Prototype : 05/03/2013 - 14/11/2012, UNIXCOPY.ASM)
  2160                              <1> 	;
  2161                              <1> 	; Modified registers: eax, edx, ebx, ecx, esi, edi, ebp
  2162                              <1> 
  2163                              <1> 	; Retro UNIX 386 v2 'mget' procedure
  2164                              <1> 	; source code reference:
  2165                              <1> 	; 'mget' procedure in UNIXHDCP.ASM (25/01/2020) by Erdogan Tan
  2166                              <1> 
  2167                              <1> 	; Get sector/block address for current file pointer
  2168                              <1> 	; (If file pointer points to a number greater than current file
  2169                              <1> 	; size, a new -empty- sector/block will be created/written.)
  2170                              <1> 
  2171                              <1> 	; Note: 'mget' procedure will be used for only RUNIX v2 FS.
  2172                              <1> 	;	(installable file system drivers will not use 'mget')
  2173                              <1> 	;	 !!! 512 bytes per sector !!!  ; 02/05/2020
  2174                              <1> 
  2175                              <1> 	; ! 64 bit fofp ! but Retro UNIX 386 v2 kernel will use 32 bit
  2176                              <1> 	; file offset for regular files and directories.
  2177                              <1> 	; ('mget' procedure will be called for regular files & directories)
  2178                              <1> 
  2179                              <1> 	; 28/10/2021
  2180                              <1> 	; Note: 'mget' uses only current inode ([ii], 'inode:')
  2181                              <1> 	; (inode must be loaded at 'inode:' addr by 'iget' before 'mget')  
  2182                              <1> 
  2183                              <1> 		; mov *u.fofp,mq / file offset in mq
  2184                              <1> 		; clr ac / later to be high sig
  2185                              <1> 		; mov $-8,lsh   / divide ac/mq by 256.
  2186                              <1> 		; mov mq,r2
  2187                              <1> 		; bit $10000,i.flgs / lg/sm is this a large or small file
  2188                              <1> 		; bne 4f / branch for large file
  2189                              <1> 
  2190                              <1> 	; 09/01/2022
  2191                              <1> 	; Return: eax = physical block/sector number
  2192                              <1> mget_0:	
  2193 000047EA 8B35[586C0000]      <1>         mov     esi, [u.fofp]
  2194 000047F0 8B1E                <1> 	mov	ebx, [esi]
  2195                              <1>         ; ebx = file offset
  2196                              <1> 
  2197                              <1> 	; 20/08/2021
  2198 000047F2 C1EB09              <1> 	shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
  2199                              <1> 
  2200 000047F5 F605[C5670000]10    <1> 	test	byte [i.flgs+1], 10h ; is this a large or small file addr?
  2201 000047FC 7405                <1> 	jz	short mget_1 ; small file addressing
  2202 000047FE E984000000          <1> 	jmp	mget_5	; large file addressing
  2203                              <1> mget_1:
  2204                              <1> 	; If large file flag is clear -not set- RUNIX v2 FS inode
  2205                              <1> 	; will contain 10 direct disk block/sector dword pointers.
  2206                              <1> 
  2207                              <1> 	; 05/05/2020
  2208                              <1> 	;shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
  2209                              <1> 
  2210 00004803 83FB0A              <1> 	cmp	ebx, 10	; block 10
  2211 00004806 7338                <1> 	jnb	short mget_3 ; file offset >= 5120
  2212                              <1> 
  2213                              <1> 	; 05/05/2020
  2214                              <1> 	;cmp	ebx, 5120
  2215                              <1> 	;jnb	short mget_3 ; file offset >= 5120
  2216                              <1> 
  2217                              <1> 	;mov	bl, bh
  2218                              <1> 	;and	bl, 1Eh ; clear all bits but bits 1,2,3,4 ; 0,2,..,18
  2219                              <1> 	;	; max. value = 12h = 10010b = 18 (because ebx <= 5119) 
  2220                              <1> 	;shl	bl, 1	; * 2 ; max. value = 24h = 100100b = 36
  2221                              <1> 	;xor	bh, bh  ; clear bh
  2222                              <1> 		; RUNIX v2 (RUFS 2) file system bytes per sector value
  2223                              <1> 		; is always 512.
  2224                              <1> 		; ebx = 4*(ebx/512)  = 0 to 36
  2225                              <1> 
  2226                              <1> 	; 05/05/2020
  2227 00004808 C0E302              <1> 	shl	bl, 2 ; * 4
  2228                              <1> 		 ; ebx = 0 to 36
  2229                              <1> 
  2230 0000480B 8B83[D0670000]      <1> 	mov	eax, [ebx+i.dskp] ; disk sector addr ptr 0 to 9 for file
  2231                              <1> 	; 22/08/2021
  2232 00004811 89DE                <1> 	mov	esi, ebx
  2233                              <1> 	;xor	ebx, ebx ; 0
  2234                              <1> 	; 09/03/2022
  2235                              <1> 	;; 09/01/2022
  2236                              <1> 	;xor	bl, bl
  2237                              <1> 
  2238 00004813 09C0                <1> 	or	eax, eax
  2239 00004815 7512                <1> 	jnz	short mget_2 ; existing block/sector (logical)
  2240                              <1> 
  2241 00004817 56                  <1> 	push	esi ; * ; 22/08/2021
  2242 00004818 E872010000          <1> 	call	alloc_m ; 24/05/2020	
  2243                              <1> 	;call	alloc	; allocate a new sector/block for this file	
  2244                              <1> 			; eax = sector/block number
  2245                              <1> 			; ebx = buffer header address
  2246 0000481D 5E                  <1> 	pop	esi ; * ; 22/08/2021
  2247                              <1> 	; 28/11/2021
  2248                              <1> 	;jc	short mget_2 
  2249                              <1> 			; cf = 1 -> eax = 'no free block' error
  2250                              <1> 	; 22/08/2021
  2251 0000481E 8986[D0670000]      <1> 	mov	[esi+i.dskp], eax  ; logical sector/block address
  2252                              <1> 
  2253                              <1> 	; 09/01/2022
  2254 00004824 E8BF040000          <1> 	call	setimod	; set inode modification flag
  2255                              <1> 			; and set modification time
  2256                              <1> 
  2257                              <1> 	; eax = logical sector/block number
  2258                              <1> 	; ([idev] = logical drive number)
  2259                              <1> 	; 28/10/2021
  2260                              <1> 	; [cdev] = logical drive number (0 or 1)
  2261                              <1> 	;	(0 = root fs, 1 = mounted fs)
  2262                              <1> mget_2:
  2263                              <1> 	; 09/01/2022
  2264                              <1> 	; eax = logical sector/block number
  2265 00004829 F605[216C0000]01    <1> 	test	byte [cdev], 1
  2266 00004830 7507                <1> 	jnz	short mget_14
  2267                              <1> 	; convert to physical sector/block number
  2268 00004832 0305[F86C0000]      <1> 	add	eax, [systm+SB.BootSectAddr]
  2269 00004838 C3                  <1> 	retn
  2270                              <1> 	; 09/01/2022
  2271                              <1> mget_14:
  2272                              <1> 	; convert to physical sector/block number
  2273 00004839 0305[006F0000]      <1> 	add	eax, [mount+SB.BootSectAddr]
  2274 0000483F C3                  <1> 	retn
  2275                              <1> 	
  2276                              <1> 		; rts r0
  2277                              <1> mget_3: ; 3: / adding on block which changes small file to a large file
  2278                              <1> 	; 22/11/2021
  2279 00004840 E84A010000          <1> 	call	alloc_m ; 24/05/2020
  2280                              <1> 	;call	alloc	; allocate a new sector/block for this file
  2281                              <1> 			; eax = sector/block number
  2282                              <1> 			; ebx = buffer header  ; 24/05/2020
  2283                              <1> 	; 28/11/2021
  2284                              <1> 	;jc	short mget_2 ; error code in eax
  2285                              <1> 
  2286                              <1> 	; 09/01/2022
  2287                              <1> 	; convert to physical block/sector number
  2288 00004845 50                  <1> 	push	eax ; *!* ; logical sector/block number 
  2289 00004846 E8DEFFFFFF          <1> 	call	mget_2
  2290                              <1> 
  2291                              <1>         ; EAX (r1) = Physical block (sector) number
  2292 0000484B E886110000          <1> 	call 	wslot
  2293                              <1> 		; jsr r0,wslot / set up I/O buffer for write, r5 points to 
  2294                              <1> 			     ; / first data word in buffer
  2295                              <1>         ; EAX (r1) = Physical block number
  2296                              <1> 	; 28/11/2021
  2297                              <1> 	; ebx = buffer (data) address
  2298                              <1> 	; 22/11/2021
  2299 00004850 31C9                <1> 	xor	ecx, ecx
  2300 00004852 B10A                <1> 	mov 	cl, 10	; r3, transfer old physical block pointers
  2301                              <1> 			; into new indirect block area for the new
  2302                              <1> 			; large file		
  2303 00004854 89DF                <1> 	mov 	edi, ebx ; r5
  2304 00004856 BE[D0670000]        <1> 	mov	esi, i.dskp  ; current inode's direct disk addr ptrs
  2305 0000485B 89C2                <1> 	mov	edx, eax
  2306 0000485D 31C0                <1> 	xor	eax, eax
  2307                              <1> mget_4:
  2308 0000485F A5                  <1> 	movsd 	
  2309 00004860 8946FC              <1> 	mov	[esi-4], eax ; 0
  2310 00004863 E2FA                <1> 	loop	mget_4
  2311                              <1> 
  2312                              <1> 	; 22/11/2021
  2313 00004865 B176                <1> 	mov 	cl, 128-10 ; clear rest of data buffer
  2314                              <1> ;mget_4: ; 1
  2315 00004867 F3AB                <1> 	rep 	stosd
  2316                              <1> 		; clr (r5)+
  2317                              <1> 		; dec r3
  2318                              <1> 		; bgt 1b
  2319 00004869 89D0                <1> 	mov	eax, edx
  2320                              <1>         ; EAX (r1) = Physical block number
  2321 0000486B E873110000          <1> 	call	dskwr
  2322                              <1> 		; jsr r0,dskwr / write new indirect block on disk
  2323                              <1> 
  2324                              <1> 	;; EAX (r1) = Physical block number
  2325                              <1> 
  2326                              <1> 	; 09/01/2022        
  2327 00004870 8F05[D0670000]      <1> 	pop	dword [i.dskp] ; *!* ; logical sector/block number
  2328                              <1>  
  2329                              <1> 	; eax = logical disk sector/block number/addr ; 09/01/2022
  2330                              <1> 	;mov 	[i.dskp], eax ; 22/11/2021 
  2331                              <1> 		; mov r1,i.dskp / put pointer to indirect block in i-node
  2332                              <1> 
  2333 00004876 800D[C5670000]10    <1> 	or	byte [i.flgs+1], 10000b ; 10h ; 16  ; large file flag
  2334                              <1> 		; bis $10000,i.flgs / set large file bit 
  2335                              <1> 				  ; / in i.flgs word of i-node
  2336 0000487D E866040000          <1> 	call	setimod
  2337                              <1> 		; jsr r0,setimod / set i-node modified flag
  2338                              <1> 
  2339 00004882 E963FFFFFF          <1> 	jmp	mget_0 ; 09/01/2022
  2340                              <1> 		; br mget
  2341                              <1> 
  2342                              <1> mget_5:  ; 4 ; large file
  2343                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
  2344                              <1> 	;
  2345                              <1> 	; Retro UNIX 386 v2 disk inode contains..
  2346                              <1> 	; (if large file flag is set)
  2347                              <1> 	; 8 indirect disk block/sector dword pointers
  2348                              <1> 	; +1 double indirect disk block/sector dword pointers
  2349                              <1> 	; +1 triple indirect disk block/sector dword pointers
  2350                              <1> 
  2351                              <1> 	; check indirect pointers limit (as file offset)
  2352                              <1> 	; 8*128 = 1024 blocks (or sectors) or 512 KB
  2353                              <1> 	; check dx (file offset hw) value
  2354                              <1> 	
  2355                              <1> 	; 03/05/2020
  2356                              <1> 	;cmp	ebx, 524288  ; is file offset >= 524288 ?
  2357                              <1> 	;jnb	short mget_6 ; yes, check double indirect limit
  2358                              <1> 
  2359                              <1> 	; 05/05/2020
  2360 00004887 81FB00040000        <1> 	cmp	ebx, 1024    ; block 1024 (byte 524288)	
  2361 0000488D 7320                <1> 	jnb	short mget_6 ; check double indirect limit
  2362                              <1> 
  2363 0000488F C605[DC6C0000]01    <1> 	mov	byte [level], 1 ; levels, 1 = indirect blocks
  2364                              <1> 
  2365                              <1> 	; 05/05/2020
  2366                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
  2367                              <1> 
  2368 00004896 88D9                <1> 	mov	cl, bl
  2369 00004898 80E17F              <1> 	and	cl, 127
  2370 0000489B 880D[DD6C0000]      <1> 	mov	[level+1], cl ; level 1, direct block ptr index (0 to 127)
  2371                              <1> 	;shr	bx, 7 ; bl = level 0, indirect block pointer index (0 to 7)
  2372                              <1> 	; 17/07/2022
  2373 000048A1 C1EB07              <1> 	shr	ebx, 7
  2374                              <1> 	;mov	[level+2], bl
  2375                              <1> 
  2376 000048A4 C0E302              <1> 	shl	bl, 2 ; * 4 to convert index number to offset
  2377                              <1> 
  2378                              <1> 	;mov	esi, i.dskp
  2379                              <1> 	;add	esi, ebx
  2380                              <1> 
  2381 000048A7 8DB3[D0670000]      <1> 	lea	esi, [ebx+i.dskp]
  2382                              <1> 
  2383 000048AD EB64                <1> 	jmp	short mget_8
  2384                              <1> 
  2385                              <1> mget_6:
  2386                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  2387                              <1> 	; 03/05/2020
  2388                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
  2389                              <1> 	; check double indirect pointer limit (as file offset)
  2390                              <1> 	; (128*128)+1024 = 16384+1024 blocks or 8 MB + 512 KB
  2391                              <1> 	; check dx (file offset hw) value
  2392                              <1> 	
  2393                              <1> 	;cmp	ebx, 8912896 ; >= 17408 sectors (16384+1024) ?	
  2394                              <1> 	;jnb	short mget_7 ; yes, use triple indirect pointer (block)
  2395                              <1> 
  2396                              <1> 	; 05/05/2020
  2397 000048AF 81FB00440000        <1> 	cmp	ebx, 17408   ; block 17408 (byte 8912896)	
  2398 000048B5 7328                <1> 	jnb	short mget_7 ; use triple indirect pointer (block)
  2399                              <1> 
  2400 000048B7 C605[DC6C0000]02    <1> 	mov	byte [level], 2  ; levels, 2 = double indirect blocks
  2401                              <1> 	
  2402                              <1> 	;sub	ebx, 524288 ; 1024 sectors
  2403                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
  2404                              <1> 			; (from sector 1024)
  2405                              <1> 	; 05/05/2020
  2406 000048BE 81EB00040000        <1> 	sub	ebx, 1024 ; offset from sector 1024
  2407                              <1> 	
  2408 000048C4 88D9                <1> 	mov	cl, bl
  2409 000048C6 80E17F              <1> 	and	cl, 127
  2410 000048C9 880D[DD6C0000]      <1> 	mov	[level+1], cl
  2411                              <1> 			; level 2, direct block ptr index (0 to 127)	
  2412                              <1> 	;shr	bx, 7
  2413                              <1> 	; 17/07/2022
  2414 000048CF C1EB07              <1> 	shr	ebx, 7
  2415 000048D2 881D[DE6C0000]      <1> 	mov	[level+2], bl
  2416                              <1> 			; level 1, indirect block ptr index (0 to 127)
  2417                              <1> 
  2418 000048D8 BE[F0670000]        <1> 	mov	esi, i.dskp + 32 ; 8*4
  2419                              <1> 			; level 0, double indirect block pointer
  2420 000048DD EB34                <1> 	jmp	short mget_8
  2421                              <1> 
  2422                              <1> mget_7:
  2423                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  2424                              <1> 	; 03/05/2020
  2425                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
  2426                              <1> 	; triple indirect pointer ; 8912896 to 1082654720 bytes
  2427                              <1> 	;mov	esi, i.dskp + 36 ; 9*4
  2428                              <1> 
  2429 000048DF C605[DC6C0000]03    <1> 	mov	byte [level], 3  ; levels, 3 = triple indirect blocks
  2430                              <1> 
  2431                              <1> 	;sub	ebx, 8912896 ; 17408 sectors (16384+1024)
  2432                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
  2433                              <1> 			; (from sector 17408)
  2434                              <1> 	; 05/05/2020
  2435 000048E6 81EB00440000        <1> 	sub	ebx, 17408 ; offset from sector 17408	
  2436                              <1> 
  2437 000048EC 88D9                <1> 	mov	cl, bl
  2438 000048EE 80E17F              <1> 	and	cl, 127
  2439 000048F1 880D[DD6C0000]      <1> 	mov	[level+1], cl  
  2440                              <1> 			; level 3, direct block ptr index (0 to 127)	
  2441 000048F7 C1EB07              <1> 	shr	ebx, 7	
  2442 000048FA 88D9                <1> 	mov	cl, bl
  2443 000048FC 80E17F              <1> 	and	cl, 127
  2444 000048FF 880D[DE6C0000]      <1> 	mov	[level+2], cl
  2445                              <1> 			; level 2, indirect block ptr index (0 to 127)
  2446                              <1> 	;shr	bx, 7
  2447                              <1> 	; 17/07/2022
  2448 00004905 C1EB07              <1> 	shr	ebx, 7
  2449 00004908 881D[DF6C0000]      <1> 	mov	[level+3], bl
  2450                              <1> 			; level 1, double indir blk ptr index (0 to 127)
  2451                              <1> 
  2452 0000490E BE[F4670000]        <1> 	mov	esi, i.dskp + 36 ; 9*4
  2453                              <1> 			; level 0, triple indirect block pointer
  2454                              <1> mget_8:
  2455                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  2456 00004913 8B06                <1> 	mov	eax, [esi]
  2457 00004915 09C0                <1> 	or 	eax, eax ; R1
  2458 00004917 751A                <1> 	jnz 	short mget_10 ; 2f
  2459                              <1> 		; bne 2f / if no indirect block exists
  2460 00004919 56                  <1> 	push	esi	; * ; 24/05/2020
  2461                              <1> 
  2462 0000491A E870000000          <1> 	call	alloc_m ; 24/05/2020
  2463                              <1> 	;call	alloc	; allocate a new block for this file	
  2464                              <1> 			; eax = block number
  2465                              <1> 			; ebx = buffer header address
  2466                              <1> 			; [pdn] = physical drive number ; 25/05/2020
  2467                              <1> 	;jc	mget_2	; cf -> 1 & eax = 0 -> no free block
  2468                              <1> 
  2469 0000491F 5E                  <1> 	pop	esi	; * ; 24/05/2020
  2470                              <1> 	;jc	short mget_9
  2471                              <1> 
  2472                              <1> 	; 09/01/2022
  2473                              <1> 	; eax = logical sector/block number
  2474                              <1> 
  2475 00004920 8906                <1> 	mov	[esi], eax ; record sector/block address on i.dskp area
  2476                              <1> 
  2477 00004922 E8C1030000          <1> 	call 	setimod
  2478                              <1> 		; jsr r0,setimod / set i-node modified byte
  2479                              <1> 	; EAX = new block number (logical)
  2480                              <1> 
  2481                              <1> 	; 09/01/2022
  2482                              <1> 	; convert to physical block/sector number
  2483 00004927 E8FDFEFFFF          <1> 	call	mget_2
  2484                              <1> 	;
  2485 0000492C E8AEFDFFFF          <1> 	call 	clear
  2486                              <1> 		; jsr r0,clear / clear new block
  2487                              <1> 	; 09/03/2022
  2488                              <1> 	;add	ebx, 8
  2489                              <1> 	; ebx = buffer data address
  2490                              <1> 	; 22/11/2021
  2491 00004931 EB0A                <1> 	jmp	short mget_11
  2492                              <1> ;mget_9:
  2493                              <1> ;	pop	edx ; *  ; 09/01/2022
  2494                              <1> ;	retn
  2495                              <1> mget_10: ;2
  2496                              <1> 	; 09/01/2022
  2497                              <1> 	; eax = logical sector/block number/address
  2498                              <1> 	; convert to physical sector/block number/address
  2499 00004933 E8F1FEFFFF          <1> 	call	mget_2	
  2500                              <1> 	; 05/03/2013
  2501                              <1> 	; EAX = r1, physical block number (of indirect block)
  2502 00004938 E835100000          <1> 	call 	dskrd ; read indirect block
  2503                              <1> 		; jsr r0,dskrd / read in indirect block
  2504                              <1> 	;jc	short mget_9
  2505                              <1> mget_11:
  2506                              <1> 	; 22/11/2021
  2507                              <1> 	; eax = physical block/sector address
  2508                              <1> 	; ebx = buffer (data) address ; 09/03/2022
  2509                              <1> 
  2510 0000493D 89C2                <1> 	mov	edx, eax ; *  ; save physical sector number in edx
  2511                              <1> 
  2512 0000493F 0FB605[DC6C0000]    <1> 	movzx	eax, byte [level]
  2513 00004946 8A80[DC6C0000]      <1> 	mov	al, [eax+level] ; get sector pointer offset
  2514 0000494C C1E002              <1> 	shl	eax, 2 ; * 4 ; 09/01/2022
  2515                              <1> 	;shl	ax, 2 ; * 4
  2516                              <1> 
  2517 0000494F 01C3                <1> 	add	ebx, eax
  2518                              <1> 
  2519 00004951 8B03                <1> 	mov 	eax, [ebx] ; put logical block no of block
  2520                              <1> 			   ; in file sought in R1 (EAX)
  2521                              <1> 		; mov (r2),r1 / put physical block no of block in file
  2522                              <1> 	               	    ; / sought in r1
  2523                              <1> 
  2524 00004953 21C0                <1> 	and	eax, eax  ; if logical sector/block number is zero
  2525                              <1> 			  ; then we need a new block for file
  2526 00004955 740D                <1> 	jz	short mget_12
  2527                              <1> 
  2528 00004957 FE0D[DC6C0000]      <1> 	dec	byte [level]
  2529 0000495D 75D4                <1> 	jnz	short mget_10
  2530                              <1> 
  2531                              <1> 	; 09/03/2022
  2532                              <1> 	;sub	ebx, ebx ; ebx = 0 ; existing sector
  2533                              <1> 
  2534                              <1> 	;retn
  2535                              <1> 	; 09/01/2022
  2536                              <1> 	; eax = logical block/sector number
  2537 0000495F E9C5FEFFFF          <1> 	jmp	mget_2
  2538                              <1> 
  2539                              <1> mget_12:
  2540                              <1> 	; 22/11/2021
  2541 00004964 52                  <1> 	push	edx ; *
  2542 00004965 53                  <1> 	push	ebx ; ** ; buffer data position
  2543 00004966 E824000000          <1> 	call	alloc_m
  2544                              <1> 	;call	alloc	 ; allocate a new block for this file	
  2545                              <1> 			 ; eax = block number (logical)
  2546                              <1> 			 ; ebx = buffer header address
  2547 0000496B 5E                  <1> 	pop	esi ; **
  2548                              <1> 	; 09/01/2022
  2549                              <1> 	;pop	edx ; *
  2550                              <1> 	;jc	short mget_9 ; cf -> 1 & eax = 0 -> no free block
  2551                              <1> 
  2552 0000496C 8906                <1> 	mov	[esi], eax ; record/save block number (logical)
  2553                              <1> 
  2554                              <1> 	; 22/11/2021
  2555 0000496E 870424              <1> 	xchg	eax, [esp] ; *
  2556                              <1> 
  2557                              <1> 	; eax (r1) = physical block number (of indirect block)
  2558 00004971 E860100000          <1> 	call 	wslot
  2559                              <1> 		; jsr r0,wslot
  2560                              <1>         ; eax (r1) = physical block number
  2561                              <1> 	; ebx (r5) = pointer to buffer (indirect block)
  2562 00004976 E868100000          <1> 	call 	dskwr
  2563                              <1> 	; eax = r1 = physical block number (of indirect block)
  2564                              <1> 		; jsr r0,dskwr / write newly modified indirect block 
  2565                              <1> 			     ; / back out on disk
  2566 0000497B 58                  <1> 	pop	eax ; *  ; 31/07/2013
  2567                              <1> 		; mov (sp),r1 / restore block number of new block	
  2568                              <1> 
  2569                              <1> 	; 09/01/2022
  2570                              <1> 	; eax = logical sector/block number/address of new block
  2571                              <1> 	; convert to physical sector/block number/address
  2572 0000497C E8A8FEFFFF          <1> 	call	mget_2	
  2573                              <1> 
  2574 00004981 E859FDFFFF          <1> 	call 	clear
  2575                              <1> 		; jsr r0,clear / clear new block
  2576                              <1> 
  2577 00004986 FE0D[DC6C0000]      <1> 	dec	byte [level]
  2578 0000498C 75AF                <1> 	jnz	short mget_11 
  2579                              <1> 		; ebx = buffer (data) address ; 09/03/2022
  2580                              <1> 
  2581                              <1> 	; 09/01/2022
  2582                              <1> 	; eax = physical sector/block number/address of new block
  2583                              <1> 	
  2584                              <1> 	; 22/11/2021
  2585                              <1> 	; ebx = buffer address
  2586                              <1> mget_13: ; 2
  2587                              <1> 	; eax (r1) = Block number of new block
  2588 0000498E C3                  <1> 	retn
  2589                              <1> 		; rts r0
  2590                              <1> 
  2591                              <1> 	; 09/01/2022
  2592                              <1> 	; 26/11/2021
  2593                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2594                              <1> alloc_m:
  2595                              <1> 	; 27/11/2021
  2596                              <1> 	; 28/10/2021
  2597                              <1> 	; 07/05/2021
  2598                              <1> 	; 26/05/2020
  2599                              <1> 	; 25/05/2020
  2600                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
  2601                              <1> 	; 'alloc' call in 'mget'
  2602                              <1> 	;
  2603                              <1> 	; (('mget_r' will be returned with error))
  2604                              <1> 	; (('mget_w' will continue to 'alloc'))
  2605                              <1> 
  2606                              <1> 	; Note: 'sysread' will return with cf = 0, eax = 0
  2607                              <1> 	; if [fofp] >= file size (eax = 0 --> EOF)
  2608                              <1> 	; So, if we are here, that means [fofp] < file size
  2609                              <1> 	;     but disk address is 0. 
  2610                              <1> 	
  2611 0000498F 803D[DA6C0000]01    <1> 	cmp	byte [mget_rw], 1 ; write access ? (mget_w) 
  2612 00004996 730F                <1> 	jnb	short alloc ; yes (this is a call from 'mget_w')
  2613                              <1> 	; ((cf = 1))	
  2614                              <1> 	; no (this is a call from 'mget_r') !
  2615                              <1> 	;mov	eax, ERR_FILE_SIZE ; file size error (inode error!)
  2616                              <1> 		; [User may change this empty/invalid inode (disk) sector
  2617                              <1> 		; pointer with a new valid inode (disk) sector pointer 
  2618                              <1> 		; by writing new clear (zero) sector to same file position
  2619                              <1> 		; in order to correct file size -inode parm/content- error.
  2620                              <1> 		; It may be useful for recovering lost data if other sector
  2621                              <1> 		; pointers are not empty.]	
  2622                              <1> 	;retn
  2623                              <1> 	; 27/11/2021
  2624 00004998 C705[B86C0000]1400- <1> 	mov	dword [u.error], ERR_FILE_SIZE 
  2624 000049A0 0000                <1>
  2625                              <1> 			; file size error (inode error!)
  2626 000049A2 E9A0E7FFFF          <1> 	jmp	error
  2627                              <1> alloc:
  2628                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  2629                              <1> 	; 27/11/2021
  2630                              <1> 	; 26/11/2021 - Major modification for Runix v2 file system
  2631                              <1> 	;	(I have called this kernel version as v1.2, it is a
  2632                              <1> 	;	 debug/test version just before Retro UNIX 386 v2 kernel)
  2633                              <1> 	;	((there were running problems on new version, 
  2634                              <1> 	;	  so i am developing an intermediate version with minimum
  2635                              <1> 	;	  modification on v1.1 code which is successfuly running))
  2636                              <1> 	;	 ; /// Erdogan Tan - Istanbul, 26/11/2021 /// 
  2637                              <1> 	;	 
  2638                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  2639                              <1> 	; 01/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  2640                              <1> 	;
  2641                              <1> 	; get a free block and 
  2642                              <1> 	; set the corresponding bit in the free storage map
  2643                              <1> 	; 
  2644                              <1> 	; INPUTS ->
  2645                              <1> 	;    cdev (current device)
  2646                              <1> 	;    r2 
  2647                              <1> 	;    r3
  2648                              <1> 	; OUTPUTS ->
  2649                              <1> 	;    r1 (physical block number of block assigned)
  2650                              <1> 	;    smod, mmod, systm (super block), mount (mountable super block)	
  2651                              <1> 	;
  2652                              <1> 	; ((AX = R1)) output
  2653                              <1> 	;    (Retro UNIX Prototype : 14/11/2012 - 21/07/2012, UNIXCOPY.ASM)
  2654                              <1>         ;    ((Modified registers: edx, ecx)) 
  2655                              <1> 
  2656                              <1> 	; 26/11/2021
  2657                              <1> 	; INPUT:
  2658                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
  2659                              <1> 	; OUTPUT:
  2660                              <1> 	;	eax = disk block/sector number/address (physical)
  2661                              <1> 	;	(ebx = disk buffer address for sector/block in eax)
  2662                              <1> 	;
  2663                              <1> 	;    Note:	
  2664                              <1> 	;	Free blocks map will be modified and written to it's disk.
  2665                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
  2666                              <1> 	;	modification flag will be set; but the superblock 
  2667                              <1> 	;	will not be written to it's disk in this 'alloc' procedure)
  2668                              <1> 	;
  2669                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi, ebp
  2670                              <1> 
  2671                              <1> 	; 09/01/2022
  2672                              <1> 	; Return: eax = logical block/sector number 
  2673                              <1> 
  2674                              <1> 	; 26/11/2021
  2675 000049A7 BB[F46C0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
  2676                              <1> 		; mov $systm,r2 / start of inode and free storage map for drum
  2677 000049AC F605[216C0000]01    <1> 	test	byte [cdev], 1
  2678                              <1> 		; tst cdev
  2679 000049B3 7405                <1> 	jz	short alloc_1
  2680                              <1> 		; beq 1f / drum is device
  2681 000049B5 BB[FC6E0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
  2682                              <1> 		; mov $mount,r2 / disk or tape is device, start of inode and
  2683                              <1> 			      ; / free storage map
  2684                              <1> alloc_1: ; 1
  2685                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
  2686 000049BA F6436A01            <1> 	test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
  2687 000049BE 7507                <1> 	jnz	short alloc_2  ; 'read only file system' error
  2688                              <1> 	;
  2689 000049C0 8B4B38              <1> 	mov	ecx, [ebx+SB.FreeBlocks] ; count of free blocks/sectors
  2690 000049C3 21C9                <1> 	and	ecx, ecx
  2691 000049C5 750F                <1> 	jnz	short alloc_3
  2692                              <1> alloc_2:
  2693                              <1> 	; 'no free blocks on disk !' error
  2694 000049C7 C705[B86C0000]2100- <1> 	mov	dword [u.error], ERR_ALLOC
  2694 000049CF 0000                <1>
  2695 000049D1 E971E7FFFF          <1> 	jmp	error
  2696                              <1> alloc_3:
  2697                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
  2698 000049D6 31C0                <1> 	xor	eax, eax
  2699                              <1> 	; 23/07/2021
  2700 000049D8 8B4B3C              <1> 	mov	ecx, [ebx+SB.FirstFreeBlk] ; 1st free sector number
  2701                              <1> 					 ; (as logical sector number)
  2702 000049DB 09C9                <1> 	or	ecx, ecx
  2703 000049DD 7415                <1> 	jz	short alloc_5 ; 0 = initial/reset value or 'not valid'
  2704 000049DF 41                  <1> 	inc	ecx ; 0FFFFFFFFh -> 0
  2705 000049E0 7412                <1> 	jz	short alloc_5 ; 'not valid' or 'not calculated'
  2706 000049E2 49                  <1> 	dec	ecx ; restore first free block value
  2707 000049E3 89C8                <1> 	mov	eax, ecx
  2708                              <1> 	; 1 allocation byte (in fbm) is for 8 sectors
  2709 000049E5 C1E903              <1> 	shr	ecx, 3	; first free block number / 8
  2710 000049E8 80E1FC              <1> 	and	cl, ~3	; dword alignment (to backward)
  2711                              <1> 	; 27/11/2021
  2712 000049EB 890D[E06C0000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm
  2713                              <1> alloc_4:
  2714 000049F1 C1E80C              <1> 	shr	eax, 12 ; 1 fbm sector for 4096 sectors
  2715                              <1> alloc_5:
  2716                              <1> 	; 26/11/2021
  2717 000049F4 53                  <1> 	push	ebx ; ** ; superblock buffer address 
  2718                              <1> 	; eax = fbm sector index
  2719 000049F5 A3[E46C0000]        <1> 	mov	[free_map_index], eax
  2720 000049FA 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
  2721                              <1> 			; free blocks map start sector addr
  2722                              <1> 	; 09/01/2022
  2723 000049FD 034304              <1> 	add	eax, [ebx+SB.BootSectAddr] 
  2724                              <1> 			; + Hidden Sectors
  2725                              <1> 	;
  2726                              <1> 	; eax = physical sector number
  2727 00004A00 E86D0F0000          <1> 	call	dskrd
  2728                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
  2729                              <1> 	; eax = physical sector number
  2730                              <1> 	; ebx = buffer data address
  2731                              <1> 	; 27/11/2021
  2732 00004A05 8B15[E06C0000]      <1> 	mov	edx, [free_map_offset] ; byte position on fbm
  2733 00004A0B A3[E86C0000]        <1> 	mov	[free_map_sector], eax ; physical sector number
  2734 00004A10 B9FF010000          <1> 	mov	ecx, 511
  2735                              <1> 	;and	edx, 511
  2736 00004A15 21CA                <1> 	and 	edx, ecx ; fbm byte offset in fbm buffer
  2737 00004A17 41                  <1> 	inc	ecx ; 512
  2738 00004A18 01D9                <1> 	add	ecx, ebx
  2739 00004A1A 01DA                <1> 	add	edx, ebx ; + buffer address
  2740 00004A1C 5B                  <1> 	pop	ebx ; ** ; superblock buffer address 
  2741                              <1> 	;
  2742                              <1> 	; ebx = superblock buffer address
  2743                              <1> 	; edx = fbm buffer address + byte offset (dword aligned)
  2744                              <1> 	; ecx = fbm buffer address + 512
  2745                              <1> alloc_6:
  2746                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
  2747                              <1> 	;		for Retro UNIX 386 v1.2
  2748                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 code
  2749                              <1> 	; (dword scan) ((1 dword = 32 sectors, 1 byte = 8 sectors))
  2750                              <1> 	; ((Note: Logical drive size must be multiplies of 32 sectors))
  2751                              <1> 	; 19/05/2020
  2752                              <1> 	; edx = free blocks map byte address 
  2753 00004A1D 0FBC02              <1> 	bsf	eax, [edx] ; Scans source operand for first bit set (1).
  2754                              <1> 			  ; Clear ZF if a bit is found set (1) and 
  2755                              <1> 			  ; loads the destination with an index to
  2756                              <1> 			  ; first set bit. (0 -> 31) 
  2757                              <1> 			  ; Sets ZF to 1 if no bits are found set.
  2758 00004A20 752A                <1> 	jnz	short alloc_8 ; ZF = 0 -> a free block has been found
  2759                              <1> 
  2760 00004A22 A1[E06C0000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
  2761 00004A27 83C004              <1> 	add	eax, 4 ; next dword
  2762 00004A2A 3B431C              <1> 	cmp	eax, [ebx+SB.FreeMapSize] ; fbm size in bytes
  2763 00004A2D 7209                <1> 	jb	short alloc_7
  2764                              <1> 	; invalidate superblock's first free block field
  2765 00004A2F C7433CFFFFFFFF      <1> 	mov	dword [ebx+SB.FirstFreeBlk], 0FFFFFFFFh
  2766                              <1> 	; 'no free blocks on disk !' error
  2767 00004A36 EB8F                <1> 	jmp	alloc_2
  2768                              <1> alloc_7:
  2769                              <1> 		; 26/05/2020
  2770                              <1> 		; NOTE: If ldrv size is not multiplies of 32 sectors,
  2771                              <1> 		; mod (ldrv size / 32) sectors (at the end of ldrv)
  2772                              <1> 		; can not be allocated (for regular files or dirs)! 
  2773                              <1> 		; (Kernel or runix fs installation program can use
  2774                              <1> 		;  this fact to save/duplicate critical sectors/data 
  2775                              <1> 		;  onto end sectors of that logical drive's runix fs.)
  2776                              <1> 
  2777                              <1> 	; 26/11/2021
  2778 00004A38 A3[E06C0000]        <1> 	mov	[free_map_offset], eax
  2779                              <1> 	; 28/07/2021
  2780                              <1> 	; set next first free block value for search
  2781 00004A3D C1E003              <1> 	shl	eax, 3 ; * 8 ; first free block
  2782                              <1>  	; 26/11/2021
  2783 00004A40 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
  2784                              <1> 	; search (scan) for next free block map dword (in buffer)
  2785 00004A43 83C204              <1> 	add	edx, 4 ; next dword
  2786 00004A46 39CA                <1> 	cmp	edx, ecx
  2787 00004A48 72D3                <1> 	jb	short alloc_6
  2788                              <1> 	; 27/11/2021
  2789 00004A4A EBA5                <1> 	jmp	short alloc_4
  2790                              <1> 
  2791                              <1> alloc_8:
  2792                              <1> 	; 26/11/2021
  2793                              <1> 	; convert bit index to xor value
  2794                              <1> 	; and then set allocated flag for corresponding fbm bit 
  2795 00004A4C 89C1                <1> 	mov	ecx, eax
  2796                              <1> 	;mov	cl, al 
  2797                              <1> 	;sub	eax, eax
  2798                              <1> 	;inc	al ; eax = 1
  2799 00004A4E B001                <1> 	mov	al, 1
  2800 00004A50 D3E0                <1> 	shl	eax, cl
  2801 00004A52 3102                <1> 	xor	[edx], eax  ; clear allocated block's bit in the fbm
  2802                              <1> 	; zero bit means allocated disk block (1 means free disk block) 
  2803                              <1> 
  2804 00004A54 A1[E06C0000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
  2805                              <1> 		; note: eax is dword aligned (0,4,8,12..) !
  2806 00004A59 C1E003              <1> 	shl	eax, 3 ; * 8 ; free block number base
  2807 00004A5C 01C8                <1> 	add	eax, ecx ; add allocation bit index (0 to 31)	
  2808 00004A5E 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax ; current free block
  2809                              <1> 				; (which is being allocated here)
  2810                              <1> 
  2811                              <1> 	;mov	eax, [ebx+SB.FreeMapAddr] 
  2812                              <1> 	;		; free blocks map start sector addr
  2813                              <1> 	;add	eax, [free_map_index]
  2814                              <1> 	
  2815                              <1> 	;;add	eax, [ebx+SB.BootSectAddr] 
  2816                              <1> 	;		; + Hidden Sectors
  2817                              <1> 	; eax = physical sector number
  2818                              <1> 	
  2819                              <1> 	; 27/11/2021
  2820 00004A61 A1[E86C0000]        <1> 	mov	eax, [free_map_sector] ; physical sector number
  2821                              <1> 	
  2822 00004A66 E86B0F0000          <1> 	call	wslot
  2823                              <1> 	; ebx = buffer data address (write operation bit is set)
  2824                              <1> 	; eax = physical sector number
  2825                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
  2826                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
  2827                              <1> 
  2828                              <1> 	; 27/11/2021
  2829                              <1> 	;mov	[free_map_buffer], ebx ; save free map buffer address
  2830                              <1> 
  2831 00004A6B E8730F0000          <1> 	call	dskwr ; writes the 1st buffer to sector
  2832                              <1> 		      ; (at the beginning/head of the buffer chain)
  2833                              <1> 
  2834                              <1> 	; if we are here, buffer has been written to disk successfully 
  2835                              <1> 	; (otherwise cpu would jump to 'error' address)
  2836                              <1> 
  2837                              <1> 	; set superblock modified flag
  2838 00004A70 BA[366C0000]        <1> 	mov	edx, smod
  2839 00004A75 BB[F46C0000]        <1> 	mov	ebx, systm
  2840 00004A7A F605[216C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
  2841 00004A81 7406                <1> 	jz	short alloc_9  ; no, root device
  2842                              <1> 	; yes, mounted device
  2843 00004A83 BB[FC6E0000]        <1> 	mov	ebx, mount
  2844                              <1> 	;mov	edx, mmod
  2845 00004A88 42                  <1> 	inc	edx ; edx = offset mmod
  2846                              <1> alloc_9: 
  2847 00004A89 FE02                <1> 	inc	byte [edx] ; superblock modified !
  2848                              <1> 	
  2849                              <1> 	; Allocating a new sector/block (for file) has been completed here.
  2850 00004A8B 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
  2851 00004A8E 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0 
  2852 00004A8F 7405                <1> 	jz	short alloc_10 ; not valid (not set)
  2853 00004A91 48                  <1> 	dec	eax ; Free Blocks
  2854 00004A92 48                  <1> 	dec	eax ; Free Blocks = Free Blocks - 1
  2855 00004A93 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax
  2856                              <1> alloc_10:
  2857 00004A96 E89E100000          <1> 	call	get_system_time
  2858                              <1> 		; eax = current time (as unix epoch time)
  2859                              <1> 	; 30/07/2021
  2860 00004A9B 89435C              <1> 	mov	[ebx+SB.ModifTime], eax
  2861                              <1> 
  2862 00004A9E 8B433C              <1> 	mov	eax, [ebx+SB.FirstFreeBlk] ; allocated block address
  2863 00004AA1 FF433C              <1> 	inc	dword [ebx+SB.FirstFreeBlk] 
  2864                              <1> 				; +1, new value of first free block
  2865                              <1> 				; (new search will be started from here)
  2866                              <1> 				; ((it may not be free, no problem))
  2867                              <1> 
  2868                              <1> 	; put free map buffer address in ebx
  2869                              <1> 	; 27/11/2021
  2870                              <1> 	;mov	ebx, [free_map_buffer]
  2871                              <1> 
  2872 00004AA4 C3                  <1> 	retn	
  2873                              <1> 
  2874                              <1> 	; 11/02/2022
  2875                              <1> 	; 09/01/2022
  2876                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2877                              <1> free:
  2878                              <1> 	; 12/04/2022 (BugFix)
  2879                              <1> 	; 09/03/2022
  2880                              <1> 	; 11/02/2022
  2881                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  2882                              <1> 	; 05/11/2021
  2883                              <1> 	; 29/10/2021 - temporary (simplified code)
  2884                              <1> 	; 14/08/2021
  2885                              <1> 	; 12/06/2021
  2886                              <1> 	; 07/06/2020
  2887                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
  2888                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  2889                              <1> 	; 07/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  2890                              <1> 	;
  2891                              <1> 	; calculates byte address and bit position for given block number
  2892                              <1> 	; then sets the corresponding bit in the free storage map
  2893                              <1> 	; 
  2894                              <1> 	; INPUTS ->
  2895                              <1> 	;    r1 - block number for a block structured device
  2896                              <1> 	;    cdev - current device 
  2897                              <1> 	; OUTPUTS ->
  2898                              <1> 	;    free storage map is updated
  2899                              <1> 	;    smod is incremented if cdev is root device (fixed disk)
  2900                              <1> 	;    mmod is incremented if cdev is a removable disk 	
  2901                              <1> 	;
  2902                              <1> 	;  (Retro UNIX Prototype : 01/12/2012, UNIXCOPY.ASM)
  2903                              <1>         ;  ((Modified registers: DX, CX))  
  2904                              <1> 
  2905                              <1> 	; 27/11/2021
  2906                              <1> 	; INPUT:
  2907                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
  2908                              <1> 	;	eax = disk block/sector number/address (logical)
  2909                              <1> 	; OUTPUT:
  2910                              <1> 	;	ebx = superblock buffer address
  2911                              <1> 	;
  2912                              <1> 	;    Note:	
  2913                              <1> 	;	Free blocks map will be modified and written to it's disk.
  2914                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
  2915                              <1> 	;	modification flag will be set; but the superblock 
  2916                              <1> 	;	will not be written to it's disk in this 'free' procedure)
  2917                              <1> 	;
  2918                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp 
  2919                              <1> 
  2920                              <1> 	; 27/11/2021
  2921 00004AA5 BB[F46C0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
  2922 00004AAA F605[216C0000]01    <1> 	test	byte [cdev], 1
  2923 00004AB1 7405                <1> 	jz	short free_1
  2924 00004AB3 BB[FC6E0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
  2925                              <1> free_1: ; 1
  2926                              <1> 	; 11/02/2022
  2927                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 file system compatibility code
  2928 00004AB8 F6436A01            <1> 	test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
  2929 00004ABC 740F                <1> 	jz	short free_2 
  2930                              <1> 	; 'read only file system' error
  2931 00004ABE C705[B86C0000]1E00- <1> 	mov	dword [u.error], ERR_READ_ONLY_FS
  2931 00004AC6 0000                <1>
  2932 00004AC8 E97AE6FFFF          <1> 	jmp	error
  2933                              <1> free_2:
  2934 00004ACD 89C1                <1> 	mov	ecx, eax ; logical sector/block number
  2935 00004ACF A3[E86C0000]        <1> 	mov	[free_map_sector], eax
  2936 00004AD4 C1E903              <1> 	shr	ecx, 3	; convert to fbmap byte offset
  2937 00004AD7 C1E80C              <1> 	shr	eax, 12 ; convert to fbmap sector index 
  2938                              <1> 			; (1 fb sector for 4096 sectors)
  2939                              <1> 	;and	cl, ~3	; dword alignment (to backward)
  2940                              <1> 	; 11/02/2022
  2941                              <1> 	;and	ecx, 511 ; convert to offset within fbm buffer
  2942 00004ADA 81E1FC010000        <1> 	and	ecx, 1FCh ; 508, dword aligned offset (32 bit scan)
  2943                              <1> 	;
  2944 00004AE0 890D[E06C0000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm buffer
  2945                              <1> 	; 27/11/2021
  2946                              <1> 	; eax = fbm sector index
  2947 00004AE6 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
  2948                              <1> 			; free blocks map start sector address
  2949                              <1> 	; 09/01/2022
  2950 00004AE9 034304              <1> 	add	eax, [ebx+SB.BootSectAddr]
  2951                              <1> 			; + Hidden Sectors
  2952                              <1> 	; 12/04/2022
  2953 00004AEC 53                  <1> 	push	ebx ; (*)
  2954                              <1> 	; ebx = superblock address
  2955                              <1> 	; eax = physical sector number
  2956 00004AED E8800E0000          <1> 	call	dskrd
  2957                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
  2958                              <1> 	; eax = physical sector number
  2959                              <1> 	; ebx = (fbm sector) buffer data address
  2960                              <1> 	; 27/11/2021
  2961 00004AF2 A3[E46C0000]        <1> 	mov	[free_map_index], eax  ; save physical sector address
  2962                              <1> 	; 12/04/2022
  2963 00004AF7 8B15[E06C0000]      <1> 	mov	edx, [free_map_offset] ; byte position in fbm buffer
  2964                              <1> 	; 11/02/2022
  2965                              <1> 	;(EDX contains -rounded down- dword aligned offset value)
  2966 00004AFD 01DA                <1> 	add	edx, ebx ; + (fbm sector) buffer start address
  2967                              <1> 	; 12/04/2022
  2968 00004AFF 5B                  <1> 	pop	ebx ; (*) superblock buffer address 	
  2969                              <1> 	;
  2970 00004B00 29C0                <1> 	sub	eax, eax
  2971 00004B02 A0[E86C0000]        <1> 	mov	al, [free_map_sector] ; logical sector number
  2972                              <1> 	;and	al, 7
  2973                              <1> 	; 11/02/2022
  2974 00004B07 241F                <1> 	and	al, 31 ; 32 bit fbm scan (with dword aligned offset)
  2975                              <1> 
  2976                              <1> 	; al = bit offset in fbm allocation byte
  2977                              <1> 	; edx = buffer address (start+offset)
  2978                              <1> 	; [free_map_offset] = byte position on fbm
  2979                              <1> 	; 27/11/2021
  2980 00004B09 0FAB02              <1> 	bts	[edx], eax  ; copy value of bit position in eax to cf
  2981                              <1> 			    ; then set same bit position at [edx]
  2982 00004B0C 7305                <1> 	jnc	short free_3 ; it was allocated sector
  2983                              <1> 
  2984                              <1> 	; already free sector !? 
  2985                              <1> 	; (nonsence or defective fs)
  2986                              <1> 
  2987 00004B0E 30C0                <1> 	xor	al, al ; 0  ; eax = 0
  2988 00004B10 48                  <1> 	dec	eax ; 0FFFFFFFFh
  2989                              <1> 	;mov	[ebx+SB.FreeBlocks], eax 
  2990                              <1> 		; invalidate free blocks count
  2991 00004B11 EB18                <1> 	jmp	short free_5
  2992                              <1> free_3:
  2993                              <1> 	; 27/11/2021
  2994 00004B13 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
  2995 00004B16 40                  <1> 	inc	eax
  2996                              <1> 	;jz	short free_4 ; 0FFFFFFFFh -> 0 (invalid!)
  2997                              <1> 	; 09/03/2022
  2998 00004B17 7501                <1> 	jnz	short free_4
  2999 00004B19 48                  <1> 	dec	eax  ; 0 -> 0FFFFFFFFh (invalid!)
  3000                              <1> free_4: 
  3001 00004B1A 50                  <1> 	push	eax ; * ; number of free blocks 
  3002                              <1> 	;mov	eax, [free_map_index] ; fbm sector index
  3003                              <1> 	;add	eax, [ebx+SB.FreeMapAddr] 
  3004                              <1> 			; free blocks map start sector address
  3005                              <1> 	;add	eax, [ebx+SB.BootSectAddr]
  3006                              <1> 	;		; + Hidden Sectors
  3007 00004B1B A1[E46C0000]        <1> 	mov	eax, [free_map_index] ; restore physical sector address
  3008                              <1> 	; eax = physical sector number
  3009 00004B20 E8B10E0000          <1> 	call	wslot
  3010                              <1> 	; ebx = buffer data address (write operation bit is set)
  3011                              <1> 	; eax = physical sector number
  3012                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
  3013                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
  3014                              <1> 
  3015 00004B25 E8B90E0000          <1> 	call	dskwr ; writes the 1st buffer to sector
  3016                              <1> 		      ; (at the beginning/head of the buffer chain)
  3017                              <1> 
  3018                              <1> 	; if we are here, buffer has been written to disk successfully 
  3019                              <1> 	; (otherwise cpu would jump to 'error' address)
  3020 00004B2A 58                  <1> 	pop	eax ; *  ; number of free blocks 
  3021                              <1> free_5:
  3022                              <1> 	; eax = number of free blocks 
  3023                              <1> 	;
  3024                              <1> 	; set superblock modified flag
  3025 00004B2B BA[366C0000]        <1> 	mov	edx, smod
  3026 00004B30 BB[F46C0000]        <1> 	mov	ebx, systm
  3027 00004B35 F605[216C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
  3028 00004B3C 7406                <1> 	jz	short free_6 ; no, root device
  3029                              <1> 	; yes, mounted device
  3030 00004B3E BB[FC6E0000]        <1> 	mov	ebx, mount
  3031                              <1> 	;mov	edx, mmod
  3032 00004B43 42                  <1> 	inc	edx ; edx = offset mmod
  3033                              <1> free_6: 
  3034 00004B44 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax 
  3035                              <1> 
  3036 00004B47 A1[E86C0000]        <1> 	mov	eax, [free_map_sector] ; logical sector number
  3037 00004B4C 3B433C              <1> 	cmp	eax, [ebx+SB.FirstFreeBlk]
  3038 00004B4F 7303                <1> 	jnb	short free_7
  3039 00004B51 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
  3040                              <1> free_7:
  3041 00004B54 FE02                <1> 	inc	byte [edx] ; superblock modified !
  3042 00004B56 C3                  <1> 	retn
  3043                              <1> 	
  3044                              <1> iget:
  3045                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  3046                              <1> 	; 30/11/2021
  3047                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  3048                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  3049                              <1> 	; 07/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
  3050                              <1> 	;
  3051                              <1> 	; get a new i-node whose i-number in r1 and whose device is in cdev
  3052                              <1> 	;
  3053                              <1> 	; ('iget' returns current i-number in r1, if input value of r1 is 0)
  3054                              <1> 	; 
  3055                              <1> 	; INPUTS ->
  3056                              <1> 	;    ii - current i-number, rootdir
  3057                              <1> 	;    cdev - new i-node device
  3058                              <1> 	;    idev - current i-node device
  3059                              <1> 	;    imod - current i-node modified flag
  3060                              <1> 	;    mnti - cross device file i-number
  3061                              <1> 	;    r1 - i-numbe rof new i-node
  3062                              <1> 	;    mntd - mountable device number		
  3063                              <1> 	; 	 
  3064                              <1> 	; OUTPUTS ->
  3065                              <1> 	;    cdev, idev, imod, ii, r1
  3066                              <1> 	;
  3067                              <1> 	; ((AX = R1)) input/output
  3068                              <1> 	;
  3069                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
  3070                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
  3071                              <1> 
  3072                              <1> 	; 22/11/2021
  3073                              <1> 	;;mov	dl, [cdev] ; 18/07/2013
  3074                              <1> 	;;mov	dh, [idev] ; 07/08/2013
  3075                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
  3076                              <1> 	;mov	dh, [cdev]
  3077                              <1> 	;mov	dl, [idev]
  3078 00004B57 668B15[206C0000]    <1> 	mov	dx, [idev] ; [idev] in dl, [cdev] in dh
  3079                              <1> 	;
  3080                              <1> 	; 22/11/2021
  3081 00004B5E 25FFFF0000          <1> 	and	eax, 0FFFFh
  3082 00004B63 3B05[1C6C0000]      <1> 	cmp 	eax, [ii]
  3083                              <1> 		; cmp r1,ii / r1 = i-number of current file
  3084 00004B69 7504                <1> 	jne 	short iget_1
  3085                              <1> 		; bne 1f
  3086 00004B6B 38F2                <1> 	cmp	dl, dh
  3087                              <1> 		; cmp idev,cdev
  3088                              <1> 			  ; / is device number of i-node = current device
  3089 00004B6D 746C                <1>         je	short iget_5
  3090                              <1> 	;	; beq 2f
  3091                              <1> 	; 14/08/2021
  3092                              <1> iget_1: ; 1:
  3093 00004B6F 30DB                <1> 	xor	bl, bl
  3094 00004B71 381D[346C0000]      <1> 	cmp	[imod], bl ; 0	
  3095                              <1> 		; tstb imod / has i-node of current file
  3096                              <1> 			  ; / been modified i.e., imod set
  3097 00004B77 7628                <1> 	jna	short iget_2
  3098                              <1> 		; beq 1f
  3099 00004B79 881D[346C0000]      <1> 	mov	[imod], bl ; 0
  3100                              <1> 		; clrb imod / if it has, 
  3101                              <1> 			   ; / we must write the new i-node out on disk
  3102                              <1> 	; 22/11/2021 (32 bit push-pop)
  3103 00004B7F 50                  <1> 	push	eax ; *
  3104                              <1> 		; mov r1,-(sp)
  3105 00004B80 52                  <1> 	push	edx ; **
  3106                              <1> 		; mov cdev,-(sp)
  3107 00004B81 A1[1C6C0000]        <1> 	mov	eax, [ii]
  3108                              <1> 		; mov ii,r1
  3109                              <1> 	;mov	dh, [idev]
  3110                              <1> 	;mov	[cdev], dh
  3111                              <1> 	; 09/01/2022
  3112 00004B86 8815[216C0000]      <1> 	mov	[cdev], dl  ; dl = [idev]
  3113                              <1> 		; mov idev,cdev
  3114 00004B8C FEC3                <1> 	inc	bl ; 1
  3115                              <1> 	; 31/07/2013
  3116 00004B8E 881D[D86C0000]      <1> 	mov     [rw], bl ; 1 == write 
  3117                              <1> 	;;28/07/2013 rw -> u.rw
  3118                              <1>         ;;mov   [u.rw], bl ; 1 == write
  3119 00004B94 E843000000          <1> 	call	icalc
  3120                              <1> 		; jsr r0,icalc; 1
  3121 00004B99 5A                  <1> 	pop	edx ; **
  3122 00004B9A 8835[216C0000]      <1> 	mov	[cdev], dh ; 22/11/2021
  3123                              <1> 		; mov (sp)+,cdev
  3124 00004BA0 58                  <1> 	pop	eax ; *
  3125                              <1> 		; mov (sp)+,r1
  3126                              <1> iget_2: ; 1:
  3127                              <1> 	;and	ax, ax
  3128 00004BA1 21C0                <1> 	and	eax, eax ; 22/11/2021 (32 bit inode number)
  3129                              <1> 		; tst r1 / is new i-number non zero
  3130 00004BA3 7431                <1> 	jz	short iget_4 ; 2f
  3131                              <1> 		; beq 2f / branch if r1=0
  3132                              <1> 
  3133                              <1> 	;mov 	dh, [cdev]
  3134 00004BA5 08F6                <1> 	or	dh, dh ; 22/11/2021
  3135                              <1> 		; tst cdev / is the current device number non zero
  3136                              <1> 			 ; / (i.e., device =/ drum)
  3137 00004BA7 7515                <1> 	jnz	short iget_3 ;  1f
  3138                              <1> 		; bne 1f / branch 1f cdev =/ 0  ;; (cdev != 0)
  3139                              <1> 	; 22/11/2021
  3140 00004BA9 3B05[2A6C0000]      <1> 	cmp	eax, [mnti]
  3141                              <1> 	;cmp	ax, [mnti]			
  3142                              <1> 		; cmp r1,mnti / mnti is the i-number of the cross device
  3143                              <1> 			    ; / file (root directory of mounted device)
  3144 00004BAF 750D                <1> 	jne	short iget_3 ; 1f
  3145                              <1> 		; bne 1f
  3146                              <1>         ;mov    bl, [mntd]
  3147 00004BB1 FEC6                <1> 	inc	dh ; mov dh, 1 ; 22/11/2021
  3148 00004BB3 8835[216C0000]      <1>         mov	[cdev], dh ; 22/11/2021
  3149                              <1> 		; mov mntd,cdev / make mounted device the current device
  3150                              <1> 	; 22/11/2021
  3151 00004BB9 A1[266C0000]        <1> 	mov	eax, [rootdir] ; rootdir = 1 (for runix v2 file system)
  3152                              <1> 	;mov	ax, [rootdir]
  3153                              <1> 		; mov rootdir,r1
  3154                              <1> iget_3: ; 1:
  3155                              <1> 	; 22/11/2021
  3156 00004BBE A3[1C6C0000]        <1> 	mov	[ii], eax ; 32 bit inode number
  3157                              <1> 	;mov	[ii], ax
  3158                              <1> 		; mov r1,ii
  3159                              <1> 	; 30/11/2021
  3160 00004BC3 8835[206C0000]      <1> 	mov	[idev], dh ; cdev 
  3161                              <1> 	;mov	[idev], dl ; cdev
  3162                              <1> 		; mov cdev,idev
  3163 00004BC9 30DB                <1> 	xor	bl, bl
  3164                              <1>         ; 31/07/2013
  3165 00004BCB 881D[D86C0000]      <1> 	mov     [rw], bl ; 0 == read 
  3166                              <1> 	;;28/07/2013 rw -> u.rw       
  3167                              <1>         ;;mov   [u.rw], bl ; 0 = read
  3168 00004BD1 E806000000          <1> 	call	icalc
  3169                              <1> 		; jsr r0,icalc; 0 / read in i-node ii
  3170                              <1> iget_4: ; 2:
  3171                              <1> 	; 22/11/2021
  3172 00004BD6 A1[1C6C0000]        <1> 	mov	eax, [ii]
  3173                              <1> 	;mov	ax, [ii]
  3174                              <1> 		; mov ii,r1
  3175                              <1> iget_5:
  3176 00004BDB C3                  <1> 	retn
  3177                              <1> 		; rts r0
  3178                              <1> 
  3179                              <1> icalc:
  3180                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  3181                              <1> 	; 28/11/2021
  3182                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification 
  3183                              <1> 	; 02/07/2015
  3184                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  3185                              <1> 	; 07/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3186                              <1> 	;
  3187                              <1> 	; calculate physical block number from i-number then
  3188                              <1> 	; read or write that block
  3189                              <1> 	;
  3190                              <1> 	; 'icalc' is called from 'iget'
  3191                              <1> 	;
  3192                              <1> 	; for original unix v1:
  3193                              <1> 	; / i-node i is located in block (i+31.)/16. and begins 32.*
  3194                              <1>        	; / (i+31.) mod 16. bytes from its start
  3195                              <1> 	;
  3196                              <1> 	; for retro unix 8086 v1:
  3197                              <1> 	;  i-node is located in block (i+47)/16 and
  3198                              <1> 	;  begins 32*(i+47) mod 16 bytes from its start
  3199                              <1> 	;
  3200                              <1> 	; INPUTS ->
  3201                              <1> 	;    r1 - i-number of i-node
  3202                              <1> 	; 	 
  3203                              <1> 	; OUTPUTS ->
  3204                              <1> 	;    inode r/w
  3205                              <1> 	;
  3206                              <1> 	; ((AX = R1)) input
  3207                              <1> 	;
  3208                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
  3209                              <1>         ;  ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))  
  3210                              <1> 	;
  3211                              <1> 
  3212                              <1> 	; 28/11/2021
  3213                              <1> 	;cmp	byte [idev], 0 ; [cdev] = [idev]
  3214 00004BDC 803D[216C0000]00    <1> 	cmp	byte [cdev], 0
  3215 00004BE3 7607                <1> 	jna	short icalc_0r
  3216 00004BE5 BD[FC6E0000]        <1> 	mov	ebp, mount  ; mounted file system's superblock 
  3217 00004BEA EB05                <1> 	jmp	short icalc_0m
  3218                              <1> icalc_0r:
  3219                              <1> 	; 28/11/2021
  3220 00004BEC BD[F46C0000]        <1> 	mov	ebp, systm  ; root file system's superblock 
  3221                              <1> icalc_0m:
  3222                              <1> 	; 22/11/2021
  3223                              <1> 	;mov	edx, eax
  3224 00004BF1 8B15[1C6C0000]      <1> 	mov	edx, [ii] ; 32 bit inode number
  3225 00004BF7 8B4528              <1> 	mov	eax, [ebp+SB.InodeTblAddr] ; inode table base address
  3226                              <1> 	;
  3227 00004BFA 4A                  <1> 	dec	edx ; 0 based inode number 
  3228                              <1> 		    ; (inode index in inode table)
  3229 00004BFB 52                  <1> 	push	edx ; *
  3230 00004BFC C1EA03              <1> 	shr	edx, 3
  3231 00004BFF 7402                <1> 	jz	short icalc_0t ; 0 for inodes 1 to 8
  3232 00004C01 01D0                <1> 	add	eax, edx
  3233                              <1> icalc_0t:
  3234                              <1> 	; 09/01/2022
  3235                              <1> 	; eax = locical block/sector number 
  3236 00004C03 034504              <1> 	add	eax, [ebp+SB.BootSectAddr]
  3237                              <1> 	; eax = physical block/sector number 
  3238 00004C06 E8670D0000          <1> 	call	dskrd
  3239                              <1> 		; jsr r0,dskrd / read in block containing i-node i.
  3240                              <1> 	; 31/07/2013
  3241 00004C0B 803D[D86C0000]00    <1>         cmp     byte [rw], 0 ; Retro Unix 8086 v1 feature !
  3242                              <1> 	;; 28/07/2013 rw -> u.rw
  3243                              <1>         ;;cmp	byte [u.rw], 0 ; Retro Unix 8086 v1 feature !
  3244                              <1> 		; tst (r0)
  3245 00004C12 7605                <1> 	jna	short icalc_1
  3246                              <1> 		; beq 1f / branch to wslot when argument
  3247                              <1> 		       ; / in icalc call = 1
  3248                              <1> 	; eAX = r1 = block number
  3249 00004C14 E8BD0D0000          <1> 	call	wslot
  3250                              <1> 		; jsr r0,wslot / set up data buffer for write
  3251                              <1> 			     ; / (will be same buffer as dskrd got)
  3252                              <1> 	; EBX = r5 points to first word in data area for this block
  3253                              <1> icalc_1: ; 1:
  3254 00004C19 5A                  <1> 	pop	edx ; *
  3255                              <1> 	; 22/11/2021
  3256 00004C1A 83E207              <1> 	and 	edx, 07h ; 8 inodes per inode table sector
  3257 00004C1D C1E206              <1> 	shl 	edx, 6 ; * 64 (inode size)
  3258                              <1> 	; edx = 64 * (mod(inodenumber-1)/8)
  3259 00004C20 89DE                <1> 	mov	esi, ebx  ; ebx points to 1st word of the buffer
  3260 00004C22 01D6                <1> 	add	esi, edx  ; edx is inode offset in the buffer
  3261                              <1>           	; eSI (r5) points to first word in i-node i.	
  3262                              <1> 		; mov (sp)+,mq / calculate offset in data buffer; 
  3263                              <1> 			     ; / 32.*(i+31.)mod16
  3264                              <1> 		; mov $5,lsh / for i-node i.
  3265                              <1> 		; add mq,r5 / r5 points to first word in i-node i.
  3266 00004C24 BF[C4670000]        <1> 	mov	edi, inode
  3267                              <1> 		; mov $inode,r1 / inode is address of first word 
  3268                              <1> 			      ; / of current i-node
  3269                              <1> 	;mov 	ecx, 8 ; 02/07/2015 (32 bit modification)
  3270                              <1> 	;	; mov $16.,r3
  3271                              <1> 	; 28/11/2021
  3272 00004C29 29C9                <1> 	sub	ecx, ecx
  3273 00004C2B B110                <1> 	mov	cl, 16 ; Retro UNIX 386 v2 inode size = 64 bytes
  3274                              <1> 	; 31/07/2013
  3275 00004C2D 382D[D86C0000]      <1>   	cmp     [rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
  3276                              <1>        ;;28/07/2013 rw -> u.rw                 
  3277                              <1>        ;;cmp    [u.rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
  3278                              <1> 		; tst (r0)+ / branch to 2f when argument in icalc call = 0
  3279 00004C33 7609                <1> 	jna	short icalc_3
  3280                              <1> 		; beq 2f / r0 now contains proper return address 
  3281                              <1> 		       ; / for rts r0
  3282                              <1> icalc_2: ; 1:
  3283 00004C35 87F7                <1> 	xchg 	esi, edi
  3284                              <1> 	; overwrite old i-node (in buffer to be written)
  3285 00004C37 F3A5                <1> 	rep 	movsd
  3286                              <1> 		; mov (r1)+,(r5)+ / over write old i-node
  3287                              <1> 		; dec r3
  3288                              <1> 		; bgt 1b
  3289                              <1> 	;call	dskwr
  3290                              <1> 	;	; jsr r0,dskwr / write inode out on device
  3291                              <1> 	;retn
  3292                              <1> 	;	; rts r0
  3293                              <1> 	; 28/11/2021
  3294 00004C39 E9A50D0000          <1> 	jmp	dskwr
  3295                              <1> icalc_3: ; 2:
  3296                              <1> 	; copy new i-node into inode area of (core) memory
  3297 00004C3E F3A5                <1> 	rep 	movsd
  3298                              <1> 		; mov (r5)+,(r1)+ / read new i-node into 
  3299                              <1> 		                ; / "inode" area of core
  3300                              <1> 		; dec r3
  3301                              <1> 		; bgt 2b
  3302 00004C40 C3                  <1> 	retn
  3303                              <1> 		; rts r0
  3304                              <1> 
  3305                              <1> access:
  3306                              <1> 	; 13/03/2022
  3307                              <1> 	; 25/12/2021
  3308                              <1> 	; 19/12/2021
  3309                              <1> 	; 28/11/2021
  3310                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
  3311                              <1> 	; 31/10/2021 - temporary (simplified code)
  3312                              <1> 	; 14/06/2021
  3313                              <1> 	; 02/05/2021
  3314                              <1> 	; 27/03/2021
  3315                              <1> 	; 26/03/2021
  3316                              <1> 	; 25/03/2021
  3317                              <1> 	; 23/03/2021 (Retro UNIX 386 v2 - Beginning)
  3318                              <1> 	;	((ref: unix v7 source - fio.c))
  3319                              <1> 	; ref: INODE STRUCTURE of Retro UNIX v2 file system
  3320                              <1> 	;	07/02/2020, 'RETRO UNIX v2 Inodes.pdf'
  3321                              <1> 	;	 
  3322                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  3323                              <1> 	; 24/04/2013 - 29/04/2013 (Retro UNIX 8086 v1)
  3324                              <1> 	;
  3325                              <1> 	; check whether user is owner of file or user has read or write
  3326                              <1> 	; permission (based on i.flgs).
  3327                              <1> 	;
  3328                              <1> 	; INPUTS ->
  3329                              <1> 	;    r1 - i-number of file
  3330                              <1> 	;    u.uid
  3331                              <1> 	; arg0 -> (owner flag mask)	 		
  3332                              <1> 	;     Retro UNIX 8086 v1 feature -> owner flag mask in DL (DX) 	 
  3333                              <1> 	; OUTPUTS ->
  3334                              <1> 	;    inode (or jump to error)
  3335                              <1> 	;
  3336                              <1> 	; ((AX = R1)) input/output
  3337                              <1> 	;
  3338                              <1> 	;  ((Modified registers: eCX, eBX, eDX, eSI, eDI, eBP))
  3339                              <1> 
  3340                              <1> 	; 26/03/2021
  3341                              <1> 	; INPUT:
  3342                              <1> 	;	eax = inode number (ax)
  3343                              <1> 	;	 dx = mode (IEXEC, IREAD or IWRITE) 
  3344                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
  3345                              <1> 	;	
  3346                              <1> 	; OUTPUT:
  3347                              <1> 	;	inode (or jump to error)
  3348                              <1> 	;	eax (ax) = [ii] = inode number
  3349                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
  3350                              <1> 	;
  3351                              <1> 	; Modified registers: (eax), ebx, ecx, edx, esi, edi, ebp
  3352                              <1> 	;
  3353                              <1> 	; IREAD	 equ 100h ; read permission flag, owner
  3354                              <1> 	; IWRITE equ 80h  ; write permission flag, owner
  3355                              <1> 	; IEXEC	 equ 40h  ; execute permission flag, owner	 
  3356                              <1> 		
  3357                              <1> 	; 23/03/2021
  3358 00004C41 52                  <1> 	push	edx ; save flag (DX)
  3359                              <1> 	;push	dx  ; save flag (DL)
  3360 00004C42 E810FFFFFF          <1> 	call	iget
  3361                              <1> 		; jsr r0,iget / read in i-node for current directory
  3362                              <1> 			    ; / (i-number passed in r1)
  3363                              <1> 	;;mov	cl, [i.flgs]
  3364                              <1> 	;;	; mov i.flgs,r2
  3365                              <1> 	; 23/03/2021
  3366                              <1> 	;mov	cx, [i.iflgs]	
  3367                              <1> 
  3368                              <1> 	;;pop	dx  ; restore flag (DL)
  3369                              <1> 	; 23/03/2021
  3370 00004C47 5A                  <1> 	pop	edx ; restore flag (DX)
  3371                              <1> 
  3372                              <1> 	; 28/11/2021 (iget will not return here if there is an error)
  3373                              <1> 	; 31/10/2021
  3374                              <1> 	;jc	short access_5
  3375                              <1> 
  3376                              <1> 	; 31/10/2021
  3377                              <1> 	; Note: If eax input is same with [mnti], 'iget' will change
  3378                              <1> 	; [cdev] to 1 and eax will be 1 (root dir of mounted fs) 
  3379                              <1> 
  3380                              <1> 	; 27/03/2021
  3381                              <1> 	; 23/03/2021
  3382                              <1> 	; (check if it is write permission flag)
  3383 00004C48 6681FA8000          <1> 	cmp	dx, 80h ; IWRITE
  3384 00004C4D 775E                <1> 	ja	short access_r	; IREAD = 100h (owner)
  3385 00004C4F 722B                <1> 	jb	short access_x	; IEXEC = 40h (owner)
  3386                              <1> 	; IWRITE (80h)
  3387                              <1> access_w:
  3388                              <1> 	; 23/03/2021
  3389                              <1> 	; ((ref: Retro UNIX 386 v2, 'ux.s', 'ldrv' structure))
  3390                              <1> 	;mov	bl, [idev]
  3391                              <1> 	;call	getfs
  3392                              <1>  	;movzx	ebx, byte [idev]  ; logical drive number
  3393                              <1> 	;shl	bx, 6 ; * 64	  ; of current inode	
  3394                              <1> 	;add	ebx, ldrvtable	
  3395                              <1> 	;;test	byte [ebx+ldrv.pflags], 01h ; read only fs flag
  3396                              <1> 	;;jz	short access_0
  3397                              <1> 	;; 14/06/2021
  3398                              <1> 	; 14/06/2021
  3399                              <1> 	; check block device (fs) if it is read only fs or not ? 
  3400                              <1> 	;mov	edi, [ebx+ldrv.superblk]
  3401                              <1> 	;test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
  3402                              <1> 	;jz	short access_0
  3403                              <1> 	; 31/10/2021
  3404 00004C51 803D[216C0000]01    <1> 	cmp	byte [cdev], 1
  3405 00004C58 7207                <1> 	jb	short access_7 ; [cdev] = 0
  3406                              <1> 	; [cdev] = 1
  3407                              <1> 	; 28/11/2021
  3408 00004C5A BF[FC6E0000]        <1> 	mov	edi, mount ; mounted file system's superblock buffer
  3409 00004C5F EB05                <1> 	jmp	short access_8
  3410                              <1> access_7:
  3411                              <1> 	; 28/11/2021
  3412 00004C61 BF[F46C0000]        <1> 	mov	edi, systm ; root file system's superblock buffer
  3413                              <1> access_8:
  3414 00004C66 F6476A01            <1> 	test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
  3415 00004C6A 7441                <1> 	jz	short access_0
  3416                              <1> 
  3417                              <1> 	; 23/03/2021
  3418                              <1> 	;mov	dword [u.error], ERR_READ_ONLY_FS
  3419                              <1> 	;		; 'read only file system !' error
  3420                              <1> 	;jmp	error
  3421                              <1> 
  3422                              <1> 	; 19/12/2021
  3423 00004C6C F605[C5670000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file ?
  3424 00004C73 7438                <1> 	jz	short access_0  ; no, device file
  3425                              <1> 
  3426                              <1> 	; 31/10/2021
  3427 00004C75 B81E000000          <1> 	mov	eax, ERR_READ_ONLY_FS
  3428                              <1> 			; 'read only file system !' error
  3429                              <1> 	; 27/03/2021
  3430 00004C7A EB27                <1> 	jmp	short access_5
  3431                              <1> 
  3432                              <1> 	; check block device (fs) if it is read only fs or not ? 
  3433                              <1> 
  3434                              <1> 	;mov	dh, [u.uid]
  3435                              <1> 	;cmp	dh, [i.uid]
  3436                              <1> 	;	; cmpb i.uid,u.uid / is user same as owner of file
  3437                              <1> 	;jne	short access_1
  3438                              <1> 		; bne 1f / no, then branch
  3439                              <1> access_x:
  3440                              <1> 	; IEXEC (40h)
  3441                              <1> 	; 27/03/2021
  3442 00004C7C 668B1D[C4670000]    <1> 	mov	bx, [i.flgs]
  3443 00004C83 F6C780              <1> 	test	bh, 80h ; regular file ?
  3444 00004C86 7416                <1> 	jz	short access_4 ; not executable file !
  3445 00004C88 F6C740              <1> 	test	bh, 40h	; directory ?
  3446 00004C8B 7511                <1> 	jnz	short access_4 ; not executable file !
  3447 00004C8D 668B0D[966C0000]    <1> 	mov	cx, [u.uid]
  3448 00004C94 6609C9              <1> 	or	cx, cx
  3449 00004C97 7520                <1> 	jnz	short access_3 ; (restricted user)
  3450                              <1> 	; (super user)
  3451                              <1> 	;test	[i.flgs], dl ; execute permission for owner
  3452                              <1> 	;test	byte [i.flgs], 49h ; for owner, group, others
  3453 00004C99 F6C349              <1> 	test	bl, 49h ; exec perm for owner, group, others
  3454 00004C9C 7549                <1> 	jnz	short access_2
  3455                              <1> access_4:
  3456                              <1> 	; 31/10/2021
  3457 00004C9E B816000000          <1> 	mov	eax, ERR_NOT_EXECUTABLE
  3458                              <1> 			; 'not executable file !' error
  3459                              <1> 	; 26/03/2021
  3460                              <1> ;;sysexec_not_exf:
  3461                              <1> ;	mov	dword [u.error], ERR_NOT_EXECUTABLE
  3462                              <1> ;			; 'not executable file !' error
  3463                              <1> ;access_5:
  3464                              <1> ;	jmp	error
  3465                              <1> 	
  3466                              <1> 	; 31/10/2021
  3467                              <1> access_5:
  3468 00004CA3 A3[B86C0000]        <1> 	mov	[u.error], eax
  3469 00004CA8 E99AE4FFFF          <1> 	jmp	error
  3470                              <1> 
  3471                              <1> access_r:
  3472                              <1> 	; 27/03/2021
  3473                              <1> access_0:
  3474                              <1> 	; 23/03/2021
  3475 00004CAD 668B0D[966C0000]    <1> 	mov	cx, [u.uid]
  3476 00004CB4 6609C9              <1> 	or	cx, cx ; 0 ; root ?
  3477                              <1> 	;jz	short access_2 ; yes
  3478                              <1> 	; 25/12/2021
  3479 00004CB7 741E                <1> 	jz	short access_1 ; yes
  3480                              <1> access_3:
  3481                              <1> 	; 13/03/2022
  3482 00004CB9 663B0D[C8670000]    <1> 	cmp	cx, [i.uid] ; owner ?
  3483 00004CC0 7415                <1> 	je	short access_1 ; yes
  3484                              <1> 	;; owner ?
  3485 00004CC2 8A1D[CA670000]      <1> 	mov	bl, [i.gid]
  3486                              <1> 	;cmp	cx, [i.uid]
  3487                              <1> 	;;je	short access_1
  3488                              <1> 	;; 02/05/2021
  3489                              <1> 	;jne	short access_6
  3490                              <1> 	; 13/03/2022
  3491                              <1> 	; same group ?
  3492 00004CC8 66C1EA03            <1> 	shr	dx, 3
  3493                              <1> 	; check owner's group number/ID
  3494 00004CCC 3A1D[9A6C0000]      <1> 	cmp	bl, [u.gid] ; same group number/ID ?
  3495 00004CD2 7403                <1> 	je	short access_1 ; yes
  3496                              <1> 	; one of others
  3497                              <1> 	;shr	dx, 6
  3498                              <1> 	;jmp	short access_1 ; others
  3499                              <1> 	; 13/03/2022
  3500                              <1> 	; one of others
  3501 00004CD4 C0EA03              <1> 	shr	dl, 3
  3502                              <1> ;	; 13/03/2022
  3503                              <1> ;	jmp	short access_1 ; others
  3504                              <1> ;access_6:
  3505                              <1> ;	;shr	cl, 2
  3506                              <1> ;	;	; asrb r2 / shift owner read write bits into non owner
  3507                              <1> ;	;	;       ; / read/write bits
  3508                              <1> ;	;	; asrb r2
  3509                              <1> ;
  3510                              <1> ;	; 23/03/2021
  3511                              <1> ;	; same group ?
  3512                              <1> ;	shr	dx, 3
  3513                              <1> ;	;mov	cl, [u.gid]
  3514                              <1> ;	;cmp	cl, [i.gid]
  3515                              <1> ;	;je	short access_1
  3516                              <1> ;	; 02/05/2021
  3517                              <1> ;	cmp	bl, [u.gid]
  3518                              <1> ;	je	short access_1 ; same group, different owner
  3519                              <1> ;
  3520                              <1> ;	; others
  3521                              <1> ;	;shr	dx, 3
  3522                              <1> ;	shr	dl, 3
  3523                              <1> ;	;jmp	short access_1	
  3524                              <1> ;
  3525                              <1> ;;access_1: ; 1:
  3526                              <1> ;	;and	cl, dl
  3527                              <1> ;	;	; bit r2,(r0)+ / test read-write flags against argument
  3528                              <1> ;	;		     ; / in access call
  3529                              <1> ;	;jnz	short access_2
  3530                              <1> ;	;	; bne 1f
  3531                              <1> ;	
  3532                              <1> ;	;or	dh, dh	; super user (root) ?
  3533                              <1> ;	;	; tstb u.uid
  3534                              <1> ;	;jz	short access_2 ; yes, super user
  3535                              <1> ;	;;jnz	error
  3536                              <1> ;	;	; beq 1f
  3537                              <1> ;	;	; jmp error
  3538                              <1> ;	
  3539                              <1> ;	;mov	dword [u.error], ERR_FILE_ACCESS 
  3540                              <1> ;	;		; 'permission denied !' error
  3541                              <1> ;	;jmp	error
  3542                              <1> 
  3543                              <1> access_1:
  3544                              <1> 	; 23/03/2021
  3545 00004CD7 668515[C4670000]    <1> 	test	dx, [i.flgs]
  3546 00004CDE 7507                <1> 	jnz	short access_2
  3547                              <1> 
  3548                              <1> 	;; r/w permission error
  3549                              <1> 	;mov	dword [u.error], ERR_FILE_ACCESS 
  3550                              <1> 	;		; 'permission denied !' error
  3551                              <1> 	;;jmp	error
  3552                              <1> 
  3553                              <1> 	; 31/10/2021
  3554 00004CE0 B80B000000          <1> 	mov	eax, ERR_FILE_ACCESS 
  3555                              <1> 			; 'permission denied !' error
  3556                              <1> 	; 27/03/2021
  3557 00004CE5 EBBC                <1> 	jmp	short access_5
  3558                              <1> 
  3559                              <1> access_2: ; 1:
  3560                              <1> 	;; DL = flags
  3561                              <1> 	;retn
  3562                              <1> 	;	; rts r0
  3563                              <1> 	; 27/03/2021
  3564                              <1> 	; DX = flag (100h-20h-04h or 80h-10h-02h or 40h-08h-01h)
  3565 00004CE7 C3                  <1> 	retn
  3566                              <1> 
  3567                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
  3568                              <1> %if 0
  3569                              <1> 
  3570                              <1> setimod:
  3571                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  3572                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3573                              <1> 	;
  3574                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
  3575                              <1> 	; the inode has been modified. Also puts the time of modification
  3576                              <1> 	; into the inode.
  3577                              <1> 	;
  3578                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
  3579                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
  3580                              <1> 	;
  3581                              <1> 	
  3582                              <1> 	;push 	edx
  3583                              <1> 	push	eax
  3584                              <1> 
  3585                              <1> 	mov 	byte [imod], 1
  3586                              <1> 		; movb $1,imod / set current i-node modified bytes
  3587                              <1> 	; Erdogan Tan 14-7-2012
  3588                              <1> 	call 	epoch
  3589                              <1> 		 ; mov s.time,i.mtim 
  3590                              <1> 			    ; / put present time into file modified time
  3591                              <1> 		 ; mov s.time+2,i.mtim+2
  3592                              <1> 
  3593                              <1> 	mov 	[i.mtim], eax
  3594                              <1> 	
  3595                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
  3596                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
  3597                              <1> 	cmp	dword [i.ctim], 0
  3598                              <1> 	jnz	short setimod_ok
  3599                              <1> 
  3600                              <1> 	mov 	[i.ctim], eax
  3601                              <1> 
  3602                              <1> setimod_ok: ; 31/07/2013
  3603                              <1> 	pop	eax
  3604                              <1> 	;pop	edx
  3605                              <1> 	
  3606                              <1> 	retn
  3607                              <1> 		; rts r0
  3608                              <1> %endif
  3609                              <1> 
  3610                              <1> setimod:
  3611                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
  3612                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
  3613                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  3614                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3615                              <1> 	;
  3616                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
  3617                              <1> 	; the inode has been modified. Also puts the time of modification
  3618                              <1> 	; into the inode.
  3619                              <1> 	;
  3620                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
  3621                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
  3622                              <1> 	;
  3623                              <1> 
  3624                              <1> 	; Reference:
  3625                              <1> 	; 25/01/2020 - 'UNIXHDCP.ASM', 'setimod' procedure
  3626                              <1> 	;	(Retro UNIX 386 v2 file system installation utility)
  3627                              <1> 
  3628                              <1> 	; 25/05/2020
  3629                              <1> 	;
  3630                              <1> 	; INPUT:
  3631                              <1> 	;	none
  3632                              <1> 	; OUTPUT:
  3633                              <1> 	;	inode times and [imod] will be set
  3634                              <1> 	;	      ([imodx] will be reset)
  3635                              <1> 	;	cf = 0 	
  3636                              <1> 
  3637                              <1> 	; Modified registers: ecx, (edx)?
  3638                              <1> 	
  3639                              <1> 	;push 	edx
  3640 00004CE8 50                  <1> 	push	eax
  3641                              <1> 
  3642 00004CE9 C605[346C0000]01    <1> 	mov 	byte [imod], 1
  3643                              <1> 		; movb $1,imod / set current i-node modified bytes
  3644                              <1> 
  3645                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
  3646 00004CF0 A1[00680000]        <1> 	mov	eax, [i.ctim] ; inode (file) creation time
  3647 00004CF5 21C0                <1> 	and	eax, eax
  3648 00004CF7 7518                <1> 	jnz	short setimod_4
  3649                              <1> 
  3650                              <1> 	; New file
  3651                              <1> setimod_1:
  3652                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 by Erdogan Tan
  3653                              <1> 	;	 (Modified UNIX v7 inode and new FS construction) 	
  3654                              <1> 	;
  3655 00004CF9 E83B0E0000          <1> 	call	get_system_time ; get current (unix epoch) time
  3656                              <1> 
  3657                              <1> 	;; Erdogan Tan 14-7-2012
  3658                              <1> 	;call 	epoch
  3659                              <1> 	;	 ; mov s.time,i.mtim 
  3660                              <1> 	;		    ; / put present time into file modified time
  3661                              <1> 	;	 ; mov s.time+2,i.mtim+2
  3662                              <1> 	;
  3663                              <1> 	;mov 	[i.mtim], eax
  3664                              <1> 
  3665                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
  3666                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
  3667                              <1> 	;cmp	dword [i.ctim], 0
  3668                              <1> 	;jnz	short setimod_ok
  3669                              <1> 		
  3670 00004CFE A3[00680000]        <1> 	mov 	[i.ctim], eax
  3671                              <1> 	
  3672                              <1> 	; 25/05/2020
  3673 00004D03 EB05                <1> 	jmp	short setimod_3
  3674                              <1> 
  3675                              <1> setimod_2:
  3676                              <1> 	; File/Directory data (file size or content) is changed
  3677                              <1> 	; This is last modification date&time
  3678 00004D05 A3[FC670000]        <1> 	mov	[i.mtim], eax
  3679                              <1> setimod_3:
  3680                              <1> 	; 19/09/2019 ('UNIXHDCP.ASM', 'setimod' by Erdogan Tan)
  3681                              <1> 	; This is last access or last changing date&time
  3682                              <1> 	; of inode (chmod,chown,chgrp,link)
  3683                              <1> 	; parameters (without file/dir data changing)
  3684 00004D0A A3[F8670000]        <1> 	mov	[i.atim], eax
  3685                              <1> 
  3686                              <1> setimod_ok: ; 31/07/2013
  3687 00004D0F 58                  <1> 	pop	eax
  3688                              <1> 	;pop	edx
  3689                              <1> 	
  3690 00004D10 C3                  <1> 	retn
  3691                              <1> 		; rts r0
  3692                              <1> setimod_4:
  3693                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
  3694 00004D11 31C9                <1> 	xor	ecx, ecx
  3695 00004D13 390D[FC670000]      <1> 	cmp	[i.mtim], ecx ; 0
  3696 00004D19 76EA                <1> 	jna	short setimod_2
  3697                              <1> 
  3698 00004D1B E8190E0000          <1> 	call	get_system_time ; get current (unix epoch) time
  3699                              <1> 	; ((system time will be updated directly by timer interrupt))
  3700                              <1> 
  3701 00004D20 803D[356C0000]00    <1> 	cmp	byte [imodx], 0 ; flag means "file/dir data is same but
  3702 00004D27 76DC                <1> 	jna	short setimod_2 ; inode has been changed"
  3703                              <1> 
  3704                              <1> 	; File/Dir data (File size or content) is same but
  3705                              <1> 	; inode's mode, link count, owner or group id has been changed
  3706                              <1> 	; (so, we do not change last modification date&time)
  3707 00004D29 C605[356C0000]00    <1> 	mov	byte [imodx], 0 ; reset inode modified (extended) flag
  3708 00004D30 EBD8                <1> 	jmp	short setimod_3
  3709                              <1> 
  3710                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
  3711                              <1> %if 0
  3712                              <1> 	; Retro UNIX 386 v1.1 'itrunc' code
  3713                              <1> itrunc:
  3714                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  3715                              <1> 	; 23/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  3716                              <1> 	;
  3717                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
  3718                              <1> 	;  to zero length.
  3719                              <1> 	;
  3720                              <1> 	; INPUTS ->
  3721                              <1> 	;    r1 - i-number of i-node
  3722                              <1> 	;    i.dskp - pointer to contents or indirect block in an i-node
  3723                              <1> 	;    i.flgs - large file flag		
  3724                              <1> 	;    i.size - size of file	
  3725                              <1> 	; 	 
  3726                              <1> 	; OUTPUTS ->
  3727                              <1> 	;    i.flgs - large file flag is cleared
  3728                              <1> 	;    i.size - set to 0	
  3729                              <1> 	;    i.dskp .. i.dskp+16 - entire list is cleared
  3730                              <1> 	;    setimod - set to indicate i-node has been modified
  3731                              <1> 	;    r1 - i-number of i-node  					
  3732                              <1> 	;
  3733                              <1> 	; ((AX = R1)) input/output
  3734                              <1> 	;
  3735                              <1> 	;  (Retro UNIX Prototype : 01/12/2012 - 10/03/2013, UNIXCOPY.ASM)
  3736                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
  3737                              <1> 
  3738                              <1> 	call	iget
  3739                              <1> 		; jsr r0,iget
  3740                              <1> 	mov	esi, i.dskp
  3741                              <1> 		; mov $i.dskp,r2 / address of block pointers in r2
  3742                              <1> 	xor	eax, eax
  3743                              <1> itrunc_1: ; 1:
  3744                              <1> 	lodsw
  3745                              <1> 		; mov (r2)+,r1 / move physical block number into r1
  3746                              <1> 	or 	ax, ax
  3747                              <1> 	jz	short itrunc_5
  3748                              <1> 		; beq 5f
  3749                              <1> 	push	esi
  3750                              <1> 		; mov r2,-(sp)
  3751                              <1> 	test    word [i.flgs], 1000h    
  3752                              <1> 		; bit $10000,i.flgs / test large file bit?
  3753                              <1> 	jz	short itrunc_4
  3754                              <1> 		; beq 4f / if clear, branch
  3755                              <1> 	push	eax
  3756                              <1> 		; mov r1,-(sp) / save block number of indirect block
  3757                              <1> 	call	dskrd
  3758                              <1> 		; jsr r0,dskrd / read in block, 1st data word 
  3759                              <1> 			     ; / pointed to by r5
  3760                              <1> 	; eBX = r5 = Buffer data address (the 1st word)
  3761                              <1> 	mov	ecx, 256
  3762                              <1> 		; mov $256.,r3 / move word count into r3
  3763                              <1> 	mov	esi, ebx
  3764                              <1> itrunc_2: ; 2:
  3765                              <1> 	lodsw
  3766                              <1> 		; mov (r5)+,r1 / put 1st data word in r1; 
  3767                              <1> 			     ; / physical block number
  3768                              <1> 	and	ax, ax
  3769                              <1> 	jz	short itrunc_3
  3770                              <1> 		; beq 3f / branch if zero
  3771                              <1> 	;push	ecx
  3772                              <1> 	push	cx
  3773                              <1> 		; mov r3,-(sp) / save r3, r5 on stack
  3774                              <1> 	;push	esi
  3775                              <1> 		; mov r5,-(sp)
  3776                              <1> 	call	free
  3777                              <1> 		; jsr r0,free / free block in free storage map
  3778                              <1> 	;pop	esi
  3779                              <1> 		; mov(sp)+,r5
  3780                              <1> 	pop	cx
  3781                              <1> 	;pop	ecx
  3782                              <1> 		; mov (sp)+,r3
  3783                              <1> itrunc_3: ; 3:
  3784                              <1> 	loop	itrunc_2
  3785                              <1> 		; dec r3 / decrement word count
  3786                              <1> 		; bgt 2b / branch if positive
  3787                              <1> 	pop	eax
  3788                              <1> 		; mov (sp)+,r1 / put physical block number of 
  3789                              <1> 			     ; / indirect block
  3790                              <1> 	; 01/08/2013
  3791                              <1>         and     word [i.flgs], 0EFFFh ; 1110111111111111b
  3792                              <1> itrunc_4: ; 4:
  3793                              <1> 	call	free
  3794                              <1> 		; jsr r0,free / free indirect block
  3795                              <1> 	pop	esi
  3796                              <1> 		; mov (sp)+,r2
  3797                              <1> itrunc_5: ; 5:
  3798                              <1> 	cmp	esi, i.dskp+16
  3799                              <1> 		; cmp r2,$i.dskp+16.
  3800                              <1> 	jb	short itrunc_1	
  3801                              <1> 		; bne 1b / branch until all i.dskp entries check
  3802                              <1> 	; 01/08/2013
  3803                              <1> 	;and     word [i.flgs], 0EFFFh ; 1110111111111111b
  3804                              <1> 		; bic $10000,i.flgs / clear large file bit
  3805                              <1> 	mov	edi, i.dskp
  3806                              <1> 	mov	cx, 8
  3807                              <1> 	xor 	ax, ax
  3808                              <1> 	mov	[i.size], ax ; 0
  3809                              <1> 		; clr i.size / zero file size
  3810                              <1> 	rep	stosw
  3811                              <1> 		; jsr r0,copyz; i.dskp; i.dskp+16. 
  3812                              <1> 			   ; / zero block pointers
  3813                              <1> 	call	setimod
  3814                              <1> 		; jsr r0,setimod / set i-node modified flag
  3815                              <1> 	mov	ax, [ii]
  3816                              <1> 		; mov ii,r1
  3817                              <1> 	retn
  3818                              <1> 		; rts r0
  3819                              <1> 
  3820                              <1> 	; Retro UNIX 386 v1.1 'imap' code
  3821                              <1> imap:
  3822                              <1> 	; 17/07/2022 (Retro UNIX 386 v1.2)
  3823                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
  3824                              <1> 	; 26/04/2013 (Retro UNIX 8086 v1)
  3825                              <1> 	;
  3826                              <1> 	; 'imap' finds the byte in core (superblock) containing
  3827                              <1> 	; allocation bit for an i-node whose number in r1.
  3828                              <1> 	;
  3829                              <1> 	; INPUTS ->
  3830                              <1> 	;    r1 - contains an i-number
  3831                              <1> 	;    fsp - start of table containing open files
  3832                              <1> 	;
  3833                              <1> 	; OUTPUTS ->
  3834                              <1> 	;    r2 - byte address of byte with the allocation bit
  3835                              <1> 	;    mq - a mask to locate the bit position.	
  3836                              <1> 	;	  (a 1 is in calculated bit posisiton)
  3837                              <1> 	;
  3838                              <1> 	; ((AX = R1)) input/output
  3839                              <1> 	; ((DL/DX = MQ)) output
  3840                              <1> 	; ((BX = R2)) output
  3841                              <1> 	;
  3842                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
  3843                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI))  
  3844                              <1> 	;
  3845                              <1> 		; / get the byte that has the allocation bit for 
  3846                              <1> 		; / the i-number contained in r1
  3847                              <1> 	;mov	dx, 1
  3848                              <1> 	mov	dl, 1
  3849                              <1> 		; mov $1,mq / put 1 in the mq
  3850                              <1> 	movzx	ebx, ax
  3851                              <1> 		; mov r1,r2 / r2 now has i-number whose byte
  3852                              <1>  		          ; / in the map we must find
  3853                              <1> 	sub	bx, 41
  3854                              <1> 		; sub $41.,r2 / r2 has i-41
  3855                              <1> 	mov	cl, bl
  3856                              <1> 		; mov r2,r3 / r3 has i-41
  3857                              <1> 	and	cl, 7
  3858                              <1> 		; bic $!7,r3 / r3 has (i-41) mod 8 to get 
  3859                              <1> 			   ; / the bit position
  3860                              <1> 	jz	short imap1
  3861                              <1> 	;shl	dx, cl
  3862                              <1> 	shl	dl, cl
  3863                              <1> 		; mov r3,lsh / move the 1 over (i-41) mod 8 positions
  3864                              <1> imap1:			   ; / to the left to mask the correct bit
  3865                              <1> 	;shr	bx, 3
  3866                              <1> 	; 17/07/2022
  3867                              <1> 	shr	ebx, 3
  3868                              <1> 		; asr r2
  3869                              <1> 		; asr r2
  3870                              <1> 		; asr r2 / r2 has (i-41) base 8 of the byte number
  3871                              <1> 		       ; / from the start of the map
  3872                              <1> 		; mov r2,-(sp) / put (i-41) base 8 on the stack
  3873                              <1> 	mov	esi, systm
  3874                              <1> 		; mov $systm,r2 / r2 points to the in-core image of
  3875                              <1> 				; / the super block for drum
  3876                              <1> 	;cmp	word [cdev], 0
  3877                              <1> 	cmp	byte [cdev], 0
  3878                              <1> 		; tst cdev / is the device the disk
  3879                              <1> 	jna	short imap2
  3880                              <1> 		; beq 1f / yes
  3881                              <1> 	add	esi, mount - systm
  3882                              <1> 		; add $mount-systm,r2 / for mounted device,
  3883                              <1> 			; / r2 points to 1st word of its super block
  3884                              <1> imap2: ; 1:
  3885                              <1> 	add	bx, [esi] ;; add free map size to si
  3886                              <1> 		; add (r2)+,(sp) / get byte address of allocation bit
  3887                              <1> 	add	bx, 4
  3888                              <1> 	add	ebx, esi
  3889                              <1>         	; add (sp)+,r2 / ?
  3890                              <1> 	;add	ebx, 4 ;; inode map offset in superblock
  3891                              <1> 		      ;; (2 + free map size + 2)
  3892                              <1> 		; add $2,r2 / ?
  3893                              <1>  	; DL/DX (MQ) has a 1 in the calculated bit position
  3894                              <1>         ; BX (R2) has byte address of the byte with allocation bit
  3895                              <1> 	retn
  3896                              <1> 		; rts r0
  3897                              <1> %endif
  3898                              <1> 
  3899                              <1> 	; Retro UNIX 386 v2.0 'itrunc' code
  3900                              <1> itrunc:
  3901                              <1> 	; 26/03/2022
  3902                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
  3903                              <1> 	; 07/06/2020
  3904                              <1> 	; 02/06/2020
  3905                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
  3906                              <1> 	;
  3907                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
  3908                              <1> 	;  to zero length.
  3909                              <1> 	; 07/06/2020
  3910                              <1> 	; 02/06/2020
  3911                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
  3912                              <1> 	;
  3913                              <1> 	; 'itrunc' truncates a file whose i-number is given
  3914                              <1> 	; in ax to zero length.
  3915                              <1> 	;
  3916                              <1> 
  3917                              <1> 	; Reference: 
  3918                              <1> 	;	Retro UNIX 386 v2 FS installation utility
  3919                              <1> 	; 17/01/2020 - 'UNIXHDCP.ASM', 'itrunc' procedure
  3920                              <1> 
  3921                              <1> 	; * Free all the disk blocks associated
  3922                              <1> 	; * with the specified inode structure.
  3923                              <1> 	
  3924                              <1> 	; INPUT: 
  3925                              <1> 	;	(e)ax = inode number
  3926                              <1> 	; OUTPUT: 
  3927                              <1> 	;	inode will be modified (file size = 0)
  3928                              <1> 	;	; 26/03/20221
  3929                              <1> 	;	eax = 0 (if cf=0)
  3930                              <1> 
  3931                              <1> 	; (Modified registers: eax, edx, ecx, ebx, esi, edi, ebp) 
  3932                              <1> 
  3933                              <1> 	; 07/06/2020
  3934                              <1> 
  3935                              <1> 	; [cdev] = current logical drive number
  3936                              <1> 	;    eax = inode number (for [cdev])
  3937                              <1> 
  3938 00004D32 E820FEFFFF          <1> 	call 	iget
  3939                              <1> 	; 10/01/2022
  3940                              <1> 	;jc	short itrunc_0 ; error code in eax (al)
  3941                              <1> 
  3942                              <1> 	;    eax = inode number, [ii]
  3943                              <1> 	; [cdev] = current logical drive number (same with input)
  3944                              <1> 	; [idev] = logical drive number of current inode, [ii]
  3945                              <1> 	;   [ii] = current inode ([ii] = ax input, if ax was not zero)
  3946                              <1> 	; [imod] = 0		
  3947                              <1> 	; ([imodx] = 0)
  3948                              <1> 
  3949 00004D37 F605[C5670000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file or directory	
  3950 00004D3E 750F                <1> 	jnz	short itrunc_1
  3951                              <1> 
  3952                              <1> 	; 10/01/2022
  3953 00004D40 C705[B86C0000]FF00- <1> 	mov	dword [u.error], ERR_NOT_REGULAR ; 255 
  3953 00004D48 0000                <1>
  3954                              <1> 			; 'not a regular file (or directory) !' error
  3955                              <1> itrunc_0:
  3956 00004D4A E9F8E3FFFF          <1> 	jmp	error
  3957                              <1> itrunc_1:
  3958 00004D4F F605[C5670000]10    <1> 	test	byte [i.flgs+1], 10h ; large file (indirect blocks)
  3959 00004D56 7528                <1> 	jnz	short itrunc_5 ; large file
  3960 00004D58 BE[D0670000]        <1> 	mov	esi, i.dskp ; disk address pointer 0
  3961                              <1> itrunc_2:
  3962 00004D5D AD                  <1> 	lodsd
  3963 00004D5E 21C0                <1> 	and	eax, eax
  3964 00004D60 740C                <1> 	jz	short itrunc_3 ; empty ! (no more sectors/blocks)
  3965                              <1> 	; eax = block address to be released
  3966 00004D62 56                  <1> 	push	esi ; * ; 10/01/2022
  3967 00004D63 E83DFDFFFF          <1> 	call	free
  3968                              <1> 	; modified registers: ebx, ecx, edx, esi, edi, ebp 
  3969                              <1> 	; 10/01/2022
  3970                              <1> 	;jc	short itrunc_0 ; error code in eax
  3971 00004D68 5E                  <1> 	pop	esi ; * ; 10/01/2022
  3972 00004D69 31C0                <1> 	xor	eax, eax ; 0
  3973 00004D6B 8946FC              <1> 	mov	[esi-4], eax ; 0
  3974                              <1> itrunc_3:
  3975 00004D6E 81FE[F8670000]      <1> 	cmp	esi, i.dskp+40
  3976 00004D74 72E7                <1> 	jb	short itrunc_2 ; next disk address ptr
  3977                              <1> itrunc_4:
  3978 00004D76 A3[CC670000]        <1> 	mov	[i.size], eax ; 0
  3979                              <1> 	;mov	[i.size_h], al ; 0
  3980                              <1> 	
  3981                              <1> 	; clear large file flag
  3982                              <1> 	;and     byte [i.flgs+1], 0EFh ; 11101111b ; not 10h
  3983                              <1> 		
  3984                              <1> 	;call	setimod
  3985                              <1> 	;retn
  3986 00004D7B E968FFFFFF          <1> 	jmp	setimod
  3987                              <1> 
  3988                              <1> itrunc_5:
  3989                              <1> 	; free disk blocks by using triple indirect blocks at first
  3990 00004D80 BE[F4670000]        <1> 	mov	esi, i.dskp+36
  3991 00004D85 8B06                <1> 	mov	eax, [esi]
  3992 00004D87 09C0                <1> 	or	eax, eax
  3993 00004D89 740C                <1> 	jz	short itrunc_6
  3994                              <1> 
  3995 00004D8B BA02000000          <1> 	mov	edx, 2 ; Triple indirect sign (level = 2)
  3996 00004D90 E835000000          <1> 	call	tloop
  3997                              <1> 	; 10/01/2022
  3998                              <1> 	;jc	short itrunc_0
  3999                              <1> 		; eax = 0	
  4000 00004D95 8906                <1> 	mov	[esi], eax ; 0
  4001                              <1> itrunc_6:
  4002                              <1> 	; free disk blocks by using double indirect blocks at second
  4003 00004D97 BE[F0670000]        <1> 	mov	esi, i.dskp+32
  4004 00004D9C 8B06                <1> 	mov	eax, [esi]
  4005 00004D9E 21C0                <1> 	and	eax, eax 
  4006 00004DA0 740C                <1> 	jz	short itrunc_7
  4007                              <1> 
  4008 00004DA2 BA01000000          <1> 	mov	edx, 1 ; Double indirect sign (level = 1)
  4009 00004DA7 E81E000000          <1> 	call	tloop
  4010                              <1> 	; 10/01/2022
  4011                              <1> 	;jc	short itrunc_0
  4012                              <1> 		; eax = 0	
  4013 00004DAC 8906                <1> 	mov	[esi], eax ; 0
  4014                              <1> 	;esi = i.dskp+32
  4015                              <1> itrunc_7:
  4016                              <1> 	; free disk blocks by using single indirect blocks at third
  4017 00004DAE 83EE04              <1> 	sub	esi, 4
  4018 00004DB1 8B06                <1> 	mov	eax, [esi]
  4019 00004DB3 09C0                <1> 	or	eax, eax
  4020 00004DB5 7409                <1> 	jz	short itrunc_8
  4021                              <1> 
  4022 00004DB7 29D2                <1> 	sub	edx, edx ; 0  ; Single indirect sign (level = 0)
  4023 00004DB9 E80C000000          <1> 	call	tloop
  4024                              <1> 	; 10/01/2022
  4025                              <1> 	;jc	short itrunc_0
  4026                              <1> 		; eax = 0
  4027 00004DBE 8906                <1> 	mov	[esi], eax ; 0
  4028                              <1> itrunc_8:
  4029 00004DC0 81FE[D0670000]      <1> 	cmp	esi, i.dskp
  4030 00004DC6 77E6                <1> 	ja	short itrunc_7
  4031 00004DC8 EBAC                <1> 	jmp	short itrunc_4
  4032                              <1> 
  4033                              <1> tloop:
  4034                              <1> 	; 26/03/2022
  4035                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
  4036                              <1> 	; 07/06/2020
  4037                              <1> 	; 03/06/2020
  4038                              <1> 	; 02/06/2020
  4039                              <1> 	; 26/05/2020 - Retro UNIX 386 v2 by Erdogan Tan
  4040                              <1> 	; 
  4041                              <1> 	; * Free all the disk blocks associated
  4042                              <1> 	; * with the specified inode structure.
  4043                              <1> 
  4044                              <1> 	; Reference: 
  4045                              <1> 	;	Retro UNIX 386 v2 FS installation utility
  4046                              <1> 	; 17/01/2020 - 'UNIXHDCP.ASM', 'tloop' procedure
  4047                              <1> 
  4048                              <1> 	; INPUT: 
  4049                              <1> 	;	03/06/2020
  4050                              <1> 	;	eax = indirect block number/address (logical)
  4051                              <1> 	;	edx = level (in dl) 
  4052                              <1> 	;	(0 = indirect, 1 = double indr. 2 = triple indr.) 	
  4053                              <1> 	;
  4054                              <1> 	; OUTPUT: 
  4055                              <1> 	;	indirect blocks will be released
  4056                              <1> 	;
  4057                              <1> 	; Modified registers: eax, ebx, ecx, edx
  4058                              <1> 
  4059                              <1> 	; 03/06/2020
  4060                              <1> 
  4061 00004DCA 57                  <1> 	push	edi ; *
  4062 00004DCB 56                  <1> 	push	esi ; **
  4063                              <1> 
  4064 00004DCC 50                  <1> 	push	eax ; ***
  4065                              <1> 
  4066 00004DCD 52                  <1> 	push	edx ; **** level
  4067                              <1> 
  4068                              <1> 	; [ii] = current inode number
  4069                              <1> 	;;[idev] = logical drive number of current inode, [ii]
  4070                              <1> 	; eax = logical sector/block number
  4071                              <1> 
  4072                              <1> 	; 26/03/2022
  4073                              <1> 	; [cdev] = logical drive number (0 or 1)
  4074                              <1> 
  4075                              <1> 	; 10/01/2022
  4076                              <1> 	; convert to physical sector/block number/address
  4077 00004DCE E856FAFFFF          <1> 	call	mget_2	
  4078                              <1> 
  4079 00004DD3 E89A0B0000          <1> 	call	dskrd ; read disk sector
  4080                              <1> 
  4081                              <1> 		;; ebx = buffer header address
  4082                              <1> 		;; eax = physical sector/block number 
  4083                              <1> 		;; [pdn] = phsysical drive (index) number
  4084                              <1> 		
  4085                              <1> 		;; Modified registers: eax, edx, ecx, esi, edi
  4086                              <1> 		;; If cf = 1 --> eax = error code (al)
  4087                              <1> 
  4088                              <1> 	; 10/01/2022
  4089                              <1> 	; Return from 'dskrd': (Retro UNIX 386 v1.2)
  4090                              <1> 	; 	eax = physical block/sector number
  4091                              <1> 	; 	ebx = buffer data address
  4092                              <1>  	; Modified registers: edx, ecx, ebx, esi, edi, ebp
  4093                              <1>  
  4094 00004DD8 5A                  <1> 	pop	edx ; **** ; level in dl
  4095                              <1> 	; 10/01/2022
  4096                              <1> 	;jc	short tloop_5
  4097                              <1> 
  4098                              <1> 	;mov	esi, [ebx+bufhdr.address] ; buffer address
  4099                              <1> 	; 10/01/2022
  4100 00004DD9 89DE                <1> 	mov	esi, ebx ; buffer data address	
  4101                              <1> 
  4102                              <1> 	; 07/06/2020
  4103 00004DDB B980000000          <1> 	mov	ecx, 512/4 ; 128 dwords	
  4104                              <1> 
  4105 00004DE0 80FA01              <1> 	cmp	dl, 1 ; -
  4106 00004DE3 722C                <1> 	jb	short tloop_7
  4107 00004DE5 7407                <1> 	je	short tloop_1
  4108 00004DE7 BF[04750000]        <1> 	mov	edi, trpi_buf ; triple indirect buffer address
  4109 00004DEC EB05                <1> 	jmp	short tloop_2
  4110                              <1> tloop_1:
  4111 00004DEE BF[04730000]        <1> 	mov	edi, dbli_buf ; double indirect buffer address
  4112                              <1> tloop_2:
  4113                              <1> 	; copy disk r/w buffer content to indirect block buffer
  4114                              <1> 	;mov	ecx, 512/4 ; 128 dwords	
  4115 00004DF3 F3A5                <1> 	rep	movsd
  4116                              <1> 
  4117 00004DF5 FECA                <1> 	dec	dl ; -
  4118                              <1> 		   ; next indirect block level, 2 -> 1, 1 -> 0
  4119 00004DF7 89FE                <1> 	mov	esi, edi  ; (dbli, trpi) indirect buffer + 512
  4120 00004DF9 B180                <1> 	mov	cl, 128 ; 128 dwords
  4121                              <1> tloop_3:
  4122 00004DFB 83EE04              <1> 	sub	esi, 4  ; previous pointer
  4123                              <1> 
  4124 00004DFE 8B06                <1> 	mov	eax, [esi]
  4125                              <1> 
  4126 00004E00 09C0                <1> 	or	eax, eax ; 0
  4127 00004E02 7409                <1> 	jz	short tloop_4
  4128                              <1> 
  4129                              <1> 	; 26/03/2022
  4130 00004E04 52                  <1> 	push	edx ; @@
  4131                              <1> 	; 03/06/2020
  4132 00004E05 51                  <1> 	push	ecx ; @
  4133 00004E06 E8BFFFFFFF          <1> 	call	tloop
  4134 00004E0B 59                  <1> 	pop	ecx ; @
  4135                              <1> 	; 26/03/2022
  4136 00004E0C 5A                  <1> 	pop	edx ; @@
  4137                              <1> 	; 10/01/2022
  4138                              <1> 	;jc	short tloop_5
  4139                              <1> tloop_4:
  4140 00004E0D E2EC                <1> 	loop	tloop_3
  4141                              <1> 
  4142 00004E0F EB1A                <1> 	jmp	short tloop_10
  4143                              <1> 
  4144                              <1> 	; 10/01/2022
  4145                              <1> ;tloop_5:
  4146                              <1> ;	pop	edx ; ***  ; discard eax
  4147                              <1> ;	; error code in eax
  4148                              <1> ;tloop_6:
  4149                              <1> ;	pop	esi ; **
  4150                              <1> ;	pop	edi ; *
  4151                              <1> ;	retn
  4152                              <1> 	
  4153                              <1> 	; free blocks in current indirect block
  4154                              <1> tloop_7:
  4155                              <1> 	;mov	ecx, 512/4  ; 128 dwords
  4156 00004E11 81C6FC010000        <1> 	add	esi, 508
  4157                              <1> tloop_8:
  4158 00004E17 8B06                <1> 	mov	eax, [esi]
  4159 00004E19 21C0                <1> 	and	eax, eax ; 0 ?
  4160 00004E1B 7409                <1> 	jz	short tloop_9
  4161                              <1> 	
  4162 00004E1D 56                  <1> 	push	esi ; **** ; 10/01/2022
  4163 00004E1E 51                  <1> 	push	ecx ; *****
  4164 00004E1F E881FCFFFF          <1> 	call	free
  4165                              <1> 		; if cf = 0 -> eax = 0
  4166                              <1> 		; if cf = 1 -> eax = error code (in al)
  4167 00004E24 59                  <1> 	pop	ecx ; *****
  4168 00004E25 5E                  <1> 	pop	esi ; **** ; 10/01/2022
  4169                              <1> 	; 10/01/2022
  4170                              <1> 	;; 07/06/2020
  4171                              <1> 	;jc	short tloop_6
  4172                              <1> tloop_9:
  4173 00004E26 83EE04              <1> 	sub	esi, 4
  4174 00004E29 E2EC                <1> 	loop	tloop_8
  4175                              <1> tloop_10:
  4176 00004E2B 58                  <1> 	pop	eax ; *** ; free indirect block's itself
  4177 00004E2C E874FCFFFF          <1> 	call	free
  4178                              <1> 		;; if cf = 0 -> eax = 0
  4179                              <1> 		;; if cf = 1 -> eax = error code (in al)
  4180                              <1> 	; 10/01/2022
  4181                              <1> 	; (if we are here, there is not an error, cf=0) 
  4182                              <1> 	;jmp	short tloop_6
  4183                              <1> 
  4184                              <1> 	; 10/02/2022
  4185 00004E31 31C0                <1> 	xor	eax, eax ; 0
  4186 00004E33 5E                  <1> 	pop	esi ; **
  4187 00004E34 5F                  <1> 	pop	edi ; *
  4188 00004E35 C3                  <1> 	retn
  4189                              <1> 
  4190                              <1> 	; Retro UNIX 386 v2.0 'imap' code
  4191                              <1> 	;	(runix v2 fs inode map)
  4192                              <1> imap:
  4193                              <1> 	; 18/04/2022
  4194                              <1> 	; 26/03/2022
  4195                              <1> 	; 12/03/2022
  4196                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
  4197                              <1> 	;	(major modification)
  4198                              <1> 	; 05/11/2021 - temporary (simplified code)
  4199                              <1> 	; 21/08/2021
  4200                              <1> 	; 15/08/2021
  4201                              <1> 	; 14/06/2021
  4202                              <1> 	; 02/05/2021
  4203                              <1> 	; 01/04/2021, 08/04/2021, 24/04/2021
  4204                              <1> 	; 29/03/2021
  4205                              <1> 	; 28/03/2021 - Retro UNIX 386 v2 (beginning)
  4206                              <1> 	;
  4207                              <1> 	; 'imap' finds the byte in inode map containing
  4208                              <1> 	; allocation bit for an i-node whose number in (E)AX
  4209                              <1> 	;
  4210                              <1> 	; (ref: 'UNIXHDCP.ASM', imap', 22/01/2020) 
  4211                              <1> 	;
  4212                              <1> 	; ((Retro UNIX 386 v2 'imap' code is mostly different
  4213                              <1> 	; than Retro UNIX 386 v1.1 'imap' code.))
  4214                              <1> 	;
  4215                              <1> 	; INPUTS ->
  4216                              <1> 	;   EAX = inode number
  4217                              <1> 	;        0 = first free inode
  4218                              <1> 	;       >0 = requested inode
  4219                              <1> 	;   [cdev] = current (logical) drive/device
  4220                              <1> 	;	
  4221                              <1> 	; OUTPUTS ->
  4222                              <1> 	;    EBX = address of the byte contains allocation bit
  4223                              <1> 	;     DX has 1 at calculated bit position
  4224                              <1> 	;   ; 05/11/2021	
  4225                              <1> 	;    EBP = superblock buffer address  
  4226                              <1> 	;    (EAX = inode number)
  4227                              <1> 	;   12/03/2022
  4228                              <1> 	;    (if EAX input is 0, EAX = first free inode > 1)
  4229                              <1> 	;	 		  	
  4230                              <1> 	;   ; 08/04/2021
  4231                              <1> 	;     If cf=1 -> error code in eax (al) 	
  4232                              <1> 	;
  4233                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp
  4234                              <1> 
  4235                              <1> 	; 05/11/2021
  4236 00004E36 803D[216C0000]00    <1> 	cmp	byte [cdev], 0
  4237 00004E3D 7616                <1> 	jna	short imap_0
  4238                              <1> 	; 10/01/2022
  4239 00004E3F BD[FC6E0000]        <1> 	mov	ebp, mount ; mounted fs superblock buffer
  4240 00004E44 EB14                <1> 	jmp	short imap_1
  4241                              <1> 
  4242                              <1> imap_ialloc_err:
  4243                              <1> 	; 10/01/2022
  4244 00004E46 C705[B86C0000]2100- <1> 	mov	dword [u.error], ERR_INO_ALLOC ; 33
  4244 00004E4E 0000                <1>
  4245                              <1> 			; 'inode allocation error !'
  4246 00004E50 E9F2E2FFFF          <1> 	jmp	error
  4247                              <1>  
  4248                              <1> imap_0:
  4249                              <1> 	; 10/01/2022
  4250 00004E55 BD[F46C0000]        <1> 	mov	ebp, systm ; root fs superblock buffer
  4251                              <1> imap_1:
  4252                              <1> 	; 26/03/2022
  4253                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
  4254                              <1> imap_x:
  4255                              <1> 	; 05/11/2021
  4256                              <1> 	; 21/08/2021
  4257                              <1> 	; 15/08/2021 (Retro UNIX 386 v2)
  4258                              <1> 	; call from 'maknod2' ; 10/01/2022
  4259                              <1> 	;
  4260                              <1> 	; eax = inode number
  4261                              <1> 	; [cdev] = device number for inode in eax
  4262                              <1> 	; ebp = superblock buffer address
  4263                              <1> 
  4264                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
  4265                              <1> 	; 'imap' and 'imap_x' will return with..
  4266                              <1> 	;    ECX = byte offset from inode map buff (imap_x)
  4267                              <1> 	;    EBX = byte addr of the byte with allocation bit
  4268                              <1> 	;    EDX (DL) has a 1 in the calculated bit position
  4269                              <1> 
  4270                              <1> 	; 02/05/2021
  4271                              <1> 	; convert inode number to first free inode if it is 0
  4272 00004E5A E83B000000          <1> 	call	imap_3 ; 10/01/2022
  4273 00004E5F 72E5                <1> 	jc	short imap_ialloc_err
  4274                              <1> 	; eax = inode number > 1 (1 = root directory inode)
  4275                              <1> 
  4276 00004E61 898584000000        <1> 	mov	[ebp+SB.LastInode], eax
  4277                              <1> 	
  4278 00004E67 50                  <1> 	push	eax ; * ; save inode number
  4279                              <1> 
  4280                              <1> 	; convert inode number to inode map sector index
  4281 00004E68 E845000000          <1> 	call	imap_8 ; 10/01/2022
  4282 00004E6D 50                  <1> 	push	eax ; ** ; byte offset in inode map buffer
  4283                              <1> 
  4284                              <1> 	; edx = inode map buffer sector index number (< 16)
  4285                              <1> 	; eax = byte offset in inode map buffer (< 512)
  4286                              <1> 
  4287                              <1> 	; 15/08/2021
  4288 00004E6E 89958C000000        <1> 	mov	[ebp+SB.ImapIndex], edx
  4289 00004E74 8B4520              <1> 	mov	eax, [ebp+SB.InodeMapAddr]
  4290 00004E77 01D0                <1> 	add	eax, edx
  4291 00004E79 034504              <1> 	add	eax, [ebp+SB.BootSectAddr]
  4292                              <1> 	; eax = physical sector number
  4293                              <1> 	; [cdev] = current device/disk number
  4294                              <1> 	
  4295                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
  4296 00004E7C 55                  <1> 	push	ebp ; ***
  4297 00004E7D E8F00A0000          <1> 	call	dskrd
  4298 00004E82 5D                  <1> 	pop	ebp ; ***
  4299                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
  4300                              <1> 	; eax = physical sector number
  4301                              <1> 	; ebx = buffer data address
  4302                              <1> 
  4303                              <1> 	; 26/03/2022
  4304                              <1> 	; (ecx may be > 255 at return from dskrd)
  4305                              <1> 	;sub	ecx, ecx ; 0
  4306                              <1> 	; 10/01/2022
  4307                              <1> 	;mov	cl, [esp+4] ; * ; inode number
  4308                              <1> 	; 18/04/2022
  4309 00004E83 8B4C2404            <1> 	mov	ecx, [esp+4] ; * ; inode number
  4310 00004E87 FEC9                <1> 	dec	cl
  4311                              <1> 	; 26/03/2022
  4312 00004E89 31D2                <1> 	xor	edx, edx
  4313                              <1> 	;mov	dl, 1
  4314 00004E8B FEC2                <1> 	inc	dl ; dl = 1
  4315                              <1> 	;and	ecx, 7
  4316                              <1> 	; 26/03/2022
  4317                              <1> 	; 02/05/2021
  4318                              <1> 	;dec	cl
  4319                              <1> 	;jz	short imap_2 ; 15/08/2021
  4320 00004E8D 80E107              <1> 	and	cl, 7	; 1 imap byte is for 8 inodes 
  4321                              <1> 	;jz	short imap_2
  4322 00004E90 D2E2                <1> 	shl	dl, cl
  4323                              <1> imap_2:
  4324                              <1> 	; 10/01/2022
  4325                              <1> 	; save physical sector number of imap sector in the SB
  4326 00004E92 89457C              <1> 	mov	[ebp+SB.ImapBuffer], eax ; ! sector addr !
  4327                              <1> 	; 
  4328 00004E95 59                  <1> 	pop	ecx ; ** ; byte offset in inode map buffer
  4329 00004E96 01CB                <1> 	add	ebx, ecx ; + byte position
  4330 00004E98 58                  <1> 	pop	eax ; * ; inode number
  4331                              <1> 
  4332                              <1> 	; 10/01/2022
  4333                              <1> 	; ECX contains byte offset from inode map buff (imap_x)
  4334                              <1> 	; EDX (DL) has a 1 in the calculated bit position
  4335                              <1> 	; EBX has byte address of the byte with allocation bit
  4336                              <1> 
  4337 00004E99 C3                  <1> 	retn
  4338                              <1> 
  4339                              <1> imap_3:
  4340                              <1> 	; 10/01/2022
  4341                              <1> 	; 15/08/2021
  4342                              <1> 	; 02/05/2021
  4343                              <1> 	; 28/03/2021
  4344                              <1> 	; get first free inode number (from superblock)
  4345                              <1> 	; and check inode number against inode count
  4346                              <1> 	;
  4347                              <1> 	; INPUT:
  4348                              <1> 	;    eax = 0 -> get first free inode number
  4349                              <1> 	;    (eax > 0 -> check inode number)
  4350                              <1> 	;    ebp = superblock address ; 15/08/2021
  4351                              <1> 	; OUTPUT:
  4352                              <1> 	;    eax = inode number 
  4353                              <1> 	;    (eax will be 2 when SB.FirstFreeIno is invalid)
  4354                              <1> 	;    cf = 1 -> inode allocation error/problem
  4355                              <1> 	
  4356 00004E9A 21C0                <1> 	and	eax, eax	
  4357 00004E9C 750E                <1> 	jnz	short imap_5
  4358                              <1> 
  4359                              <1> 	; get first free inode
  4360                              <1> 	;mov	eax, [ebp+SB.FreeInodes]
  4361                              <1> 	;and	eax, eax
  4362                              <1> 	;jz	short imap_6
  4363                              <1> 	; 10/01/2022
  4364 00004E9E 394530              <1> 	cmp	[ebp+SB.FreeInodes], eax ; 0
  4365 00004EA1 760D                <1> 	jna	short imap_6	
  4366 00004EA3 8B4534              <1> 	mov	eax, [ebp+SB.FirstFreeIno] ; 1 based inode num
  4367 00004EA6 40                  <1> 	inc	eax
  4368 00004EA7 7502                <1> 	jnz	short imap_4 ; 0FFFFFFFFh -> 0
  4369                              <1> 	; invalid first free inode value (not initialized)
  4370 00004EA9 B003                <1> 	mov	al, 3 ; first free inode to be searched + 1
  4371                              <1> imap_4:
  4372 00004EAB 48                  <1> 	dec	eax
  4373                              <1> imap_5:
  4374                              <1> 	; 15/08/2021
  4375                              <1> 	; check inode number against inode count of the fs
  4376 00004EAC 394514              <1> 	cmp	[ebp+SB.InodeCount], eax
  4377 00004EAF C3                  <1> 	retn	; if cf = 1 --> inode number > inode count
  4378                              <1> imap_6:
  4379                              <1> 	; 'imap' inode allocation error !
  4380 00004EB0 F9                  <1> 	stc
  4381                              <1> imap_7:
  4382 00004EB1 C3                  <1> 	retn
  4383                              <1> 
  4384                              <1> imap_8:
  4385                              <1> 	; 10/01/2022
  4386                              <1> 	; 15/08/2021
  4387                              <1> 	; 02/05/2021
  4388                              <1> 	; 28/03/2021
  4389                              <1> 	; convert inode count to inode map sector index
  4390                              <1> 	;
  4391                              <1> 	; INPUT: 
  4392                              <1> 	;    eax = inode number
  4393                              <1> 	; OUTPUT:
  4394                              <1> 	;    edx = inode map sector offset/index number
  4395                              <1> 	;    eax = byte offset from start of imapbuf	 
  4396                              <1> 
  4397 00004EB2 31D2                <1> 	xor	edx, edx
  4398 00004EB4 48                  <1> 	dec	eax ; zero based inode number
  4399 00004EB5 74FA                <1> 	jz	short imap_7
  4400                              <1> 
  4401 00004EB7 C1E803              <1> 	shr	eax, 3 ; 8 inodes per inode map byte
  4402                              <1> 		; eax = byte offset from start of inode map
  4403 00004EBA 88E2                <1> 	mov	dl, ah ; ah <= 31 (1Fh) for Retro UNIX 386 v2
  4404 00004EBC D0EA                <1> 	shr	dl, 1
  4405                              <1> 		; edx = inode map sector offset/index number
  4406                              <1> 	;and	eax, 511
  4407 00004EBE 6625FF01            <1> 	and	ax, 511
  4408                              <1> 		; eax = byte offset from start of imapbuf
  4409 00004EC2 C3                  <1> 	retn
  2094                                  %include 'u6.s'      ; 31/05/2015
  2095                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2096                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2097                              <1> ; ****************************************************************************
  2098                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS6.INC
  2099                              <1> ; Last Modification: 19/07/2022
  2100                              <1> ; ----------------------------------------------------------------------------
  2101                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2102                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2103                              <1> ;
  2104                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2105                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2106                              <1> ; <Bell Laboratories (17/3/1972)>
  2107                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2108                              <1> ;
  2109                              <1> ; Retro UNIX 8086 v1 - U6.ASM (23/07/2014) //// UNIX v1 -> u6.s
  2110                              <1> ;
  2111                              <1> ; ****************************************************************************
  2112                              <1> 
  2113                              <1> 	; 09/03/2022
  2114                              <1> 	; 25/12/2021
  2115                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2116                              <1> readi:
  2117                              <1> 	; 20/05/2015
  2118                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2119                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  2120                              <1> 	;
  2121                              <1> 	; Reads from an inode whose number in R1
  2122                              <1> 	; 
  2123                              <1> 	; INPUTS ->
  2124                              <1> 	;    r1 - inode number
  2125                              <1> 	;    u.count - byte count user desires
  2126                              <1> 	;    u.base - points to user buffer
  2127                              <1> 	;    u.fofp - points to word with current file offset
  2128                              <1> 	; OUTPUTS ->
  2129                              <1> 	;    u.count - cleared
  2130                              <1> 	;    u.nread - accumulates total bytes passed back
  2131                              <1> 	;
  2132                              <1> 	; ((AX = R1)) input/output
  2133                              <1> 	;    (Retro UNIX Prototype: 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
  2134                              <1>         ;    ((Modified registers: edx, ebx, ecx, esi, edi)) -15/07/2022- 
  2135                              <1> 
  2136 00004EC3 31D2                <1> 	xor	edx, edx ; 0
  2137 00004EC5 8915[706C0000]      <1> 	mov 	[u.nread], edx ; 0
  2138                              <1> 		; clr u.nread / accumulates number of bytes transmitted
  2139 00004ECB 668915[B06C0000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
  2140 00004ED2 3915[6C6C0000]      <1> 	cmp 	[u.count], edx ; 0
  2141                              <1> 		; tst u.count / is number of bytes to be read greater than 0
  2142 00004ED8 7701                <1> 	ja 	short readi_1 ; 1f
  2143                              <1> 		; bgt 1f / yes, branch
  2144 00004EDA C3                  <1> 	retn
  2145                              <1> 		; rts r0 / no, nothing to read; return to caller
  2146                              <1> readi_1: ; 1:
  2147                              <1> 	;	; mov r1,-(sp) / save i-number on stack
  2148                              <1> 	;cmp	ax, 40
  2149                              <1> 	;	; cmp r1,$40. / want to read a special file 
  2150                              <1> 	;	;             / (i-nodes 1,...,40 are for special files)
  2151                              <1>         ;ja	dskr 
  2152                              <1> 	;	; ble 1f / yes, branch
  2153                              <1> 	;	; jmp dskr / no, jmp to dskr; 
  2154                              <1> 	;	;         / read file with i-node number (r1)
  2155                              <1> 	;	;    / starting at byte ((u.fofp)), read in u.count bytes
  2156                              <1> 	
  2157                              <1> 	; 28/11/2021
  2158 00004EDB F605[B66C0000]FF    <1> 	test	byte [u.kcall], 0FFh
  2159                              <1> 	;jnz	short readi_2  ; 'readi' called by 'namei'
  2160                              <1> 	; 09/03/2022
  2161                              <1> 	;jz	short _readi_2
  2162                              <1> 	;jmp	dskr
  2163 00004EE2 750C                <1> 	jnz	short readi_2 ; 'readi' called by 'namei'
  2164                              <1> ;_readi_2:	; 09/03/2022
  2165                              <1> 	; eax = inode number
  2166                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
  2167 00004EE4 E86EFCFFFF          <1> 	call	iget
  2168                              <1> ;readi_2:
  2169                              <1> 	; 28/11/2021
  2170                              <1> 	; eax = inode number
  2171                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
  2172 00004EE9 E800050000          <1> 	call	is_regular_file
  2173                              <1> 	;jz	dskr ; regular file 
  2174                              <1> 	; 25/12/2021
  2175 00004EEE 7505                <1> 	jnz	short readi_5 ; device file 
  2176                              <1> readi_2:	 ; 09/03/2022
  2177                              <1> 	; regular file
  2178 00004EF0 E9E3000000          <1> 	jmp	dskr
  2179                              <1> readi_5:
  2180                              <1> 	; (20/05/2015)
  2181 00004EF5 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
  2182                              <1> 
  2183                              <1> 	; 28/11/2021	
  2184                              <1> 	; device file
  2185 00004EF6 BB[104F0000]        <1> 	mov	ebx, readi_4
  2186 00004EFB 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
  2187 00004EFE 720E                <1> 	jb	short readi_3
  2188 00004F00 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
  2189 00004F03 7709                <1> 	ja	short readi_3	
  2190                              <1> 	
  2191                              <1> 	; convert v2 inode number to v1 device inode number
  2192 00004F05 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
  2193 00004F07 89C1                <1> 	mov	ecx, eax
  2194 00004F09 C0E102              <1> 	shl	cl, 2 ; * 4
  2195 00004F0C 01CB                <1> 	add	ebx, ecx
  2196                              <1> readi_3:
  2197 00004F0E FF23                <1> 	jmp	dword [ebx]	
  2198                              <1> 		 ; jmp *1f-2(r1)
  2199                              <1> readi_4: ; 1:
  2200 00004F10 [604F0000]          <1> 	dd	null ; 28/11/2021
  2201 00004F14 [644F0000]          <1> 	dd	rtty ; tty, AX = 1 (runix)
  2202                              <1> 		 ;rtty / tty; r1=2
  2203                              <1> 		 ;rppt / ppt; r1=4
  2204 00004F18 [B44F0000]          <1> 	dd	rmem ; mem, AX = 2 (runix)
  2205                              <1> 		 ;rmem / mem; r1=6
  2206                              <1> 		 ;rrf0 / rf0
  2207                              <1> 		 ;rrk0 / rk0
  2208                              <1> 		 ;rtap / tap0
  2209                              <1> 		 ;rtap / tap1
  2210                              <1> 		 ;rtap / tap2
  2211                              <1> 		 ;rtap / tap3
  2212                              <1> 		 ;rtap / tap4
  2213                              <1> 		 ;rtap / tap5
  2214                              <1> 		 ;rtap / tap6
  2215                              <1> 		 ;rtap / tap7
  2216 00004F1C [33580000]          <1> 	dd	rfd ; fd0, AX = 3 (runix only)
  2217 00004F20 [33580000]          <1> 	dd	rfd ; fd1, AX = 4 (runix only)
  2218 00004F24 [33580000]          <1> 	dd	rhd ; hd0, AX = 5 (runix only)
  2219 00004F28 [33580000]          <1> 	dd	rhd ; hd1, AX = 6 (runix only)	
  2220 00004F2C [33580000]          <1> 	dd	rhd ; hd2, AX = 7 (runix only)
  2221 00004F30 [33580000]          <1> 	dd	rhd ; hd3, AX = 8 (runix only)	
  2222 00004F34 [C94F0000]          <1> 	dd	rlpr ; lpr, AX = 9 (invalid, write only device !?)
  2223 00004F38 [B04F0000]          <1> 	dd	rcvt ; tty0, AX = 10 (runix)	  
  2224                              <1> 		 ;rcvt / tty0
  2225 00004F3C [B04F0000]          <1> 	dd	rcvt ; tty1, AX = 11 (runix)	  
  2226                              <1> 		 ;rcvt / tty1
  2227 00004F40 [B04F0000]          <1> 	dd	rcvt ; tty2, AX = 12 (runix)	  
  2228                              <1> 		 ;rcvt / tty2
  2229 00004F44 [B04F0000]          <1> 	dd	rcvt ; tty3, AX = 13 (runix)	  
  2230                              <1> 		 ;rcvt / tty3
  2231 00004F48 [B04F0000]          <1> 	dd	rcvt ; tty4, AX = 14 (runix)	  
  2232                              <1> 		 ;rcvt / tty4
  2233 00004F4C [B04F0000]          <1> 	dd	rcvt ; tty5, AX = 15 (runix)	  
  2234                              <1> 		 ;rcvt / tty5
  2235 00004F50 [B04F0000]          <1> 	dd	rcvt ; tty6, AX = 16 (runix)	  
  2236                              <1> 		 ;rcvt / tty6
  2237 00004F54 [B04F0000]          <1> 	dd	rcvt ; tty7, AX = 17 (runix)	  
  2238                              <1> 		 ;rcvt / tty7
  2239 00004F58 [B04F0000]          <1> 	dd	rcvt ; COM1, AX = 18 (runix only)	  
  2240                              <1> 		 ;rcrd / crd
  2241 00004F5C [B04F0000]          <1> 	dd	rcvt ; COM2, AX = 19 (runix only)
  2242                              <1> 
  2243                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2244                              <1> null:
  2245 00004F60 31C0                <1> 	xor	eax, eax
  2246 00004F62 58                  <1> 	pop	eax
  2247 00004F63 C3                  <1> 	retn
  2248                              <1> 
  2249                              <1> 	; 11/01/2022
  2250                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
  2251                              <1> rtty: ; / read from console tty
  2252                              <1> 	; 17/10/2015 - 16/07/2015 (Retro UNIX 8086 v1)
  2253                              <1> 	; 	     (Only 1 byte is read, by ignoring byte count!)
  2254                              <1> 	;  	     WHAT FOR: Every character from Keyboard input 
  2255                              <1> 	;	     must be written immediate on video page (screen)
  2256                              <1> 	;	     when it is required.	
  2257                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2258                              <1> 	; 11/03/2013 - 19/06/2014 (Retro UNIX 8086 v1)
  2259                              <1> 	;
  2260                              <1> 	; Console tty buffer is PC keyboard buffer
  2261                              <1> 	; and keyboard-keystroke handling is different than original
  2262                              <1> 	; unix (PDP-11) here. TTY/Keyboard procedures here are changed
  2263                              <1> 	; according to IBM PC compatible ROM BIOS keyboard functions. 
  2264                              <1> 	;
  2265                              <1> 	; 06/12/2013
  2266 00004F64 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  2267 00004F6B 8A83[43680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
  2268                              <1> rttys:
  2269                              <1> 		; mov tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
  2270                              <1> 	               ; / of the control and status block
  2271                              <1> 		; tst 2(r5) / for the console tty; this word points to the console
  2272                              <1> 		       ; / tty buffer
  2273                              <1> 	; 28/07/2013
  2274 00004F71 A2[796C0000]        <1> 	mov 	[u.ttyn], al
  2275                              <1> 	; 13/01/2014
  2276 00004F76 FEC0                <1> 	inc	al
  2277 00004F78 A2[7A6C0000]        <1> 	mov	[u.ttyp], al ; tty number + 1
  2278                              <1> rtty_nc: ; 01/02/2014
  2279                              <1> 	; 29/09/2013
  2280                              <1> 	;mov	ecx, 10
  2281                              <1> 	; 11/01/2022
  2282 00004F7D 29C9                <1> 	sub	ecx, ecx
  2283 00004F7F B10A                <1> 	mov	cl, 10
  2284                              <1> rtty_1: 	; 01/02/2014
  2285                              <1> 	;push 	cx ; 29/09/2013
  2286                              <1> 	; 11/12/2021
  2287 00004F81 51                  <1> 	push	ecx
  2288                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
  2289 00004F82 B001                <1> 	mov 	al, 1
  2290 00004F84 E8C20B0000          <1> 	call 	getc
  2291                              <1> 	;pop 	cx ; 29/09/2013	
  2292                              <1> 	; 11/12/2021
  2293 00004F89 59                  <1> 	pop	ecx
  2294 00004F8A 7516                <1> 	jnz	short rtty_2
  2295                              <1> 		; bne 1f / 2nd word of console tty buffer contains number
  2296                              <1> 	               ; / of chars. Is this number non-zero?
  2297 00004F8C E20D                <1> 	loop	rtty_idle ; 01/02/2014
  2298                              <1> 	; 05/10/2013
  2299 00004F8E 8A25[796C0000]      <1> 	mov	ah, [u.ttyn]
  2300                              <1> 	; 29/09/2013
  2301 00004F94 E8C9F7FFFF          <1> 	call	sleep
  2302                              <1> 		; jsr r0,canon; ttych / if 0, call 'canon' to get a line
  2303                              <1>                 ;           / (120 chars.)
  2304                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
  2305 00004F99 EBE2                <1> 	jmp	short rtty_nc ; 01/02/2014
  2306                              <1> 
  2307                              <1> rtty_idle:
  2308                              <1> 	; 29/07/2013
  2309 00004F9B E835F7FFFF          <1> 	call 	idle
  2310 00004FA0 EBDF                <1> 	jmp	short rtty_1 ; 01/02/2014
  2311                              <1> 	;1:
  2312                              <1> 		; tst 2(r5) / is the number of characters zero
  2313                              <1> 		; beq ret1 / yes, return to caller via 'ret1'
  2314                              <1> 		; movb *4(r5),r1 / no, put character in r1
  2315                              <1> 		; inc 4(r5) / 3rd word of console tty buffer points to byte which
  2316                              <1> 		          ; / contains the next char.
  2317                              <1> 		; dec 2(r5) / decrement the character count
  2318                              <1> rtty_2:
  2319 00004FA2 30C0                <1> 	xor 	al, al
  2320 00004FA4 E8A20B0000          <1> 	call 	getc
  2321 00004FA9 E895000000          <1> 	call	passc
  2322                              <1> 		; jsr r0,passc / move the character to core (user)
  2323                              <1> 	;; 17/10/2015 - 16/07/2015
  2324                              <1> 	; 19/06/2014
  2325                              <1> 	;;jnz	short rtty_nc
  2326 00004FAE 58                  <1> 	pop	eax  ; (20/05/2015)
  2327 00004FAF C3                  <1> 	retn 
  2328                              <1> ;ret1:
  2329                              <1> 		; jmp ret / return to caller via 'ret'
  2330                              <1> 
  2331                              <1> rcvt:   ; < receive/read character from tty >
  2332                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2333                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  2334                              <1> 	;
  2335                              <1> 	; Retro UNIX 8086 v1 modification !
  2336                              <1> 	; 
  2337                              <1> 	; In original UNIX v1, 'rcvt' routine 
  2338                              <1> 	;		(exactly different than this one)
  2339                              <1> 	;	was in 'u9.s' file.
  2340                              <1> 	;
  2341 00004FB0 2C0A                <1> 	sub 	al, 10
  2342                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
  2343                              <1> 	; 16/07/2013
  2344                              <1> 	; 21/05/2013
  2345 00004FB2 EBBD                <1>         jmp     short rttys
  2346                              <1>       
  2347                              <1> ;rppt: / read paper tape
  2348                              <1> ;	jsr	r0,pptic / gets next character in clist for ppt input and
  2349                              <1> ;			 / places
  2350                              <1> ;		br ret / it in r1; if there 1s no problem with reader, it
  2351                              <1> ;		       / also enables read bit in prs
  2352                              <1> ;	jsr	r0,passc / place character in users buffer area
  2353                              <1> ;	br	rppt
  2354                              <1> 
  2355                              <1> rmem: ; / transfer characters from memory to a user area of core
  2356                              <1> 	; 17/10/2015
  2357                              <1> 	; 11/06/2015
  2358                              <1> 	; 24/05/2015
  2359                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2360                              <1> 	;
  2361 00004FB4 8B35[586C0000]      <1> 	mov     esi, [u.fofp]
  2362                              <1> rmem_1:
  2363 00004FBA 8B1E                <1>         mov     ebx, [esi]        
  2364                              <1> 	        ; mov *u.fofp,r1 / save file offset which points to the char
  2365                              <1> 		               ; / to be transferred to user
  2366 00004FBC FF06                <1>         inc     dword [esi] ; 17/10/2015
  2367                              <1> 		; inc *u.fofp / increment file offset to point to 'next' 
  2368                              <1> 			    ; / char in memory file
  2369 00004FBE 8A03                <1> 	mov	al, [ebx]
  2370                              <1> 		; movb (r1),r1 / get character from memory file, 
  2371                              <1> 		             ; / put it in r1
  2372 00004FC0 E87E000000          <1> 	call	passc        ; jsr r0,passc / move this character to 
  2373                              <1> 			     ;  / the next byte of the users core area
  2374                              <1> 		; br rmem / continue
  2375 00004FC5 75F3                <1> 	jnz	short rmem_1
  2376                              <1> ret_:
  2377 00004FC7 58                  <1> 	pop	eax ; 09/06/2015
  2378 00004FC8 C3                  <1> 	retn
  2379                              <1> 
  2380                              <1> rlpr:
  2381                              <1> ;1:
  2382                              <1> ;rcrd:
  2383 00004FC9 C705[B86C0000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
  2383 00004FD1 0000                <1>
  2384 00004FD3 E96FE1FFFF          <1> 	jmp	error
  2385                              <1> 		;jmp	error / see 'error' routine
  2386                              <1> 
  2387                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2388                              <1> dskr:
  2389                              <1> 	; 19/07/2022
  2390                              <1> 	; 12/10/2015
  2391                              <1> 	; 21/08/2015
  2392                              <1> 	; 25/07/2015
  2393                              <1> 	; 10/07/2015
  2394                              <1> 	; 16/06/2015
  2395                              <1> 	; 31/05/2015
  2396                              <1> 	; 24/05/2015 (Retro UNIX 386 v1 - Beginning)
  2397                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
  2398                              <1> dskr_0:
  2399 00004FD8 50                  <1> 	push	eax
  2400                              <1> 		; mov (sp),r1 / i-number in r1
  2401                              <1> 	; AX = i-number
  2402 00004FD9 E879FBFFFF          <1> 	call	iget
  2403                              <1> 		; jsr r0,iget / get i-node (r1) into i-node section of core
  2404                              <1>         ;movzx	edx, word [i.size] ; 16/06/2015
  2405                              <1> 	;	; mov i.size,r2 / file size in bytes in r2
  2406                              <1> 	; 28/11/2021
  2407 00004FDE 8B15[CC670000]      <1> 	mov	edx, [i.size] ; 32 bit file size (runix v2 inode)
  2408                              <1> 	;
  2409 00004FE4 8B1D[586C0000]      <1> 	mov	ebx, [u.fofp]
  2410 00004FEA 2B13                <1> 	sub	edx, [ebx]
  2411                              <1> 		; sub *u.fofp,r2 / subtract file offset
  2412                              <1>         ; 12/10/2015
  2413                              <1> 	; jna	short ret_ 
  2414                              <1> 		; blos ret
  2415 00004FEC 7709                <1> 	ja	short dskr_1
  2416                              <1> 	;
  2417                              <1> dskr_retn: ; 12/10/2015
  2418 00004FEE 58                  <1> 	pop	eax
  2419 00004FEF C605[B66C0000]00    <1> 	mov	byte [u.kcall], 0
  2420 00004FF6 C3                  <1> 	retn	
  2421                              <1> dskr_1: 
  2422 00004FF7 3B15[6C6C0000]      <1> 	cmp     edx, [u.count] 
  2423                              <1> 		; cmp r2,u.count / are enough bytes left in file 
  2424                              <1> 			       ; / to carry out read
  2425 00004FFD 7306                <1> 	jnb	short dskr_2
  2426                              <1> 		; bhis 1f
  2427 00004FFF 8915[6C6C0000]      <1> 	mov	[u.count], edx
  2428                              <1> 		; mov r2,u.count / no, just read to end of file
  2429                              <1> dskr_2: ; 1:
  2430                              <1> 	; (E)AX = i-number ; 28/11/2021 (32 bit inode number)
  2431                              <1> 	;call	mget
  2432                              <1> 		; jsr r0,mget / returns physical block number of block 
  2433                              <1> 		    ; / in file where offset points
  2434                              <1> 	; 28/11/2021
  2435 00005005 E8D9F7FFFF          <1> 	call	mget_r
  2436                              <1> 
  2437                              <1> 	; eax = physical block number
  2438                              <1> 	; [cdev] = current device number 
  2439 0000500A E863090000          <1> 	call	dskrd
  2440                              <1> 		; jsr r0,dskrd / read in block, r5 points to 
  2441                              <1> 			     ; / 1st word of data in buffer
  2442                              <1> 	; 09/06/2015
  2443 0000500F 803D[B66C0000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
  2444 00005016 770F                <1> 	ja	short dskr_4	  ; zf=0 -> the caller is 'namei'
  2445 00005018 66833D[B06C0000]00  <1> 	cmp	word [u.pcount], 0
  2446 00005020 7705                <1> 	ja	short dskr_4
  2447                              <1> dskr_3:
  2448                              <1> 	; [u.base] = virtual address to transfer (as destination address)
  2449 00005022 E857000000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
  2450                              <1> dskr_4:
  2451                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
  2452 00005027 E843030000          <1> 	call	sioreg
  2453                              <1> 		; jsr r0,sioreg
  2454                              <1> 	
  2455                              <1> 	; 19/07/2022
  2456                              <1> 	;xchg	esi, edi
  2457                              <1> 	
  2458                              <1> 	; 19/07/2022
  2459                              <1> 	;  EDX = user data offset (previous value of [u.pbase])
  2460                              <1> 	;  ESI = pointer to file offset 
  2461                              <1> 	;  EDI = system (I/O) buffer offset
  2462                              <1> 	;  ECX = byte count
  2463                              <1> 	;  EBX = system buffer (data) address	
  2464                              <1> 	;  EAX = remain bytes after byte count within page frame 
  2465                              <1> 
  2466 0000502C 010E                <1> 	add	[esi], ecx 
  2467                              <1> 			; new file offset (old offset + byte count)
  2468                              <1> 	;
  2469 0000502E 89FE                <1> 	mov	esi, edi ; sector (I/O) buffer offset
  2470 00005030 89D7                <1> 	mov	edi, edx
  2471                              <1> 
  2472                              <1> 	; EDI = file (user data) offset
  2473                              <1> 	; ESI = sector (I/O) buffer offset
  2474                              <1> 	; ECX = byte count
  2475 00005032 F3A4                <1> 	rep	movsb
  2476                              <1> 		; movb (r2)+,(r1)+ / move data from buffer into working core
  2477                              <1> 		                 ; / starting at u.base
  2478                              <1> 		; dec r3
  2479                              <1> 		; bne 2b / branch until proper number of bytes are transferred
  2480                              <1> 	; 25/07/2015
  2481                              <1> 	; eax = remain bytes in buffer
  2482                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  2483 00005034 09C0                <1> 	or	eax, eax
  2484 00005036 75EA                <1> 	jnz	short dskr_3 ; (page end before system buffer end!)		
  2485                              <1> 	; 03/08/2013
  2486                              <1> 	;pop	eax
  2487 00005038 390D[6C6C0000]      <1> 	cmp	[u.count], ecx ; 0
  2488                              <1> 		; tst u.count / all bytes read off disk
  2489                              <1> 		; bne dskr
  2490                              <1> 		; br ret
  2491                              <1>         ;ja	short dskr_0
  2492                              <1> 	;mov	[u.kcall], cl ; 0 ; 09/06/2015
  2493                              <1> 	;retn
  2494                              <1> 	; 12/10/2015
  2495 0000503E 76AE                <1> 	jna	short dskr_retn
  2496 00005040 58                  <1> 	pop	eax  ; (i-node number)
  2497 00005041 EB95                <1> 	jmp	short dskr_0
  2498                              <1> 	
  2499                              <1> passc:
  2500                              <1> 	; 18/10/2015
  2501                              <1> 	; 10/07/2015
  2502                              <1> 	; 01/07/2015
  2503                              <1> 	; 08/06/2015
  2504                              <1> 	; 04/06/2015
  2505                              <1> 	; 20/05/2015
  2506                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2507                              <1> 	;
  2508                              <1>    	;(Retro UNIX 386 v1 - translation from user's virtual address
  2509                              <1> 	;		      to physical address
  2510 00005043 66833D[B06C0000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
  2511                              <1> 			     ; 1-4095 --> use previous physical base address
  2512                              <1> 			     ; in [u.pbase]
  2513 0000504B 7705                <1> 	ja	short passc_3
  2514                              <1> 	; 08/06/2015 - 10/07/2015
  2515 0000504D E82C000000          <1> 	call	trans_addr_w
  2516                              <1> passc_3:
  2517                              <1> 	; 19/05/2015
  2518 00005052 66FF0D[B06C0000]    <1> 	dec	word [u.pcount]
  2519                              <1> 	;
  2520 00005059 8B1D[AC6C0000]      <1> 	mov	ebx, [u.pbase]
  2521 0000505F 8803                <1> 	mov	[ebx], al
  2522                              <1> 		; movb r1,*u.base / move a character to the next byte of the
  2523                              <1> 		               ; / users buffer
  2524 00005061 FF05[686C0000]      <1> 	inc	dword [u.base]
  2525                              <1> 		; inc u.base / increment the pointer to point to 
  2526                              <1> 			  ; / the next byte in users buffer
  2527 00005067 FF05[AC6C0000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
  2528 0000506D FF05[706C0000]      <1> 	inc	dword [u.nread]
  2529                              <1> 		; inc u.nread / increment the number of bytes read
  2530 00005073 FF0D[6C6C0000]      <1> 	dec	dword [u.count]
  2531                              <1> 		; dec u.count / decrement the number of bytes to be read
  2532                              <1> 		; bne 1f / any more bytes to read? ; yes, branch
  2533 00005079 C3                  <1> 	retn
  2534                              <1> 		; mov (sp)+,r0 / no, do a non-local return to the caller of
  2535                              <1> 		             ; / 'readi' by:
  2536                              <1> 		;/ (1) pop the return address off the stack into r0
  2537                              <1> 		; mov (sp)+,r1 / (2) pop the i-number off the stack into r1
  2538                              <1> 	;1:
  2539                              <1> 		; clr	*$ps / clear processor status
  2540                              <1> 		; rts r0 / return to address currently on top of stack
  2541                              <1> 
  2542                              <1> trans_addr_r:
  2543                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
  2544                              <1> 	;	-'add_to_swap_queue' call is disabled as temporary-
  2545                              <1> 	; Translate virtual address to physical address 
  2546                              <1> 	; for reading from user's memory space
  2547                              <1> 	; (Retro UNIX 386 v1 feature only !)
  2548                              <1> 	; 18/10/2015
  2549                              <1> 	; 10/07/2015
  2550                              <1> 	; 09/06/2015
  2551                              <1> 	; 08/06/2015 
  2552                              <1> 	; 04/06/2015
  2553                              <1> 	;
  2554                              <1> 	; 18/10/2015
  2555 0000507A 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
  2556 0000507C EB04                <1> 	jmp 	short trans_addr_rw
  2557                              <1> 
  2558                              <1> 	;push	eax
  2559                              <1> 	;push	ebx
  2560                              <1> 	;mov	ebx, [u.base]
  2561                              <1> 	;call	get_physical_addr ; get physical address
  2562                              <1> 	;;jnc	short cpass_0
  2563                              <1> 	;jnc	short passc_1
  2564                              <1> 	;mov	[u.error], eax
  2565                              <1> 	;;pop	ebx
  2566                              <1> 	;;pop	eax
  2567                              <1> 	;jmp	error
  2568                              <1> ;cpass_0:
  2569                              <1> 	; 18/10/2015
  2570                              <1> 	; 20/05/2015
  2571                              <1> 	;mov 	[u.pbase], eax ; physical address	
  2572                              <1> 	;mov	[u.pcount], cx ; remain byte count in page (1-4096)
  2573                              <1> 	;pop	ebx
  2574                              <1> 	;pop	eax
  2575                              <1> 	;retn	; 08/06/2015
  2576                              <1> 
  2577                              <1> trans_addr_w:
  2578                              <1> 	; 31/12/2021
  2579                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
  2580                              <1> 	;	-'add_to_swap_queue' call is disabled as temporary-
  2581                              <1> 	; Translate virtual address to physical address
  2582                              <1> 	; for writing to user's memory space
  2583                              <1> 	; (Retro UNIX 386 v1 feature only !)
  2584                              <1> 	; 18/10/2015
  2585                              <1> 	; 29/07/2015
  2586                              <1> 	; 10/07/2015
  2587                              <1> 	; 09/06/2015
  2588                              <1> 	; 08/06/2015
  2589                              <1> 	; 04/06/2015 (passc)
  2590                              <1> 	;
  2591                              <1> 	; 18/10/2015
  2592 0000507E 29D2                <1> 	sub	edx, edx
  2593 00005080 FEC2                <1> 	inc	dl ; 1 (write access sign)
  2594                              <1> trans_addr_rw:
  2595 00005082 50                  <1> 	push	eax
  2596 00005083 53                  <1> 	push	ebx
  2597                              <1> 	; 18/10/2015
  2598 00005084 52                  <1> 	push 	edx ; r/w sign (in DL)
  2599                              <1> 	;
  2600 00005085 8B1D[686C0000]      <1> 	mov	ebx, [u.base]
  2601 0000508B E81DD7FFFF          <1> 	call	get_physical_addr ; get physical address
  2602 00005090 730A                <1> 	jnc	short passc_0
  2603 00005092 A3[B86C0000]        <1> 	mov	[u.error], eax
  2604                              <1> 	;pop	edx
  2605                              <1> 	;pop 	ebx
  2606                              <1> 	;pop	eax
  2607 00005097 E9ABE0FFFF          <1> 	jmp	error
  2608                              <1> passc_0:
  2609 0000509C F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page ; 18/10/2015
  2610 0000509F 5A                  <1> 	pop	edx ; 18/10/2015
  2611 000050A0 7517                <1> 	jnz	short passc_1
  2612                              <1> 	; 18/10/2015
  2613 000050A2 20D2                <1> 	and 	dl, dl
  2614 000050A4 7413                <1> 	jz	short passc_1
  2615                              <1> 	; 20/05/2015
  2616                              <1> 	; read only (duplicated) page -must be copied to a new page-
  2617                              <1> 	; EBX = linear address
  2618 000050A6 51                  <1> 	push 	ecx
  2619                              <1> 	; 31/12/2021 - Retro UNIX 386 v1.2 (BugFix)
  2620 000050A7 53                  <1> 	push	ebx ;* ; BugFix  ; 31/12/2021
  2621 000050A8 E871D6FFFF          <1> 	call 	copy_page
  2622 000050AD 5B                  <1> 	pop	ebx ;* ; BugFix  ; 31/12/2021
  2623 000050AE 59                  <1> 	pop	ecx
  2624 000050AF 7217                <1> 	jc	short passc_2
  2625                              <1> 	; 30/11/2021
  2626                              <1> 	;push	eax ; physical address of the new/allocated page
  2627                              <1> 	;call	add_to_swap_queue
  2628                              <1> 	;pop	eax
  2629                              <1> 	; 18/10/2015
  2630 000050B1 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
  2631                              <1> 	;mov 	ecx, PAGE_SIZE
  2632                              <1> 	;sub	ecx, ebx 
  2633 000050B7 01D8                <1> 	add	eax, ebx  
  2634                              <1> passc_1: 
  2635                              <1> 	; 18/10/2015
  2636                              <1> 	; 20/05/2015
  2637 000050B9 A3[AC6C0000]        <1> 	mov 	[u.pbase], eax ; physical address	
  2638 000050BE 66890D[B06C0000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
  2639 000050C5 5B                  <1> 	pop	ebx
  2640 000050C6 58                  <1> 	pop	eax
  2641 000050C7 C3                  <1> 	retn	; 08/06/2015
  2642                              <1> passc_2:
  2643 000050C8 C705[B86C0000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
  2643 000050D0 0000                <1>
  2644                              <1> 	;pop 	ebx
  2645                              <1> 	;pop	eax
  2646 000050D2 E970E0FFFF          <1> 	jmp	error
  2647                              <1> 
  2648                              <1> 	; 09/03/2022
  2649                              <1> 	; 25/12/2021
  2650                              <1> 	; 11/12/2021
  2651                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2652                              <1> writei:
  2653                              <1> 	; 20/05/2015
  2654                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2655                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  2656                              <1> 	;
  2657                              <1> 	; Write data to file with inode number in R1
  2658                              <1> 	; 
  2659                              <1> 	; INPUTS ->
  2660                              <1> 	;    r1 - inode number
  2661                              <1> 	;    u.count - byte count to be written
  2662                              <1> 	;    u.base - points to user buffer
  2663                              <1> 	;    u.fofp - points to word with current file offset
  2664                              <1> 	; OUTPUTS ->
  2665                              <1> 	;    u.count - cleared
  2666                              <1> 	;    u.nread - accumulates total bytes passed back	
  2667                              <1> 	; ((AX = R1))
  2668                              <1> 	;    (Retro UNIX Prototype: 18/11/2012 - 11/11/2012, UNIXCOPY.ASM)
  2669                              <1> 	;    ((Modified registers: edx, ebx, ecx, esi, edi)) -15/07/2022-	
  2670                              <1> 
  2671 000050D7 31C9                <1> 	xor	ecx, ecx
  2672 000050D9 890D[706C0000]      <1> 	mov 	[u.nread], ecx  ; 0
  2673                              <1> 		; clr u.nread / clear the number of bytes transmitted during
  2674                              <1> 		            ; / read or write calls
  2675 000050DF 66890D[B06C0000]    <1> 	mov	[u.pcount], cx	; 19/05/2015
  2676 000050E6 390D[6C6C0000]      <1> 	cmp 	[u.count], ecx
  2677                              <1> 	;	; tst u.count / test the byte count specified by the user
  2678 000050EC 770B                <1> 	ja 	short writei_1	; 1f
  2679                              <1> 		; bgt 1f / any bytes to output; yes, branch
  2680                              <1> 
  2681                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
  2682 000050EE 83F810              <1> 	cmp	eax, 16  ; LPR_INODE ; lpt (parallel port printer) ?
  2683 000050F1 7505                <1> 	jne	short writei_0
  2684 000050F3 E943010000          <1> 	jmp	lpr_stat	; get/read line status
  2685                              <1> writei_0:
  2686 000050F8 C3                  <1> 	retn
  2687                              <1> 	;	; rts r0 / no, return - no writing to do
  2688                              <1> writei_1: ;1:
  2689                              <1> 	;	; mov r1 ,-(sp) / save the i-node number on the stack
  2690                              <1> 	;cmp 	ax, 40
  2691                              <1> 	;	; cmp r1,$40.
  2692                              <1> 	;	; / does the i-node number indicate a special file?
  2693                              <1>         ;ja	dskw 
  2694                              <1> 	;	; bgt dskw / no, branch to standard file output
  2695                              <1> 
  2696                              <1> 	; 28/11/2021
  2697 000050F9 F605[B66C0000]FF    <1> 	test	byte [u.kcall], 0FFh
  2698 00005100 750C                <1> 	jnz	short writei_2  ; 'writei' called by 'mkdir'
  2699                              <1> 
  2700                              <1> 	; eax = inode number
  2701                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
  2702 00005102 E850FAFFFF          <1> 	call	iget
  2703                              <1> ;writei_2:
  2704                              <1> 	; 28/11/2021
  2705                              <1> 	; eax = inode number
  2706                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
  2707 00005107 E8E2020000          <1> 	call	is_regular_file
  2708                              <1> 	;jz	dskw ; regular file 
  2709                              <1> 	; 25/12/2021
  2710 0000510C 7505                <1> 	jnz	short writei_5 ; device file
  2711                              <1> writei_2:	 ; 09/03/2022 
  2712                              <1> 	; regular file
  2713 0000510E E968010000          <1> 	jmp	dskw
  2714                              <1> writei_5:
  2715                              <1> 	; (20/05/2015)
  2716 00005113 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
  2717                              <1> 	
  2718                              <1> 	; 28/11/2021	
  2719                              <1> 	; device file
  2720 00005114 BB[2E510000]        <1> 	mov	ebx, writei_4
  2721 00005119 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
  2722 0000511C 720E                <1> 	jb	short writei_3
  2723 0000511E 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
  2724 00005121 7709                <1> 	ja	short writei_3 ; 11/12/2021	
  2725                              <1> 	
  2726                              <1> 	; convert v2 inode number to v1 device inode number
  2727 00005123 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
  2728 00005125 89C1                <1> 	mov	ecx, eax
  2729 00005127 C0E102              <1> 	shl	cl, 2 ; * 4
  2730 0000512A 01CB                <1> 	add	ebx, ecx
  2731                              <1> writei_3:
  2732 0000512C FF23                <1> 	jmp	dword [ebx]	
  2733                              <1> 		; jmp *1f-2(r1)
  2734                              <1> 		; / jump table and jump to the appropriate routine
  2735                              <1> writei_4: ;1:
  2736 0000512E [604F0000]          <1> 	dd	null ; 28/11/2021
  2737 00005132 [7E510000]          <1> 	dd	wtty ; tty, AX = 1 (runix)
  2738                              <1> 		 ;wtty / tty; r1=2
  2739                              <1> 		 ;wppt / ppt; r1=4
  2740 00005136 [D1510000]          <1> 	dd	wmem ; mem, AX = 2 (runix)
  2741                              <1> 		 ;wmem / mem; r1=6
  2742                              <1> 		 ;wrf0 / rf0
  2743                              <1> 		 ;wrk0 / rk0
  2744                              <1> 		 ;wtap / tap0
  2745                              <1> 		 ;wtap / tap1
  2746                              <1> 		 ;wtap / tap2
  2747                              <1> 		 ;wtap / tap3
  2748                              <1> 		 ;wtap / tap4
  2749                              <1> 		 ;wtap / tap5
  2750                              <1> 		 ;wtap / tap6
  2751                              <1> 		 ;wtap / tap7
  2752 0000513A [A8580000]          <1> 	dd	wfd ; fd0, AX = 3 (runix only)
  2753 0000513E [A8580000]          <1> 	dd	wfd ; fd1, AX = 4 (runix only)
  2754 00005142 [A8580000]          <1> 	dd	whd ; hd0, AX = 5 (runix only)
  2755 00005146 [A8580000]          <1> 	dd	whd ; hd1, AX = 6 (runix only)	
  2756 0000514A [A8580000]          <1> 	dd	whd ; hd2, AX = 7 (runix only)
  2757 0000514E [A8580000]          <1> 	dd	whd ; hd3, AX = 8 (runix only)	
  2758 00005152 [01520000]          <1> 	dd	wlpr ; lpr, AX = 9   (runix)
  2759 00005156 [CB510000]          <1> 	dd	xmtt ; tty0, AX = 10 (runix)	  
  2760                              <1> 		 ;xmtt / tty0
  2761 0000515A [CB510000]          <1> 	dd	xmtt ; tty1, AX = 11 (runix)	  
  2762                              <1> 		 ;xmtt / tty1
  2763 0000515E [CB510000]          <1> 	dd	xmtt ; tty2, AX = 12 (runix)	  
  2764                              <1> 		 ;xmtt / tty2
  2765 00005162 [CB510000]          <1> 	dd	xmtt ; tty3, AX = 13 (runix)	  
  2766                              <1> 		 ;xmtt / tty3
  2767 00005166 [CB510000]          <1> 	dd	xmtt ; tty4, AX = 14 (runix)	  
  2768                              <1> 		 ;xmtt / tty4
  2769 0000516A [CB510000]          <1> 	dd	xmtt ; tty5, AX = 15 (runix)	  
  2770                              <1> 		 ;xmtt / tty5
  2771 0000516E [CB510000]          <1> 	dd	xmtt ; tty6, AX = 16 (runix)	  
  2772                              <1> 		 ;xmtt / tty6
  2773 00005172 [CB510000]          <1> 	dd	xmtt ; tty7, AX = 17 (runix)	  
  2774                              <1> 		 ;xmtt / tty7
  2775 00005176 [CB510000]          <1> 	dd	xmtt ; COM1, AX = 18 (runix only)	  
  2776                              <1> 		; / wlpr / lpr
  2777 0000517A [CB510000]          <1> 	dd	xmtt ; COM2, AX = 19 (runix only)
  2778                              <1> 
  2779                              <1> ;	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  2780                              <1> ;null:
  2781                              <1> ;	xor	eax, eax
  2782                              <1> ;	pop	eax
  2783                              <1> ;	retn	
  2784                              <1> 
  2785                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
  2786                              <1> wtty: ; write to console tty (write to screen)
  2787                              <1> 	; 18/11/2015
  2788                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2789                              <1> 	; 12/03/2013 - 07/07/2014 (Retro UNIX 8086 v1)
  2790                              <1> 	;
  2791                              <1> 	; Console tty output is on current video page
  2792                              <1> 	; Console tty character output procedure is changed here
  2793                              <1> 	; acconding to IBM PC compatible ROM BIOS video (text mode) functions.
  2794                              <1> 	;
  2795 0000517E 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  2796 00005185 8AA3[43680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  2797 0000518B 88E0                <1> 	mov	al, ah ; 07/07/2014
  2798                              <1> wttys:	
  2799                              <1> 	; 10/10/2013
  2800 0000518D 8825[796C0000]      <1> 	mov 	[u.ttyn], ah
  2801                              <1> 	; 13/01/2014
  2802 00005193 FEC0                <1> 	inc	al
  2803 00005195 A2[7B6C0000]        <1> 	mov	[u.ttyp+1], al ; tty number + 1
  2804                              <1> wtty_nc: ; 15/05/2013
  2805                              <1> 	; AH = [u.ttyn] = tty number ; 28/07/2013
  2806 0000519A E870010000          <1> 	call	cpass
  2807                              <1> 		; jsr r0,cpass / get next character from user buffer area; if
  2808                              <1> 		             ; / none go to return address in syswrite
  2809                              <1> 		; tst r1 / is character = null
  2810                              <1> 		; beq wtty / yes, get next character
  2811                              <1> 	; 10/10/2013
  2812 0000519F 7428                <1> 	jz	short wret
  2813                              <1> 	;1 :
  2814                              <1> 		;mov 	$240,*$ps / no, set processor priority to five
  2815                              <1> 		;cmpb	cc+1,$20. / is character count for console tty greater
  2816                              <1> 		;	          / than 20
  2817                              <1> 		;bhis	2f / yes; branch to put process to sleep
  2818                              <1> 	; 27/06/2014
  2819                              <1> wtty_1:
  2820                              <1> 	; AH = tty number
  2821                              <1> 	; AL = ASCII code of the character
  2822                              <1> 	; 15/04/2014
  2823                              <1> 	;push	ax
  2824                              <1> 	; 11/12/2021
  2825 000051A1 50                  <1> 	push	eax
  2826 000051A2 E8120A0000          <1> 	call	putc ; 14/05/2013
  2827 000051A7 731D                <1> 	jnc	short wtty_2
  2828                              <1> 	; 18/11/2015
  2829 000051A9 E827F5FFFF          <1> 	call	idle
  2830                              <1> 	;mov	ax, [esp]
  2831                              <1> 	; 11/12/2021
  2832 000051AE 8B0424              <1> 	mov	eax, [esp]
  2833 000051B1 E8030A0000          <1> 	call	putc
  2834 000051B6 730E                <1> 	jnc	short wtty_2 
  2835                              <1> 	; 02/06/2014
  2836 000051B8 8A25[796C0000]      <1> 	mov	ah, [u.ttyn]
  2837 000051BE E89FF5FFFF          <1> 	call	sleep
  2838                              <1> 	;pop	ax
  2839                              <1> 	; 11/12/2021
  2840 000051C3 58                  <1> 	pop	eax
  2841 000051C4 EBDB                <1> 	jmp 	short wtty_1
  2842                              <1> 		; jc 	error ; 15/05/2013 (COM1 or COM2 serial port error)
  2843                              <1> 		; jsr 	r0,putc; 1 / find place in freelist to assign to 
  2844                              <1> 			      ; / console tty and
  2845                              <1> 		; br 	2f / place character in list; if none available
  2846                              <1> 		   	  ; / branch to put process to sleep
  2847                              <1> 		; jsr	r0,startty / attempt to output character on tty
  2848                              <1> wtty_2:
  2849                              <1> 	; 15/04/2014
  2850                              <1> 	;pop	ax
  2851                              <1> 	; 11/12/2021
  2852 000051C6 58                  <1> 	pop	eax
  2853 000051C7 EBD1                <1> 	jmp	short wtty_nc
  2854                              <1> 		; br wtty
  2855                              <1> wret:	; 10/10/2013 (20/05/2015)
  2856 000051C9 58                  <1> 	pop	eax
  2857 000051CA C3                  <1> 	retn
  2858                              <1> 	;2:
  2859                              <1> 		;mov	r1,-(sp) / place character on stack
  2860                              <1> 		;jsr	r0,sleep; 1 / put process to sleep
  2861                              <1> 		;mov	(sp)+,r1 / remove character from stack
  2862                              <1> 		;br	1b / try again to place character in clist and output
  2863                              <1> 
  2864                              <1> xmtt:   ; < send/write character to tty >
  2865                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2866                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  2867                              <1> 	;
  2868                              <1> 	; Retro UNIX 8086 v1 modification !
  2869                              <1> 	; 
  2870                              <1> 	; In original UNIX v1, 'xmtt' routine 
  2871                              <1> 	;		(exactly different than this one)
  2872                              <1> 	;	was in 'u9.s' file.
  2873                              <1> 	;
  2874 000051CB 2C0A                <1> 	sub 	al, 10
  2875                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
  2876                              <1> 	; 10/10/2013
  2877 000051CD 88C4                <1> 	mov	ah, al
  2878                              <1> 	; 28/07/2013
  2879 000051CF EBBC                <1> 	jmp	short wttys
  2880                              <1> 
  2881                              <1> ;wppt:
  2882                              <1> ;	jsr	r0,cpass / get next character from user buffer area,
  2883                              <1> ;		         / if none return to writei's calling routine
  2884                              <1> ;	jsr	r0,pptoc / output character on ppt
  2885                              <1> ;	br	wppt
  2886                              <1> 
  2887                              <1> wmem: ; / transfer characters from a user area of core to memory file
  2888                              <1> 	; 17/10/2015
  2889                              <1> 	; 11/06/2015
  2890                              <1> 	; 24/05/2015
  2891                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  2892                              <1> 	;
  2893 000051D1 813D[EF060000]-     <1> 	cmp	dword [x_timer], clock ; multi tasking clock/timer
  2893 000051D7 [F8460000]          <1>
  2894 000051DB 7415                <1>         je      short wmem_acc_err
  2895                              <1> 	;
  2896 000051DD 8B35[586C0000]      <1>         mov     esi, [u.fofp] 
  2897                              <1> wmem_1:
  2898 000051E3 E827010000          <1> 	call	cpass
  2899                              <1> 		; jsr r0,cpass / get next character from users area of
  2900                              <1> 			     ; / core and put it in r1
  2901                              <1>         	; mov r1,-(sp) / put character on the stack
  2902                              <1> 	; 20/09/2013
  2903 000051E8 74DF                <1> 	jz	short wret ; wmem_2  
  2904 000051EA 8B1E                <1>         mov     ebx, [esi]
  2905                              <1> 		; mov *u.fofp,r1 / save file offset in r1
  2906 000051EC FF06                <1>         inc     dword [esi] ; 17/10/2015
  2907                              <1> 		; inc *u.fofp / increment file offset to point to next
  2908                              <1> 			    ; / available location in file
  2909 000051EE 8803                <1> 	mov	[ebx], al	
  2910                              <1> 		; movb (sp)+,(r1) / pop char off stack, put in memory loc 
  2911                              <1> 			        ; / assigned to it
  2912 000051F0 EBF1                <1> 	jmp	short wmem_1
  2913                              <1> 		; br wmem / continue
  2914                              <1> 	;1:
  2915                              <1> 	;jmp	error / ?
  2916                              <1> ;wmem_2:	
  2917                              <1> ;	; 20/09/2013
  2918                              <1> ;	pop	ax
  2919                              <1> ;	retn
  2920                              <1> 
  2921                              <1> wmem_acc_err:
  2922 000051F2 C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  2922 000051FA 0000                <1>
  2923 000051FC E946DFFFFF          <1> 	jmp	error
  2924                              <1> 
  2925                              <1> ;wlpr:
  2926                              <1> 	; 12/06/2022
  2927                              <1> 	;mov	dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
  2928                              <1> 	;jmp 	error   ; ... Printing procedure will be located here ...
  2929                              <1> 		;/	jsr	r0,cpass
  2930                              <1> 		;/	cmp	r0,$'a
  2931                              <1> 		;/	blo	1f
  2932                              <1> 		;/	cmp	r1,$'z
  2933                              <1> 		;/	bhi	1f
  2934                              <1> 		;/	sub	$40,r1
  2935                              <1> 		;/1:
  2936                              <1> 		;/	jsr	r0,lptoc
  2937                              <1> 		;/	br	wlpr
  2938                              <1> 		; br rmem / continue
  2939                              <1> 
  2940                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - PRINTER BIOS (Functions)
  2941                              <1> 
  2942                              <1> ;; Ref: MSDOS 3.3 (Retro DOS 3.2) Printer driver code (MSLPT.ASM)
  2943                              <1> ;; MSLPT.ASM - MSDOS 3.3 - 24/07/1987
  2944                              <1> ;; 23/03/2018 - Retro DOS v2.0
  2945                              <1> ;; RETRODOS32.ASM - 03/08/2019 (Retro DOS v3.2)
  2946                              <1> 
  2947                              <1> ; IBM ROMBIOS (INT 17h) STATUS BITS
  2948                              <1> 
  2949                              <1> NOTBUSYSTATUS	equ 10000000b	; NOT BUSY
  2950                              <1> ACKSTATUS	equ 01000000b	; ACKNOWLEDGE (FOR WHAT?)
  2951                              <1> NOPAPERSTATUS	equ 00100000b	; NO MORE PAPER
  2952                              <1> SELECTEDSTATUS	equ 00010000b	; THE PRINTER SAID IT WAS SELECTED
  2953                              <1> IOERRSTATUS	equ 00001000b	; SOME KIND ERROR
  2954                              <1> RESERVED	equ 00000110b	; NOPS
  2955                              <1> TIMEOUTSTATUS	equ 00000001b	; TIME OUT.
  2956                              <1> 
  2957                              <1> ;----------------------------------------------------------------
  2958                              <1> ;								:
  2959                              <1> ;		WRITE TO PRINTER DEVICE 			:
  2960                              <1> ;								:
  2961                              <1> ;   CX has count of bytes to be printed 			:
  2962                              <1> ;   ES:DI point to source buffer contains characters		:
  2963                              <1> ;   AuxNum (in msbio.asm) has printer number			:
  2964                              <1> ;								:
  2965                              <1> ;----------------------------------------------------------------
  2966                              <1> 
  2967                              <1> wlpr:
  2968                              <1> 	; 15/07/2022
  2969                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
  2970                              <1> PRN$WRIT:
  2971                              <1> 	; INPUT:
  2972                              <1> 	;	[u.count] = count of characters to be printed
  2973                              <1> 	;	[u.base] = buffer address in user's memory space
  2974                              <1> 	;
  2975                              <1> 	;	(if ECX = 0, printer status will be returned)
  2976                              <1> 	
  2977                              <1> 	;xor	ebx, ebx
  2978                              <1> PRN$LOOP:
  2979 00005201 E809010000          <1> 	call	cpass		  ; Get a character into AL
  2980 00005206 7431                <1> 	jz	short pr_exit
  2981                              <1> 	;
  2982 00005208 B302                <1> 	mov	bl, 2  ; retry count
  2983                              <1> PRN$OUT:
  2984                              <1> 	; al = character which will be printed
  2985 0000520A 30E4                <1> 	xor	ah, ah ; 0	  ; PRINT THE CHARACTER IN (AL)
  2986 0000520C E850000000          <1> 	call	PRNOP
  2987 00005211 74EE                <1> 	jz	short PRN$LOOP 	  ; if error, try to print again
  2988                              <1> PrRetry:
  2989                              <1> 	; al = character
  2990 00005213 FECB                <1> 	dec	bl
  2991 00005215 75F3                <1> 	jnz	short PRN$OUT
  2992                              <1> pr_err_exit:
  2993 00005217 0FB6C0              <1> 	movzx	eax, al
  2994 0000521A A3[B86C0000]        <1> 	mov	[u.error], eax
  2995 0000521F A3[446C0000]        <1> 	mov	[u.r0], eax ; error code in AL
  2996                              <1> 	;mov 	ebp, [u.sp]
  2997 00005224 8B1D[3C6C0000]      <1> 	mov	ebx, [u.sp] ; 15/07/2022
  2998                              <1> 			; Kernel stack at the beginning of sys call
  2999 0000522A 8B15[706C0000]      <1> 	mov	edx, [u.nread]
  3000 00005230 4A                  <1> 	dec	edx ; last char failed
  3001                              <1> 	;mov	[ebp+20], edx ; count of printed characters in edx
  3002 00005231 895314              <1> 	mov	[ebx+20], edx ; 15/07/2022
  3003 00005234 E90EDFFFFF          <1> 	jmp	error
  3004                              <1> pr_exit:
  3005 00005239 58                  <1> 	pop	eax ; inode number
  3006                              <1> 
  3007                              <1> 	;mov	eax, [u.nread]
  3008                              <1> 	;mov	[u.r0], eax ; count of printed chacters
  3009                              <1> 	;jmp	sysret
  3010 0000523A C3                  <1> 	retn	; return from writei to syswrite (rw0)
  3011                              <1> 
  3012                              <1> ; 12/06/2022
  3013                              <1> 
  3014                              <1> ;----------------------------------------------------------------
  3015                              <1> ;								:
  3016                              <1> ;		PRINTER STATUS ROUTINE				:
  3017                              <1> ;								:
  3018                              <1> ;----------------------------------------------------------------
  3019                              <1> ;
  3020                              <1> 	
  3021                              <1> lpr_stat:
  3022                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2					   
  3023                              <1> PRN$STAT:
  3024 0000523B E81F000000          <1> 	call	PRNSTAT		  ; get the status
  3025 00005240 750E                <1> 	jnz	short prn_stat_retn
  3026                              <1> 				  ; if error jump to error routine
  3027                              <1> 	;mov	al, 9		  ; AGAIN, ASSUME OUT OF PAPER...    
  3028 00005242 B01F                <1> 	mov	al, ERR_PRN_PAPER
  3029 00005244 F6C420              <1> 	test	ah, NOPAPERSTATUS					   
  3030 00005247 7507                <1> 	jnz	short prn_stat_retn
  3031 00005249 F6C480              <1> 	test	ah, NOTBUSYSTATUS					   
  3032 0000524C 750D                <1> 	jnz	short prn_stat_ok ; if not busy return (with cf=0)
  3033 0000524E B022                <1> 	mov	al, ERR_PRN_BUSY  ; else busy, return to busy exit
  3034                              <1> prn_stat_retn:
  3035                              <1> 	; al = error code
  3036                              <1> 	; ah = status flags
  3037 00005250 A3[446C0000]        <1> 	mov	[u.r0], eax
  3038                              <1> 	;movzx	eax, al
  3039                              <1> 	;mov 	[u.error], eax
  3040 00005255 58                  <1> 	pop	eax ; discard return address to syswrite
  3041 00005256 E90CDFFFFF          <1> 	jmp	sysret
  3042                              <1> prn_stat_ok:
  3043 0000525B 30C0                <1> 	xor	al, al ; 0
  3044 0000525D EBF1                <1> 	jmp	short prn_stat_retn
  3045                              <1> 
  3046                              <1> ;
  3047                              <1> ;   PRNSTAT	get printer status
  3048                              <1> ;   PRNOP	print a character
  3049                              <1> ;
  3050                              <1> ; PRNSTAT and PRNOP are two routines which call on the ROM-BIOS
  3051                              <1> ; printer routines.  The routines share code which calls on the bios and
  3052                              <1> ; then determines which, if any, error occured. PRNSTAT and PRNOP differ
  3053                              <1> ; only by the value put into AH before the ROM-BIOS call.
  3054                              <1> ;
  3055                              <1> ;   INPUT	if PRNOP then character in AL
  3056                              <1> ;
  3057                              <1> ;   OUTPUT	- AL holds error code
  3058                              <1> ;		- AH status byte from printer
  3059                              <1> ;		- flag NZ if error
  3060                              <1> 
  3061                              <1> PRNSTAT:						   
  3062 0000525F B402                <1> 	mov	ah, 2		  ; set command for get status 
  3063                              <1> 
  3064                              <1> PRNOP:
  3065                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
  3066                              <1> 	;
  3067                              <1> 	; Print character (on paper)
  3068                              <1> 
  3069                              <1> 	; INPUT:
  3070                              <1> 	;	al = character to be printed
  3071                              <1> 	; OUTPUT:
  3072                              <1> 	;	zf = 1 -> ok
  3073                              <1> 	;	zf = 0 -> error code in AL
  3074                              <1> 
  3075 00005261 E8A20B0000          <1> 	call	int17h	 ; call lpt bios
  3076                              <1> 	
  3077 00005266 F6C408              <1> 	test	ah, IOERRSTATUS	  ; I/O ERROR?			   
  3078 00005269 740A                <1> 	jz	short short prnop_chk_nrdy ; NO, TRY NOT READY
  3079                              <1> 
  3080                              <1> 	; AT THIS POINT, WE KNOW WE HAVE AN ERROR.
  3081                              <1> 	; THE CONVERSE IS NOT TRUE.	   
  3082                              <1> 									   
  3083                              <1> 	;mov	al, 9		  ; FIRST, ASSUME OUT OF PAPER	   
  3084 0000526B B01F                <1> 	mov	al, ERR_PRN_PAPER
  3085 0000526D F6C420              <1> 	test	ah, NOPAPERSTATUS ; OUT OF PAPER SET?		   
  3086 00005270 7502                <1> 	jnz	short PRNOP1	  ; YES, ERROR IS SET
  3087                              <1> 	;mov	al, ERR_PRN_IO
  3088 00005272 FEC0                <1> 	inc	al		  ; INDICATE I/O ERROR		   
  3089                              <1> PRNOP1:									   
  3090                              <1> 									   
  3091                              <1> ; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT)	   
  3092                              <1> 									   
  3093 00005274 C3                  <1> 	retn			  ; RETURN WITH ERROR		   
  3094                              <1> 									   
  3095                              <1> ; THE BITS SAID NO ERROR.
  3096                              <1> ; UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WORK HERE. 								   
  3097                              <1> 									   
  3098                              <1> prnop_chk_nrdy:								   
  3099                              <1> 	;mov	al, 2		  ; ASSUME NOT-READY		   
  3100 00005275 B019                <1> 	mov	al, ERR_PRN_TIMEOUT ; ''time out !' error
  3101                              <1> 	
  3102 00005277 F6C401              <1> 	test	ah, TIMEOUTSTATUS ; IS TIME-OUT SET?		   
  3103                              <1> 				  ; IF NZ THEN ERROR, ELSE OK???
  3104                              <1> PRNOP2: 
  3105 0000527A C3                  <1> 	retn
  3106                              <1> 
  3107                              <1> 
  3108                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  3109                              <1> 
  3110                              <1> dskw: ; / write routine for non-special files
  3111                              <1> 	;
  3112                              <1> 	; 19/07/2022
  3113                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
  3114                              <1> 	; 28/11/2021
  3115                              <1> 	; 25/07/2015
  3116                              <1> 	; 16/06/2015
  3117                              <1> 	; 09/06/2015
  3118                              <1> 	; 31/05/2015 (Retro UNIX 386 v1 - Beginning)
  3119                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
  3120                              <1> 
  3121                              <1> 	; 01/08/2013 (mkdir_w check)
  3122                              <1> 	;push	ax ; 26/04/2013
  3123                              <1> 	;	; mov (sp),r1 / get an i-node number from the stack into r1
  3124                              <1> 	; 28/11/2021
  3125 0000527B 50                  <1> 	push	eax
  3126                              <1> 	; AX = inode number
  3127 0000527C E8D6F8FFFF          <1> 	call	iget
  3128                              <1> 		; jsr r0,iget / write i-node out (if modified), 
  3129                              <1> 		            ; / read i-node 'r1' into i-node area of core
  3130 00005281 8B1D[586C0000]      <1>         mov     ebx, [u.fofp] 
  3131 00005287 8B13                <1> 	mov 	edx, [ebx]
  3132                              <1> 		; mov *u.fofp,r2 / put the file offset [(u.off) or the offset
  3133                              <1> 			       ; / in the fsp entry for this file] in r2
  3134 00005289 0315[6C6C0000]      <1> 	add 	edx, [u.count]	
  3135                              <1> 		; add u.count,r2 / no. of bytes to be written
  3136                              <1> 			       ; / + file offset is put in r2
  3137                              <1> 	;; 16/06/2015        
  3138                              <1> 	;cmp	edx, 65535 ; file size limit (for UNIX v1 file system)
  3139                              <1> 	;jna	short dskw_0
  3140                              <1> 	;mov	dword [u.error], ERR_FILE_SIZE ; 'file size error !'
  3141                              <1> 	;jmp	error
  3142                              <1> dskw_0:	
  3143                              <1> 	; 28/11/2021
  3144 0000528F 3B15[CC670000]      <1> 	cmp	edx, [i.size] ; 32 bit file size (runix v2 inode)
  3145                              <1> 	;cmp	dx, [i.size]
  3146                              <1> 	;	; cmp r2,i.size / is this greater than the present size of
  3147                              <1> 		              ; / the file?
  3148 00005295 760B                <1> 	jna	short dskw_1
  3149                              <1> 		; blos 1f / no, branch
  3150 00005297 8915[CC670000]      <1> 	mov	[i.size], edx ; 32 bit file size (runix v2 inode)
  3151                              <1> 	;mov	[i.size], dx
  3152                              <1> 	 	; mov r2,i.size / yes, increase the file size to 
  3153                              <1> 			      ; / file offset + no. of data bytes
  3154 0000529D E846FAFFFF          <1> 	call	setimod
  3155                              <1> 	 	; jsr r0,setimod / set imod=1 (i.e., core inode has been
  3156                              <1> 		          ; / modified), stuff time of modification into
  3157                              <1> 	          	  ; / core image of i-node
  3158                              <1> dskw_1: ; 1:
  3159                              <1> 	; 28/11/2021
  3160                              <1> 	;call	mget
  3161 000052A2 E833F5FFFF          <1> 	call	mget_w
  3162                              <1> 		; jsr r0,mget / get the block no. in which to write 
  3163                              <1> 			    ; /	the next data byte
  3164                              <1> 	; eax = physical block/sector number
  3165 000052A7 8B1D[586C0000]      <1> 	mov     ebx, [u.fofp]
  3166 000052AD 8B13                <1> 	mov	edx, [ebx]
  3167 000052AF 81E2FF010000        <1> 	and	edx, 1FFh  
  3168                              <1> 		; bit *u.fofp,$777 / test the lower 9 bits of the file offset
  3169 000052B5 750C                <1> 	jnz	short dskw_2
  3170                              <1> 		; bne 2f / if its non-zero, branch; if zero, file offset = 0,
  3171                              <1> 		       ; / 512, 1024,...(i.e., start of new block)
  3172 000052B7 813D[6C6C0000]0002- <1> 	cmp	dword [u.count], 512
  3172 000052BF 0000                <1>
  3173                              <1> 		; cmp u.count,$512. / if zero, is there enough data to fill
  3174                              <1> 				  ; / an entire block? (i.e., no. of
  3175 000052C1 7305                <1> 	jnb	short dskw_3
  3176                              <1> 		; bhis 3f / bytes to be written greater than 512.? 
  3177                              <1> 			; / Yes, branch. Don't have to read block
  3178                              <1> dskw_2: ; 2: / in as no past info. is to be saved (the entire block will be
  3179                              <1>    		; / overwritten).
  3180 000052C3 E8AA060000          <1> 	call	dskrd
  3181                              <1> 		; jsr r0,dskrd / no, must retain old info.. 
  3182                              <1> 			     ; / Hence, read block 'r1' into an I/O buffer
  3183                              <1> dskw_3: ; 3:
  3184                              <1> 	; EAX (r1) = block/sector number
  3185 000052C8 E809070000          <1> 	call	wslot
  3186                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
  3187                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
  3188 000052CD 803D[B66C0000]00    <1> 	cmp	byte [u.kcall], 0
  3189 000052D4 770F                <1> 	ja	short dskw_5 ; zf=0 -> the caller is 'mkdir'
  3190                              <1> 	;
  3191 000052D6 66833D[B06C0000]00  <1> 	cmp	word [u.pcount], 0
  3192 000052DE 7705                <1> 	ja	short dskw_5
  3193                              <1> dskw_4:
  3194                              <1> 	; [u.base] = virtual address to transfer (as source address)
  3195 000052E0 E895FDFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
  3196                              <1> dskw_5:
  3197                              <1> 	; eBX (r5) = system (I/O) buffer address
  3198 000052E5 E885000000          <1> 	call	sioreg
  3199                              <1> 		; jsr r0,sioreg / r3 = no. of bytes of data, 
  3200                              <1> 			     ; / r1 = address of data, r2 points to location
  3201                              <1> 			     ; / in buffer in which to start writing data
  3202                              <1> 	; 19/07/2022
  3203                              <1> 	;  EDX = user data offset (previous value of [u.pbase])
  3204                              <1> 	;  ESI = pointer to file offset 
  3205                              <1> 	;  EDI = system (I/O) buffer offset
  3206                              <1> 	;  ECX = byte count
  3207                              <1> 	;  EBX = system buffer (data) address	
  3208                              <1> 	;  EAX = remain bytes after byte count within page frame 
  3209                              <1> 
  3210                              <1> 	; 19/07/2022 - Erdogan Tan
  3211                              <1> 	; BugFix (Also original unix v1 kernel code has this bug!)
  3212                              <1> 	; ((Against a possible disk write failure/error, 
  3213                              <1> 	;   file offset must not be updated/increased before 'dskwr'
  3214                              <1> 	;   but it was updated in 'sioreg'. I have modified 'sioreg'
  3215                              <1> 	;   and 'dskw' procedures for that.))
  3216                              <1> 
  3217                              <1> 	; 19/07/2022
  3218 000052EA 56                  <1> 	push	esi ; *	 ; save file offset (pointer)
  3219 000052EB 51                  <1> 	push	ecx ; ** ; save byte count
  3220 000052EC 89D6                <1> 	mov	esi, edx
  3221                              <1> 
  3222                              <1> 	; ESI = file (user data) offset
  3223                              <1> 	; EDI = sector (I/O) buffer offset
  3224                              <1> 	; ECX = byte count
  3225                              <1> 	;
  3226 000052EE F3A4                <1>   	rep	movsb
  3227                              <1> 		; movb (r1 )+,(r2)+ 
  3228                              <1> 		         ; / transfer a byte of data to the I/O buffer
  3229                              <1> 		; dec r3 / decrement no. of bytes to be written
  3230                              <1> 		; bne 2b / have all bytes been transferred? No, branch
  3231                              <1> 	; 25/07/2015
  3232                              <1> 	; eax = remain bytes in buffer
  3233                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  3234 000052F0 09C0                <1> 	or	eax, eax
  3235 000052F2 75EC                <1> 	jnz	short dskw_4 ; (page end before system buffer end!)	
  3236                              <1> dskw_6:
  3237 000052F4 E8EA060000          <1> 	call	dskwr
  3238                              <1> 		; jsr r0,dskwr / yes, write the block and the i-node
  3239                              <1> 
  3240                              <1> 	; 19/07/2022
  3241                              <1> 	; (there is not a disk write error, we can increase file offset)
  3242 000052F9 58                  <1> 	pop	eax ; ** ; byte count
  3243 000052FA 5F                  <1> 	pop	edi ; *  ; file offset (pointer)
  3244                              <1> 	;
  3245 000052FB 0107                <1> 	add	[edi], eax
  3246                              <1> 			; new file offset (old offset + byte count)
  3247                              <1> 
  3248 000052FD 833D[6C6C0000]00    <1>         cmp     dword [u.count], 0
  3249                              <1> 		; tst u.count / any more data to write?
  3250 00005304 779C                <1> 	ja	short dskw_1
  3251                              <1> 		; bne 1b / yes, branch
  3252                              <1> 	; 03/08/2013
  3253 00005306 C605[B66C0000]00    <1> 	mov	byte [u.kcall], 0
  3254                              <1> 	; 20/09/2013 (;;)
  3255                              <1> 	;pop	ax
  3256                              <1> 	; 28/11/2021
  3257 0000530D 58                  <1> 	pop	eax  
  3258 0000530E C3                  <1> 	retn
  3259                              <1> 	;;jmp 	short dskw_ret 
  3260                              <1> 	        ; jmp ret / no, return to the caller via 'ret'
  3261                              <1> 
  3262                              <1> 	; 24/12/2021
  3263                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
  3264                              <1> cpass: ; / get next character from user area of core and put it in r1
  3265                              <1> 	; 18/10/2015
  3266                              <1> 	; 10/10/2015
  3267                              <1> 	; 10/07/2015
  3268                              <1> 	; 02/07/2015
  3269                              <1> 	; 01/07/2015
  3270                              <1> 	; 24/06/2015
  3271                              <1> 	; 08/06/2015
  3272                              <1> 	; 04/06/2015
  3273                              <1> 	; 20/05/2015
  3274                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  3275                              <1> 	;
  3276                              <1> 	; INPUTS -> 
  3277                              <1> 	;     [u.base] = virtual address in user area
  3278                              <1> 	;     [u.count] = byte count (max.)
  3279                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
  3280                              <1> 	; OUTPUTS -> 
  3281                              <1> 	;     AL = the character which is pointed by [u.base]
  3282                              <1> 	;     zf = 1 -> transfer count has been completed	
  3283                              <1>         ;
  3284                              <1> 	; ((Modified registers: EAX, EDX, ECX))
  3285                              <1> 	;
  3286                              <1> 	;
  3287 0000530F 833D[6C6C0000]00    <1> 	cmp 	dword [u.count], 0  ; 14/08/2013
  3288                              <1> 		; tst u.count / have all the characters been transferred
  3289                              <1> 			    ; / (i.e., u.count, # of chars. left
  3290 00005316 763F                <1> 	jna	short cpass_3
  3291                              <1> 		; beq 1f / to be transferred = 0?) yes, branch
  3292 00005318 FF0D[6C6C0000]      <1> 	dec	dword [u.count]
  3293                              <1> 		; dec u.count / no, decrement u.count
  3294                              <1>         ; 19/05/2015 
  3295                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
  3296                              <1> 	;		      to physical address
  3297 0000531E 66833D[B06C0000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
  3298                              <1> 			     ; 1-4095 --> use previous physical base address
  3299                              <1> 			     ; in [u.pbase]
  3300 00005326 770E                <1> 	ja	short cpass_1
  3301                              <1> 	; 02/07/2015
  3302 00005328 833D[A86C0000]00    <1> 	cmp	dword [u.ppgdir], 0  ; is the caller os kernel
  3303 0000532F 7427                <1> 	je	short cpass_k 	; (sysexec, '/etc/init') ? 
  3304                              <1> 	; 08/06/2015 - 10/07/2015
  3305 00005331 E844FDFFFF          <1> 	call	trans_addr_r
  3306                              <1> cpass_1:
  3307                              <1> 	; 02/07/2015
  3308                              <1> 	; 24/06/2015
  3309 00005336 66FF0D[B06C0000]    <1> 	dec	word [u.pcount]
  3310                              <1> cpass_2: 
  3311                              <1> 	; 10/10/2015
  3312                              <1> 	; 02/07/2015
  3313 0000533D 8B15[AC6C0000]      <1> 	mov	edx, [u.pbase]
  3314 00005343 8A02                <1> 	mov	al, [edx] ; 10/10/2015
  3315                              <1> 		; movb *u.base,r1 / take the character pointed to 
  3316                              <1> 				; / by u.base and put it in r1
  3317 00005345 FF05[706C0000]      <1> 	inc	dword [u.nread]
  3318                              <1> 		; inc u.nread / increment no. of bytes transferred
  3319 0000534B FF05[686C0000]      <1> 	inc	dword [u.base]
  3320                              <1> 		; inc u.base / increment the buffer address to point to the
  3321                              <1> 			   ; / next byte
  3322 00005351 FF05[AC6C0000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
  3323                              <1> cpass_3:
  3324 00005357 C3                  <1> 	retn
  3325                              <1> 		; rts	r0 / next byte
  3326                              <1> 	; 1: 
  3327                              <1> 		; mov (sp)+,r0 
  3328                              <1> 		         ; / put return address of calling routine into r0
  3329                              <1> 		; mov (sp)+,r1 / i-number in r1
  3330                              <1> 		; rts r0 / non-local return
  3331                              <1> cpass_k:
  3332                              <1> 	; 02/07/2015
  3333                              <1> 	; The caller is os kernel 
  3334                              <1> 	; (get sysexec arguments from kernel's memory space)
  3335                              <1> 	;
  3336 00005358 8B1D[686C0000]      <1> 	mov	ebx, [u.base]
  3337 0000535E 66C705[B06C0000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
  3337 00005366 10                  <1>
  3338 00005367 891D[AC6C0000]      <1> 	mov	[u.pbase], ebx
  3339 0000536D EBCE                <1> 	jmp	short cpass_2
  3340                              <1> 	
  3341                              <1> sioreg: 
  3342                              <1> 	; 19/07/2022
  3343                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
  3344                              <1> 	; 25/07/2015
  3345                              <1> 	; 18/07/2015
  3346                              <1> 	; 02/07/2015
  3347                              <1> 	; 17/06/2015
  3348                              <1> 	; 09/06/2015
  3349                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
  3350                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
  3351                              <1> 	;
  3352                              <1> 	; INPUTS -> 
  3353                              <1> 	;     EBX = system buffer (data) address (r5)
  3354                              <1> 	;     [u.fofp] = pointer to file offset pointer
  3355                              <1> 	;     [u.base] = virtual address of the user buffer
  3356                              <1> 	;     [u.pbase] = physical address of the user buffer
  3357                              <1> 	;     [u.count] = byte count
  3358                              <1> 	;     [u.pcount] = byte count within page frame 			
  3359                              <1> 	; OUTPUTS -> 
  3360                              <1> 	;     ESI = user data offset (r1)
  3361                              <1> 	;     EDI = system (I/O) buffer offset (r2)
  3362                              <1> 	;     ECX = byte count (r3)
  3363                              <1> 	;     EAX = remain bytes after byte count within page frame
  3364                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
  3365                              <1>         ;
  3366                              <1> 	; ((Modified registers:  EDX))
  3367                              <1> 
  3368                              <1> 	; 19/07/2022
  3369                              <1> 	; OUTPUTS -> 
  3370                              <1> 	;	EDX = user data offset (previous value of [u.pbase])
  3371                              <1> 	;	ESI = pointer to file offset 
  3372                              <1> 	; 	EDI = system (I/O) buffer offset
  3373                              <1> 	;	ECX = byte count
  3374                              <1> 	;	EBX = system buffer (data) address	
  3375                              <1> 	;	EAX = remain bytes after byte count within page frame
  3376                              <1>  
  3377 0000536F 8B35[586C0000]      <1>         mov     esi, [u.fofp]
  3378 00005375 8B3E                <1>         mov     edi, [esi]
  3379                              <1> 		; mov *u.fofp,r2 / file offset (in bytes) is moved to r2
  3380 00005377 89F9                <1> 	mov	ecx, edi
  3381                              <1> 		; mov r2,r3 / and also to r3
  3382 00005379 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
  3383                              <1> 		; bis $177000,r3 / set bits 9,...,15 of file offset in r3
  3384 0000537F 81E7FF010000        <1> 	and	edi, 1FFh
  3385                              <1> 		; bic $!777,r2 / calculate file offset mod 512.
  3386 00005385 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
  3387                              <1> 		; add r5,r2 / r2 now points to 1st byte in system buffer
  3388                              <1> 			  ; / where data is to be placed
  3389                              <1>                 ; mov u.base,r1 / address of data is in r1
  3390 00005387 F7D9                <1> 	neg	ecx
  3391                              <1> 		; neg r3 / 512 - file offset (mod512.) in r3 
  3392                              <1> 		       ; / (i.e., the no. of free bytes in the file block)
  3393 00005389 3B0D[6C6C0000]      <1> 	cmp	ecx, [u.count]
  3394                              <1> 		; cmp r3,u.count / compare this with the no. of data bytes
  3395                              <1> 			       ; / to be written to the file
  3396 0000538F 7606                <1> 	jna	short sioreg_0
  3397                              <1> 		; blos	2f / if less than branch. Use the no. of free bytes
  3398                              <1> 			 ; / in the file block as the number to be written
  3399 00005391 8B0D[6C6C0000]      <1> 	mov	ecx, [u.count]
  3400                              <1> 		; mov u.count,r3 / if greater than, use the no. of data 
  3401                              <1> 			       ; / bytes as the number to be written
  3402                              <1> sioreg_0:
  3403                              <1> 	; 17/06/2015
  3404 00005397 803D[B66C0000]00    <1> 	cmp	byte [u.kcall], 0 
  3405 0000539E 7613                <1> 	jna	short sioreg_1
  3406                              <1> 	; 25/07/2015
  3407                              <1> 	 ; the caller is 'mkdir' or 'namei'
  3408 000053A0 A1[686C0000]        <1> 	mov	eax, [u.base] ; 25/07/2015
  3409 000053A5 A3[AC6C0000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
  3410 000053AA 66890D[B06C0000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
  3411 000053B1 EB0B                <1> 	jmp	short sioreg_2
  3412                              <1> sioreg_1:
  3413                              <1> 	; 25/07/2015
  3414                              <1> 	; 18/07/2015
  3415                              <1> 	; 09/06/2015 
  3416 000053B3 0FB715[B06C0000]    <1> 	movzx	edx, word [u.pcount]
  3417                              <1> 		; ecx and [u.pcount] are always > 0, here
  3418 000053BA 39D1                <1> 	cmp	ecx, edx	
  3419 000053BC 7728                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
  3420                              <1> sioreg_2: ; 2:
  3421 000053BE 31C0                <1> 	xor 	eax, eax ; 25/07/2015
  3422                              <1> sioreg_3:
  3423 000053C0 010D[706C0000]      <1> 	add 	[u.nread], ecx
  3424                              <1> 		; add r3,u.nread / r3 + number of bytes xmitted 
  3425                              <1> 			         ; / during write is put into u.nread
  3426 000053C6 290D[6C6C0000]      <1> 	sub 	[u.count], ecx
  3427                              <1> 		; sub r3,u.count / u.count = no. of bytes that still 
  3428                              <1> 			       ; / must be written or read
  3429 000053CC 010D[686C0000]      <1> 	add 	[u.base], ecx
  3430                              <1> 		; add r3,u.base / u.base points to the 1st of the remaining
  3431                              <1> 			      ; / data bytes
  3432                              <1>         ; 19/07/2022
  3433                              <1> 	;add 	[esi], ecx 
  3434                              <1> 	;	; add r3,*u.fofp / new file offset = number of bytes done
  3435                              <1> 			       ; / + old file offset
  3436                              <1> 	; 25/07/2015
  3437                              <1> 	;mov	esi, [u.pbase]
  3438                              <1> 	; 19/07/2022
  3439 000053D2 8B15[AC6C0000]      <1> 	mov	edx, [u.pbase]
  3440                              <1> 
  3441 000053D8 66290D[B06C0000]    <1> 	sub	[u.pcount], cx
  3442 000053DF 010D[AC6C0000]      <1> 	add	[u.pbase], ecx
  3443 000053E5 C3                  <1>         retn
  3444                              <1> 		; rts r0
  3445                              <1> 		; transfer count > [u.pcount]
  3446                              <1> sioreg_4:
  3447                              <1> 	; 25/07/2015
  3448                              <1> 	; transfer count > [u.pcount] 
  3449                              <1> 	; (ecx > edx)
  3450 000053E6 89C8                <1> 	mov	eax, ecx
  3451 000053E8 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
  3452 000053EA 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
  3453 000053EC EBD2                <1> 	jmp	short sioreg_3
  3454                              <1> 
  3455                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
  3456                              <1> is_regular_file:
  3457                              <1> 	; check if it is a regular file or device file inode
  3458                              <1> 	;
  3459                              <1> 	; INPUT:
  3460                              <1> 	;	current inode
  3461                              <1> 	; OUTPUT:
  3462                              <1> 	;	cf = 0 and zf = 1 -> regular file
  3463                              <1> 	;	cf = 0 and zf = 0 -> device file
  3464                              <1> 	;	cf = 1 -> invalid file (jump to 'error')
  3465                              <1> 	;
  3466                              <1> 	; Modified registers: ecx (cl)
  3467                              <1> 
  3468                              <1> 	; 28/11/2021
  3469 000053EE 8A0D[C5670000]      <1> 	mov	cl, [i.flgs+1]
  3470 000053F4 F6C180              <1> 	test	cl, 80h		; regular file ?
  3471 000053F7 7514                <1> 	jnz	short isregf_1  ; yes 
  3472 000053F9 80E120              <1> 	and	cl, 20h 	; device file ?
  3473 000053FC 7511                <1> 	jnz	short isregf_2  ; yes 
  3474                              <1> 
  3475                              <1> 	; 28/11/2021
  3476                              <1> 	; invalid inode/file type !
  3477 000053FE C705[B86C0000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
  3477 00005406 0000                <1>
  3478                              <1> 	;stc
  3479                              <1> 	;retn
  3480 00005408 E93ADDFFFF          <1> 	jmp	error
  3481                              <1> isregf_1:
  3482 0000540D 30C9                <1> 	xor	cl, cl  ; cl = 0
  3483                              <1> 	; zf = 1
  3484                              <1> 	;retn
  3485                              <1> isregf_2:
  3486                              <1> 	; zf = 0
  3487                              <1> 	; cl = 20h
  3488 0000540F C3                  <1> 	retn	
  2095                                  %include 'u7.s'      ; 18/04/2015
  2096                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2097                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2098                              <1> ; ****************************************************************************
  2099                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - SYS7.INC
  2100                              <1> ; Last Modification: 12/06/2022
  2101                              <1> ; ----------------------------------------------------------------------------
  2102                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2103                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2104                              <1> ;
  2105                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2106                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2107                              <1> ; <Bell Laboratories (17/3/1972)>
  2108                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2109                              <1> ;
  2110                              <1> ; Retro UNIX 8086 v1 - U7.ASM (13/07/2014) //// UNIX v1 -> u7.s
  2111                              <1> ;
  2112                              <1> ; ****************************************************************************
  2113                              <1> 
  2114                              <1> sysmount: ; / mount file system; args special; name
  2115                              <1> 	; 15/05/2022
  2116                              <1> 	; 09/05/2022
  2117                              <1> 	;	 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
  2118                              <1> 	; 08/02/2022
  2119                              <1> 	; 07/02/2022
  2120                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
  2121                              <1> 	; 14/11/2015
  2122                              <1> 	; 24/10/2015
  2123                              <1> 	; 13/10/2015
  2124                              <1> 	; 10/07/2015
  2125                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  2126                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  2127                              <1> 	;
  2128                              <1> 	; 'sysmount' anounces to the system that a removable 
  2129                              <1> 	; file system has been mounted on a special file.
  2130                              <1> 	; The device number of the special file is obtained via
  2131                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
  2132                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
  2133                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
  2134                              <1> 	; to read file system into core, i.e. the first block on the
  2135                              <1> 	; mountable file system is read in. This block is super block
  2136                              <1> 	; for the file system. This call is super user restricted.	
  2137                              <1> 	;
  2138                              <1> 	; Calling sequence:
  2139                              <1> 	;	sysmount; special; name
  2140                              <1> 	; Arguments:
  2141                              <1> 	;	special - pointer to name of special file (device)
  2142                              <1> 	;	name -  pointer to name of the root directory of the
  2143                              <1> 	;		newly mounted file system. 'name' should 
  2144                              <1> 	;		always be a directory.
  2145                              <1> 	; Inputs: - 
  2146                              <1> 	; Outputs: -
  2147                              <1> 	; ...............................................................
  2148                              <1> 	;				
  2149                              <1> 	; Retro UNIX 8086 v1 modification: 
  2150                              <1> 	;       'sysmount' system call has two arguments; so,
  2151                              <1> 	;	* 1st argument, special is pointed to by BX register
  2152                              <1> 	;	* 2nd argument, name is in CX register
  2153                              <1> 	;
  2154                              <1> 	;	NOTE: Device numbers, names and related procedures are 
  2155                              <1> 	;	       already modified for IBM PC compatibility and 
  2156                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
  2157                              <1> 	
  2158                              <1> 	;call	arg2
  2159                              <1> 		; jsr r0,arg2 / get arguments special and name
  2160 00005410 891D[606C0000]      <1> 	mov	[u.namep], ebx
  2161                              <1> 	; 07/02/2022
  2162                              <1> 	;push	ecx ; directory name
  2163                              <1> 	;cmp	dword [mnti], 0 ; 11/01/2022 (32 bit inode number)
  2164 00005416 66833D[2A6C0000]00  <1> 	cmp	word [mnti], 0
  2165                              <1> 		; tst mnti / is the i-number of the cross device file
  2166                              <1> 			 ; / zero?
  2167                              <1> 	;;ja	error
  2168                              <1>         	; bne errora / no, error
  2169                              <1> 	;ja	sysmnt_err0
  2170                              <1> 	; 11/01/2022
  2171 0000541E 7605                <1> 	jna	short sysmnt_0 ; 12/01/2022
  2172                              <1> sysmnt_0_err:
  2173 00005420 E993010000          <1> 	jmp	sysmnt_err0
  2174                              <1> sysmnt_0:
  2175                              <1> 	; 07/02/2022
  2176 00005425 51                  <1> 	push	ecx ; directory name
  2177 00005426 E875010000          <1> 	call	getspl
  2178                              <1> 		; jsr r0,getspl / get special files device number in r1
  2179                              <1> 	; 07/02/2022
  2180 0000542B 8F05[606C0000]      <1> 	pop	dword [u.namep] ; directory name
  2181                              <1> 
  2182                              <1> 	; 09/05/2022 - Retro UNIX v1.2 (Kernel v0.2.2.1)
  2183                              <1> 	; (root fs/device must not be mounted again)
  2184 00005431 3A05[226C0000]      <1> 	cmp	al, [rdev]
  2185                              <1> 	;je	sysmnt_err0
  2186 00005437 74E7                <1> 	je	short sysmnt_0_err ; permission denied error
  2187                              <1> 
  2188                              <1> 	; 13/10/2015
  2189                              <1> 	;movzx	ebx, ax ; Retro UNIX 8086 v1 device number (0 to 5)
  2190                              <1>         ; 11/01/2022
  2191 00005439 29DB                <1> 	sub	ebx, ebx
  2192 0000543B 88C3                <1> 	mov	bl, al
  2193 0000543D F683[4E620000]80    <1> 	test    byte [ebx+drv.status], 80h ; 24/10/2015 
  2194 00005444 750F                <1> 	jnz	short sysmnt_1
  2195                              <1> sysmnt_err1:
  2196 00005446 C705[B86C0000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
  2196 0000544E 0000                <1>
  2197 00005450 E9F2DCFFFF          <1> 	jmp	error
  2198                              <1> sysmnt_1:
  2199                              <1> 	; 07/02/2022
  2200                              <1> 	;pop	dword [u.namep]
  2201                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
  2202                              <1> 				  ; / on the device
  2203                              <1> 	; 14/11/2015
  2204 00005455 53                  <1> 	push	ebx ; 13/10/2015
  2205                              <1> 		; mov r1,-(sp) / save the device number
  2206                              <1>         ;
  2207 00005456 E803ECFFFF          <1> 	call	namei
  2208                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  2209                              <1> 		       ; ax = 0 -> file not found 	
  2210                              <1> 	;jz	error
  2211                              <1> 	;jc	error
  2212                              <1> 		; jsr r0,namei / get the i-number of the file
  2213                              <1>                	; br errora
  2214 0000545B 730F                <1> 	jnc	short sysmnt_2
  2215                              <1> sysmnt_err2:
  2216 0000545D C705[B86C0000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
  2216 00005465 0000                <1>
  2217 00005467 E9DBDCFFFF          <1> 	jmp	error
  2218                              <1> sysmnt_2:
  2219                              <1> 	; 11/01/2022
  2220 0000546C A3[2A6C0000]        <1> 	mov	[mnti], eax ; 32 bit inode number (<= 65535)	
  2221                              <1> 	;mov	[mnti], ax
  2222                              <1>         	; mov r1,mnti / put it in mnti
  2223                              <1> 
  2224                              <1> 	; 15/05/2022
  2225                              <1> 	; -Retro UNIX 8086/386 v1 feaure only-
  2226 00005471 A1[1C6C0000]        <1> 	mov	eax, [ii]
  2227 00005476 A3[2E6C0000]        <1> 	mov	[mntp], eax ; parent dir inumber of [mnti]
  2228                              <1> 
  2229                              <1> 	; 11/01/2022
  2230 0000547B BB[F46E0000]        <1> 	mov	ebx, sb1 ; super block buffer header (of mounted disk)
  2231                              <1> sysmnt_3: ;1:
  2232                              <1>         ;cmp	byte [ebx+1], 0
  2233                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
  2234                              <1> 			   ; / dismountable device set?
  2235                              <1>         ;jna	short sysmnt_4		
  2236                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
  2237                              <1> 	;call	idle 	; (wait for hardware interrupt)
  2238                              <1> 	;jmp	short sysmnt_3
  2239                              <1> sysmnt_4:   
  2240 00005480 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
  2241 00005481 A2[236C0000]        <1> 	mov	[mdev], al
  2242                              <1> 		; mov (sp),mntd / no, put the device number in mntd
  2243 00005486 8803                <1> 	mov	[ebx], al
  2244                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
  2245                              <1> 			      ; / of the I/O queue entry
  2246                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
  2247                              <1>         	; mov (sp)+,cdev / put device number in cdev
  2248 00005488 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
  2249                              <1> 		; bis $2000,sb1 / set the read bit
  2250                              <1> 
  2251                              <1> 	; 09/05/2022
  2252 0000548D 31FF                <1> 	xor	edi, edi
  2253 0000548F 897B04              <1> 	mov	dword [ebx+4], edi ; 0 ; physical block number = 0
  2254                              <1> 
  2255                              <1> 	; 09/05/2022
  2256                              <1> 	; Retro UNIX v2 Hard Disk FS recognition.
  2257                              <1> 	;
  2258 00005492 3C02                <1> 	cmp	al, 2 ; fd0 = 0, fd1 = 1, hd0 = 2, hd1 = 3
  2259 00005494 7217                <1> 	jb	short sysmnt_8
  2260                              <1> 
  2261                              <1> 	; hard disk, read masterboot sector/block at first 
  2262 00005496 E817060000          <1> 	call 	diskio
  2263 0000549B 721A                <1> 	jc	short sysmnt_9 ; disk read error !
  2264                              <1> sysmnt_6:
  2265                              <1>   	; return start sector address of
  2266                              <1> 	; retro unix v2 partition in esi
  2267 0000549D 8D7308              <1> 	lea	esi, [ebx+8] ; (mbr buffer data address)
  2268 000054A0 E86DDBFFFF          <1> 	call	runix_p_bs
  2269 000054A5 7206                <1> 	jc	short sysmnt_8 ; runix partition not found
  2270                              <1> 			       ; try to read superblock on
  2271                              <1> 			       ; physical sector 1	 
  2272                              <1> 	; eax = start sector/block
  2273 000054A7 894304              <1> 	mov	dword [ebx+4], eax ; (boot sector address)
  2274                              <1> 	; esi = partition table entry + 4
  2275 000054AA 8B7E08              <1> 	mov	edi, [esi+ptSectors-ptFileSystemID]
  2276                              <1> 	; edi = partition size in sectors
  2277                              <1> sysmnt_8:
  2278                              <1> 	; Retro UNIX 386 v1 modification : 
  2279                              <1> 	;	32 bit block number at buffer header offset 4
  2280                              <1> 	; 09/05/2022
  2281                              <1> 	;mov	dword [ebx+4], 1 ; physical block number = 1
  2282 000054AD FF4304              <1> 	inc	dword [ebx+4] ; +1 ; superblock address
  2283 000054B0 E8FD050000          <1> 	call 	diskio
  2284 000054B5 7345                <1> 	jnc	short sysmnt_5
  2285                              <1> sysmnt_9:
  2286 000054B7 31C0                <1> 	xor 	eax, eax
  2287 000054B9 66A3[2A6C0000]      <1> 	mov	[mnti], ax ; 0
  2288 000054BF A2[236C0000]        <1> 	mov	[mdev], al ; 0
  2289                              <1> 	;mov	[cdev], al ; 0
  2290                              <1> 	; 08/02/2022
  2291 000054C4 803D[B76C0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
  2292 000054CB 7508                <1> 	jne	short sysmnt_err3
  2293                              <1> 	; yes, clear [u.brwdev] for next check
  2294                              <1> 	; ([u.error] = DRV_NOT_RDY or OUT_OF_VOLUME error) 
  2295 000054CD FE05[B76C0000]      <1> 	inc	byte [u.brwdev] ; 0, reset
  2296 000054D3 EB0A                <1> 	jmp	short sysmnt_err4
  2297                              <1> sysmnt_err3:	; 08/02/2022
  2298                              <1> 	; no, set [u.error] to disk read error
  2299 000054D5 C705[B86C0000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; 'disk read error !'
  2299 000054DD 0000                <1>
  2300                              <1> sysmnt_err4:
  2301                              <1> 	; 08/02/2022
  2302                              <1> 	; 14/11/2015
  2303 000054DF FEC8                <1> 	dec 	al
  2304 000054E1 8903                <1> 	mov	[ebx], eax ; 000000FFh
  2305 000054E3 FEC0                <1> 	inc	al
  2306 000054E5 48                  <1> 	dec	eax
  2307 000054E6 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
  2308 000054E9 E959DCFFFF          <1> 	jmp	error
  2309                              <1> sysmnt_invd:
  2310                              <1> 	; 08/02/2022
  2311 000054EE C705[B86C0000]1C00- <1> 	mov	dword [u.error], ERR_INV_FS ; 28
  2311 000054F6 0000                <1>
  2312                              <1> 				 ;'invalid fs/superblock !' error
  2313 000054F8 30C0                <1> 	xor	al, al ; 0
  2314 000054FA EBE3                <1> 	jmp	short sysmnt_err4
  2315                              <1> 
  2316                              <1> sysmnt_5:
  2317                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
  2318                              <1> 	; Retro UNIX v2 Hard Disk FS recognition.
  2319                              <1> 	; edi = 0 -> diskette or 'not a runix v2 hdfs partition'
  2320                              <1> 	; edi > 0 -> retro unix v2 hdfs partition (volume) size
  2321                              <1> 	;	     in sectors
  2322                              <1> 
  2323 000054FC 21FF                <1> 	and	edi, edi
  2324 000054FE 740D                <1> 	jz	short sysmnt_10
  2325                              <1> 
  2326 00005500 8B530C              <1> 	mov	edx, [ebx+12] ; SB.BootSectAddr (Hidden Sectors)
  2327 00005503 42                  <1> 	inc	edx ; +1 
  2328 00005504 3B5304              <1> 	cmp	edx, [ebx+4]  ; superblock (disk) address
  2329 00005507 75E5                <1> 	jne	short sysmnt_invd  ; invalid file system !
  2330                              <1> 
  2331 00005509 89F9                <1> 	mov	ecx, edi ; volume size (from partition table entry)
  2332 0000550B EB0C                <1> 	jmp	short sysmnt_11 ; bypass disk size comparison
  2333                              <1> 
  2334                              <1> sysmnt_10:
  2335                              <1> 	; 08/02/2022
  2336                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.1 BugFix)
  2337                              <1> 	;  v1.2 Note: This code will be changed for hard disk partitions
  2338                              <1> 	;	    ! (for now, rufs v2 floppy disks can be mounted) !		
  2339                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
  2340                              <1> 	; (Following check is needed to prevent mounting an
  2341                              <1> 	; invalid file system (invalid super block).
  2342                              <1> 	; 
  2343 0000550D 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
  2344 00005510 C0E002              <1> 	shl	al, 2 ; 4*index
  2345 00005513 8B88[32620000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
  2346                              <1> 	;shr 	ecx, 3 ; 11/01/2021 (8 sectors per 1 fbm byte)
  2347                              <1> 	; ecx = number of free map bytes (required)
  2348                              <1> 	;;movzx	edx, word [sb1+8] ; the 1st data word ('mount:')
  2349                              <1> 	;movzx	edx, word [ebx+8] ; the 1st data word (of the buffer)	
  2350                              <1> 	; edx = number of free blocks map bytes
  2351                              <1> 	;;shl	edx, 3 ; convert free map bytes to free map bits
  2352                              <1> 	;cmp	ecx, edx ; compare free map bits and volume size
  2353                              <1> 	;		 ; (in sectors), if they are not equal
  2354                              <1> 	;		 ; the disk to be mounted is an...
  2355                              <1> 	;jne	short sysmnt_invd ; invalid disk !
  2356                              <1> 	;		 ; (which has not got a valid super block)
  2357                              <1> sysmnt_11:	
  2358                              <1> 	; 07/02/2022
  2359                              <1> 	;xor	al, al ; 08/02/2022
  2360                              <1> 	; 11/01/2022
  2361                              <1> 	; Retro UNIX 386 v2 superblock (offset 8, volume size)
  2362 00005519 8B5310              <1> 	mov	edx, [ebx+16] ; SB.VolumeSize (in sectors)
  2363 0000551C 39D1                <1> 	cmp	ecx, edx ; compare SB.VolumeSize and Disk volume size
  2364                              <1> 			 ; (in sectors), if they are not equal
  2365                              <1> 			 ; the disk to be mounted is an...	
  2366 0000551E 75CE                <1> 	jne	short sysmnt_invd ; invalid disk !
  2367                              <1> 			 ; (which has not got a valid shuper block)
  2368                              <1> 	;
  2369 00005520 C6430100            <1> 	mov	byte [ebx+1], 0
  2370                              <1> 	       	; jsr r0,ppoke / read in entire file system
  2371                              <1> ;sysmnt_6: ;1:
  2372                              <1> 	;;cmp	byte [sb1+1], 0
  2373                              <1> 		; tstb sb1+1 / done reading?
  2374                              <1>    	;;jna	sysret
  2375                              <1> 	;;call	idle ; (wait for hardware interrupt)
  2376                              <1> 	;;jmp	short sysmnt_6
  2377                              <1> 		;bne 1b / no, wait
  2378                              <1>         	;br sysreta / yes
  2379 00005524 E93EDCFFFF          <1> 	jmp	sysret
  2380                              <1> 
  2381                              <1> sysumount: ; / special dismount file system
  2382                              <1> 	; 15/05/2022
  2383                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
  2384                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
  2385                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  2386                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  2387                              <1> 	;
  2388                              <1> 	; 04/11/2013
  2389                              <1> 	; 09/07/2013
  2390                              <1> 	; 'sysumount' anounces to the system that the special file, 
  2391                              <1> 	; indicated as an argument is no longer contain a removable
  2392                              <1> 	; file system. 'getspl' gets the device number of the special
  2393                              <1> 	; file. If no file system was mounted on that device an error
  2394                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
  2395                              <1> 	; to 'sysret'.
  2396                              <1> 	;
  2397                              <1> 	; Calling sequence:
  2398                              <1> 	;	sysmount; special
  2399                              <1> 	; Arguments:
  2400                              <1> 	;	special - special file to dismount (device)
  2401                              <1> 	;
  2402                              <1> 	; Inputs: - 
  2403                              <1> 	; Outputs: -
  2404                              <1> 	; ...............................................................
  2405                              <1> 	;				
  2406                              <1> 	; Retro UNIX 8086 v1 modification: 
  2407                              <1> 	;       'sysumount' system call has one argument; so,
  2408                              <1> 	;	* Single argument, special is pointed to by BX register
  2409                              <1> 	;
  2410                              <1> 	
  2411                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
  2412                              <1> 	;call	arg
  2413                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
  2414 00005529 891D[606C0000]      <1>         mov	[u.namep], ebx
  2415 0000552F E86C000000          <1> 	call	getspl
  2416                              <1> 		; jsr r0,getspl / get the device number in r1
  2417                              <1> 	;;;
  2418                              <1> 	; 09/05/2022 - Erdogan Tan
  2419                              <1> 	; (I have added [mnti] check because
  2420                              <1> 	;  retro unix device number of /dev/fd0 is 0
  2421                              <1> 	;  .. so, 'cmp al, [mdev]' is not enough
  2422                              <1> 	;  for dismounting /dev/fd0. sysumount system call would give
  2423                              <1> 	;  wrong cf=0 result while /dev/fd0 is not mounted.)
  2424 00005534 66833D[2A6C0000]00  <1> 	cmp	word [mnti], 0
  2425 0000553C 767A                <1> 	jna	short sysmnt_err0 ; there is not a mounted device !
  2426                              <1> 	;;;	
  2427                              <1> 
  2428 0000553E 3A05[236C0000]      <1> 	cmp	al, [mdev]
  2429                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
  2430 00005544 7572                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
  2431                              <1> 	;jne	error
  2432                              <1>         	; bne errora / no error
  2433 00005546 30C0                <1> 	xor	al, al ; ah = 0
  2434                              <1> 	; (eax = 0) ; 11/01/2022
  2435                              <1> sysumnt_0: ;1:
  2436                              <1>      	; 11/01/2022
  2437                              <1> 	;cmp 	[sb1+1], al ; 0
  2438                              <1> 	;	; tstb sb1+1 / yes, is the device still doing I/O 
  2439                              <1> 	;		   ; / (inhibit bit set)?
  2440                              <1> 	;jna	short sysumnt_1		
  2441                              <1> 	;	; bne 1b / yes, wait
  2442                              <1> 	;call	idle ; (wait for hardware interrupt)
  2443                              <1> 	;jmp	short sysumnt_0
  2444                              <1> sysumnt_1:
  2445                              <1> 	; 15/05/2022
  2446                              <1> 	; change user's current directory to mounting directory
  2447                              <1> 	; if it is on the mounted device (chdir back to root fs)
  2448 00005548 3805[4C6C0000]      <1> 	cmp	byte [u.cdrv], al ; 0
  2449 0000554E 7641                <1> 	jna	short sysumnt_4
  2450                              <1> 	;;;
  2451                              <1> 	; 15/05/2022
  2452                              <1> 	; It is needed to change the parent process's current
  2453                              <1> 	; directory because shell runs (/etc/umount) 
  2454                              <1> 	; as child process.
  2455 00005550 31DB                <1> 	xor	ebx, ebx 
  2456 00005552 8A1D[956C0000]      <1> 	mov	bl, [u.uno]
  2457 00005558 D0E3                <1> 	shl	bl, 1 ; >= 2 .. <= 32
  2458 0000555A 81C3[22680000]      <1> 	add	ebx, p.ppid-2
  2459 00005560 668B13              <1> 	mov	dx, [ebx] ; process id of the parent [p.ppid]	
  2460 00005563 BE[04680000]        <1> 	mov	esi, p.pid
  2461 00005568 29C9                <1> 	sub	ecx, ecx
  2462 0000556A B110                <1> 	mov	cl, nproc ; 16  
  2463                              <1> sysumnt_2:	
  2464 0000556C 66AD                <1> 	lodsw
  2465 0000556E 6639D0              <1> 	cmp	ax, dx
  2466 00005571 7402                <1> 	je	short sysumnt_3
  2467 00005573 E2F7                <1> 	loop	sysumnt_2
  2468                              <1> sysumnt_3:
  2469 00005575 31C0                <1> 	xor	eax, eax
  2470 00005577 81EE[04680000]      <1> 	sub	esi, p.pid
  2471 0000557D D1E6                <1> 	shl	esi, 1
  2472 0000557F 8B9E[70680000]      <1> 	mov	ebx, [esi+p.upage-4] ; the parent's upage
  2473                              <1> 	; ebx points to user (u) structure in upage
  2474 00005585 8B15[2A6C0000]      <1> 	mov	edx, [mnti] ; * (32 bit inumber but < 65536)
  2475                              <1> 	;mov	[u.cdir], dx
  2476                              <1> 	;mov	[u.cdrv], al ; 0
  2477 0000558B 89530C              <1> 	mov	[ebx+u.cdir-user], edx 
  2478                              <1> 			    ; * (32 bit inumber but < 65536)
  2479 0000558E 884310              <1> 	mov	[ebx+u.cdrv-user], al ; 0
  2480                              <1> 	;;;
  2481                              <1> sysumnt_4:
  2482 00005591 A2[236C0000]        <1> 	mov	[mdev], al ; 0
  2483                              <1> 	     	; clr mntd / no, clear these
  2484 00005596 A3[2A6C0000]        <1>    	mov	[mnti], eax ; 11/01/2022 (eax = 0)
  2485                              <1> 	;mov	[mnti], ax ; 0
  2486                              <1>         	; clr mnti
  2487                              <1> 
  2488                              <1> 	;; 15/05/2022
  2489                              <1> 	;mov	[cdev], al ; 0 ; [u.cdrv] = 0
  2490                              <1> 	;mov	eax, edx  ; [u.cdir]
  2491                              <1> 	;call	iget
  2492                              <1> 
  2493 0000559B E9C7DBFFFF          <1>         jmp	sysret
  2494                              <1> 		; br sysreta / return
  2495                              <1> 
  2496                              <1> 	; 11/01/2022 - Retro UNIX 386 v1.2
  2497                              <1> 	;	(runix v2 fs inode numbers)
  2498                              <1> getspl: ; / get device number from a special file name
  2499 000055A0 E8B9EAFFFF          <1> 	call	namei
  2500                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  2501                              <1> 		       ; ax = 0 -> file not found 	
  2502                              <1> 	;jc	sysmnt_err2 ; 'file not found !' error
  2503                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
  2504 000055A5 7305                <1> 	jnc	short getspl_0
  2505 000055A7 E9B1FEFFFF          <1> 	jmp	sysmnt_err2
  2506                              <1> getspl_0:
  2507                              <1> 	;jz	error
  2508                              <1> 	;jc	error
  2509                              <1> 		; jsr r0,namei / get the i-number of the special file
  2510                              <1>                 ; br errora / no such file
  2511                              <1>         ; 11/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode numbers)
  2512 000055AC 6683E80A            <1> 	sub	ax, 10 ; fd0 inode number = 10, hd3 inode number = 15
  2513                              <1> 		      ;	i-number-10, 0 = fd0, 5 = hd3 
  2514                              <1> 	;sub	ax, 3 ; Retro UNIX 8086 v1 modification !
  2515                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
  2516                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
  2517 000055B0 7206                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
  2518                              <1> 	;jc	error
  2519                              <1> 		; ble errora / less than 0?  yes, error
  2520 000055B2 6683F805            <1>         cmp	ax, 5 ; 5 = hd3
  2521                              <1> 		; cmp r1,$9. / greater than 9  tap 7
  2522                              <1> 	;ja	short sysmnt_err0 ; 'permission denied !' error
  2523                              <1> 	;;ja	error
  2524                              <1> 		; bgt errora / yes, error
  2525                              <1> 	; 11/01/2022
  2526 000055B6 760F                <1> 	jna	short getspl_retn
  2527                              <1> 	; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
  2528                              <1> ;iopen_retn:
  2529                              <1> ;	retn
  2530                              <1> 		; rts    r0 / return with device number in r1
  2531                              <1> sysmnt_err0:
  2532 000055B8 C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  2532 000055C0 0000                <1>
  2533 000055C2 E980DBFFFF          <1> 	jmp	error
  2534                              <1> 
  2535                              <1> getspl_retn:
  2536                              <1> 	; 11/01/2022
  2537                              <1> 	; eax = Retro UNIX 386 v1 device number (0 to 5)
  2538                              <1> iopen_retn:
  2539 000055C7 C3                  <1> 	retn
  2540                              <1> 
  2541                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 
  2542                              <1> 	;			(Printer initialization)
  2543                              <1> 	; 11/02/2022
  2544                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
  2545                              <1> iopen:
  2546                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
  2547                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
  2548                              <1> 	; 19/05/2015
  2549                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
  2550                              <1> 	; 21/05/2013 - 27/08/2013 (Retro UNIX 8086 v1)
  2551                              <1> 	;
  2552                              <1> 	; open file whose i-number is in r1
  2553                              <1> 	; 
  2554                              <1> 	; INPUTS ->
  2555                              <1> 	;    r1 - inode number
  2556                              <1> 	; OUTPUTS ->
  2557                              <1> 	;    file's inode in core	
  2558                              <1> 	;    r1 - inode number (positive)
  2559                              <1> 	;
  2560                              <1> 	; ((AX = R1))
  2561                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi, ebp)) 
  2562                              <1> 	;        
  2563                              <1> ; / open file whose i-number is in r1
  2564                              <1> ;	test	ah, 80h ; Bit 15 of AX
  2565                              <1> ;		; tst r1 / write or read access?
  2566                              <1> ;       jnz	short iopen_2
  2567                              <1> ;		; blt 2f / write, go to 2f
  2568                              <1> ;	mov	dl, 2 ; read access
  2569                              <1> ;	call	access
  2570                              <1> ;       	; jsr r0,access; 2 
  2571                              <1> ;	; / get inode into core with read access
  2572                              <1> ;	; DL=2
  2573                              <1> ;iopen_0:
  2574                              <1> ;       cmp	ax, 40
  2575                              <1> ;		; cmp r1,$40. / is it a special file
  2576                              <1> ;       ja	short iopen_retn
  2577                              <1> ;		; bgt 3f / no. 3f
  2578                              <1> 
  2579                              <1> 	; 05/12/2021
  2580                              <1> 	; DL = 0 -> open for read
  2581                              <1> 	; DL = 1 -> open for write
  2582                              <1> 	; 11/02/2022
  2583                              <1> 	; DL = 2 -> create (open for write)
  2584                              <1> 		    ; (caller: syscreat)
  2585                              <1> 
  2586 000055C8 52                  <1> 	push	edx ; *
  2587                              <1> 
  2588                              <1> 	; set permission/mode flag for 'access' 
  2589                              <1> 	;	(DX = 100h -> IREAD, DX = 80h -> IWRITE)
  2590                              <1> 
  2591 000055C9 B601                <1> 	mov	dh, 1
  2592 000055CB 08D2                <1> 	or	dl, dl ; dl = 0, open for read	
  2593 000055CD 7404                <1> 	jz	short iopen_0 ; DX = IREAD (100h)
  2594                              <1> 	; dl = 1, open for write 
  2595                              <1> 	; or
  2596                              <1> 	; dl = 2, create (regular) file	; 11/02/2022
  2597 000055CF FECE                <1> 	dec	dh
  2598 000055D1 B280                <1> 	mov	dl, 80h
  2599                              <1> 	; DX = IWRITE (80h)
  2600                              <1> iopen_0:
  2601                              <1> 	; 27/03/2021
  2602                              <1> 	;   EAX = inode number (in AX)
  2603                              <1> 	;    DX = access mode, 100h = read, 80h = write
  2604                              <1> 
  2605                              <1> 	; 24/06/2020 - Retro UNIX 386 v2	
  2606 000055D3 E869F6FFFF          <1> 	call	access
  2607                              <1> 		; jsr r0,access; 1 / get inode in core
  2608                              <1> 	
  2609                              <1> 	; 27/03/2021
  2610                              <1> 	; DX return value from 'access' subroutine
  2611                              <1> 	;    may be 100h, 20h, 04h for DX = 100h (IREAD) input
  2612                              <1> 	;	     80h, 10h, 02h for DX = 80h (IWRITE) input
  2613                              <1> 
  2614                              <1> 	; 05/12/2021
  2615 000055D8 5A                  <1> 	pop	edx ; * ; dl = 0 -> open for read
  2616                              <1> 			; dl = 1 -> open for write
  2617                              <1> 			; 11/02/2022
  2618                              <1> 			; dl = 2 -> create (regular) file
  2619                              <1> 			;	   (open for writing)
  2620                              <1> 	; 24/06/2020
  2621 000055D9 8A0D[C5670000]      <1> 	mov	cl, [i.flgs+1]
  2622                              <1> 
  2623 000055DF F6C180              <1> 	test	cl, 80h		; regular file ?
  2624 000055E2 7525                <1> 	jnz	short iopen_1	; yes ; 05/12/2021
  2625 000055E4 F6C120              <1> 	test	cl, 20h 	; device file ?
  2626                              <1> 	;jnz	short iopen_2	; yes
  2627                              <1> 	; 11/02/2022
  2628 000055E7 7414                <1> 	jz	short iopen_invf ; no, invalid file/inode !
  2629                              <1> 	; device file/inode
  2630 000055E9 F6C202              <1> 	test	dl, 2 ; create file ?
  2631 000055EC 7425                <1> 	jz	short iopen_2	; device file r/w (dl=0 or dl=1)
  2632                              <1> 	; an attempt to create a file 
  2633                              <1> 	; whith name of existing device file in same directory!
  2634                              <1> iopen_pdnd:
  2635 000055EE C705[B86C0000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; 11
  2635 000055F6 0000                <1>
  2636                              <1> 				; 'permission denied !' error
  2637                              <1> iopen_err:
  2638 000055F8 E94ADBFFFF          <1> 	jmp	error
  2639                              <1> iopen_invf:
  2640                              <1> 	; invalid inode (flags)
  2641 000055FD C705[B86C0000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
  2641 00005605 0000                <1>
  2642 00005607 EBEF                <1> 	jmp	short iopen_err
  2643                              <1> 
  2644                              <1> iopen_1:
  2645                              <1> 	; 05/12/2021
  2646                              <1> 	; (If open mode is 'write' and the file/inode is a directory,
  2647                              <1> 	;  open request will/must be rejected.)
  2648                              <1> 	;
  2649                              <1> 	; (If inode is a regular file and it is not a directory,
  2650                              <1> 	; there is nothing to do here, we need to return to 'sysopen'
  2651                              <1> 	; for completing the rest of file opening procedure.) 
  2652                              <1> 	
  2653 00005609 F6C140              <1> 	test	cl, 40h	; directory ?
  2654 0000560C 74B9                <1> 	jz	short iopen_retn ; no
  2655                              <1> 	
  2656 0000560E 20D2                <1> 	and	dl, dl ; open mode is 1 (write) 
  2657                              <1> 	;jz	short iopen_retn ; no
  2658                              <1> 	; 11/02/2022
  2659                              <1> 	; open mode 1 (write) or 2 (create)
  2660 00005610 75DC                <1> 	jnz	short iopen_pdnd ; 'permission denied !' error
  2661                              <1> ;iopen_retn:
  2662 00005612 C3                  <1> 	retn
  2663                              <1> 
  2664                              <1> 	; !!!	
  2665                              <1> 	; 'sysopen' for writing
  2666                              <1> 	;	 is not applicable for directories
  2667                              <1> 	; (Directory entries must be created or deleted by
  2668                              <1> 	; relevant system calls.)
  2669                              <1> 
  2670                              <1> 	;;mov	dword [u.error], ERR_DIR_ACCESS ; 11
  2671                              <1> 	;mov	dword [u.error], ERR_PERM_DENIED ; 11
  2672                              <1> 	;			; 'permission denied !' error
  2673                              <1> 	;;jmp	error
  2674                              <1> 	;jmp	short iopen_err
  2675                              <1> 
  2676                              <1> ;iopen_retn:
  2677                              <1> ;	retn
  2678                              <1> 
  2679                              <1> iopen_2:
  2680                              <1> 	;push	ax
  2681                              <1> 	;	; mov r1,-(sp) / yes, figure out
  2682                              <1> 	;movzx	ebx, al
  2683                              <1> 	;shl	bx, 2
  2684                              <1> 	;	; asl r1
  2685                              <1>         ;add	ebx, iopen_1 - 4
  2686                              <1> 	;jmp	dword [ebx]
  2687                              <1>         ;	; jmp *1f-2(r1) / which one and transfer to it
  2688                              <1> 	
  2689                              <1> 	; 05/12/2021
  2690 00005613 50                  <1> 	push	eax ; save inode number
  2691                              <1> 	; device file
  2692 00005614 BB[30560000]        <1> 	mov	ebx, iopen_4
  2693 00005619 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
  2694 0000561C 720E                <1> 	jb	short iopen_3 ; null
  2695 0000561E 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
  2696 00005621 7709                <1> 	ja	short iopen_3 ; null	
  2697                              <1> 	; convert v2 inode number to v1 device inode number
  2698 00005623 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
  2699 00005625 89C1                <1> 	mov	ecx, eax
  2700 00005627 C0E102              <1> 	shl	cl, 2 ; * 4
  2701 0000562A 01CB                <1> 	add	ebx, ecx
  2702                              <1> iopen_3:
  2703 0000562C FEC2                <1> 	inc	dl ; 1 = read, 2 = write
  2704 0000562E FF23                <1> 	jmp	dword [ebx]	
  2705                              <1> 		; jmp *1f-2(r1)
  2706                              <1> ;iopen_1: ; 1:
  2707                              <1> iopen_4:
  2708 00005630 [604F0000]          <1> 	dd	null ; 05/12/2021
  2709 00005634 [80560000]          <1> 	dd	otty ; tty, AX = 1 (runix)
  2710                              <1>  		 ;otty / tty ; r1=2
  2711                              <1>         	 ;oppt / ppt ; r1=4
  2712 00005638 [38570000]          <1> 	dd	sret ; mem, AX = 2 (runix)
  2713                              <1> 		 ;sret / mem ; r1=6
  2714                              <1> 		 ;sret / rf0
  2715                              <1>         	 ;sret / rk0
  2716                              <1>         	 ;sret / tap0
  2717                              <1>         	 ;sret / tap1
  2718                              <1>         	 ;sret / tap2
  2719                              <1>         	 ;sret / tap3
  2720                              <1>         	 ;sret / tap4
  2721                              <1>         	 ;sret / tap5
  2722                              <1>         	 ;sret / tap6
  2723                              <1>         	 ;sret / tap7
  2724 0000563C [38570000]          <1>         dd	sret ; fd0, AX = 3 (runix only)
  2725 00005640 [38570000]          <1>         dd	sret ; fd1, AX = 4 (runix only)
  2726 00005644 [38570000]          <1>         dd	sret ; hd0, AX = 5 (runix only)
  2727 00005648 [38570000]          <1>         dd	sret ; hd1, AX = 6 (runix only) 
  2728 0000564C [38570000]          <1>         dd	sret ; hd2, AX = 7 (runix only)
  2729 00005650 [38570000]          <1>         dd	sret ; hd3, AX = 8 (runix only) 
  2730                              <1> 	;;dd	error ; lpr, AX = 9 (error !)
  2731                              <1>         ;dd	sret ; lpr, AX = 9 (runix)
  2732                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 (lpt_init)
  2733 00005654 [14580000]          <1>         dd	ejec ; lpr, AX = 9 (runix)	
  2734 00005658 [91560000]          <1> 	dd	ocvt ; tty0, AX = 10 (runix)	  
  2735                              <1> 		 ;ocvt / tty0
  2736 0000565C [91560000]          <1> 	dd	ocvt ; tty1, AX = 11 (runix)	  
  2737                              <1> 		 ;ocvt / tty1
  2738 00005660 [91560000]          <1> 	dd	ocvt ; tty2, AX = 12 (runix)	  
  2739                              <1> 		 ;ocvt / tty2
  2740 00005664 [91560000]          <1> 	dd	ocvt ; tty3, AX = 13 (runix)	  
  2741                              <1> 		 ;ocvt / tty3
  2742 00005668 [91560000]          <1> 	dd	ocvt ; tty4, AX = 14 (runix)	  
  2743                              <1> 		 ;ocvt / tty4
  2744 0000566C [91560000]          <1> 	dd	ocvt ; tty5, AX = 15 (runix)	  
  2745                              <1> 		 ;ocvt / tty5
  2746 00005670 [91560000]          <1> 	dd	ocvt ; tty6, AX = 16 (runix)	  
  2747                              <1> 		 ;ocvt / tty6
  2748 00005674 [91560000]          <1> 	dd	ocvt ; tty7, AX = 17 (runix)	  
  2749                              <1> 		 ;ocvt / tty7
  2750 00005678 [91560000]          <1> 	dd	ocvt ; COM1, AX = 18 (runix only)	  
  2751                              <1> 		 ;error / crd
  2752 0000567C [91560000]          <1> 	dd	ocvt ; COM2, AX = 19 (runix only)
  2753                              <1> 
  2754                              <1> ;iopen_2: ; 2: / check open write access
  2755                              <1> ;	neg	ax
  2756                              <1> ;		; neg r1 / make inode number positive
  2757                              <1> ;	mov	dl, 1 ; write access
  2758                              <1> ;	call	access
  2759                              <1> ;		; jsr r0,access; 1 / get inode in core
  2760                              <1> ;	; DL=1
  2761                              <1> ;	test	word [i.flgs], 4000h ; Bit 14 : Directory flag
  2762                              <1> ;		;bit $40000,i.flgs / is it a directory?
  2763                              <1> ;	jz	short iopen_0
  2764                              <1> ;	;mov	[u.error], ERR_DIR_ACCESS
  2765                              <1> ;	;jmp	error ; permission denied !
  2766                              <1> ;	jmp	sysmnt_err0
  2767                              <1> ;	;;jnz	error		
  2768                              <1> ;      		; bne 2f / yes, transfer (error)
  2769                              <1> ;       ;;jmp     short iopen_0
  2770                              <1> ;	;cmp	ax, 40
  2771                              <1> ;		; cmp r1,$40. / no, is it a special file?
  2772                              <1> ;        ;ja	short iopen_2
  2773                              <1> ;		; bgt 3f / no, return
  2774                              <1> ;	;push	ax
  2775                              <1> ;		; mov r1,-(sp) / yes
  2776                              <1> ;	;movzx	ebx, al
  2777                              <1> ;	;shl	bx, 1
  2778                              <1> ;		; asl r1
  2779                              <1> ;	;add	ebx, ipen_3 - 2
  2780                              <1> ;	;jmp	dword [ebx]
  2781                              <1> ;		; jmp *1f-2(r1) / figure out 
  2782                              <1> ;			; / which special file it is and transfer
  2783                              <1> ;iopen_3: ; 1:
  2784                              <1> ;	dd 	otty ; tty, AX = 1 (runix)
  2785                              <1> ; 		 ;otty / tty ; r1=2
  2786                              <1> ;        	 ;leadr / ppt ; r1=4
  2787                              <1> ;	dd	sret ; mem, AX = 2 (runix)
  2788                              <1> ;		 ;sret / mem ; r1=6
  2789                              <1> ;		 ;sret / rf0
  2790                              <1> ;        	 ;sret / rk0
  2791                              <1> ;        	 ;sret / tap0
  2792                              <1> ;        	 ;sret / tap1
  2793                              <1> ;        	 ;sret / tap2
  2794                              <1> ;        	 ;sret / tap3
  2795                              <1> ;        	 ;sret / tap4
  2796                              <1> ;        	 ;sret / tap5
  2797                              <1> ;        	 ;sret / tap6
  2798                              <1> ;        	 ;sret / tap7
  2799                              <1> ;	dd 	sret ; fd0, AX = 3 (runix only)
  2800                              <1> ;	dd 	sret ; fd1, AX = 4 (runix only)
  2801                              <1> ;	dd 	sret ; hd0, AX = 5 (runix only)
  2802                              <1> ;	dd 	sret ; hd1, AX = 6 (runix only)	
  2803                              <1> ;	dd 	sret ; hd2, AX = 7 (runix only)
  2804                              <1> ;	dd 	sret ; hd3, AX = 8 (runix only)	
  2805                              <1> ;	dd	sret ; lpr, AX = 9  (runix)
  2806                              <1> ;	;dd	ejec ; lpr, AX = 9  (runix)
  2807                              <1> ;	dd	sret ; tty0, AX = 10 (runix)	  
  2808                              <1> ;		 ;ocvt / tty0
  2809                              <1> ;	dd	sret ; tty1, AX = 11 (runix)	  
  2810                              <1> ;		 ;ocvt / tty1
  2811                              <1> ;	dd	sret ; tty2, AX = 12 (runix)	  
  2812                              <1> ;		 ;ocvt / tty2
  2813                              <1> ;	dd	sret ; tty3, AX = 13 (runix)	  
  2814                              <1> ;		 ;ocvt / tty3
  2815                              <1> ;	dd	sret ; tty4, AX = 14 (runix)	  
  2816                              <1> ;		 ;ocvt / tty4
  2817                              <1> ;	dd	sret ; tty5, AX = 15 (runix)	  
  2818                              <1> ;		 ;ocvt / tty5
  2819                              <1> ;	dd	sret ; tty6, AX = 16 (runix)	  
  2820                              <1> ;		 ;ocvt / tty6
  2821                              <1> ;	dd	sret ; tty7, AX = 17 (runix)	  
  2822                              <1> ;		 ;ocvt / tty7
  2823                              <1> ;	dd	ocvt ; COM1, AX = 18 (runix only)	  
  2824                              <1> ;		 ;/ ejec / lpr
  2825                              <1> ;	dd	ocvt ; COM2, AX = 19 (runix only)
  2826                              <1> 
  2827                              <1> otty: ;/ open console tty for reading or writing
  2828                              <1> 	; 03/03/2022
  2829                              <1> 	; 23/02/2022
  2830                              <1> 	; 22/02/2022
  2831                              <1> 	; 09/02/2022
  2832                              <1> 	; 06/02/2022
  2833                              <1> 	; 08/01/2022
  2834                              <1> 	; 01/01/2022
  2835                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  2836                              <1> 	; 16/11/2015
  2837                              <1> 	; 12/11/2015
  2838                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
  2839                              <1> 	; 21/05/2013 - 13/07/2014 (Retro UNIX 8086 v1)
  2840                              <1> 	; 16/07/2013
  2841                              <1> 	; Retro UNIX 8086 v1 modification:
  2842                              <1> 	;  If a tty is open for read or write by
  2843                              <1> 	;     a process (u.uno), only same process can open
  2844                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
  2845                              <1> 	;
  2846                              <1> 	; (INPUT: DL=2 for Read, DL=1 for Write, DL=0 for sysstty)
  2847                              <1> 	;
  2848                              <1> 
  2849 00005680 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  2850 00005687 8A83[43680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
  2851                              <1> 	; 13/01/2014
  2852                              <1> 	;jmp	short ottyp
  2853                              <1> 	; 23/02/2022
  2854 0000568D 88C4                <1> 	mov	ah, al
  2855                              <1> 	; 06/02/2022
  2856 0000568F EB06                <1> 	jmp	short otty_0
  2857                              <1> ocvt:
  2858 00005691 2C0A                <1> 	sub	al, 10
  2859                              <1> ;ottyp:	; (call from sysstty)
  2860                              <1> 	; 08/01/2022
  2861 00005693 31DB                <1> 	xor	ebx, ebx
  2862                              <1> ottyp:	; 03/03/2022
  2863                              <1> 	; (ebx < 256) ; 06/02/2022
  2864                              <1> 	; 23/02/2022
  2865 00005695 B4FF                <1> 	mov	ah, 0FFh
  2866                              <1> 	; 22/02/2022
  2867                              <1> otty_0:
  2868                              <1> 	; 09/02/2022
  2869                              <1> 	; INPUT:
  2870                              <1> 	;	DL=1 for read, DL=2 for write, DL=0 for sysstty
  2871                              <1> 	;
  2872                              <1> 	; 08/01/2022
  2873                              <1> 	; 01/01/2022
  2874                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  2875                              <1> 	; 16/11/2015
  2876                              <1> 	; 12/11/2015
  2877                              <1> 	; 18/05/2015 (32 bit modifications)
  2878                              <1> 	; 06/12/2013 - 13/07/2014
  2879 00005697 88C6                <1> 	mov	dh, al ; tty number
  2880                              <1> 	;movzx 	ebx, al ; AL = tty number (0 to 9), AH = 0
  2881                              <1> 	; 08/01/2022
  2882 00005699 88C3                <1> 	mov	bl, al
  2883 0000569B D0E3                <1> 	shl 	bl, 1  ; aligned to word
  2884                              <1> 	; 26/01/2014	
  2885 0000569D 81C3[54670000]      <1> 	add 	ebx, ttyl
  2886 000056A3 668B0B              <1> 	mov 	cx, [ebx]
  2887                              <1> 		   ; CL = lock value (0 or process number)
  2888                              <1> 		   ; CH = open count 
  2889 000056A6 20C9                <1> 	and 	cl, cl
  2890                              <1> 	; 13/01/2014
  2891                              <1> 	;jz 	short otty_ret
  2892                              <1> 	; 05/12/2021
  2893 000056A8 7447                <1> 	jz 	short ottys_0
  2894                              <1> 	;
  2895                              <1> 	; 16/11/2015
  2896 000056AA 3A0D[956C0000]      <1> 	cmp 	cl, [u.uno]
  2897 000056B0 746E                <1> 	je	short ottys_3
  2898                              <1> 	;
  2899                              <1> 	; 23/02/2022
  2900                              <1> 	; (is it the console tty of the current process?)
  2901                              <1> 	; ((fast check/permit for console tty open function))
  2902 000056B2 38E0                <1> 	cmp	al, ah ; cmp dh, ah
  2903 000056B4 746A                <1> 	je	short ottys_3 ; bypass parent process check
  2904                              <1> 	;
  2905                              <1> 	;
  2906                              <1> 	; 22/02/2022
  2907                              <1> 	;movzx 	ebx, cl ; the process which has locked the tty
  2908                              <1> 	;shl 	bl, 1
  2909                              <1> 	;mov 	ax, [ebx+p.pid-2]
  2910                              <1> 	;;movzx ebx, byte [u.uno]
  2911                              <1> 	;mov	bl, [u.uno]
  2912                              <1> 	;shl 	bl, 1
  2913                              <1> 	;cmp 	ax, [ebx+p.ppid-2]
  2914                              <1> 	;je 	short ottys_3  ; 16/11/2015
  2915                              <1> 	; 22/02/2022 (BugFix) ; *
  2916 000056B6 0FB6F1              <1> 	movzx 	esi, cl ; the process which has locked the tty
  2917 000056B9 D1E6                <1> 	shl 	esi, 1
  2918 000056BB 668B86[02680000]    <1> 	mov 	ax, [esi+p.pid-2]
  2919 000056C2 96                  <1> 	xchg	esi, eax
  2920 000056C3 A0[956C0000]        <1> 	mov	al, [u.uno]
  2921 000056C8 D0E0                <1> 	shl 	al, 1
  2922 000056CA 663BB0[22680000]    <1> 	cmp 	si, [eax+p.ppid-2]	
  2923 000056D1 744D                <1> 	je 	short ottys_3 ; *
  2924                              <1> 	; 23/02/2022
  2925                              <1> 	; check console tty of the process
  2926                              <1> 	; (open permission must be given if the -requested- tty is
  2927                              <1> 	;  console tty of current process)
  2928 000056D3 D0E8                <1> 	shr	al, 1
  2929 000056D5 38B0[43680000]      <1> 	cmp	[eax+p.ttyc-1], dh ; console tty ?
  2930 000056DB 7443                <1> 	je 	short ottys_3
  2931                              <1> 	;
  2932                              <1> 	; the tty is locked by another process
  2933                              <1> 	; except the parent process (p.ppid)
  2934                              <1>         ; 09/02/2022
  2935                              <1> 	;mov	dword [u.error], ERR_DEV_ACCESS
  2936                              <1> 	;		; permission denied ! error
  2937                              <1> otty_err: ; 13/01/2014
  2938                              <1> 	;or 	dl, dl	; DL = 0 -> called by sysstty
  2939                              <1> 	;;jnz	error
  2940                              <1> 	; 05/12/2021
  2941                              <1> 	;jz	short otty_stc_retn
  2942                              <1> 	;jmp	error
  2943                              <1> 	; 09/02/2022
  2944 000056DD 80FA01              <1> 	cmp	dl, 1 ; dl = 0 ?
  2945 000056E0 7257                <1> 	jb	short otty_retn ; yes, cf=1, called by sysstty
  2946                              <1> 	; iopen (dl=1 or dl=2)
  2947 000056E2 C705[B86C0000]0B00- <1> 	mov     dword [u.error], ERR_DEV_ACCESS
  2947 000056EA 0000                <1>
  2948                              <1> 			; permission denied ! error
  2949 000056EC E956DAFFFF          <1> 	jmp	error
  2950                              <1> ;otty_stc_retn:
  2951                              <1> 	;stc
  2952                              <1> 	;retn
  2953                              <1> ottys_0:
  2954                              <1> 	; 05/12/2021
  2955                              <1> otty_ret:
  2956                              <1> 	; 13/01/2014
  2957 000056F1 80FE07              <1> 	cmp 	dh, 7
  2958 000056F4 7624                <1> 	jna	short ottys_2
  2959                              <1> 	; 16/11/2015
  2960                              <1> com_port_check:
  2961 000056F6 BE[72670000]        <1> 	mov	esi, com1p
  2962 000056FB 80FE08              <1> 	cmp	dh, 8	; COM1 (tty8) ?
  2963 000056FE 7601                <1> 	jna	short ottys_1 ; yes, it is COM1
  2964 00005700 46                  <1> 	inc	esi	; no, it is COM2 (tty9)
  2965                              <1> ottys_1:
  2966                              <1> 	; 12/11/2015
  2967 00005701 803E00              <1> 	cmp	byte [esi], 0 ; E3h (or 23h)
  2968 00005704 7714                <1> 	ja	short com_port_ready
  2969                              <1> 	;
  2970                              <1> 	; 09/02/2022
  2971 00005706 80FA01              <1> 	cmp	dl, 1 ; dl = 0 ?
  2972 00005709 722E                <1> 	jb	short otty_retn ; yes, cf=1, called by sysstty
  2973 0000570B C705[B86C0000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY
  2973 00005713 0000                <1>
  2974                              <1> 			   ; device not ready ! error
  2975                              <1> 	;jmp	short otty_err
  2976 00005715 E92DDAFFFF          <1> 	jmp	error	 
  2977                              <1> com_port_ready:
  2978                              <1> ottys_2:
  2979                              <1> 	; 03/03/2022
  2980                              <1> 	;or	cl, cl  ; cl = lock/owner, ch = open count
  2981                              <1> 	;jnz	short ottys_3
  2982 0000571A 8A0D[956C0000]      <1> 	mov	cl, [u.uno]
  2983                              <1> ottys_3:
  2984 00005720 FEC5                <1> 	inc 	ch
  2985 00005722 66890B              <1> 	mov 	[ebx], cx ; set tty lock again
  2986                              <1> 	; 06/12/2013
  2987 00005725 FEC6                <1> 	inc	dh ; tty number + 1
  2988 00005727 BB[7A6C0000]        <1> 	mov	ebx, u.ttyp
  2989                              <1> 	; 13/01/2014
  2990                              <1> 	;test	dl, 2 ; open for read sign
  2991                              <1> 	;jnz	short ottys_4
  2992                              <1> 	; 05/12/2021
  2993                              <1> 	;test	dl, 2
  2994                              <1> 	;jz	short ottys_4 ; open for read
  2995                              <1> 	; 01/01/2022
  2996 0000572C F6C201              <1> 	test	dl, 1
  2997 0000572F 7501                <1> 	jnz	short ottys_4 ; open for read (dl=1)
  2998                              <1> 	; dl=2 (open for write) or dl=0 (sysstty)
  2999 00005731 43                  <1> 	inc	ebx
  3000                              <1> ottys_4:
  3001                              <1> 	; Set 'u.ttyp' ('the recent TTY') value
  3002 00005732 8833                <1> 	mov 	[ebx], dh ; tty number + 1
  3003                              <1> 	; 09/02/2022
  3004 00005734 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
  3005 00005736 7401                <1> 	jz	short otty_retn ; 03/03/2022
  3006                              <1> sret:
  3007                              <1> 	;pop 	ax
  3008                              <1> 	; 05/12/2021
  3009 00005738 58                  <1> 	pop	eax
  3010                              <1> otty_retn:	; 09/02/2022
  3011                              <1> iclose_retn:	
  3012 00005739 C3                  <1> 	retn
  3013                              <1> 
  3014                              <1> 	;
  3015                              <1> 	; Original UNIX v1 'otty' routine:
  3016                              <1> 	;	
  3017                              <1> 	;mov    $100,*$tks / set interrupt enable bit (zero others) in
  3018                              <1>         ;                 / reader status reg
  3019                              <1>         ;mov    $100,*$tps / set interrupt enable bit (zero others) in
  3020                              <1>         ;                 / punch status reg
  3021                              <1>         ;mov    tty+[ntty*8]-8+6,r5 / r5 points to the header of the
  3022                              <1>         ;                          / console tty buffer
  3023                              <1>         ;incb   (r5) / increment the count of processes that opened the
  3024                              <1>         ;            / console tty
  3025                              <1>         ;tst    u.ttyp / is there a process control tty (i.e., has a tty
  3026                              <1>         ;             / buffer header
  3027                              <1>         ;bne    sret / address been loaded into u.ttyp yet)?  yes, branch
  3028                              <1>         ;mov    r5,u.ttyp / no, make the console tty the process control
  3029                              <1>         ;                 / tty
  3030                              <1>         ;br     sret / ?
  3031                              <1> ;sret:
  3032                              <1> 		;clr *$ps / set processor priority to zero
  3033                              <1> ;	pop	ax
  3034                              <1>         	;mov (sp)+,r1 / pop stack to r1
  3035                              <1> ;3:
  3036                              <1> ;	retn
  3037                              <1>         	;rts r0
  3038                              <1> 	
  3039                              <1> ;ocvt:	; < open tty >
  3040                              <1> 	; 13/01/2014
  3041                              <1> 	; 06/12/2013 (major modification: p.ttyc, u.ttyp)
  3042                              <1> 	; 24/09/2013 consistency check -> ok
  3043                              <1> 	; 16/09/2013
  3044                              <1> 	; 03/09/2013
  3045                              <1> 	; 27/08/2013
  3046                              <1> 	; 16/08/2013
  3047                              <1> 	; 16/07/2013
  3048                              <1> 	; 27/05/2013
  3049                              <1> 	; 21/05/2013
  3050                              <1> 	;
  3051                              <1> 	; Retro UNIX 8086 v1 modification !
  3052                              <1> 	; 
  3053                              <1> 	; In original UNIX v1, 'ocvt' routine 
  3054                              <1> 	;		(exactly different than this one)
  3055                              <1> 	;	was in 'u9.s' file.
  3056                              <1> 	;
  3057                              <1> 	; 16/07/2013
  3058                              <1> 	; Retro UNIX 8086 v1 modification:
  3059                              <1> 	;  If a tty is open for read or write by
  3060                              <1> 	;     a process (u.uno), only same process can open
  3061                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
  3062                              <1> 	;
  3063                              <1> 	; INPUT: DL=2 for Read DL=1 for Write
  3064                              <1> 
  3065                              <1> 	; 16/09/2013
  3066                              <1> 	; sub 	al, 10
  3067                              <1> 	
  3068                              <1> 	; 06/12/2013
  3069                              <1> 	;cmp	al, 7
  3070                              <1>         ;jna	short ottyp
  3071                              <1> 	; 13/01/2014
  3072                              <1> 	;jmp	short ottyp
  3073                              <1> 
  3074                              <1> ;oppt: / open paper tape for reading or writing
  3075                              <1> ;        mov    $100,*$prs / set reader interrupt enable bit
  3076                              <1> ;        tstb   pptiflg / is file already open
  3077                              <1> ;        bne    2f / yes, branch
  3078                              <1> ;1:
  3079                              <1> ;        mov    $240,*$ps / no, set processor priority to 5
  3080                              <1> ;        jsr    r0,getc; 2 / remove all entries in clist
  3081                              <1> ;               br .+4 / for paper tape input and place in free list
  3082                              <1> ;        br     1b
  3083                              <1> ;        movb   $2,pptiflg / set pptiflg to indicate file just open
  3084                              <1> ;        movb   $10.,toutt+1 / place 10 in paper tape input tout entry
  3085                              <1> ;        br     sret
  3086                              <1> ;2:
  3087                              <1> ;        jmp    error / file already open
  3088                              <1> 
  3089                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
  3090                              <1> iclose:
  3091                              <1> 	; 09/02/2022
  3092                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
  3093                              <1> 	; 10/04/2021
  3094                              <1> 	; 08/04/2021
  3095                              <1> 	; 04/04/2021 - Retro UNIX 386 v2
  3096                              <1> 	; 19/05/2015
  3097                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
  3098                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
  3099                              <1> 	;
  3100                              <1> 	; close file whose i-number is in r1
  3101                              <1> 	; 
  3102                              <1> 	; INPUTS ->
  3103                              <1> 	;    r1 - inode number
  3104                              <1> 	; OUTPUTS ->
  3105                              <1> 	;    file's inode in core	
  3106                              <1> 	;    r1 - inode number (positive)
  3107                              <1> 	;
  3108                              <1> 	; ((AX = R1))
  3109                              <1>         ;    ((Modified registers: -ebx-, edx)) 
  3110                              <1> 	;        
  3111                              <1> ;;/ close file whose i-number is in r1
  3112                              <1> ;	mov	dl, 2 ; 12/01/2014
  3113                              <1> ;	test	ah, 80h ; Bit 15 of AX
  3114                              <1> ;		;tst r1 / test i-number
  3115                              <1> ;	;jnz	short iclose_2
  3116                              <1> ;		;blt 2f / if neg., branch
  3117                              <1> ;	jz	short iclose_0 ; 30/07/2013
  3118                              <1> ;	; 16/07/2013 
  3119                              <1> ;	neg	ax ; make it positive
  3120                              <1> ;	; 12/01/2014
  3121                              <1> ;	dec	dl ; dl = 1 (open for write)
  3122                              <1> ;iclose_0:
  3123                              <1> ;	cmp	ax, 40
  3124                              <1> ;		;cmp r1,$40. / is it a special file
  3125                              <1> ;       ja	short iclose_retn  ; 13/01/2014
  3126                              <1> ;		;bgt 3b / no, return
  3127                              <1> ;	; 12/01/2014
  3128                              <1> ;	; DL=2 -> special file was opened for reading
  3129                              <1> ;	; DL=1 -> special file was opened for writing
  3130                              <1> 
  3131                              <1> 	; 04/04/2021
  3132                              <1> 	; INPUT:
  3133                              <1> 	;	(e)ax = inode number
  3134                              <1> 	;	   dl = open mode
  3135                              <1> 	;		0 = control mode
  3136                              <1> 	;		1 = read
  3137                              <1> 	;		2 = write
  3138                              <1> 	; OUTPUT:
  3139                              <1> 	;	none
  3140                              <1> 	;	(if cf=1 -> eax = error code)
  3141                              <1> 	;	(if cf=0 -> ax = inode number)
  3142                              <1> 
  3143                              <1> 	; 10/04/2021
  3144                              <1>         ; Modified registers: ebx, ecx, edx, esi, edi, (ebp) 
  3145                              <1> 
  3146                              <1> 	; 05/12/2021
  3147                              <1> 	; 08/04/2021
  3148                              <1> 
  3149 0000573A 52                  <1> 	push	edx
  3150 0000573B E817F4FFFF          <1> 	call	iget
  3151 00005740 5A                  <1> 	pop	edx 
  3152                              <1> 
  3153 00005741 8A0D[C5670000]      <1> 	mov	cl, [i.flgs+1]
  3154                              <1> 
  3155                              <1> 	; if i.flgs bit 15 is 1, it is regular file 
  3156                              <1> 	;test	byte [i.flgs+1], 80h ; is it a special file?
  3157 00005747 F6C180              <1> 	test	cl, 80h ; is it a special file?
  3158 0000574A 75ED                <1> 	jnz	short iclose_retn ; no
  3159                              <1> 
  3160                              <1> 	;; inode flags - bit 13 must be 1 
  3161                              <1> 	;test	cl, 20h ; is it a valid device inode
  3162                              <1> 	;jz	short iclose_retn ; no ; 19/01/2022
  3163                              <1> 	
  3164                              <1> 	;push	ax
  3165                              <1> 	;	;mov r1,-(sp) / yes, save r1 on stack
  3166                              <1> 	;movzx	ebx, al
  3167                              <1> 	;shl	bx, 2
  3168                              <1> 	;	; asl r1
  3169                              <1> 	;add	ebx, iclose_1 - 4
  3170                              <1> 	;jmp	dword [ebx]
  3171                              <1> 	;	; jmp *1f-2(r1) / compute jump address and transfer
  3172                              <1> 
  3173                              <1> 	; 05/12/2021
  3174 0000574C 50                  <1> 	push	eax ; save inode number
  3175                              <1> 	; device file
  3176 0000574D BB[67570000]        <1> 	mov	ebx, iclose_1
  3177 00005752 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
  3178 00005755 720E                <1> 	jb	short iclose_0
  3179 00005757 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
  3180 0000575A 7709                <1> 	ja	short iclose_0
  3181                              <1> 	; convert v2 inode number to v1 device inode number
  3182 0000575C 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
  3183 0000575E 89C1                <1> 	mov	ecx, eax
  3184 00005760 C0E102              <1> 	shl	cl, 2 ; * 4
  3185 00005763 01CB                <1> 	add	ebx, ecx
  3186                              <1> iclose_0:
  3187 00005765 FF23                <1> 	jmp	dword [ebx]	
  3188                              <1> 		; jmp *1f-2(r1)
  3189                              <1> iclose_1: ; 1:
  3190 00005767 [604F0000]          <1> 	dd	null ; 05/12/2021
  3191 0000576B [B7570000]          <1> 	dd	ctty ; tty, AX = 1 (runix)
  3192 0000576F [12580000]          <1> 	dd	cret ; mem, AX = 2 (runix)
  3193 00005773 [12580000]          <1> 	dd	cret ; fd0, AX = 3 (runix only)
  3194 00005777 [12580000]          <1> 	dd	cret ; fd1, AX = 4 (runix only)
  3195 0000577B [12580000]          <1> 	dd	cret ; hd0, AX = 5 (runix only)
  3196 0000577F [12580000]          <1> 	dd	cret ; hd1, AX = 6 (runix only)	
  3197 00005783 [12580000]          <1> 	dd	cret ; hd2, AX = 7 (runix only)
  3198 00005787 [12580000]          <1> 	dd	cret ; hd3, AX = 8 (runix only)	
  3199 0000578B [12580000]          <1> 	dd	cret ; lpr, AX = 9 (runix)
  3200                              <1> 	;dd	error; lpr, AX = 9 (error!)
  3201                              <1> 	;;dd	ejec ;;lpr, AX = 9  
  3202 0000578F [C6570000]          <1> 	dd	ccvt ; tty0, AX = 10 (runix)	  
  3203 00005793 [C6570000]          <1> 	dd	ccvt ; tty1, AX = 11 (runix)	  
  3204 00005797 [C6570000]          <1> 	dd	ccvt ; tty2, AX = 12 (runix)	  
  3205 0000579B [C6570000]          <1> 	dd	ccvt ; tty3, AX = 13 (runix)	  
  3206 0000579F [C6570000]          <1> 	dd	ccvt ; tty4, AX = 14 (runix)	  
  3207 000057A3 [C6570000]          <1> 	dd	ccvt ; tty5, AX = 15 (runix)	  
  3208 000057A7 [C6570000]          <1> 	dd	ccvt ; tty6, AX = 16 (runix)	  
  3209 000057AB [C6570000]          <1> 	dd	ccvt ; tty7, AX = 17 (runix)	  
  3210 000057AF [C6570000]          <1> 	dd	ccvt ; COM1, AX = 18 (runix only)	  
  3211 000057B3 [C6570000]          <1> 	dd	ccvt ; COM2, AX = 19 (runix only)
  3212                              <1> 
  3213                              <1> 	; 1:
  3214                              <1> 	;        ctty   / tty
  3215                              <1> 	;        cppt   / ppt
  3216                              <1> 	;        sret   / mem
  3217                              <1> 	;        sret   / rf0
  3218                              <1> 	;        sret   / rk0
  3219                              <1> 	;        sret   / tap0
  3220                              <1> 	;        sret   / tap1
  3221                              <1> 	;        sret   / tap2
  3222                              <1> 	;        sret   / tap3
  3223                              <1> 	;        sret   / tap4
  3224                              <1> 	;        sret   / tap5
  3225                              <1> 	;        sret   / tap6
  3226                              <1> 	;        sret   / tap7
  3227                              <1> 	;        ccvt   / tty0
  3228                              <1> 	;        ccvt   / tty1
  3229                              <1> 	;        ccvt   / tty2
  3230                              <1> 	;        ccvt   / tty3
  3231                              <1> 	;        ccvt   / tty4
  3232                              <1> 	;        ccvt   / tty5
  3233                              <1> 	;        ccvt   / tty6
  3234                              <1> 	;        ccvt   / tty7
  3235                              <1> 	;        error / crd
  3236                              <1> 
  3237                              <1> ;iclose_2: ; 2: / negative i-number
  3238                              <1> 	;neg	ax
  3239                              <1> 		;neg r1 / make it positive
  3240                              <1> 	;cmp	ax, 40
  3241                              <1> 		;cmp r1,$40. / is it a special file?
  3242                              <1>         ;ja	short @b
  3243                              <1> 		;bgt 3b / no. return
  3244                              <1> 	;push	ax
  3245                              <1> 		;mov r1,-(sp)
  3246                              <1> 	;movzx	ebx, al
  3247                              <1> 	;shl	bx, 1
  3248                              <1> 		;asl r1 / yes. compute jump address and transfer
  3249                              <1> 	;add	ebx, iclose_3 - 2
  3250                              <1> 	;jmp	dword [ebx]
  3251                              <1> 		;jmp *1f-2(r1) / figure out 
  3252                              <1> ;iclose_3:
  3253                              <1> 	;dd	ctty ; tty, AX = 1 (runix)
  3254                              <1> 	;dd	sret ; mem, AX = 2 (runix)
  3255                              <1> 	;dd	sret ; fd0, AX = 3 (runix only)
  3256                              <1> 	;dd	sret ; fd1, AX = 4 (runix only)
  3257                              <1> 	;dd	sret ; hd0, AX = 5 (runix only)
  3258                              <1> 	;dd	sret ; hd1, AX = 6 (runix only)	
  3259                              <1> 	;dd	sret ; hd2, AX = 7 (runix only)
  3260                              <1> 	;dd	sret ; hd3, AX = 8 (runix only)
  3261                              <1> 	;;dd	sret ; lpr, AX = 9	
  3262                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
  3263                              <1> 	;dd	ccvt ; tty0, AX = 10 (runix)	  
  3264                              <1> 	;dd	ccvt ; tty1, AX = 11 (runix)	  
  3265                              <1> 	;dd	ccvt ; tty2, AX = 12 (runix)	  
  3266                              <1> 	;dd	ccvt ; tty3, AX = 13 (runix)	  
  3267                              <1> 	;dd	ccvt ; tty4, AX = 14 (runix)	  
  3268                              <1> 	;dd	ccvt ; tty5, AX = 15 (runix)	  
  3269                              <1> 	;dd	ccvt ; tty6, AX = 16 (runix)	  
  3270                              <1> 	;dd	ccvt ; tty7, AX = 17 (runix)	  
  3271                              <1> 	;dd	ccvt ; COM1, AX = 18 (runix only)	  
  3272                              <1> 	;dd	ccvt ; COM2, AX = 19 (runix only) 
  3273                              <1> 	
  3274                              <1> 	;1:
  3275                              <1> 	;      	ctty   / tty
  3276                              <1> 	;       leadr  / ppt
  3277                              <1> 	;       sret   / mem
  3278                              <1> 	;       sret   / rf0
  3279                              <1> 	;       sret   / rk0
  3280                              <1> 	;       sret   / tap0
  3281                              <1> 	;       sret   / tap1
  3282                              <1> 	;       sret   / tap2
  3283                              <1> 	;       sret   / tap3
  3284                              <1> 	;       sret   / tap4
  3285                              <1> 	;       sret   / tap5
  3286                              <1> 	;       sret   / tap6
  3287                              <1> 	;       sret   / tap7
  3288                              <1> 	;       ccvt   / tty0
  3289                              <1> 	;       ccvt   / tty1
  3290                              <1> 	;       ccvt   / tty2
  3291                              <1> 	;       ccvt   / tty3
  3292                              <1> 	;       ccvt   / tty4
  3293                              <1> 	;       ccvt   / tty5
  3294                              <1> 	;       ccvt   / tty6
  3295                              <1> 	;       ccvt   / tty7
  3296                              <1> 	;/      ejec   / lpr
  3297                              <1> 
  3298                              <1> ctty: ; / close console tty
  3299                              <1> 	; 09/02/2022
  3300                              <1> 	; 06/02/2022
  3301                              <1> 	; 08/01/2022
  3302                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  3303                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
  3304                              <1> 	; 21/05/2013 - 26/01/2014 (Retro UNIX 8086 v1)
  3305                              <1> 	;
  3306                              <1> 	; Retro UNIX 8086 v1 modification !
  3307                              <1> 	; (DL = 2 -> it is open for reading)
  3308                              <1> 	; (DL = 1 -> it is open for writing)
  3309                              <1> 	; (DL = 0 -> it is open for sysstty system call)
  3310                              <1> 	;
  3311                              <1> 	; 06/12/2013
  3312 000057B7 0FB61D[956C0000]    <1>         movzx   ebx, byte [u.uno] ; process number
  3313 000057BE 8A83[43680000]      <1>         mov     al, [ebx+p.ttyc-1]
  3314                              <1> 	; 13/01/2014
  3315                              <1> 	;jmp	short cttyp
  3316                              <1> 	; 06/02/2022
  3317 000057C4 EB04                <1> 	jmp	short ctty_0
  3318                              <1> ccvt:
  3319 000057C6 2C0A                <1> 	sub 	al, 10
  3320                              <1> cttyp:
  3321                              <1> 	; 08/01/2022
  3322 000057C8 31DB                <1> 	xor	ebx, ebx
  3323                              <1> ctty_0:		; 06/02/2022
  3324                              <1> 	; 09/02/2022
  3325                              <1> 	;    DL=2 -> open for writing
  3326                              <1> 	;    DL=1 -> open for reading
  3327                              <1> 	;    DL=0 -> open for sysstty system call	
  3328                              <1> 	; 08/01/2022
  3329                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  3330                              <1> 	; 18/05/2015 (32 bit modifications)
  3331                              <1> 	; 16/08/2013 - 26/01/2014
  3332                              <1> 	;movzx 	ebx, al ; tty number (0 to 9)
  3333                              <1> 	; 08/01/2022
  3334 000057CA 88C3                <1> 	mov	bl, al
  3335 000057CC D0E3                <1> 	shl 	bl, 1  ; aligned to word	
  3336                              <1> 	; 26/01/2014
  3337 000057CE 81C3[54670000]      <1> 	add 	ebx, ttyl
  3338 000057D4 88C6                <1> 	mov 	dh, al ; tty number
  3339 000057D6 668B03              <1> 	mov 	ax, [ebx]
  3340                              <1> 		   ; AL = lock value (0 or process number)
  3341                              <1> 		   ; AH = open count 
  3342 000057D9 20E4                <1> 	and 	ah, ah
  3343 000057DB 7514                <1> 	jnz	short ctty_ret
  3344                              <1> 	; 09/02/2022
  3345 000057DD 80FA01              <1> 	cmp	dl, 1	; DL = 0 -> called by sysstty
  3346 000057E0 7231                <1> 	jb	short ctty_stc_retn ; cf=1
  3347                              <1> 	; iclose (dl=1 or dl=2)
  3348 000057E2 C705[B86C0000]0A00- <1>         mov     dword [u.error], ERR_DEV_NOT_OPEN
  3348 000057EA 0000                <1>
  3349                              <1> 			; device not open ! error
  3350                              <1> 	;jmp 	short ctty_err ; open count = 0, it is not open !
  3351 000057EC E956D9FFFF          <1> 	jmp	error
  3352                              <1> 	; 26/01/2014
  3353                              <1> ctty_ret:
  3354 000057F1 FECC                <1> 	dec 	ah ; decrease open count
  3355 000057F3 7502                <1> 	jnz	short ctty_1
  3356 000057F5 30C0                <1> 	xor	al, al ; unlock/free tty
  3357                              <1> ctty_1:
  3358 000057F7 668903              <1> 	mov 	[ebx], ax ; close tty instance
  3359                              <1> 	;
  3360 000057FA BB[7A6C0000]        <1> 	mov	ebx, u.ttyp
  3361                              <1> 	;;test	dl, 1 ; open for write sign
  3362                              <1> 	;;jz	short ctty_2
  3363                              <1> 	; 05/12/2021
  3364                              <1> 	;test	dl, 2 ; open for write sign
  3365                              <1> 	;jz	short ctty_2	
  3366                              <1> 	; 09/02/2022
  3367 000057FF F6C201              <1> 	test	dl, 1 ; open for read sign
  3368 00005802 7501                <1> 	jnz	short ctty_2
  3369                              <1> 	; open for write (dl=0 or dl=2)
  3370 00005804 43                  <1> 	inc	ebx
  3371                              <1> ctty_2:
  3372 00005805 FEC6                <1> 	inc	dh ; tty number + 1
  3373 00005807 3A33                <1> 	cmp	dh, [ebx]
  3374                              <1> 	;jne	short cret
  3375 00005809 7503                <1> 	jne	short ctty_3 ; 09/02/2022
  3376                              <1> 	; Reset/Clear 'u.ttyp' ('the recent TTY') value
  3377 0000580B C60300              <1> 	mov	byte [ebx], 0
  3378                              <1> ctty_3:
  3379                              <1> 	; 09/02/2022
  3380 0000580E 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
  3381 00005810 7401                <1> 	jz	short ctty_4
  3382                              <1> cret:
  3383                              <1> 	;pop	ax
  3384                              <1> 	; 05/12/2021
  3385 00005812 58                  <1> 	pop	eax
  3386                              <1> ctty_stc_retn:	; 09/02/2022
  3387                              <1> ctty_4:
  3388 00005813 C3                  <1> 	retn
  3389                              <1> 
  3390                              <1> ;ctty_err: ; 13/01/2014
  3391                              <1> ;	or 	dl, dl ; DL = 0 -> called by sysstty
  3392                              <1> ;	jnz	error
  3393                              <1> ;	stc
  3394                              <1> ;	retn
  3395                              <1> 
  3396                              <1> 	; Original UNIX v1 'ctty' routine:
  3397                              <1> 	;	
  3398                              <1>         ;mov    tty+[ntty*8]-8+6,r5 
  3399                              <1> 	;		;/ point r5 to the console tty buffer
  3400                              <1>         ;decb   (r5) / dec number of processes using console tty
  3401                              <1>         ;br     sret / return via sret
  3402                              <1> 
  3403                              <1> ;ccvt:	; < close tty >
  3404                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
  3405                              <1> 	;
  3406                              <1> 	; Retro UNIX 8086 v1 modification !
  3407                              <1> 	; 
  3408                              <1> 	; In original UNIX v1, 'ccvt' routine 
  3409                              <1> 	;		(exactly different than this one)
  3410                              <1> 	;	was in 'u9.s' file.
  3411                              <1> 	;
  3412                              <1> 	; DL = 2 -> it is open for reading
  3413                              <1> 	; DL = 1 -> it is open for writing
  3414                              <1> 	;
  3415                              <1> 	; 17/09/2013
  3416                              <1> 	;sub 	al, 10
  3417                              <1> 	;cmp	al, 7
  3418                              <1> 	;jna	short cttyp
  3419                              <1> 	; 13/01/2014
  3420                              <1> 	;jmp	short cttyp
  3421                              <1> 
  3422                              <1> ;cppt: / close paper tape
  3423                              <1> ;        clrb   pptiflg / set pptiflg to indicate file not open
  3424                              <1> ;1:
  3425                              <1> ;        mov    $240,*$ps /set process or priority to 5
  3426                              <1> ;        jsr    r0,getc; 2 / remove all ppt input entries from clist
  3427                              <1> ;                          / and assign to free list
  3428                              <1> ;               br sret
  3429                              <1> ;        br     1b
  3430                              <1> 
  3431                              <1> ;ejec:	
  3432                              <1> ;	jmp	error
  3433                              <1> ;/ejec:
  3434                              <1> ;/       mov    $100,*$lps / set line printer interrupt enable bit
  3435                              <1> ;/       mov    $14,r1 / 'form feed' character in r1 (new page).
  3436                              <1> ;/       jsr    r0,lptoc / space the printer to a new page
  3437                              <1> ;/       br     sret / return to caller via 'sret'
  3438                              <1> 
  3439                              <1> ejec:
  3440                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 - Printer Initialization
  3441                              <1> lpt_init:	
  3442                              <1> 	; Ref: IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985
  3443                              <1> 	;
  3444                              <1> 	; Default printer port: 378h ; LPT1
  3445                              <1> 	
  3446 00005814 B401                <1>  	mov	ah, 1  ; INITIALIZE THE PRINTER PORT
  3447                              <1> 	;call	int17h
  3448 00005816 E846FAFFFF          <1> 	call	PRNOP
  3449 0000581B 7414                <1> 	jz	short lpt_init_ok
  3450                              <1> 	
  3451                              <1> 	; replace error code with 'device not ready' error
  3452                              <1> 	; (this may be better for 'sysopen')
  3453 0000581D B80F000000          <1> 	mov	eax, ERR_PRN_NOT_RDY
  3454 00005822 A3[B86C0000]        <1> 	mov	[u.error], eax
  3455                              <1> 	;jmp	sysret ; (may be) ? ([u.r0] = file descriptor)
  3456 00005827 A3[446C0000]        <1> 	mov	[u.r0], eax
  3457 0000582C E916D9FFFF          <1> 	jmp	error ; (better)	
  3458                              <1> 	
  3459                              <1> lpt_init_ok:
  3460                              <1> 	;jmp	short cret
  3461 00005831 58                  <1> 	pop	eax    ; inode number
  3462 00005832 C3                  <1> 	retn
  3463                              <1> 	
  2096                                  %include 'u8.s'      ; 11/06/2015
  2097                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2098                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2099                              <1> ; ****************************************************************************
  2100                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - SYS8.INC
  2101                              <1> ; Last Modification: 19/07/2022
  2102                              <1> ; ----------------------------------------------------------------------------
  2103                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2104                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2105                              <1> ;
  2106                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2107                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2108                              <1> ; <Bell Laboratories (17/3/1972)>
  2109                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2110                              <1> ;
  2111                              <1> ; Retro UNIX 8086 v1 - U8.ASM (18/01/2014) //// UNIX v1 -> u8.s
  2112                              <1> ;
  2113                              <1> ; ****************************************************************************
  2114                              <1> 
  2115                              <1> ; 15/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2116                              <1> ; 15/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
  2117                              <1> ; 14/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
  2118                              <1> ;---------------------------------------------------------------------
  2119                              <1> ; Buffer Header: -8 bytes-
  2120                              <1> ; word 1 - byte 0 - device (disk index) number (0 to 5)
  2121                              <1> ;	   byte 1 - status bits
  2122                              <1> ;	 	bit 0 - valid buffer bit (1 = valid, 0 = invalid, new)
  2123                              <1> ;		bit 1 - write bit (also modified bit)
  2124                              <1> ;		bit 2 - read bit	
  2125                              <1> ;		bit 3 to bit 7 are not used
  2126                              <1> ; word 2 - byte & byte 3 not used
  2127                              <1> ; word 3 & word 4 - byte 3, byte 5, byte 6, byte 7:
  2128                              <1> ;		physical block/sector address (32 bit LBA)
  2129                              <1> ;---------------------------------------------------------------------
  2130                              <1> 
  2131                              <1> ;; I/O Buffer - Retro UNIX 386 v1 modification
  2132                              <1> ;;     (8+512 bytes, 8 bytes header, 512 bytes data)
  2133                              <1> ;; Word 1, byte 0 = device id
  2134                              <1> ;; Word 1, byte 1 = status bits (bits 8 to 15)
  2135                              <1> ;;          bit 9 = write bit
  2136                              <1> ;;	    bit 10 = read bit	  
  2137                              <1> ;;	    bit 12 = waiting to write bit	
  2138                              <1> ;;	    bit 13 = waiting to read bit
  2139                              <1> ;;	    bit 15 = inhibit bit
  2140                              <1> ;; Word 2 (byte 2 & byte 3) = reserved (for now - 07/06/2015)
  2141                              <1> ;; Word 3 + Word 4 (byte 4,5,6,7) = physical block number 
  2142                              <1> ;;		   (In fact, it is 32 bit LBA for Retro UNIX 386 v1)
  2143                              <1> ;;
  2144                              <1> ;; I/O Buffer ((8+512 bytes in original Unix v1))
  2145                              <1> ;;	      ((4+512 bytes in Retro UNIX 8086 v1))
  2146                              <1> ;;
  2147                              <1> ;; I/O Queue Entry (of original UNIX operating system v1)
  2148                              <1> ;; Word 1, Byte 0 = device id
  2149                              <1> ;; Word 1, Byte 1 = (bits 8 to 15)
  2150                              <1> ;;          bit 9 = write bit
  2151                              <1> ;;	    bit 10 = read bit	  
  2152                              <1> ;;	    bit 12 = waiting to write bit	
  2153                              <1> ;;	    bit 13 = waiting to read bit
  2154                              <1> ;;	    bit 15 = inhibit bit
  2155                              <1> ;; Word 2 = physical block number (In fact, it is LBA for Retro UNIX 8086 v1)
  2156                              <1> ;;
  2157                              <1> ;; Original UNIX v1 ->
  2158                              <1> ;;		Word 3 = number of words in buffer (=256) 		
  2159                              <1> ;; Original UNIX v1 -> 
  2160                              <1> ;;		Word 4 = bus address (addr of first word of data buffer)
  2161                              <1> ;;
  2162                              <1> ;; Retro UNIX 8086 v1 -> Buffer Header (I/O Queue Entry) size is 4 bytes !
  2163                              <1> ;;
  2164                              <1> ;; Device IDs (of Retro Unix 8086 v1)
  2165                              <1> ;;          0 = fd0
  2166                              <1> ;;	    1 = fd1
  2167                              <1> ;;	    2 = hd0
  2168                              <1> ;;	    3 = hd1
  2169                              <1> ;;	    4 = hd2
  2170                              <1> ;;	    5 = hd3
  2171                              <1> 
  2172                              <1> ; Retro UNIX 386 v1 - 32 bit modifications (rfd, wfd, rhd, whd) - 09/06/2015
  2173                              <1> 
  2174                              <1> 	; 08/02/2022
  2175                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
  2176                              <1> rfd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2177                              <1> 	; 26/04/2013
  2178                              <1>    	; 13/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
  2179                              <1>    	;sub 	ax, 3 ; zero based device number (Floppy disk)
  2180                              <1>       	;jmp 	short bread ; **** returns to routine that called readi			
  2181                              <1> 
  2182                              <1> 	; 08/02/2022
  2183                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
  2184                              <1> rhd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2185                              <1> 	; 26/04/2013
  2186                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
  2187                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
  2188                              <1>    	;jmp	short bread ; **** returns to routine that called readi	
  2189                              <1> 
  2190                              <1> bread: 
  2191                              <1> 	; 19/07/2022
  2192                              <1> 	; 15/07/2022
  2193                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2194                              <1> 	; 08/02/2022
  2195                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
  2196                              <1> 	; 14/07/2015
  2197                              <1> 	; 10/07/2015
  2198                              <1> 	; 09/06/2015
  2199                              <1> 	; 07/06/2015 (Retro UNIX 386 v1 - Beginning)
  2200                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
  2201                              <1> 	;	
  2202                              <1> 	; / read a block from a block structured device
  2203                              <1> 	;
  2204                              <1> 	; INPUTS ->
  2205                              <1> 	;    [u.fopf] points to the block number
  2206                              <1> 	;    ECX = maximum block number allowed on device
  2207                              <1> 	;	 ; that was an arg to bread, in original Unix v1, but
  2208                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
  2209                              <1> 	;    [u.count] number of bytes to read in
  2210                              <1> 	; OUTPUTS ->
  2211                              <1> 	;    [u.base] starting address of data block or blocks in user area  	
  2212                              <1> 	;    [u.fopf] points to next consecutive block to be read
  2213                              <1> 	;
  2214                              <1> 	; ((Modified registers: eax, edx, ecx, ebx, esi, edi))
  2215                              <1> 	;
  2216                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if read
  2217                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
  2218                              <1> 	;	is increased by 1. For example: If user/program request 
  2219                              <1> 	;       to read 16 bytes in current block, 'sys read' increases
  2220                              <1> 	;  	the next block number just as 512 byte reading is done.
  2221                              <1> 	;       This wrong is done in 'bread'. So, in Retro UNIX 8086 v1, 
  2222                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
  2223                              <1> 	;       enough to keep byte position/offset of the disk), this
  2224                              <1> 	;	defect will not be corrected, user/program must request
  2225                              <1> 	;	512 byte read per every 'sys read' call to block devices
  2226                              <1> 	;       for achieving correct result. In future version(s), 
  2227                              <1> 	;	this defect will be corrected by using different 
  2228                              <1> 	;       user (u) structure. 26/07/2013 - Erdogan Tan 	
  2229                              <1> 
  2230                              <1> 	   	; jsr r0,tstdeve / error on special file I/O 
  2231                              <1> 			       ; / (only works on tape)
  2232                              <1> 		; mov *u.fofp,r1 / move block number to r1
  2233                              <1> 		; mov $2.-cold,-(sp) / "2-cold" to stack
  2234                              <1> ;1:
  2235                              <1> 		; cmp r1,(r0) / is this block # greater than or equal to
  2236                              <1> 			    ; / maximum block # allowed on device
  2237                              <1> 		; jnb short @f
  2238                              <1> 		; bhis	1f / yes, 1f (error)
  2239                              <1> 		; mov r1,-(sp) / no, put block # on stack
  2240                              <1> 		; jsr r0,preread / read in the block into an I/O buffer
  2241                              <1> 		; mov (sp)+,r1 / return block # to r1
  2242                              <1> 		; inc r1 / bump block # to next consecutive block
  2243                              <1> 		; dec (sp) / "2-1-cold" on stack
  2244                              <1> 		; bgt 1b / 2-1-cold = 0? No, go back and read in next block
  2245                              <1> ;1:
  2246                              <1> 		; tst (sp)+ / yes, pop stack to clear off cold calculation
  2247                              <1> 	;push	ecx ; **
  2248                              <1> 	; 26/04/2013
  2249                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
  2250 00005833 2C03                <1> 	sub	al, 3
  2251                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
  2252 00005835 A2[B76C0000]        <1> 	mov	[u.brwdev], al
  2253                              <1> 	; 09/06/2015
  2254                              <1> 	;movzx	ebx, al
  2255                              <1> 	;mov	ecx, [ebx+drv.size] ; disk size (in sectors)
  2256                              <1> 	; 12/01/2022 (BugFix)
  2257 0000583A C0E002              <1> 	shl	al, 2 ; * 4
  2258 0000583D 8B88[32620000]      <1> 	mov	ecx, [eax+drv.size] ; disk size (in sectors)
  2259                              <1> bread_0:
  2260 00005843 51                  <1> 	push	ecx ; ** ; 09/06/2015 
  2261                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
  2262                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
  2263 00005844 8B1D[586C0000]      <1> 	mov	ebx, [u.fofp]
  2264 0000584A 8B03                <1> 	mov	eax, [ebx]
  2265 0000584C C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
  2266                              <1> 		; mov *u.fofp,r1 / restore r1 to initial value of the
  2267                              <1> 			       ; / block #
  2268 0000584F 39C8                <1> 	cmp	eax, ecx
  2269                              <1> 		; cmp r1,(r0)+ / block # greater than or equal to maximum
  2270                              <1>        	                     ; / block number allowed
  2271                              <1> 	;jnb	error 	     ; 18/04/2013
  2272                              <1> 		; bhis error10 / yes, error
  2273                              <1> 	; 08/02/2022
  2274                              <1> 	;jb	short bread_1
  2275                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
  2276                              <1> 	;jmp	error
  2277 00005851 7346                <1> 	jnb	short brw_oov_err ; 'out of volume' error
  2278                              <1> bread_1:
  2279                              <1> 	;inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
  2280                              <1> 		; inc *u.fofp / no, *u.fofp has next block number
  2281                              <1> 	; EAX = Block number (zero based)
  2282                              <1> 		;;jsr r0,preread / read in the block whose number is in r1
  2283                              <1> preread: ;; call preread
  2284 00005853 BF[B76C0000]        <1> 	mov	edi, u.brwdev ; block device number for direct I/O
  2285 00005858 E8E1010000          <1> 	call	bufaloc_0 ; 26/04/2013
  2286                              <1> 	;; jc 	error
  2287                              <1> 	; EBX = Buffer (Header) Address -Physical-
  2288                              <1>         ; EAX = Block/Sector number (r1)
  2289                              <1> 	       ; jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
  2290                              <1> 	; 14/03/2013
  2291 0000585D 7411                <1>         jz	short bread_2 ; Retro UNIX 8086 v1 modification
  2292                              <1>        		; br 1f / branch if block already in a I/O buffer
  2293 0000585F 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
  2294                              <1>         	; bis $2000,(r5) / set read bit (bit 10 in I/O buffer)
  2295 00005864 E8AD010000          <1> 	call	poke
  2296                              <1>         	; jsr r0,poke / perform the read
  2297                              <1> 	;;jc	error ;2 0/07/2013
  2298                              <1> ; 1:
  2299                              <1>  		; clr *$ps / ps = 0
  2300                              <1>         	; rts r0
  2301                              <1> 	; 08/02/2022
  2302 00005869 7305                <1> 	jnc	short bread_2
  2303 0000586B E919010000          <1> 	jmp	dskrd_err
  2304                              <1> 	;
  2305                              <1> ;; return from preread
  2306                              <1> bread_2:
  2307                              <1> 	; 15/07/2022
  2308                              <1> 	;or	word [ebx], 4000h 
  2309                              <1> 	;	; bis $40000,(r5) 
  2310                              <1> 	;		; / set bit 14 of the 1st word of the I/O buffer
  2311                              <1> bread_3: ; 1:
  2312                              <1> 	; 15/07/2022
  2313                              <1> 	;test	word [ebx], 2400h
  2314                              <1> 	;	; bit $22000,(r5) / are 10th and 13th bits set (read bits)
  2315                              <1> 	;jz	short bread_4
  2316                              <1> 	;	; beq 1f / no
  2317                              <1> 	;	; cmp cdev,$1 / disk or drum?
  2318                              <1> 	;	; ble 2f / yes
  2319                              <1> 	;	; tstb uquant / is the time quantum = 0?
  2320                              <1> 	;	; bne 2f / no, 2f
  2321                              <1> 	;	; mov r5,-(sp) / yes, save r5 (buffer address)
  2322                              <1> 	;	; jsr r0,sleep; 31. 
  2323                              <1> 	;		; / put process to sleep in channel 31 (tape)
  2324                              <1> 	;	; mov (sp)+,r5 / restore r5
  2325                              <1> 	;	; br 1b / go back
  2326                              <1> ; 2: / drum or disk
  2327                              <1>         ;; mov     cx, [s.wait_]+2 ;; 29/07/2013
  2328                              <1> 	;call	idle
  2329                              <1> 	;	; jsr r0,idle; s.wait+2 / wait
  2330                              <1> 	;jmp	short bread_3
  2331                              <1>        	;	; br 1b
  2332                              <1> bread_4: ; 1: / 10th and 13th bits not set
  2333                              <1> 	;and	word [ebx], 0BFFFh ; 1011111111111111b
  2334                              <1> 	;	; bic $40000,(r5) / clear bit 14
  2335                              <1>        	;	; jsr r0,tstdeve / test device for error (tape)
  2336                              <1> 	; 15/07/2022
  2337 00005870 83C308              <1> 	add	ebx, 8
  2338                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
  2339                              <1> 	; 09/06/2015
  2340 00005873 66833D[B06C0000]00  <1> 	cmp	word [u.pcount], 0
  2341 0000587B 7705                <1> 	ja	short bread_5
  2342 0000587D E8FCF7FFFF          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
  2343                              <1> bread_5:
  2344                              <1> 	; EBX = system (I/O) buffer address
  2345 00005882 E87C000000          <1> 	call	dioreg
  2346                              <1>        		; jsr r0,dioreg / do bookkeeping on u.count etc.
  2347                              <1> 
  2348                              <1> 	; 19/07/2022
  2349                              <1> 	; EDI = user data offset (previous value of [u.pbase])
  2350                              <1> 	; ESI = pointer to file offset 
  2351                              <1> 	; EAX = system (I/O) buffer offset (>= EBX)
  2352                              <1> 	; ECX = byte count
  2353                              <1> 	; EBX = system buffer (data) address
  2354                              <1> 
  2355                              <1> 	; 19/07/2022
  2356 00005887 010E                <1> 	add	[esi], ecx ; new file (disk) offset
  2357 00005889 89C6                <1> 	mov	esi, eax
  2358                              <1> 
  2359                              <1> 	; esi = start address of the transfer (in the buffer)
  2360                              <1> 	; edi = [u.pbase], destination address in user's memory space
  2361                              <1> 	; ecx = transfer count (in bytes)
  2362                              <1> 	;
  2363                              <1> ;1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
  2364                              <1> ;   / of users data
  2365 0000588B F3A4                <1> 	rep	movsb
  2366                              <1> 		; movb (r5)+,(r2)+ / move data from the I/O buffer
  2367                              <1>        		; dec r3 / to the user's area in core starting at u.base
  2368                              <1>        		; bne 1b
  2369 0000588D 59                  <1> 	pop	ecx ; **
  2370 0000588E 833D[6C6C0000]00    <1> 	cmp	dword [u.count], 0
  2371                              <1> 		; tst u.count / done
  2372 00005895 77AC                <1> 	ja	short bread_0 ; 09/06/2015
  2373                              <1>        		; beq 1f / yes, return
  2374                              <1> 		; tst -(r0) / no, point r0 to the argument again
  2375                              <1>        		; br bread / read some more
  2376                              <1> ; 1:
  2377 00005897 58                  <1> 	pop	eax ; ****
  2378                              <1>        		; mov (sp)+,r0
  2379 00005898 C3                  <1>         retn		; 09/06/2015
  2380                              <1> 	;jmp	ret_ 
  2381                              <1> 		;jmp ret / jump to routine that called readi
  2382                              <1> 
  2383                              <1> 	; 08/02/2022
  2384                              <1> brw_oov_err:
  2385 00005899 C705[B86C0000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
  2385 000058A1 0000                <1>
  2386 000058A3 E99FD8FFFF          <1> 	jmp	error
  2387                              <1> 
  2388                              <1> 	; 08/02/2022
  2389                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
  2390                              <1> wfd:    ; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2391                              <1> 	; 26/04/2013
  2392                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
  2393                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
  2394                              <1>    	;jmp	short bwrite ; **** returns to routine that called writei
  2395                              <1> 
  2396                              <1> 	; 08/02/2022
  2397                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)				
  2398                              <1> whd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2399                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
  2400                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
  2401                              <1>    	;jmp 	short bwrite ; **** returns to routine that called writei ('jmp ret')
  2402                              <1> 
  2403                              <1> bwrite:
  2404                              <1> 	; 19/07/2022
  2405                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
  2406                              <1> 	; 15/07/2022
  2407                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3) 
  2408                              <1> 	; 08/02/2022
  2409                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
  2410                              <1> 	; 14/07/2015
  2411                              <1> 	; 10/07/2015
  2412                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2413                              <1> 	; 14/03/2013 - 20/07/2013 (Retro UNIX 8086 v1)
  2414                              <1> 	;	
  2415                              <1> 	;; / write on block structured device
  2416                              <1> 	;
  2417                              <1> 	; INPUTS ->
  2418                              <1> 	;    [u.fopf] points to the block number
  2419                              <1> 	;    ECX = maximum block number allowed on device
  2420                              <1> 	;	 ; that was an arg to bwrite, in original Unix v1, but
  2421                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
  2422                              <1> 	;    [u.count]	number of bytes to user desires to write
  2423                              <1> 	; OUTPUTS ->
  2424                              <1> 	;    [u.fopf] points to next consecutive block to be written into
  2425                              <1> 	;
  2426                              <1> 	; ((Modified registers: edx, ecx, ebx, esi, edi))
  2427                              <1> 	;
  2428                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if write
  2429                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
  2430                              <1> 	;	is increased by 1. For example: If user/program request 
  2431                              <1> 	;       to write 16 bytes in current block, 'sys write' increases
  2432                              <1> 	;  	the next block number just as 512 byte writing is done.
  2433                              <1> 	;       This wrong is done in 'bwrite'. So, in Retro UNIX 8086 v1, 
  2434                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
  2435                              <1> 	;       enough to keep byte position/offset of the disk), this
  2436                              <1> 	;	defect will not be corrected, user/program must request
  2437                              <1> 	;	512 byte write per every 'sys write' call to block devices
  2438                              <1> 	;       for achieving correct result. In future version(s), 
  2439                              <1> 	;	this defect will be corrected by using different 
  2440                              <1> 	;       user (u) structure. 26/07/2013 - Erdogan Tan 	
  2441                              <1> 
  2442                              <1>        		; jsr r0,tstdeve / test the device for an error
  2443                              <1> 	;push	ecx ; **
  2444                              <1> 	;26/04/2013
  2445                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
  2446 000058A8 2C03                <1> 	sub	al, 3
  2447                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
  2448 000058AA A2[B76C0000]        <1> 	mov	[u.brwdev], al
  2449                              <1> 	; 09/06/2015
  2450                              <1> 	;movzx	ebx, al
  2451                              <1> 	;mov	ecx, [ebx+drv.size] ; disk size (in sectors)
  2452                              <1> 	; 12/01/2022 (BugFix)
  2453 000058AF C0E002              <1> 	shl	al, 2 ; * 4
  2454 000058B2 8B88[32620000]      <1> 	mov	ecx, [eax+drv.size] ; disk size (in sectors)
  2455                              <1> bwrite_0:
  2456 000058B8 51                  <1> 	push	ecx ; ** ; 09/06/2015
  2457                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
  2458                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
  2459 000058B9 8B1D[586C0000]      <1> 	mov	ebx, [u.fofp]
  2460 000058BF 8B03                <1> 	mov	eax, [ebx]       
  2461 000058C1 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
  2462                              <1> 		; mov *u.fofp,r1 / put the block number in r1
  2463 000058C4 39C8                <1> 	cmp	eax, ecx
  2464                              <1> 		; cmp r1,(r0)+ / does block number exceed maximum allowable #
  2465                              <1>        	                     ; / block number allowed
  2466                              <1> 	;jnb	error	     ; 18/04/2013
  2467                              <1> 		; bhis error10 / yes, error
  2468                              <1>      	; 08/02/2022
  2469                              <1> 	;jb	short bwrite_1
  2470                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
  2471                              <1> 	;jmp	error
  2472 000058C6 73D1                <1> 	jnb	short brw_oov_err ; 'out of volume' error
  2473                              <1> bwrite_1:
  2474                              <1> 	;inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
  2475                              <1> 		; inc *u.fofp / no, increment block number
  2476                              <1> 	; 09/06/2015 - 10/07/2015
  2477 000058C8 66833D[B06C0000]00  <1> 	cmp	word [u.pcount], 0
  2478 000058D0 7705                <1> 	ja	short bwrite_2
  2479 000058D2 E8A3F7FFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
  2480                              <1> bwrite_2:
  2481 000058D7 BF[B76C0000]        <1> 	mov	edi, u.brwdev  ; block device number for direct I/O
  2482 000058DC E8C9000000          <1>        	call	bwslot ; 26/04/2013 (wslot -> bwslot)	 				
  2483                              <1> 		; jsr r0,wslot / get an I/O buffer to write into
  2484                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
  2485 000058E1 E81D000000          <1>         call	dioreg
  2486                              <1> 		; jsr r0,dioreg / do the necessary bookkeeping
  2487                              <1> 
  2488                              <1> 	; 19/07/2022
  2489                              <1> 	; EDI = user data offset (previous value of [u.pbase])
  2490                              <1> 	; ESI = pointer to file offset 
  2491                              <1> 	; EAX = system (I/O) buffer offset (>= EBX)
  2492                              <1> 	; ECX = byte count
  2493                              <1> 	; EBX = system buffer (data) address
  2494                              <1> 
  2495                              <1> 	; 19/07/2022 - Erdogan Tan
  2496                              <1> 	; ((Against a possible disk write failure/error, 
  2497                              <1> 	;   file offset must not be updated/increased before 'dskwr'
  2498                              <1> 	;   but it was updated in 'dioreg'. I have modified 'dioreg'
  2499                              <1> 	;   and 'bwrite' procedures for that.))
  2500                              <1> 
  2501                              <1> 	; 19/07/2022
  2502 000058E6 56                  <1> 	push	esi ; (!)  ; save file offset (pointer)
  2503 000058E7 51                  <1> 	push	ecx ; (!!) ; save byte count
  2504                              <1> 	;mov	esi, eax
  2505                              <1> 	
  2506                              <1> 	; esi = destination address (in the buffer)
  2507                              <1> 	; edi = [u.pbase], start address of transfer in user's memory space
  2508                              <1> 	; ecx = transfer count (in bytes)
  2509                              <1> ; 1: / r2 points to the users data; r5 points to the I/O buffers data area
  2510                              <1> 	;xchg 	esi, edi ; 14/07/2015
  2511                              <1> 
  2512                              <1> 	; 19/07/2022
  2513 000058E8 89FE                <1> 	mov	esi, edi
  2514 000058EA 89C7                <1> 	mov	edi, eax
  2515                              <1> 
  2516 000058EC F3A4                <1> 	rep	movsb
  2517                              <1> 		; movb (r2)+,(r5)+ / ; r3, has the byte count
  2518                              <1>        		; dec r3 / area to the I/O buffer
  2519                              <1>        		; bne 1b
  2520                              <1> 
  2521 000058EE E8F0000000          <1> 	call	dskwr
  2522                              <1> 		; jsr r0,dskwr / write it out on the device
  2523                              <1> 
  2524                              <1> 	; 19/07/2022
  2525                              <1> 	; (there is not a disk write error, we can increase file offset)
  2526 000058F3 58                  <1> 	pop	eax ; (!!) ; byte count
  2527 000058F4 5F                  <1> 	pop	edi ; (!)  ; file offset (pointer)
  2528                              <1> 	;
  2529 000058F5 0107                <1> 	add	[edi], eax ; new file offset (old offset + byte count)
  2530                              <1> 
  2531 000058F7 59                  <1> 	pop	ecx ; **
  2532                              <1> 
  2533 000058F8 833D[6C6C0000]00    <1>         cmp     dword [u.count], 0
  2534                              <1> 		; tst u.count / done
  2535 000058FF 77B7                <1> 	ja	short bwrite_0 ; 09/06/2015
  2536                              <1> 		; beq 1f / yes, 1f
  2537                              <1> 		; tst -(r0) / no, point r0 to the argument of the call
  2538                              <1>        		; br bwrite / go back and write next block
  2539                              <1> ; 1:
  2540 00005901 58                  <1> 	pop	eax ; ****
  2541                              <1>        		; mov (sp)+,r0
  2542 00005902 C3                  <1> 	retn		; 09/06/2015
  2543                              <1>         ;jmp	ret_ 
  2544                              <1> 		; jmp ret / return to routine that called writei
  2545                              <1> ;error10:
  2546                              <1> ;       jmp     error  ; / see 'error' routine
  2547                              <1> 
  2548                              <1> dioreg:
  2549                              <1> 	; 19/07/2022
  2550                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
  2551                              <1> 	;
  2552                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
  2553                              <1> 	; 14/07/2015
  2554                              <1> 	; 10/07/2015 (UNIX v1 bugfix - [u.fofp]: byte pos., not block)
  2555                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2556                              <1> 	; 14/03/2013 (Retro UNIX 8086 v1)
  2557                              <1> 	;	
  2558                              <1> 	; bookkeeping on block transfers of data
  2559                              <1> 	;
  2560                              <1> 	; * returns value of u.pbase before it gets updated, in EDI
  2561                              <1> 	; * returns byte count (to transfer) in ECX (<=512)
  2562                              <1> 	; 10/07/2015
  2563                              <1> 	; * returns byte offset from beginning of current sector buffer
  2564                              <1> 	; (beginning of data) in ESI
  2565                              <1> 
  2566                              <1> 	; 19/07/2022
  2567                              <1> 	; OUTPUTS:
  2568                              <1> 	;   EDI = user data offset (previous value of [u.pbase])
  2569                              <1> 	;   ESI = pointer to file offset 
  2570                              <1> 	;   EAX = system (I/O) buffer offset
  2571                              <1> 	;   ECX = byte count
  2572                              <1> 	;   EBX = system buffer (data) address	
  2573                              <1> 
  2574 00005903 8B0D[6C6C0000]      <1> 	mov	ecx, [u.count]
  2575                              <1> 		; mov u.count,r3 / move char count to r3
  2576                              <1> 	; 08/02/2022
  2577 00005909 31D2                <1> 	xor	edx, edx
  2578 0000590B B602                <1> 	mov	dh, 2
  2579                              <1> 	; edx = 512
  2580 0000590D 39D1                <1> 	cmp	ecx, edx ; 512
  2581                              <1> 	;cmp 	ecx, 512
  2582                              <1> 		; cmp r3,$512. / more than 512. char?
  2583 0000590F 7602                <1> 	jna	short dioreg_0
  2584                              <1> 		; blos 1f / no, branch
  2585 00005911 89D1                <1> 	mov	ecx, edx ; 512
  2586                              <1> 	;mov	ecx, 512
  2587                              <1> 		; mov $512.,r3 / yes, just take 512.
  2588                              <1> dioreg_0:
  2589                              <1> 	; 09/06/2015
  2590 00005913 663B0D[B06C0000]    <1> 	cmp	cx, [u.pcount]
  2591 0000591A 7607                <1> 	jna	short dioreg_1
  2592 0000591C 668B0D[B06C0000]    <1> 	mov	cx, [u.pcount]
  2593                              <1> dioreg_1:
  2594                              <1> ; 1:
  2595 00005923 8B15[686C0000]      <1> 	mov	edx, [u.base] ; 09/06/2015 (eax -> edx)
  2596                              <1> 	        ; mov u.base,r2 / put users base in r2
  2597 00005929 010D[706C0000]      <1> 	add	[u.nread], ecx
  2598                              <1> 		; add r3,u.nread / add the number to be read to u.nread
  2599 0000592F 290D[6C6C0000]      <1> 	sub	[u.count], ecx
  2600                              <1> 		; sub r3,u.count / update count
  2601 00005935 010D[686C0000]      <1> 	add	[u.base], ecx
  2602                              <1> 		; add r3,u.base / update base
  2603                              <1> 	; 10/07/2015
  2604                              <1> 	; Retro UNIX 386 v1 - modification !
  2605                              <1> 	; (File pointer points to byte position, not block/sector no.)
  2606                              <1> 	; (It will point to next byte position instead of next block no.)
  2607 0000593B 8B35[586C0000]      <1> 	mov	esi, [u.fofp] ; u.fopf points to byte position pointer  
  2608 00005941 8B06                <1> 	mov	eax, [esi] ; esi points to current byte pos. on the disk
  2609                              <1> 	; 19/07/2022
  2610                              <1> 	;add	[esi], ecx ; ecx is added to set the next byte position
  2611 00005943 25FF010000          <1> 	and	eax, 1FFh  ; get offset from beginning of current block	
  2612                              <1> 	;mov	esi, ebx   ; beginning of data in sector/block buffer
  2613                              <1> 	;add	esi, eax   ; esi contains start address of the transfer
  2614                              <1> 	; 19/07/2022
  2615 00005948 01D8                <1> 	add	eax, ebx   ; eax contains start address of the transfer	
  2616                              <1> 	; 09/06/2015 - 10/07/2015
  2617 0000594A 66290D[B06C0000]    <1> 	sub	[u.pcount], cx
  2618 00005951 81E2FF0F0000        <1> 	and	edx, PAGE_OFF ; 0FFFh
  2619 00005957 8B3D[AC6C0000]      <1> 	mov	edi, [u.pbase]
  2620 0000595D 81E700F0FFFF        <1> 	and	edi, ~PAGE_OFF
  2621 00005963 01D7                <1> 	add	edi, edx
  2622 00005965 893D[AC6C0000]      <1> 	mov	[u.pbase], edi
  2623 0000596B 010D[AC6C0000]      <1> 	add	[u.pbase], ecx ; 14/07/2015
  2624 00005971 C3                  <1> 	retn
  2625                              <1> 		; rts r0 / return
  2626                              <1> 
  2627                              <1> dskrd:
  2628                              <1> 	; 15/07/2022
  2629                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2630                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
  2631                              <1> 	; 18/08/2015
  2632                              <1> 	; 02/07/2015
  2633                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2634                              <1> 	; 14/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
  2635                              <1> 	;
  2636                              <1> 	; 'dskrd' acquires an I/O buffer, puts in the proper
  2637                              <1> 	; I/O queue entries (via bufaloc) then reads a block
  2638                              <1> 	; (number specified in r1) in the acquired buffer.)
  2639                              <1> 	; If the device is busy at the time dskrd is called,	
  2640                              <1> 	; dskrd calls idle.
  2641                              <1> 	; 
  2642                              <1> 	; INPUTS ->
  2643                              <1> 	;    r1 - block number
  2644                              <1> 	;    cdev - current device number 
  2645                              <1> 	; OUTPUTS ->
  2646                              <1> 	;    r5 - points to first data word in I/O buffer
  2647                              <1> 	;
  2648                              <1> 	; ((AX = R1)) input/output
  2649                              <1> 	; ((BX = R5)) output 
  2650                              <1> 	;
  2651                              <1>         ; ((Modified registers: edx, ecx, ebx, esi, edi))  
  2652                              <1> 	;
  2653 00005972 E8BA000000          <1> 	call 	bufaloc
  2654                              <1> 		; jsr r0,bufaloc / shuffle off to bufaloc; 
  2655                              <1> 			       ; / get a free I/O buffer
  2656                              <1> 	;;jc	error ; 20/07/2013
  2657 00005977 740C                <1> 	jz	short dskrd_1 ; Retro UNIX 8086 v1 modification
  2658                              <1>        		; br 1f / branch if block already in a I/O buffer
  2659                              <1> 	
  2660                              <1> 	; 15/07/2022
  2661                              <1> 	; (buffer header byte 1, bit 2 is disk read bit/flag)
  2662                              <1> dskrd_0:
  2663                              <1> 	; 10/07/2015 (wslot)
  2664 00005979 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
  2665                              <1>         	; bis $2000,(r5) / set bit 10 of word 1 of 
  2666                              <1> 		               ; / I/O queue entry for buffer
  2667 0000597E E893000000          <1> 	call	poke
  2668                              <1> 		; jsr r0,poke / just assigned in bufaloc, 
  2669                              <1> 			    ; /	bit 10=1 says read
  2670                              <1> 	; 09/06/2015
  2671                              <1> 	;jnc	short dskrd_1
  2672                              <1> 	;mov	dword [u.error], ERR_DRV_READ ; disk read error !
  2673                              <1> 	;jmp	error
  2674                              <1> 	; 08/02/2022
  2675 00005983 7204                <1> 	jc	short dskrd_3
  2676                              <1> dskrd_1: ; 1:
  2677                              <1>        	; 15/07/2022
  2678                              <1> 	;
  2679                              <1> 	;	;clr *$ps
  2680                              <1>        	;test	word [ebx], 2400h
  2681                              <1> 	;	; bit $22000,(r5) / if either bits 10, or 13 are 1; 
  2682                              <1> 	;			; / jump to idle
  2683                              <1>        	;jz	short dskrd_2
  2684                              <1> 	;	; beq 1f
  2685                              <1>         ;;;mov   ecx, [s.wait_]
  2686                              <1>        	;call	idle
  2687                              <1> 	;	; jsr r0,idle; s.wait+2
  2688                              <1> 	;jmp 	short dskrd_1
  2689                              <1>        	;	; br 1b
  2690                              <1> dskrd_2: ; 1:
  2691 00005985 83C308              <1>         add	ebx, 8
  2692                              <1> 		; add $8,r5 / r5 points to first word of data in block 
  2693                              <1> 			  ; / just read in
  2694 00005988 C3                  <1>        	retn
  2695                              <1> 		; rts r0
  2696                              <1> dskrd_err: 
  2697                              <1> 	; 08/02/2022
  2698                              <1> 	; (jump from 'bread' error)	
  2699                              <1> dskrd_3:	
  2700                              <1> 	; 08/02/2022
  2701 00005989 803D[B76C0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
  2702 00005990 7509                <1> 	jne	short dskrd_4 ; no
  2703                              <1> 	; yes, clear [u.brwdev] for next check and jump to 'error'
  2704 00005992 C605[B76C0000]00    <1> 	mov	byte [u.brwdev], 0
  2705 00005999 EB0A                <1> 	jmp	short dskrd_5
  2706                              <1> dskrd_4:
  2707 0000599B C705[B86C0000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; disk read error !
  2707 000059A3 0000                <1>
  2708                              <1> dskrd_5:
  2709 000059A5 E99DD7FFFF          <1> 	jmp	error
  2710                              <1> 
  2711                              <1> bwslot:
  2712                              <1> 	; 15/07/2022
  2713                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2714                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
  2715                              <1> 	; 10/07/2015
  2716                              <1> 	;	If the block/sector is not placed in a buffer
  2717                              <1> 	;	before 'wslot', it must be read before
  2718                              <1> 	;	it is written! (Otherwise transfer counts less
  2719                              <1> 	;	than 512 bytes will be able to destroy existing 
  2720                              <1> 	;	data on disk.)
  2721                              <1> 	;
  2722                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
  2723                              <1> 	; 26/04/2013(Retro UNIX 8086 v1)
  2724                              <1> 	; Retro UNIX 8086 v1 modification !
  2725                              <1> 	; ('bwslot' will be called from 'bwrite' only!)
  2726                              <1> 	; INPUT -> EDI - points to device id (in u.brwdev)	
  2727                              <1> 	;	-> EAX = block number
  2728                              <1> 	;
  2729 000059AA E88F000000          <1> 	call	bufaloc_0
  2730 000059AF 742A                <1> 	jz	short wslot_0 ; block/sector already is in the buffer
  2731                              <1> 	; 12/01/2022
  2732                              <1> 	; ebx = buffer header address
  2733                              <1> bwslot_0:
  2734                              <1> 	; 10/07/2015
  2735 000059B1 8B35[586C0000]      <1> 	mov	esi, [u.fofp]
  2736 000059B7 8B06                <1> 	mov	eax, [esi]
  2737 000059B9 25FF010000          <1> 	and	eax, 1FFh ; offset from beginning of the sector/block
  2738 000059BE 750C                <1> 	jnz 	short bwslot_1 ; it is not a full sector write
  2739                              <1> 		       ; recent disk data must be placed in the buffer
  2740 000059C0 813D[6C6C0000]0002- <1> 	cmp	dword [u.count], 512
  2740 000059C8 0000                <1>
  2741 000059CA 730F                <1> 	jnb	short wslot_0	
  2742                              <1> bwslot_1:
  2743 000059CC E8A8FFFFFF          <1> 	call	dskrd_0
  2744                              <1> 	; 12/01/2022
  2745                              <1> 	; ebx = buffer data address = buffer header addr + 8
  2746 000059D1 83EB08              <1> 	sub	ebx, 8 ; set ebx to the buffer header address again	
  2747 000059D4 EB05                <1> 	jmp 	short wslot_0
  2748                              <1> 
  2749                              <1> wslot:
  2750                              <1> 	; 16/07/2022
  2751                              <1> 	; 15/07/2022
  2752                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2753                              <1> 	;
  2754                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
  2755                              <1> 	; 		(32 bit modifications)
  2756                              <1> 	; 14/03/2013 - 29/07/2013(Retro UNIX 8086 v1)
  2757                              <1> 	;
  2758                              <1> 	; 'wslot' calls 'bufaloc' and obtains as a result, a pointer
  2759                              <1> 	; to the I/O queue of an I/O buffer for a block structured
  2760                              <1> 	; device. It then checks the first word of I/O queue entry.	
  2761                              <1> 	; If bits 10 and/or 13 (read bit, waiting to read bit) are set,
  2762                              <1> 	; wslot calls 'idle'. When 'idle' returns, or if bits 10 
  2763                              <1> 	; and/or 13 are not set, 'wslot' sets bits 9 and 15 of the first
  2764                              <1> 	; word of the I/O queue entry (write bit, inhibit bit).
  2765                              <1> 	;
  2766                              <1> 	; INPUTS ->
  2767                              <1>  	;    r1 - block number
  2768                              <1> 	;    cdev - current (block/disk) device number
  2769                              <1>  	;
  2770                              <1> 	; OUTPUTS ->
  2771                              <1> 	;    bufp - bits 9 and 15 are set, 
  2772                              <1> 	;           the remainder of the word left unchanged
  2773                              <1> 	;    r5 - points to first data word in I/O buffer
  2774                              <1> 	;
  2775                              <1> 	; ((AX = R1)) input/output
  2776                              <1> 	; ((BX = R5)) output 
  2777                              <1> 	;
  2778                              <1>         ; ((Modified registers: edx, ecx, ebx, esi, edi)) 
  2779                              <1> 
  2780 000059D6 E856000000          <1> 	call	bufaloc
  2781                              <1> 	; 10/07/2015
  2782                              <1> 		; jsr r0,bufaloc / get a free I/O buffer; pointer to first
  2783                              <1>         	; br 1f / word in buffer in r5
  2784                              <1> 	; EBX = Buffer (Header) Address (r5) (ES=CS=DS, system/kernel segment)
  2785                              <1>         ; EAX = Block/Sector number (r1)
  2786                              <1> wslot_0: ;1:
  2787                              <1> 	; 15/07/2022
  2788                              <1> 	;
  2789                              <1>      	;test	word [ebx], 2400h
  2790                              <1> 	;	; bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
  2791                              <1> 	;			; / of I/O queue entry
  2792                              <1> 	;jz	short wslot_1
  2793                              <1>         ;       ; beq 1f  / branch if 10, 13 zero (i.e., not reading, 
  2794                              <1> 	;	       ; / or not waiting to read)
  2795                              <1> 	;
  2796                              <1> 	;;mov	ecx, [s.wait_] ; 29/07/2013
  2797                              <1> 	;call	idle
  2798                              <1> 	;	; jsr r0,idle; / if buffer is reading or writing to read,
  2799                              <1>        	;                   ; / idle
  2800                              <1> 	;jmp	short wslot_0
  2801                              <1> 	;	; br 1b / till finished
  2802                              <1> wslot_1: ;1:
  2803                              <1> 	;or	word [ebx], 8200h
  2804                              <1>        	;	; bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
  2805                              <1>         ;			; / (write, inhibit bits)
  2806                              <1> 	;	; clr *$ps / clear processor status
  2807                              <1> 
  2808                              <1> 	; 16/07/2022
  2809                              <1> ;dskwr_1:	; 09/03/2022
  2810                              <1> 	;add	ebx, 8 ; 11/06/2015
  2811                              <1> 		; add $8,r5 / r5 points to first word in data area 
  2812                              <1> 			  ; / for this block
  2813                              <1> 	; 15/07/2022
  2814                              <1> 	; (set disk write bit/flag)
  2815                              <1> 	;or	word [ebx], 200h	
  2816 000059DB 43                  <1> 	inc	ebx
  2817 000059DC 800B02              <1> 	or	byte [ebx], 2
  2818 000059DF 83C307              <1> 	add	ebx, 7
  2819                              <1> 	; 16/07/2022
  2820                              <1> dskwr_1:	; 08/02/2022
  2821 000059E2 C3                  <1>        	retn
  2822                              <1> 		; rts r0
  2823                              <1> dskwr:
  2824                              <1> 	; 16/07/2022
  2825                              <1> 	; 15/07/2022
  2826                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2827                              <1> 	; 09/03/2022
  2828                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
  2829                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2830                              <1> 	; 14/03/2013 - 03/08/2013 (Retro UNIX 8086 v1)
  2831                              <1> 	;
  2832                              <1> 	; 'dskwr' writes a block out on disk, via ppoke. The only
  2833                              <1> 	; thing dskwr does is clear bit 15 in the first word of I/O queue
  2834                              <1> 	; entry pointed by 'bufp'. 'wslot' which must have been called
  2835                              <1> 	; previously has supplied all the information required in the
  2836                              <1> 	; I/O queue entry.
  2837                              <1> 	;
  2838                              <1> 	; (Modified registers: ebx, ecx, edx, esi, edi)
  2839                              <1> 	;
  2840 000059E3 8B1D[D46B0000]      <1> 	mov	ebx, [bufp]
  2841 000059E9 668123FF7F          <1> 	and	word [ebx], 7FFFh ; 0111111111111111b
  2842                              <1> 		; bic $100000,*bufp / clear bit 15 of I/O queue entry at
  2843                              <1>                                   ; / bottom of queue
  2844 000059EE E823000000          <1> 	call	poke
  2845                              <1> 	; 09/06/2015
  2846 000059F3 73ED                <1> 	jnc	short dskwr_1 ; 16/07/2022
  2847                              <1> 	; ebx = buffer header ; 09/03/2022
  2848                              <1> 	; 08/02/2022
  2849 000059F5 803D[B76C0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
  2850 000059FC 7509                <1> 	jne	short dskwr_0 ; no
  2851                              <1> 	; yes, clear [u.brwdev] for next check and jump to 'error'
  2852 000059FE C605[B76C0000]00    <1> 	mov	byte [u.brwdev], 0
  2853 00005A05 EB0A                <1> 	jmp	short dskwr_2
  2854                              <1> dskwr_0:
  2855 00005A07 C705[B86C0000]1200- <1> 	mov	dword [u.error], ERR_DRV_WRITE ; disk write error !
  2855 00005A0F 0000                <1>
  2856                              <1> dskwr_2:
  2857 00005A11 E931D7FFFF          <1> 	jmp	error
  2858                              <1> ;dskwr_1:
  2859                              <1> ;	add	ebx, 8 ; 09/03/2022
  2860                              <1> ;	; ebx = buffer data address
  2861                              <1> ;	retn
  2862                              <1> 
  2863                              <1> ;ppoke:
  2864                              <1>        		; mov $340,*$ps
  2865                              <1>        		; jsr r0,poke
  2866                              <1>        		; clr *$ps
  2867                              <1> 		; rts r0
  2868                              <1> 
  2869                              <1> poke:
  2870                              <1> 	; 15/07/2022
  2871                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  2872                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
  2873                              <1> 	; 14/07/2022
  2874                              <1> 	;	! Major Modification !
  2875                              <1> 	;	Retro UNIX 386 v1 (Kernel v0.2.0.22)
  2876                              <1> 	;
  2877                              <1> 	; 04/02/2022 (32 bit reg push pop)
  2878                              <1> 	; 24/10/2015
  2879                              <1> 	; 20/08/2015
  2880                              <1> 	; 18/08/2015
  2881                              <1> 	; 02/07/2015
  2882                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2883                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
  2884                              <1> 	;
  2885                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
  2886                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
  2887                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
  2888                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
  2889                              <1> 	;
  2890                              <1> 	; Basic I/O functions for all block structured devices
  2891                              <1> 	;
  2892                              <1>         ; (Modified registers: ECX, EDX, ESI, EDI)
  2893                              <1> 	;
  2894                              <1> 	; 20/07/2013 modifications
  2895                              <1> 	;            (Retro UNIX 8086 v1 features only !)
  2896                              <1> 	; INPUTS -> 
  2897                              <1> 	;        EBX = buffer header address
  2898                              <1> 	; OUTPUTS ->
  2899                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
  2900                              <1> 	;	 cf=1 -> error, word [EBX] = 0FFFFh
  2901                              <1> 	;		(drive not ready or r/w error!)
  2902                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
  2903                              <1> 	;	 (dword [EBX+4] = 0FFFFFFFFh means RW/IO error)
  2904                              <1> 	;        (also it indicates invalid buffer data)
  2905                              <1> 	
  2906                              <1> 	; 15/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
  2907                              <1> 	; 14/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
  2908                              <1> 	; Buffer header:
  2909                              <1> 	;	byte 0 - device/disk (index) number
  2910                              <1> 	;	byte 1 - status
  2911                              <1> 	;	    before 'poke'	
  2912                              <1> 	;		bit 0 - valid bit 
  2913                              <1> 	;		   (0 for new buffer)
  2914                              <1> 	;		   (1 for existing buffer)	
  2915                              <1> 	;		bit 1 - write (modified) bit, disk write flag
  2916                              <1> 	;		bit 2 - read bit, disk read flag
  2917                              <1> 	;	    after 'poke'
  2918                              <1> 	;		if disk r/w is successed
  2919                              <1> 	;		   bit 0 = 1
  2920                              <1> 	;		   bit 1 = 0
  2921                              <1> 	;		   bit 2 = 0
  2922                              <1> 	;		if disk r/w is failed
  2923                              <1> 	;		   bit 0 = 0 (invalid buffer)
  2924                              <1> 	;		   bit 1 = 0 (write bit)
  2925                              <1> 	;		   bit 2 = 0 (read bit)	
  2926                              <1>  	;
  2927                              <1> 	;	byte 2 & byte 3 - not used
  2928                              <1> 	;	byte 4 to byte 7 - disk block/sector address
  2929                              <1> 	
  2930                              <1> 	; 04/02/2022
  2931 00005A16 50                  <1> 	push	eax
  2932 00005A17 E896000000          <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
  2933 00005A1C 58                  <1> 	pop	eax
  2934 00005A1D 730D                <1> 	jnc	short seta ; 14/07/2022
  2935                              <1> 	
  2936                              <1> 	; 14/07/2022
  2937                              <1> 	; (invalidate buffer)
  2938                              <1> 	
  2939                              <1> 	; 02/07/2015 (32 bit modification)
  2940                              <1> 	; 20/07/2013
  2941 00005A1F C74304FFFFFFFF      <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
  2942                              <1>        		; mov $-1,2(r1) / destroy associativity
  2943 00005A26 66C703FF00          <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
  2944                              <1> 		; clrb 1(r1) / do not do I/O
  2945                              <1> 	;stc
  2946 00005A2B C3                  <1> 	retn
  2947                              <1>         	; rts r0
  2948                              <1> seta: 
  2949 00005A2C C6430101            <1> 	mov	byte [ebx+1], 1 ; clear write/read bits, set valid bit
  2950                              <1> 	;clc
  2951 00005A30 C3                  <1> 	retn
  2952                              <1> 
  2953                              <1> %if 0
  2954                              <1> 
  2955                              <1> poke:
  2956                              <1> 	; 29/11/2021 (32 bit reg push-pop)
  2957                              <1> 	; 24/10/2015
  2958                              <1> 	; 20/08/2015
  2959                              <1> 	; 18/08/2015
  2960                              <1> 	; 02/07/2015
  2961                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
  2962                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
  2963                              <1> 	;
  2964                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
  2965                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
  2966                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
  2967                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
  2968                              <1> 	;
  2969                              <1> 	; Basic I/O functions for all block structured devices
  2970                              <1> 	;
  2971                              <1>         ; (Modified registers: ecx, edx, esi, edi)
  2972                              <1> 	;
  2973                              <1> 	; 20/07/2013 modifications
  2974                              <1> 	;            (Retro UNIX 8086 v1 features only !)
  2975                              <1> 	; INPUTS -> 
  2976                              <1> 	;        (EBX = buffer header address)
  2977                              <1> 	; OUTPUTS ->
  2978                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
  2979                              <1> 	;	 cf=1 -> error, word [EBX] = 0FFFFh
  2980                              <1> 	;		(drive not ready or r/w error!)
  2981                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
  2982                              <1> 	;	 (dword [EBx+4] = 0FFFFFFFFh means RW/IO error)
  2983                              <1> 	;        (also it indicates invalid buffer data)
  2984                              <1> 	;
  2985                              <1> 	push	ebx
  2986                              <1>        		; mov r1,-(sp)
  2987                              <1>        		; mov r2,-(sp)
  2988                              <1>        		; mov r3,-(sp)
  2989                              <1> 	push 	eax ; Physical Block Number (r1) (mget)
  2990                              <1> 	;
  2991                              <1> 	; 09/06/2015
  2992                              <1> 	; (permit read/write after a disk R/W error)
  2993                              <1> 	mov	cl, [ebx] ; device id (0 to 5)
  2994                              <1> 	mov	al, 1
  2995                              <1> 	shl	al, cl
  2996                              <1> 	test 	al, [active] ; busy ? (error)
  2997                              <1> 	jz	short poke_0
  2998                              <1> 	not	al
  2999                              <1> 	and	[active], al ; reset busy bit for this device only
  3000                              <1> poke_0:
  3001                              <1>         mov     esi, bufp + (4*(nbuf+2)) 
  3002                              <1> 		; mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority
  3003                              <1> 					 ; / I/O queue pointer
  3004                              <1> poke_1: ; 1:
  3005                              <1>         sub	esi, 4
  3006                              <1> 	mov	ebx, [esi]
  3007                              <1> 		; mov -(r2),r1 / r1 points to an I/O queue entry
  3008                              <1> 	mov	ax, [ebx] ; 17/07/2013
  3009                              <1>        	test	ah, 06h
  3010                              <1> 	;test	word [ebx], 600h ; 0000011000000000b
  3011                              <1> 		; bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O 
  3012                              <1> 			       ; / queue entry
  3013                              <1>         jz      short poke_5
  3014                              <1> 		; beq 2f / branch to 2f if both are clear
  3015                              <1> 	; 31/07/2013
  3016                              <1> 	;test	ah, 0B0h ; (*)
  3017                              <1> 	;;test	word [ebx], 0B000h ; 1011000000000000b
  3018                              <1> 		; bit $130000,(r1) / test bits 12, 13, and 15
  3019                              <1>         ;jnz	short poke_5 ; 31/07/2013 (*)
  3020                              <1> 		; bne 2f / branch if any are set
  3021                              <1> 	;movzx	ecx, byte [ebx] ; 09/06/2015 ; Device Id
  3022                              <1>     		; movb (r1),r3 / get device id
  3023                              <1> 	movzx	ecx, al ; 18/08/2015
  3024                              <1> 	;mov	edi, ecx ; 26/04/2013
  3025                              <1> 	xor 	eax, eax ; 0
  3026                              <1> 	;cmp 	[edi+drv.error], al ; 0
  3027                              <1> 		; tstb deverr(r3) / test for errors on this device
  3028                              <1>        	;jna	short poke_2 
  3029                              <1> 		; beq 3f / branch if no errors
  3030                              <1> 	; 02/07/2015
  3031                              <1> 	;dec	eax
  3032                              <1> 	;mov	[ebx+4], ax ; 0FFFFFFFFh ; -1 
  3033                              <1>        		; mov $-1,2(r1) / destroy associativity
  3034                              <1> 	;shr	eax, 24
  3035                              <1> 	;mov	[ebx], eax ; 000000FFh, reset
  3036                              <1> 		; clrb 1(r1) / do not do I/O
  3037                              <1> 	;jmp	short poke_5
  3038                              <1>         ;       ; br 2f
  3039                              <1>                 ; rts r0
  3040                              <1> poke_2: ; 3:
  3041                              <1> 	; 02/07/2015
  3042                              <1> 	inc	cl ; 0FFh -> 0
  3043                              <1> 	jz	short poke_5
  3044                              <1> 	inc	al ; mov ax, 1
  3045                              <1> 	dec	cl
  3046                              <1> 	jz	short poke_3
  3047                              <1> 	; 26/04/2013 Modification
  3048                              <1> 	;inc	al ; mov ax, 1
  3049                              <1> 	;or	cl, cl ; Retro UNIX 8086 v1 device id.
  3050                              <1> 	;jz	short poke_3 ; cl = 0
  3051                              <1> 	shl	al, cl ; shl ax, cl
  3052                              <1> poke_3:
  3053                              <1> 	;test	[active], ax
  3054                              <1> 	test	[active], al
  3055                              <1> 		; bit $2,active / test disk busy bit
  3056                              <1> 	jnz     short poke_5
  3057                              <1> 		; bne 2f / branch if bit is set
  3058                              <1> 	;or	[active], ax
  3059                              <1> 	or	[active], al
  3060                              <1> 		; bis $2,active / set disk busy bit
  3061                              <1> 	push	eax ; 29/11/2021
  3062                              <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
  3063                              <1> 	;mov    [edi+drv.error], ah
  3064                              <1> 	pop	eax
  3065                              <1> 	jnc	short poke_4 ; 20/07/2013
  3066                              <1> 	;cmp 	[edi+drv.error], al ; 0	
  3067                              <1> 	;jna	short poke_4
  3068                              <1> 		; tstb deverr(r3) / test for errors on this device
  3069                              <1>        		; beq 3f / branch if no errors
  3070                              <1> 	; 02/07/2015 (32 bit modification)
  3071                              <1> 	; 20/07/2013
  3072                              <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
  3073                              <1>        		; mov $-1,2(r1) / destroy associativity
  3074                              <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
  3075                              <1> 		; clrb 1(r1) / do not do I/O
  3076                              <1> 	jmp     short poke_5
  3077                              <1> poke_4:	; 20/07/2013
  3078                              <1> 	; 17/07/2013
  3079                              <1> 	not 	al 
  3080                              <1> 	and	[active], al ; reset, not busy
  3081                              <1> 	; EBX = system I/O buffer header (queue entry) address
  3082                              <1> seta: ; / I/O queue bookkeeping; set read/write waiting bits.
  3083                              <1> 	mov	ax, [ebx]
  3084                              <1>        		; mov (r1),r3 / move word 1 of I/O queue entry into r3
  3085                              <1>         and	ax, 600h
  3086                              <1> 		; bic $!3000,r3 / clear all bits except 9 and 10
  3087                              <1> 	and 	word [ebx], 0F9FFh
  3088                              <1>        		; bic $3000,(r1) / clear only bits 9 and 10
  3089                              <1> 	shl	ah, 3
  3090                              <1>        		; rol r3
  3091                              <1>                 ; rol r3
  3092                              <1>                 ; rol r3	
  3093                              <1> 	or	[ebx], ax
  3094                              <1> 		; bis r3,(r1) / or old value of bits 9 and 10 with 
  3095                              <1> 			   ; bits 12 and 13
  3096                              <1> 	call	idle ; 18/01/2014
  3097                              <1> 	;; sti
  3098                              <1> 	;hlt 	; wait for a hardware interrupt
  3099                              <1> 	;; cli
  3100                              <1> 	; NOTE: In fact, disk controller's 'disk I/O completed' 
  3101                              <1>         ; interrupt would be used to reset busy bits, but INT 13h
  3102                              <1> 	; returns when disk I/O is completed. So, here, as temporary
  3103                              <1> 	; method, this procedure will wait for a time according to
  3104                              <1> 	; multi tasking and time sharing concept.
  3105                              <1> 	;
  3106                              <1> 	; 24/10/2015
  3107                              <1> 	;not	ax 
  3108                              <1> 	mov 	ax, 0FFh ; 24/10/2015 (temporary)
  3109                              <1> 	and	[ebx], ax ; clear bits 12 and 13
  3110                              <1> poke_5: ;2:
  3111                              <1>         cmp     esi, bufp
  3112                              <1> 		; cmp r2,$bufp / test to see if entire I/O queue 
  3113                              <1>                             ; / has been scanned
  3114                              <1> 	ja      short poke_1
  3115                              <1> 		; bhi 1b
  3116                              <1> 	; 24/03/2013
  3117                              <1>        		; mov (sp)+,r3
  3118                              <1>        		; mov (sp)+,r2
  3119                              <1>        		; mov (sp)+,r1
  3120                              <1>         pop 	eax  ; Physical Block Number (r1) (mget)
  3121                              <1> 	pop 	ebx
  3122                              <1> 	; 02/07/2015 (32 bit modification)
  3123                              <1> 	; 20/07/2013
  3124                              <1> 	;cmp 	dword [ebx+4], 0FFFFFFFFh
  3125                              <1> 	cmp	byte [ebx], 0FFh ; 20/08/2015
  3126                              <1> 	;	
  3127                              <1> 	; 'poke' returns with cf=0 if the requested buffer is read 
  3128                              <1> 	; or written successfully; even if an error occurs while
  3129                              <1> 	; reading to or writing from other buffers. 20/07/2013
  3130                              <1> 	;
  3131                              <1> 	; 09/06/2015
  3132                              <1> 	cmc
  3133                              <1> 	retn
  3134                              <1>                 ; rts r0
  3135                              <1> 
  3136                              <1> %endif
  3137                              <1> 
  3138                              <1> bufaloc:
  3139                              <1> 	; 15/07/2022
  3140                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  3141                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  3142                              <1> 	; 20/08/2015
  3143                              <1> 	; 19/08/2015
  3144                              <1> 	; 02/07/2015
  3145                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
  3146                              <1> 	;	     (32 bit modifications)	
  3147                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
  3148                              <1> 	;
  3149                              <1> 	; bufaloc - Block device I/O buffer allocation
  3150                              <1> 	; 
  3151                              <1> 	; INPUTS ->
  3152                              <1> 	;    r1 - block number
  3153                              <1> 	;    cdev - current (block/disk) device number
  3154                              <1> 	;    bufp+(2*n)-2 --- n = 1 ... nbuff
  3155                              <1> 	; OUTPUTS ->
  3156                              <1> 	;    r5 - pointer to buffer allocated
  3157                              <1> 	;    bufp ... bufp+12 --- (bufp), (bufp)+2
  3158                              <1> 	;
  3159                              <1> 	; ((AX = R1)) input/output
  3160                              <1> 	; ((BX = R5)) output
  3161                              <1>         ;    ((Modified registers: DX, CX, BX, SI, DI, BP))
  3162                              <1> 	;    zf=1 -> block already in a I/O buffer
  3163                              <1> 	;    zf=0 -> a new I/O buffer has been allocated
  3164                              <1> 	;    ((DL = Device ID))
  3165                              <1> 	;    (((DH = 0 or 1)))
  3166                              <1> 	;    (((CX = previous value of word ptr [bufp])))
  3167                              <1> 	;    ((CX and DH will not be used after return)))
  3168                              <1> 
  3169                              <1> 	; 15/07/2022
  3170                              <1> 	;	Modified registers: EBX, ECX, EDX, ESI, EDI
  3171                              <1> 
  3172                              <1> 	;;push 	esi ; ***
  3173                              <1> 		; mov r2,-(sp) / save r2 on stack
  3174                              <1>        		; mov $340,*$ps / set processor priority to 7
  3175                              <1> 	; 20/07/2013
  3176                              <1> 	; 26/04/2013
  3177                              <1> 	;movzx	ebx, byte [cdev] ; 0 or 1
  3178                              <1> 	;mov	edi, rdev ; offset mdev = offset rdev + 1
  3179                              <1> 	;add	edi, ebx
  3180                              <1> 	; 09/01/2022
  3181 00005A31 0FB63D[216C0000]    <1> 	movzx	edi, byte [cdev] ; 0 or 1
  3182 00005A38 81C7[226C0000]      <1> 	add	edi, rdev
  3183                              <1> bufaloc_0: ; 26/04/2013 !! here is called from bread or bwrite !!
  3184                              <1> 			;; EDI points to device id.
  3185 00005A3E 0FB61F              <1> 	movzx	ebx, byte [edi] ; [EDI] -> rdev/mdev or brwdev
  3186                              <1> 	; 11/06/2021
  3187 00005A41 80BB[4E620000]F0    <1> 	cmp 	byte [ebx+drv.status], 0F0h ; Drive not ready !
  3188 00005A48 720F                <1> 	jb	short bufaloc_9
  3189 00005A4A C705[B86C0000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
  3189 00005A52 0000                <1>
  3190 00005A54 E9EED6FFFF          <1> 	jmp	error
  3191                              <1> bufaloc_9:
  3192 00005A59 89DA                <1> 	mov	edx, ebx ; dh = 0, dl = device number (0 to 5)
  3193                              <1> bufaloc_10: ; 02/07/2015
  3194                              <1> 	; 14/07/2022
  3195                              <1> 	;xor 	ebp, ebp ; 0
  3196                              <1> 	;push	ebp ; 0
  3197                              <1>         ;mov	ebp, esp
  3198 00005A5B 31FF                <1> 	xor	edi, edi ; 0
  3199 00005A5D 57                  <1> 	push	edi
  3200                              <1> bufaloc_1: ;1:
  3201                              <1> 		; clr -(sp) / vacant buffer
  3202 00005A5E BE[D46B0000]        <1>         mov 	esi, bufp
  3203                              <1> 		; mov $bufp,r2 / bufp contains pointers to I/O queue 
  3204                              <1> 			     ; / entrys in buffer area
  3205                              <1> bufaloc_2: ;2:
  3206 00005A63 8B1E                <1> 	mov	ebx, [esi]
  3207                              <1>        		; mov (r2)+,r5 / move pointer to word 1 of an I/O 
  3208                              <1> 			    ; queue entry into r5
  3209                              <1> 	; 15/07/2022
  3210 00005A65 8B0B                <1> 	mov	ecx, [ebx]	
  3211                              <1> 	;test	word [ebx], 0F600h
  3212                              <1> 	; 15/07/2022
  3213 00005A67 F6C501              <1> 	test	ch, 1 ; valid buffer (content) ?
  3214                              <1> 		; bit $173000,(r5) / lock+keep+active+outstanding
  3215 00005A6A 7505                <1>         jnz	short bufaloc_3 ; yes
  3216                              <1> 		; bne 3f / branch when 
  3217                              <1> 		       ; / any of bits 9,10,12,13,14,15 are set
  3218                              <1>                        ; / (i.e., buffer busy)
  3219                              <1> 	;mov    [ebp], esi ; pointer to I/0 queue entry
  3220                              <1> 	; 15/07/2022
  3221                              <1> 	; save free buffer pointer 
  3222 00005A6C 893424              <1> 	mov	[esp], esi
  3223                              <1>                 ; mov r2,(sp) ;/ save pointer to last non-busy buffer
  3224                              <1> 			; / found points to word 2 of I/O queue entry)
  3225                              <1> 	; continue to see if requested sector/block buffer
  3226                              <1> 	;	already is one of existing (valid) buffers
  3227                              <1> 	;jmp	short bufaloc_4
  3228 00005A6F EB0E                <1> 	jmp	short bufaloc_11 ; 15/07/2022
  3229                              <1> bufaloc_3: ;3:
  3230                              <1> 	;mov	dl, [edi] ; 26/04/2013
  3231                              <1> 	;
  3232 00005A71 38D1                <1> 	cmp	cl, dl ; 15/07/2022
  3233                              <1> 	;cmp	[ebx], dl	
  3234                              <1> 		; cmpb (r5),cdev / is device in I/O queue entry same 
  3235                              <1> 			       ; / as current device
  3236 00005A73 7508                <1> 	jne	short bufaloc_4
  3237                              <1>        		; bne 3f
  3238 00005A75 394304              <1> 	cmp	[ebx+4], eax
  3239                              <1>        		; cmp 2(r5),r1 / is block number in I/O queue entry, 
  3240                              <1> 			     ; / same as current block number
  3241 00005A78 7503                <1>        	jne	short bufaloc_4
  3242                              <1> 		; bne 3f
  3243                              <1> 	;add	esp, 4
  3244 00005A7A 59                  <1> 	pop	ecx
  3245                              <1>        		; tst (sp)+ / bump stack pointer
  3246 00005A7B EB1D                <1> 	jmp	short bufaloc_7 ; Retro Unix 8086 v1 modification
  3247                              <1> 				; jump to bufaloc_6 in original Unix v1
  3248                              <1>        		; br 1f / use this buffer
  3249                              <1> bufaloc_4: ;3:
  3250                              <1> 	; 15/07/2022
  3251                              <1> 	; save last valid buffer 
  3252                              <1> 	; (will be used if there is not a free buffer)
  3253 00005A7D 89F7                <1> 	mov	edi, esi	
  3254                              <1> bufaloc_11:
  3255 00005A7F 83C604              <1> 	add	esi, 4 ; 20/08/2015
  3256                              <1> 	;
  3257 00005A82 81FE[146C0000]      <1> 	cmp	esi, bufp + (nbuf*4)
  3258                              <1> 		; cmp r2,$bufp+nbuf+nbuf
  3259 00005A88 72D9                <1> 	jb	short bufaloc_2
  3260                              <1> 		; blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
  3261                              <1>                        ; / buffers not checked)
  3262 00005A8A 5E                  <1>         pop	esi
  3263                              <1> 		; mov (sp)+,r2 / once all bufs are examined move pointer
  3264                              <1> 			     ; / to last free block
  3265 00005A8B 09F6                <1>        	or	esi, esi 
  3266 00005A8D 7502                <1> 	jnz	short bufaloc_5
  3267                              <1> 		; bne 2f / if (sp) is non zero, i.e., 
  3268                              <1> 	        ; / if a free buffer is found branch to 2f
  3269                              <1> 
  3270                              <1> 	; 15/07/2022        
  3271                              <1> 	; if there is not a free buffer
  3272                              <1> 	; we can use last valid buffer (the oldest buffer)
  3273                              <1> 	; ((ptr to new buffer is located at head of buff ptr chain))
  3274 00005A8F 89FE                <1> 	mov	esi, edi
  3275                              <1> 
  3276                              <1> 	;;mov  ecx, [s.wait_]
  3277                              <1> 	;call	idle
  3278                              <1> 	;	; jsr r0,idle; s.wait+2 / idle if no free buffers
  3279                              <1> 	;jmp 	short bufaloc_10 ; 02/07/2015
  3280                              <1>        	;	; br 1b
  3281                              <1> bufaloc_5: ;2:
  3282                              <1> 		; tst (r0)+ / skip if warmed over buffer
  3283                              <1> 	; 15/07/2022
  3284                              <1> 	;inc	dh ; Retro UNIX 8086 v1 modification
  3285                              <1> bufaloc_6: ;1:
  3286 00005A91 8B1E                <1>         mov    	ebx, [esi] 
  3287                              <1> 		; mov -(r2),r5 / put pointer to word 1 of I/O queue 
  3288                              <1> 			     ; / entry in r5
  3289                              <1> 	;; 26/04/2013
  3290                              <1>         ;;mov	dl, [edi] ; byte [rdev] or byte [mdev]
  3291                              <1> 	;mov 	[ebx], dl
  3292                              <1> 		; movb cdev,(r5) / put current device number 
  3293                              <1> 				 ; / in I/O queue entry
  3294                              <1> 	; 15/07/2022
  3295                              <1> 	; invalidate buffer before r/w (new) disk sector/block
  3296                              <1> 	;mov	[ebx+1], dh ; 0
  3297                              <1> 	; 15/07/2022
  3298 00005A93 8913                <1> 	mov	[ebx], edx  ; dh = 0
  3299                              <1> 	
  3300 00005A95 894304              <1> 	mov 	[ebx+4], eax
  3301                              <1> 		; mov r1,2(r5) / move block number into word 2
  3302                              <1> 			     ; / of I/O queue entry
  3303                              <1> 	; 15/07/2022
  3304 00005A98 FEC6                <1> 	inc	dh ; dh = 1
  3305                              <1> bufaloc_7: ;1:
  3306 00005A9A 81FE[D46B0000]      <1>         cmp	esi, bufp
  3307                              <1> 		; cmp r2,$bufp / bump all entrys in bufp 
  3308                              <1> 			     ; / and put latest assigned
  3309 00005AA0 760B                <1> 	jna	short bufaloc_8	
  3310                              <1>        		; blos 1f / buffer on the top 
  3311                              <1> 			; / (this makes if the lowest priority)
  3312                              <1> 	; 15/07/2022
  3313 00005AA2 89F7                <1> 	mov	edi, esi
  3314 00005AA4 83EE04              <1> 	sub	esi, 4
  3315 00005AA7 8B0E                <1> 	mov	ecx, [esi]
  3316 00005AA9 890F                <1> 	mov	[edi], ecx ; 15/07/2022
  3317                              <1> 	;mov	[esi+4], ecx
  3318                              <1> 		; mov -(r2),2(r2) / job for a particular device
  3319 00005AAB EBED                <1> 	jmp 	short bufaloc_7
  3320                              <1> 		; br 1b
  3321                              <1> bufaloc_8: ;1:
  3322 00005AAD 891E                <1>         mov	[esi], ebx
  3323                              <1> 		; mov r5,(r2)
  3324                              <1> 	;;pop	esi ; ***
  3325                              <1>        		; mov (sp)+,r2 / restore r2
  3326 00005AAF 08F6                <1>        	or 	dh, dh ; 0 or 1 ?
  3327                              <1> 		; Retro UNIX 8086 v1 modification
  3328                              <1> 		; zf=1 --> block already is in an I/O buffer
  3329                              <1> 		; zf=0 --> a new I/O buffer has been allocated
  3330 00005AB1 C3                  <1> 	retn
  3331                              <1> 		; rts r0
  3332                              <1> 
  3333                              <1> diskio:
  3334                              <1> 	; 16/07/2022
  3335                              <1> 	; 12/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  3336                              <1> 	; 08/07/2022
  3337                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3338                              <1> 	;	((simplified and shortened 'diskio.s' code))
  3339                              <1> 	; 12/02/2022
  3340                              <1> 	; 10/02/2022
  3341                              <1> 	; 08/02/2022
  3342                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
  3343                              <1> 	; 28/11/2021
  3344                              <1> 	; 10/07/2015
  3345                              <1> 	; 02/07/2015
  3346                              <1> 	; 16/06/2015
  3347                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
  3348                              <1> 	;	     (80386 protected mode modifications)	
  3349                              <1> 	; 15/03/2013 - 29/04/2013 (Retro UNIX 8086 v1)
  3350                              <1> 	;
  3351                              <1> 	; Retro UNIX 8086 v1 feature only !
  3352                              <1> 	;
  3353                              <1> 	; Derived from proc_chs_read procedure of TRDOS DISKIO.ASM (2011)
  3354                              <1> 	; 04/07/2009 - 20/07/2011
  3355                              <1> 	;
  3356                              <1> 	; NOTE: Reads only 1 block/sector (sector/block size is 512 bytes)
  3357                              <1> 	;
  3358                              <1>         ; INPUTS ->
  3359                              <1> 	; 	   ebx = System I/O Buffer header address
  3360                              <1> 	;
  3361                              <1>         ; OUTPUTS -> cf=0 --> done 
  3362                              <1> 	; 	     cf=1 --> error code in AH
  3363                              <1> 	;	     ; 08/02/2022
  3364                              <1> 	;	     cf=1 & [u.brwdev] = 0FFh -->
  3365                              <1> 	;		error code in [u.error]
  3366                              <1> 	;		
  3367                              <1> 	; (Modified registers: eax, ecx, edx)
  3368                              <1> 	
  3369                              <1> ;rw_disk_sector:
  3370                              <1> 	; 16/07/2022
  3371                              <1> 	; 12/07/2022
  3372                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  3373                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3374                              <1> 	; 12/02/2022
  3375                              <1> 	; 10/02/2022
  3376                              <1> 	; 08/02/2022
  3377                              <1> 	; 28/11/2021
  3378                              <1> 	; 10/07/2015
  3379                              <1> 	; 02/07/2015
  3380                              <1> 	; 11/06/2015 - Retro UNIX 386 v1 - 'u8.s' 
  3381                              <1> 	; 21/02/2015 ('dsectpm.s', 'read_disk_sector')
  3382                              <1> 	; 16/02/2015 (Retro UNIX 386 v1 test - 'unix386.s')
  3383                              <1> 	; 01/12/2014 - 18/01/2015 ('dsectrm2.s')
  3384                              <1> 	;
  3385                              <1> 	;;mov	dx, 0201h ; Read 1 sector/block
  3386                              <1> 	;mov	dh, 2
  3387                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3388 00005AB2 B602                <1> 	mov	dh, 2 ; Write 1 sector/block
  3389 00005AB4 668B03              <1> 	mov	ax, [ebx] 
  3390                              <1> 	;
  3391 00005AB7 56                  <1> 	push	esi ; ****
  3392 00005AB8 53                  <1> 	push	ebx ; ***
  3393                              <1> 	;
  3394 00005AB9 0FB6C8              <1> 	movzx	ecx, al
  3395                              <1> 	; 28/11/2021
  3396                              <1> 	;mov	ecx, eax
  3397 00005ABC 89CE                <1> 	mov	esi, ecx
  3398                              <1> 	;
  3399 00005ABE 38F1                <1> 	cmp	cl, dh ; 2
  3400 00005AC0 7202                <1> 	jb	short rwdsk0
  3401 00005AC2 047E                <1> 	add	al, 7Eh  ; 80h, 81h, 82h, 83h
  3402                              <1> rwdsk0:
  3403                              <1> 	; 16/07/2022
  3404                              <1> 	; 12/07/2022
  3405                              <1> 	;mov	[drv], al
  3406 00005AC4 81C6[4E620000]      <1> 	add	esi, drv.status
  3407                              <1> 	; 11/06/2015
  3408 00005ACA 803EF0              <1> 	cmp	byte [esi], 0F0h 
  3409 00005ACD 7204                <1> 	jb      short rwdsk1
  3410                              <1> 	; 'drive not ready' error
  3411                              <1> 	; 10/02/2022
  3412                              <1> 	; 08/02/2022
  3413                              <1> 	;mov	byte [u.brwdev], 0FFh ; error code in [u.error]
  3414                              <1> 	;mov	dword [u.error], ERR_DRV_NOT_RDY
  3415                              <1> 	;;jmp	error
  3416                              <1> 	;stc	; cf = 1
  3417                              <1> 	;retn
  3418                              <1> 	; 10/02/2022
  3419 00005ACF B10F                <1> 	mov	cl, ERR_DRV_NOT_RDY
  3420 00005AD1 EB1F                <1> 	jmp	short rwdsk_err1
  3421                              <1> rwdsk1:
  3422                              <1> 	; 16/07/2022
  3423                              <1> 	;test	ah, 2
  3424                              <1> 	;;test	ax, 200h ; Bit 9 of word 0 (status word)
  3425                              <1> 	;		 ; write bit
  3426                              <1> 	;jz	short rwdsk2
  3427                              <1> 	
  3428                              <1> 	;;test	ah, 4
  3429                              <1> 	;;;test	ax, 400h ; Bit 10 of word 0 (status word)
  3430                              <1> 	;;		 ; read bit
  3431                              <1> 	;;jz	short diskio_ret
  3432                              <1> 
  3433                              <1> 	;inc	dh ; 03h = write
  3434                              <1> 
  3435                              <1> 	; 08/07/2022
  3436 00005AD3 84F4                <1> 	test	ah, dh ; test ah, 2
  3437 00005AD5 7502                <1> 	jnz	short rwdsk2 ; dh = 02h = write
  3438 00005AD7 FECE                <1> 	dec	dh
  3439                              <1> 		; dh = 01h = read
  3440                              <1> rwdsk2:
  3441 00005AD9 88C2                <1> 	mov	dl, al
  3442 00005ADB 83C304              <1> 	add	ebx, 4 ; sector/block address/number pointer
  3443 00005ADE 8B03                <1> 	mov	eax, [ebx] ; sector/block number (LBA)
  3444 00005AE0 C0E102              <1> 	shl	cl, 2
  3445 00005AE3 81C1[32620000]      <1> 	add	ecx, drv.size ; disk size
  3446 00005AE9 3B01                <1> 	cmp	eax, [ecx] ; Last sector + 1 (number of secs.)
  3447 00005AEB 7214                <1> 	jb      short rwdsk3
  3448                              <1>  	; 'out of volume' error
  3449                              <1> 	; 10/02/2022
  3450                              <1> 	; 08/02/2022
  3451                              <1> 	;mov	byte [u.brwdev], 0FFh ; error code in [u.error]
  3452                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE
  3453                              <1> 	;;jmp	error
  3454                              <1> 	;stc	; cf = 1
  3455                              <1> 	;retn
  3456                              <1> 	; 10/02/2022
  3457 00005AED B910000000          <1> 	mov	ecx, ERR_DEV_VOL_SIZE
  3458                              <1> rwdsk_err1:
  3459 00005AF2 C605[B76C0000]FF    <1> 	mov	byte [u.brwdev], 0FFh
  3460 00005AF9 890D[B86C0000]      <1> 	mov	[u.error], ecx ; 12/02/2022
  3461 00005AFF EB27                <1> 	jmp	short rwdsk_err2
  3462                              <1> rwdsk3:
  3463                              <1> 	; 11/06/2015
  3464 00005B01 83C304              <1> 	add	ebx, 4 ; buffer address
  3465 00005B04 C605[DB6C0000]04    <1> 	mov	byte [retry_count], 4
  3466                              <1> 	; 12/07/2022
  3467                              <1> 	;test	byte [esi], 1 ; LBA ready ?
  3468                              <1>         ;jz	short rwdsk_chs
  3469                              <1> rwdsk_lba:
  3470                              <1> 	; LBA read/write (with private LBA function) 
  3471                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
  3472 00005B0B 83C607              <1>         add     esi, drv.error - drv.status ; 10/07/2015
  3473 00005B0E 89C1                <1> 	mov	ecx, eax ; sector number
  3474                              <1> 	; ebx = buffer (data) address
  3475                              <1> 	; dl = physical drive number (0, 1, 80h, 81h, 82h, 83h)
  3476                              <1> rwdsk_lba_retry:
  3477                              <1> 	;mov	dl, [drv]
  3478                              <1> 		; Function 1Bh = LBA read, 1Ch = LBA write
  3479                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3480                              <1> 	;;mov	ah, 1Ch - 03h ; LBA write function number - 3
  3481                              <1> 	;mov	ah, 2 ; LBA write function number - 2
  3482                              <1> 	;add	ah, dh		
  3483                              <1> 	;mov	al, 1
  3484                              <1> 	;int	13h
  3485                              <1> 	;call	int13h
  3486                              <1> 	; 12/07/2022
  3487 00005B10 88F0                <1> 	mov	al, dh	; function (1 or 2)
  3488                              <1> 			; (1 = read, 2 = write )
  3489                              <1> 	; ecx = disk sector address (LBA)
  3490                              <1> 	; ebx = buffer address
  3491                              <1> 	;  dl = (physical) disk number
  3492                              <1> 	;  al = function (r/w)
  3493 00005B12 E835C4FFFF          <1> 	call	DISK_IO
  3494                              <1> 
  3495 00005B17 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
  3496 00005B19 730E                <1> 	jnc	short rwdsk_lba_ok
  3497 00005B1B 80FC80              <1> 	cmp	ah, 80h ; time out ?
  3498 00005B1E 7408                <1>         je      short rwdsk_lba_fails
  3499 00005B20 FE0D[DB6C0000]      <1> 	dec	byte [retry_count]
  3500 00005B26 7504                <1>         jnz     short rwdsk_lba_reset ; 10/07/2015
  3501                              <1> rwdsk_err2:	; 10/02/2022
  3502                              <1> rwdsk_lba_fails:
  3503 00005B28 F9                  <1> 	stc
  3504                              <1> rwdsk_lba_ok:
  3505 00005B29 5B                  <1> 	pop	ebx ; ***
  3506 00005B2A 5E                  <1> 	pop	esi ; ****
  3507 00005B2B C3                  <1> 	retn
  3508                              <1> rwdsk_lba_reset:
  3509                              <1> 	;mov	ah, 0Dh ; Alternate reset
  3510                              <1> 	;int	13h
  3511                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3512                              <1> 	;mov	ah, 5 ; Alternate reset	 
  3513                              <1> 	;call	int13h
  3514                              <1> 	;jnc	short rwdsk_lba_retry
  3515                              <1> 	; 12/07/2022
  3516 00005B2C 30C0                <1> 	xor	al, al ; 0 ; reset
  3517 00005B2E E819C4FFFF          <1> 	call	DISK_IO
  3518 00005B33 73DB                <1> 	jnc	short rwdsk_lba_retry
  3519                              <1> 
  3520 00005B35 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
  3521 00005B37 EBF0                <1> 	jmp	short rwdsk_lba_ok
  3522                              <1> 
  3523                              <1> 	; 12/07/2022 
  3524                              <1> 	;	(CHS Read/Write setup is not needed here.)
  3525                              <1> 	; 	(LBA address will be converted to CHS parameters 
  3526                              <1> 	;	in 'DISK_IO' procedure when/if it is required.)
  3527                              <1>  
  3528                              <1> ;	; CHS read (convert LBA address to CHS values)	
  3529                              <1> ;rwdsk_chs:
  3530                              <1> ;	; 10/07/2015
  3531                              <1> ;	sub	esi, drv.status
  3532                              <1> ;	mov	ecx, esi
  3533                              <1> ;	add 	esi, drv.error
  3534                              <1> ;	; 02/07/2015
  3535                              <1> ;	; 16/06/2015
  3536                              <1> ;	; 11/06/2015 
  3537                              <1> ;	push	ebx ; ** ; buffer
  3538                              <1> ;	shl	ecx, 1
  3539                              <1> ;	push	ecx ; * 
  3540                              <1> ;	;
  3541                              <1> ;	mov	ebx, ecx
  3542                              <1> ;	mov	[rwdsk], dh ; 02/07/2015
  3543                              <1> ;	xor	edx, edx ; 0
  3544                              <1> ;	; 09/01/2022
  3545                              <1> ;	;sub	ecx, ecx 
  3546                              <1> ;       add     ebx, drv.spt
  3547                              <1> ;	mov	cx, [ebx] ; sector per track
  3548                              <1> ;		; EDX:EAX = LBA
  3549                              <1> ;	div	ecx
  3550                              <1> ;	mov	cl, dl	; sector number - 1
  3551                              <1> ;	inc	cl	; sector number (1 based)
  3552                              <1> ;	pop	ebx ; * ; 11/06/2015
  3553                              <1> ;	;push	cx
  3554                              <1> ;	; 09/01/2022
  3555                              <1> ;	push	ecx
  3556                              <1> ;	add     ebx, drv.heads
  3557                              <1> ;	mov	cx, [ebx] ; heads
  3558                              <1> ;	xor	edx, edx
  3559                              <1> ;		; EAX = cylinders * heads + head
  3560                              <1> ;	div	ecx
  3561                              <1> ;	;pop	cx     ; sector number
  3562                              <1> ;	; 09/01/2022
  3563                              <1> ;	pop	ecx
  3564                              <1> ;	mov	dh, dl ; head number
  3565                              <1> ;	mov	dl, [drv]
  3566                              <1> ;	mov	ch, al ; cylinder (bits 0-7)
  3567                              <1> ;	shl	ah, 6
  3568                              <1> ;	or	cl, ah ; cylinder (bits 8-9)
  3569                              <1> ;		       ; sector (bits 0-7)
  3570                              <1> ;	pop	ebx ; ** ; buffer ; 11/06/2015
  3571                              <1> ;		; CL = sector (bits 0-5)
  3572                              <1> ;		;      cylinder (bits 8-9 -> bits 6-7)
  3573                              <1> ;		; CH = cylinder (bits 0-7)
  3574                              <1> ;		; DH = head
  3575                              <1> ;		; DL = drive
  3576                              <1> ;	;
  3577                              <1> ;	mov	byte [retry_count], 4
  3578                              <1> ;rwdsk_retry:	
  3579                              <1> ;	;mov	ah, [rwdsk] ; 02h = read, 03h = write
  3580                              <1> ;	; 08/07/2022
  3581                              <1> ;	mov	ah, [rwdsk] ; 01h = read, 02h = write
  3582                              <1> ;	mov	al, 1 ; sector count	
  3583                              <1> ;	;int	13h
  3584                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3585                              <1> ;	call	int13h
  3586                              <1> ;	mov	[esi], ah ; error code ; 10/07/2015
  3587                              <1> ;	jnc	short rwdsk_ok ; ah = 0
  3588                              <1> ;	cmp	ah, 80h ; time out ?
  3589                              <1> ;	je	short rwdsk_fails
  3590                              <1> ;	dec	byte [retry_count]
  3591                              <1> ;	jnz	short rwdsk_reset
  3592                              <1> ;rwdsk_fails:
  3593                              <1> ;	stc
  3594                              <1> ;rwdsk_ok:
  3595                              <1> ;	pop	ebx ; ***
  3596                              <1> ;	pop	esi ; ****
  3597                              <1> ;	retn
  3598                              <1> ;rwdsk_reset:
  3599                              <1> ;	; 02/02/2015
  3600                              <1> ;	sub	ah, ah
  3601                              <1> ;	cmp	dl, 80h
  3602                              <1> ;	jb	short rwdsk_fd_reset
  3603                              <1> ;	;mov	ah, 0Dh ; Alternate reset
  3604                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  3605                              <1> ;	mov	ah, 5  ; Alternate reset
  3606                              <1> ;rwdsk_fd_reset:
  3607                              <1> ;	;int	13h
  3608                              <1> ;	call	int13h
  3609                              <1> ;	jnc	short rwdsk_retry
  3610                              <1> ;	mov	[esi], ah ; error code ; 10/07/2015
  3611                              <1> ;	jmp 	short rwdsk_ok
  3612                              <1> 
  3613                              <1> ; Original UNIX v1 - drum (& disk) interrupt routine
  3614                              <1> ;	(Equivalent to IRQ 14 & IRQ 15 disk/hardware interrupts)
  3615                              <1> ;
  3616                              <1> ; This feature is not used in Retro UNIX 386 (& 8086) for now.
  3617                              <1> ; Because, current Retro UNIX 386 disk I/O -INT13H- routine is 
  3618                              <1> ; derived from IBM PC AT -infact: XT286- BIOS source code, int 13h
  3619                              <1> ; that uses hardware -transfer has been completed- interrupt inside it. 
  3620                              <1> ; In a next Retro UNIX 386 version, these interrupts
  3621                              <1> ; (fdc_int, hdc1_int, hdc2_int) will be handled by a separate routine
  3622                              <1> ; as in original unix v1.
  3623                              <1> ; I am not removing IBM BIOS source code derivatives -compatible code-
  3624                              <1> ; for now, regarding the new/next 32 bit TRDOS project by me
  3625                              <1> ; (to keep source code files easy adaptable to 32 bit TRDOS.)
  3626                              <1> ;
  3627                              <1> ; Erdogan tan (10/07/2015) 
  3628                              <1> 
  3629                              <1> ;drum: / interrupt handler
  3630                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
  3631                              <1> ;       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
  3632                              <1> ;                                      / error
  3633                              <1> ;               br 3f / no, error
  3634                              <1> ;       br      2f / error
  3635                              <1> ;
  3636                              <1> ;disk:
  3637                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
  3638                              <1> ;       jmp     *$0f
  3639                              <1> ;0:
  3640                              <1> ;       jsr     r0,trapt; rkcs; rkap; 2
  3641                              <1> ;      	        br 3f / no, errors
  3642                              <1> ;       mov     $115,(r2) / drive reset, errbit was set
  3643                              <1> ;       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
  3644                              <1> ;                        / to 1f
  3645                              <1> ;       br      4f
  3646                              <1> ;1:
  3647                              <1> ;       bit     $20000,rkcs
  3648                              <1> ;       beq     4f / wait for seek complete
  3649                              <1> ;       mov     $0b,0b-2
  3650                              <1> ;       mov     rkap,r1
  3651                              <1> ;2:
  3652                              <1> ;       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
  3653                              <1> ;                          / the disk buffer
  3654                              <1> ;       bne     3f / no, branch ignore error if outstanding
  3655                              <1> ;       inc     r1
  3656                              <1> ;       asr     (r1)
  3657                              <1> ;       asr     (r1)
  3658                              <1> ;       asr     (r1) / reissue request
  3659                              <1> ;       dec     r1
  3660                              <1> ;3:
  3661                              <1> ;       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
  3662                              <1> ;       mov     ac,-(sp)
  3663                              <1> ;       mov     mq,-(sp) / put these on the stack
  3664                              <1> ;       mov     sc,-(sp)
  3665                              <1> ;       jsr     r0,poke
  3666                              <1> ;       mov     (sp)+,sc
  3667                              <1> ;       mov     (sp)+,mq / pop them off stack
  3668                              <1> ;       mov     (sp)+,ac
  3669                              <1> ;4:
  3670                              <1> ;       jmp     retisp / u4-3
  3671                              <1> ;
  3672                              <1> ;trapt:                  / r2 points to the
  3673                              <1> ;       mov     (r0)+,r2 / device control register
  3674                              <1> ;       mov     *(r0)+,r1 / transaction pointer points to buffer
  3675                              <1> ;       tst     (sp)+
  3676                              <1> ;       tstb    (r2) / is ready bit of dcs set?
  3677                              <1> ;       bge     4b / device still active so branch
  3678                              <1> ;       bit     (r0),active / was device busy?
  3679                              <1> ;       beq     4b / no, stray interrupt
  3680                              <1> ;       bic     (r0)+,active / yes, set active to zero
  3681                              <1> ;       tst     (r2) / test the err(bit is) of dcs
  3682                              <1> ;       bge     2f / if no error jump to 2f
  3683                              <1> ;       tst     (r0)+ / skip on error
  3684                              <1> ; 2:
  3685                              <1> ;       jmp     (r0)
  3686                              <1> 
  3687                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatibility code
  3688                              <1> get_system_time:
  3689                              <1> 	; 27/10/2021
  3690                              <1> 	; 21/02/2020 - Retro UNIX 386 v2
  3691                              <1> 	; get system time
  3692                              <1> 	;  (from recent value which is saved in RTC interrupt)
  3693                              <1> 	; Input:
  3694                              <1> 	; 	none
  3695                              <1> 	; Return:
  3696                              <1> 	;   	eax = system time in unix epoch format 
  3697                              <1> 	;
  3698                              <1> 	; Modified registers: eax, ecx, edx
  3699                              <1> 	
  3700                              <1> 	; 27/11/2021
  3701 00005B39 53                  <1> 	push	ebx
  3702 00005B3A E8E1D0FFFF          <1> 	call	epoch
  3703 00005B3F 5B                  <1> 	pop	ebx
  3704 00005B40 C3                  <1> 	retn
  3705                              <1> 	
  3706                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
  3707                              <1> 	;  ('get_serial_number' is not used in v1.2 kernel)
  3708                              <1> ;get_serial_number:
  3709                              <1> 	; temporary - 21/02/2020
  3710                              <1> 	; 26/04/2020 (esi)
  3711                              <1> 	; 25/04/2020
  3712                              <1> 	; (Possible) Modified registers: eax, ecx, edx
  3713                              <1> 	; (edi, ebx & esi registers must be preserved)
  3714                              <1> 	; Return:
  3715                              <1> 	; eax = 32 bit serial number  
  3716                              <1> 	; (edx = high 32 bit of 64 bit serial number)
  3717                              <1> 	; -64 bit serial numbers will not be used in RUNIX 386 v2-
  3718                              <1> 	
  3719                              <1> 	;retn
  2097                                  %include 'u9.s'      ; 29/06/2015
  2098                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2099                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2100                              <1> ; ****************************************************************************
  2101                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - SYS9.INC
  2102                              <1> ; Last Modification: 12/06/2022
  2103                              <1> ; ----------------------------------------------------------------------------
  2104                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
  2105                              <1> ; (v0.1 - Beginning: 11/07/2012)
  2106                              <1> ;
  2107                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2108                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2109                              <1> ; <Bell Laboratories (17/3/1972)>
  2110                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2111                              <1> ;
  2112                              <1> ; Retro UNIX 8086 v1 - U9.ASM (01/09/2014) //// UNIX v1 -> u9.s
  2113                              <1> ;
  2114                              <1> ; ****************************************************************************
  2115                              <1> 
  2116                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - Printer BIOS (Functions)
  2117                              <1> 
  2118                              <1> getch:
  2119                              <1> 	; 30/06/2015
  2120                              <1> 	; 18/02/2015 - Retro UNIX 386 v1 - feature only!
  2121 00005B41 28C0                <1> 	sub	al, al ; 0
  2122                              <1> getch_q: ; 06/08/2015
  2123 00005B43 8A25[36670000]      <1> 	mov 	ah, [ptty] ; active (current) video page
  2124 00005B49 EB06                <1>         jmp     short getc_n
  2125                              <1> 
  2126                              <1> getc: 
  2127                              <1> 	; 12/11/2015
  2128                              <1> 	; 15/09/2015
  2129                              <1> 	; 01/07/2015
  2130                              <1> 	; 30/06/2015
  2131                              <1> 	; 18/02/2015 (Retro UNIX 386 v1 - Beginning)
  2132                              <1> 	; 13/05/2013 - 04/07/2014 (Retro UNIX 8086 v1)
  2133                              <1> 	;
  2134                              <1> 	; Retro UNIX 8086 v1 modification !
  2135                              <1> 	; 
  2136                              <1> 	; 'getc' gets (next) character 
  2137                              <1> 	;	 from requested TTY (keyboard) buffer 
  2138                              <1> 	; INPUTS ->
  2139                              <1> 	;     [u.ttyn] = tty number (0 to 7) (8 is COM1, 9 is COM2)	
  2140                              <1> 	;     AL=0 -> Get (next) character from requested TTY buffer
  2141                              <1> 	;	(Keyboard buffer will point to 
  2142                              <1> 	;			next character at next call)
  2143                              <1> 	;     AL=1 -> Test a key is available in requested TTY buffer
  2144                              <1> 	;	(Keyboard buffer will point to 
  2145                              <1> 	;			current character at next call)
  2146                              <1> 	; OUTPUTS ->
  2147                              <1> 	;     (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
  2148                              <1> 	;     			 ZF=0 -> AX has (current) character
  2149                              <1> 	;      AL = ascii code
  2150                              <1> 	;      AH = scan code	(AH = line status for COM1 or COM2)	 			
  2151                              <1> 	; 		        (cf=1 -> error code/flags in AH)
  2152                              <1> 	; Original UNIX V1 'getc': 
  2153                              <1> 	;		get a character off character list
  2154                              <1> 	;
  2155                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))	
  2156                              <1> 	;
  2157                              <1> 	; 30/06/2015 (32 bit modifications)
  2158                              <1> 	; 16/07/2013
  2159                              <1> 	; mov 	[getctty], ah
  2160                              <1> 	;
  2161                              <1> 
  2162 00005B4B 8A25[796C0000]      <1> 	mov	ah, [u.ttyn] 	; 28/07/2013
  2163                              <1> getc_n:
  2164                              <1> 	; 30/06/2015
  2165 00005B51 08E4                <1> 	or	ah, ah
  2166 00005B53 740D                <1> 	jz	short getc0 
  2167 00005B55 D0E4                <1> 	shl	ah, 1
  2168 00005B57 0FB6DC              <1> 	movzx	ebx, ah
  2169 00005B5A 81C3[38670000]      <1> 	add	ebx, ttychr
  2170 00005B60 EB05                <1> 	jmp	short getc1
  2171                              <1> getc0:
  2172 00005B62 BB[38670000]        <1> 	mov	ebx, ttychr
  2173                              <1> getc1:
  2174 00005B67 668B0B              <1> 	mov	cx, [ebx] 	; ascii & scan code
  2175                              <1> 				; (by kb_int)	
  2176 00005B6A 6609C9              <1> 	or	cx, cx
  2177 00005B6D 7507                <1> 	jnz	short getc2
  2178 00005B6F 20C0                <1> 	and 	al, al
  2179 00005B71 7415                <1> 	jz	short getc_s
  2180                              <1> 	;xor	ax, ax
  2181                              <1> 	; 30/11/2021
  2182 00005B73 31C0                <1> 	xor	eax, eax
  2183 00005B75 C3                  <1> 	retn
  2184                              <1> getc2:	
  2185 00005B76 20C0                <1> 	and	al, al
  2186 00005B78 6689C8              <1> 	mov	ax, cx
  2187 00005B7B 66B90000            <1> 	mov	cx, 0
  2188 00005B7F 7506                <1> 	jnz	short getc3
  2189                              <1> getc_sn:
  2190 00005B81 66890B              <1> 	mov	[ebx], cx ; 0, reset
  2191 00005B84 6639C8              <1> 	cmp	ax, cx  ; zf = 0
  2192                              <1> getc3:
  2193 00005B87 C3                  <1> 	retn
  2194                              <1> getc_s:
  2195                              <1> 	; 12/11/2015
  2196                              <1> 	; 15/09/2015
  2197                              <1> 	; 01/07/2015
  2198                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
  2199                              <1> 	; 16/07/2013 - 14/02/2014 (Retro UNIX 8086 v1)
  2200                              <1> 	;
  2201                              <1> 	; tty  of the current process is not 
  2202                              <1> 	; current tty (ptty); so, current process only 
  2203                              <1> 	; can use keyboard input when its tty becomes 
  2204                              <1> 	; current tty (ptty).
  2205                              <1> 	; 'sleep' is for preventing an endless lock
  2206                              <1> 	; during this tty input request.
  2207                              <1> 	; (Because, the user is not looking at the video page
  2208                              <1> 	; of the process to undersand there is a keyboard
  2209                              <1> 	; input request.)
  2210                              <1> 	;
  2211                              <1> 	;((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
  2212                              <1> 	;
  2213                              <1> 	; 05/10/2013
  2214                              <1> 	; ah = byte ptr [u.ttyn] ; (tty number)
  2215                              <1> 	;
  2216                              <1> 	; 10/10/2013
  2217                              <1> gcw0:
  2218 00005B88 B10A                <1> 	mov	cl, 10 ; ch = 0
  2219                              <1> gcw1:	
  2220                              <1> 	; 12/11/2015
  2221 00005B8A E8C5D6FFFF          <1> 	call intract ; jumps to 'sysexit' if [u.quit] = FFFFh
  2222                              <1> 	; 10/10/2013
  2223 00005B8F E841EBFFFF          <1> 	call	idle
  2224 00005B94 668B03              <1> 	mov	ax, [ebx] 	; ascii & scan code
  2225                              <1> 				; (by kb_int)
  2226 00005B97 6609C0              <1> 	or	ax, ax
  2227                              <1> ;	jnz	short gcw3
  2228 00005B9A 7519                <1> 	jnz	short gcw2 ; 15/09/2015
  2229                              <1> 	; 30/06/2015
  2230 00005B9C FEC9                <1> 	dec	cl
  2231 00005B9E 75EA                <1> 	jnz	short gcw1
  2232                              <1> 	;
  2233 00005BA0 8A25[796C0000]      <1> 	mov	ah, [u.ttyn] 	; 20/10/2013
  2234                              <1> ;	; 10/12/2013
  2235                              <1> ;	cmp 	ah, [ptty]
  2236                              <1> ;	jne	short gcw2
  2237                              <1> ;	; 14/02/2014
  2238                              <1> ;	cmp	byte [u.uno], 1
  2239                              <1> ;	jna	short gcw0		
  2240                              <1> ;gcw2:
  2241 00005BA6 E8B7EBFFFF          <1> 	call	sleep
  2242                              <1> 	;
  2243                              <1> 	; 20/09/2013
  2244 00005BAB 8A25[796C0000]      <1> 	mov	ah, [u.ttyn]
  2245 00005BB1 30C0                <1> 	xor 	al, al
  2246 00005BB3 EB9C                <1> 	jmp	short getc_n
  2247                              <1> ;gcw3:
  2248                              <1> gcw2: 	; 15/09/2015
  2249                              <1> 	; 10/10/2013
  2250 00005BB5 30C9                <1> 	xor	cl, cl
  2251 00005BB7 EBC8                <1> 	jmp	short getc_sn
  2252                              <1> 
  2253                              <1> putc:	
  2254                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  2255                              <1> 	; 13/08/2015
  2256                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
  2257                              <1> 	; 15/05/2013 - 27/07/2014 (Retro UNIX 8086 v1)
  2258                              <1> 	;
  2259                              <1> 	; Retro UNIX 8086 v1 modification !
  2260                              <1> 	; 
  2261                              <1> 	; 'putc' puts a character 
  2262                              <1> 	;	 onto requested (tty) video page or
  2263                              <1> 	;	 serial port
  2264                              <1> 	; INPUTS ->
  2265                              <1> 	;     AL = ascii code of the character
  2266                              <1> 	;     AH = video page (tty) number (0 to 7)
  2267                              <1> 	;			  (8 is COM1, 9 is COM2)	
  2268                              <1> 	; OUTPUTS ->
  2269                              <1> 	;    (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
  2270                              <1> 	;      			ZF=0 -> AX has (current) character
  2271                              <1> 	;     cf=0 and AH = 0 -> no error
  2272                              <1> 	;     cf=1 and AH > 0 -> error (only for COM1 and COM2)
  2273                              <1> 	; 
  2274                              <1> 	; Original UNIX V1 'putc': 
  2275                              <1> 	;     put a character at the end of character list
  2276                              <1> 	;
  2277                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
  2278                              <1> 	;
  2279 00005BB9 80FC07              <1> 	cmp	ah, 7
  2280 00005BBC 770A                <1>         ja      short sndc ; 05/12/2021
  2281                              <1> 	; 30/06/2015
  2282 00005BBE 0FB6DC              <1> 	movzx	ebx, ah
  2283                              <1> 	; 13/08/2015
  2284 00005BC1 B407                <1> 	mov	ah, 07h ; black background, light gray character color
  2285 00005BC3 E9D2B6FFFF          <1> 	jmp	write_tty ; 'video.inc'
  2286                              <1> 
  2287                              <1> sndc:   ; <Send character>
  2288                              <1> 	;
  2289                              <1> 	; 12/01/2022
  2290                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
  2291                              <1> 	; 17/11/2015
  2292                              <1> 	; 16/11/2015
  2293                              <1> 	; 11/11/2015
  2294                              <1> 	; 10/11/2015
  2295                              <1> 	; 09/11/2015
  2296                              <1> 	; 08/11/2015
  2297                              <1> 	; 07/11/2015
  2298                              <1> 	; 06/11/2015 (serial4.asm, 'sendchr')	
  2299                              <1> 	; 29/10/2015
  2300                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
  2301                              <1> 	; 14/05/2013 - 28/07/2014 (Retro UNIX 8086 v1)
  2302                              <1> 	;
  2303                              <1> 	; Retro UNIX 8086 v1 feature only !
  2304                              <1> 	;
  2305                              <1> 	; ah = [u.ttyn]
  2306                              <1> 	;
  2307                              <1> 	; 30/06/2015
  2308 00005BC8 80EC08              <1> 	sub	ah, 8 ; ; 0 = tty8 or 1 = tty9
  2309                              <1> 	; 07/11/2015
  2310 00005BCB 0FB6DC              <1> 	movzx	ebx, ah ; serial port index (0 or 1)
  2311                              <1> sndc0:
  2312                              <1> 	; 07/11/2015
  2313 00005BCE E8DDEBFFFF          <1> 	call	isintr ; quit (ctrl+break) check
  2314 00005BD3 7405                <1> 	jz	short sndc1
  2315 00005BD5 E87AD6FFFF          <1> 	call	intract ; quit (ctrl+break) check
  2316                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
  2317                              <1> sndc1:
  2318                              <1> 	; 16/11/2015
  2319                              <1> 	;mov	cx, ax	; *** al = character (to be sent)
  2320                              <1> 	; 24/12/2021
  2321 00005BDA 89C1                <1> 	mov	ecx, eax ; *** al = character (to be sent)
  2322                              <1> sndcx:
  2323 00005BDC 8A83[7A670000]      <1> 	mov	al, [ebx+schar] ; last sent character
  2324 00005BE2 8AA3[78670000]      <1> 	mov	ah, [ebx+rchar] ; last received character
  2325                              <1> 	;
  2326                              <1> 	; 17/11/2015
  2327                              <1> 	; check 'request for response' status
  2328 00005BE8 80BB[74670000]00    <1> 	cmp	byte [ebx+req_resp], 0
  2329 00005BEF 740A                <1> 	jz	short query
  2330                              <1> response:
  2331 00005BF1 FE05[77670000]      <1> 	inc 	byte [comqr] ; query or response status
  2332 00005BF7 B0FF                <1> 	mov	al, 0FFh	 
  2333 00005BF9 EB14                <1> 	jmp	short sndc3
  2334                              <1> query:
  2335 00005BFB 08C0                <1> 	or 	al, al  ; 0 = query (also end of text)
  2336 00005BFD 750E                <1> 	jnz 	short sndc2 ; normal character
  2337                              <1> 	;cmp 	ah, 0FFh     ; is it responded by terminal ?
  2338                              <1> 	;je	short sndc2  ; yes, already responded
  2339                              <1> 	; 16/11/2015
  2340                              <1> 	; query: request for response (again)
  2341 00005BFF 8883[78670000]      <1> 	mov	[ebx+rchar], al ; 0 ; reset
  2342 00005C05 FE05[77670000]      <1> 	inc 	byte [comqr] ; query or response status
  2343 00005C0B EB02                <1> 	jmp	short sndc3
  2344                              <1> sndc2:
  2345 00005C0D 88C8                <1> 	mov	al, cl 	; *** character (to be sent)
  2346                              <1> sndc3:
  2347 00005C0F 8883[7A670000]      <1> 	mov	[ebx+schar], al ; current character (to be sent)
  2348 00005C15 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
  2349                              <1> 	; 30/06/2015
  2350 00005C17 E869CFFFFF          <1> 	call	sp_status ; get serial port status
  2351                              <1> 	; AL = Line status, AH = Modem status
  2352                              <1> 	; 07/11/2015
  2353 00005C1C A880                <1> 	test	al, 80h
  2354 00005C1E 7504                <1> 	jnz	short sndc4
  2355 00005C20 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
  2356 00005C22 751A                <1> 	jnz	short sndc5
  2357                              <1> sndc4: 	; Check line status again
  2358                              <1> 	; 16/11/2015
  2359                              <1> 	;push	cx
  2360                              <1> 	; 24/12/2021
  2361 00005C24 51                  <1> 	push	ecx
  2362                              <1> 	;mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
  2363                              <1> 	; 12/01/2022
  2364 00005C25 31C9                <1> 	xor	ecx, ecx
  2365 00005C27 B106                <1> 	mov	cl, 6
  2366 00005C29 E863B7FFFF          <1> 	call	WAITF
  2367                              <1> 	;pop	cx
  2368                              <1> 	; 24/12/1021
  2369 00005C2E 59                  <1> 	pop	ecx
  2370                              <1> 	;
  2371 00005C2F 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
  2372 00005C31 E84FCFFFFF          <1> 	call	sp_status ; get serial port status
  2373                              <1> 	; 16/11/2015
  2374                              <1> 	; 09/11/2015
  2375                              <1> 	; 08/11/2015
  2376 00005C36 A880                <1> 	test	al, 80h	; time out error
  2377 00005C38 7565                <1>         jnz     short sndc7
  2378 00005C3A A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
  2379 00005C3C 7461                <1>         jz	short sndc7
  2380                              <1> sndc5:  
  2381 00005C3E 8A83[7A670000]      <1> 	mov	al, [ebx+schar] ; character (to be sent)
  2382 00005C44 66BAF803            <1> 	mov	dx, 3F8h   ; data port (COM2)
  2383 00005C48 28DE                <1> 	sub	dh, bl
  2384 00005C4A EE                  <1> 	out	dx, al	   ; send on serial port
  2385                              <1> 	; 10/11/2015
  2386                              <1> 	; delay for 3*30 (3*(15..80)) micro seconds
  2387                              <1> 	; (to improve text flow to the terminal)
  2388                              <1> 	; ('diskette.inc': 'WAITF')
  2389                              <1> 	; Uses port 61h, bit 4 to have CPU speed independent waiting.
  2390                              <1> 	; (refresh periods = 1 per 30 microseconds on most machines)
  2391                              <1> 	;push	cx
  2392                              <1> 	; 24/12/2021
  2393 00005C4B 51                  <1> 	push	ecx
  2394                              <1> 	;mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
  2395                              <1> 	; 12/01/2022
  2396 00005C4C 29C9                <1> 	sub	ecx, ecx
  2397 00005C4E B106                <1> 	mov	cl, 6
  2398 00005C50 E83CB7FFFF          <1> 	call	WAITF
  2399                              <1> 	;pop	cx
  2400                              <1> 	; 24/12/1021
  2401 00005C55 59                  <1> 	pop	ecx
  2402                              <1>     	;
  2403                              <1> 	; 07/11/2015
  2404 00005C56 88D8                <1> 	mov	al, bl ; al = 0 (tty8) or 1 (tty9)
  2405                              <1> 	;
  2406 00005C58 E828CFFFFF          <1> 	call	sp_status ; get serial port status
  2407                              <1> 	; AL = Line status, AH = Modem status
  2408                              <1> 	;
  2409 00005C5D E84EEBFFFF          <1> 	call	isintr ; quit (ctrl+break) check
  2410 00005C62 7405                <1> 	jz	short sndc6
  2411 00005C64 E8EBD5FFFF          <1> 	call	intract ; quit (ctrl+break) check
  2412                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
  2413                              <1> sndc6:
  2414 00005C69 3C80                <1> 	cmp	al, 80h
  2415 00005C6B 7332                <1> 	jnb	short sndc7		
  2416                              <1> 	;
  2417 00005C6D 803D[77670000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
  2418 00005C74 7244                <1> 	jb	short sndc8 	; no, normal character
  2419 00005C76 883D[77670000]      <1> 	mov 	byte [comqr], bh ; 0 ; reset
  2420                              <1> 	; 17/11/2015
  2421 00005C7C E854EAFFFF          <1> 	call	idle
  2422                              <1> 	;
  2423 00005C81 38BB[7A670000]      <1> 	cmp	[ebx+schar], bh ; 0 ; query ?
  2424                              <1>         ;ja	sndc2       ; response (will be followed by
  2425                              <1> 			    ; a normal character)
  2426                              <1> 	; 24/12/2021
  2427 00005C87 7602                <1> 	jna	short sndc_10
  2428 00005C89 EB82                <1> 	jmp	sndc2
  2429                              <1> sndc_10:
  2430                              <1> 	; Query request must be responded by the terminal
  2431                              <1> 	; before sending a normal character !
  2432 00005C8B 53                  <1> 	push	ebx
  2433                              <1> 	;push	cx ; *** cl = character (to be sent)
  2434                              <1> 	; 24/12/2021
  2435 00005C8C 51                  <1> 	push	ecx ; *** cl = character (to be sent)
  2436 00005C8D 8A25[796C0000]      <1> 	mov	ah, [u.ttyn]
  2437 00005C93 E8CAEAFFFF          <1> 	call	sleep ; this process will be awakened by
  2438                              <1> 		      ; received data available interrupt
  2439                              <1> 	;pop	cx ; *** cl = character (to be sent)
  2440                              <1> 	; 24/12/2021
  2441 00005C98 59                  <1> 	pop	ecx ; *** cl = character (to be sent) 
  2442 00005C99 5B                  <1> 	pop	ebx
  2443 00005C9A E93DFFFFFF          <1>         jmp	sndcx
  2444                              <1> sndc7:
  2445                              <1> 	 ; 16/11/2015
  2446 00005C9F 803D[77670000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
  2447 00005CA6 7213                <1> 	jb	short sndc9 	; no
  2448                              <1> 	;
  2449 00005CA8 88BB[78670000]      <1> 	mov	[ebx+rchar], bh ; 0 ; reset
  2450 00005CAE 88BB[7A670000]      <1> 	mov	[ebx+schar], bh ; 0 ; reset
  2451                              <1> 	;
  2452 00005CB4 883D[77670000]      <1> 	mov	byte [comqr], bh ; 0 ; reset  
  2453                              <1> sndc8:
  2454 00005CBA F5                  <1> 	cmc  ; jnc -> jc, jb -> jnb
  2455                              <1> sndc9:
  2456                              <1> 	; AL = Line status, AH = Modem status
  2457 00005CBB C3                  <1> 	retn
  2458                              <1> 
  2459                              <1> get_cpos:
  2460                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
  2461                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
  2462                              <1> 	;
  2463                              <1> 	; INPUT -> bl = video page number
  2464                              <1> 	; RETURN -> dx = cursor position
  2465                              <1> 
  2466 00005CBC 53                  <1> 	push	ebx
  2467 00005CBD 83E30F              <1> 	and	ebx, 0Fh ; 07h ; tty0 to tty7
  2468 00005CC0 D0E3                <1> 	shl	bl, 1
  2469 00005CC2 81C3[26670000]      <1> 	add	ebx, cursor_posn
  2470 00005CC8 668B13              <1> 	mov	dx, [ebx]
  2471 00005CCB 5B                  <1> 	pop	ebx
  2472 00005CCC C3                  <1> 	retn
  2473                              <1> 
  2474                              <1> read_ac_current:
  2475                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
  2476                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
  2477                              <1> 	;
  2478                              <1> 	; INPUT -> bl = video page number
  2479                              <1> 	; RETURN -> ax = character (al) and attribute (ah)
  2480                              <1> 
  2481 00005CCD E82EB7FFFF          <1> 	call 	find_position ; 'video.inc'
  2482                              <1> 	; dx = status port
  2483                              <1> 	; esi = cursor location/address
  2484 00005CD2 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
  2485 00005CD8 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
  2486 00005CDB C3                  <1> 	retn
  2487                              <1> 
  2488                              <1> syssleep:
  2489                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
  2490                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
  2491                              <1> 	;
  2492                              <1> 	; Retro UNIX 8086 v1 feature only
  2493                              <1> 	; (INPUT -> none)
  2494                              <1> 	;
  2495 00005CDC 0FB61D[956C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  2496 00005CE3 8AA3[43680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  2497 00005CE9 E874EAFFFF          <1> 	call	sleep
  2498 00005CEE E974D4FFFF          <1> 	jmp	sysret
  2499                              <1> 
  2500                              <1> vp_clr:
  2501                              <1> 	; Reset/Clear Video Page
  2502                              <1> 	;
  2503                              <1> 	; 05/12/2021 - (Retro UNIX 386 v1.2)
  2504                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
  2505                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
  2506                              <1> 	;
  2507                              <1> 	; Retro UNIX 8086 v1 feature only !
  2508                              <1> 	;
  2509                              <1> 	; INPUTS -> 
  2510                              <1> 	;   BL = video page number	 
  2511                              <1> 	;
  2512                              <1> 	; OUTPUT ->
  2513                              <1> 	;   none
  2514                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
  2515                              <1> 	;
  2516                              <1> 	; 04/12/2013
  2517 00005CF3 28C0                <1> 	sub	al, al
  2518                              <1> 	; al = 0 (clear video page)
  2519                              <1> 	; bl = video page
  2520 00005CF5 B407                <1> 	mov	ah, 07h
  2521                              <1> 	; ah = 7 (attribute/color)
  2522                              <1> 	;xor 	cx, cx ; 0, left upper column (cl) & row (cl)
  2523                              <1> 	; 05/12/2021
  2524 00005CF7 31C9                <1> 	xor	ecx, ecx
  2525 00005CF9 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
  2526 00005CFD E828B7FFFF          <1> 	call	scroll_up
  2527                              <1> 	; bl = video page
  2528                              <1> 	;xor	dx, dx ; 0 (cursor position) 
  2529                              <1> 	; 05/12/2021
  2530 00005D02 31D2                <1> 	xor	edx, edx
  2531 00005D04 E99BB6FFFF          <1> 	jmp 	set_cpos
  2532                              <1> 
  2533                              <1> sysmsg:
  2534                              <1> 	; 11/12/2021
  2535                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
  2536                              <1> 	; 11/11/2015
  2537                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
  2538                              <1> 	; Print user-application message on user's console tty
  2539                              <1> 	;
  2540                              <1> 	; Input -> EBX = Message address
  2541                              <1> 	;	   ECX = Message length (max. 255)
  2542                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
  2543                              <1> 	;
  2544 00005D09 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
  2545                              <1> 	;ja	sysret ; nothing to do with big message size
  2546 00005D0F 7779                <1> 	ja	short sysmsg8 ; 11/12/2021
  2547 00005D11 08C9                <1> 	or	cl, cl
  2548                              <1> 	;jz	sysret
  2549 00005D13 7475                <1> 	jz	short sysmsg8 ; 11/12/2021
  2550 00005D15 20D2                <1> 	and	dl, dl
  2551 00005D17 7502                <1> 	jnz	short sysmsg0
  2552 00005D19 B207                <1> 	mov	dl, 07h ; default color
  2553                              <1> 		; (black background, light gray character)
  2554                              <1> sysmsg0:
  2555 00005D1B 891D[686C0000]      <1> 	mov	[u.base], ebx
  2556 00005D21 8815[37670000]      <1> 	mov	[ccolor], dl ; color attributes
  2557 00005D27 89E5                <1> 	mov	ebp, esp
  2558 00005D29 31DB                <1> 	xor	ebx, ebx ; 0
  2559 00005D2B 891D[706C0000]      <1> 	mov	[u.nread], ebx ; 0
  2560                              <1> 	;
  2561 00005D31 381D[B66C0000]      <1> 	cmp	[u.kcall], bl ; 0
  2562 00005D37 7772                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
  2563                              <1> 	;
  2564 00005D39 890D[6C6C0000]      <1> 	mov	[u.count], ecx
  2565 00005D3F 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ ; 04/12/2021
  2566                              <1> 	; 04/12/2021
  2567                              <1> 	; (dword alignment for esp)
  2568 00005D40 F6C103              <1> 	test	cl, 3
  2569 00005D43 7404                <1> 	jz	short sysmsg_7
  2570 00005D45 80C903              <1> 	or	cl, 3
  2571 00005D48 41                  <1> 	inc	ecx
  2572                              <1> sysmsg_7:
  2573 00005D49 29CC                <1> 	sub	esp, ecx
  2574 00005D4B 89E7                <1> 	mov	edi, esp
  2575 00005D4D 89E6                <1> 	mov	esi, esp
  2576 00005D4F 66891D[B06C0000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
  2577                              <1> 	; 11/11/2015 
  2578 00005D56 8A25[7A6C0000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
  2579                              <1> 	; 0 = none
  2580 00005D5C FECC                <1> 	dec	ah
  2581 00005D5E 790C                <1> 	jns	short sysmsg1 
  2582 00005D60 8A1D[956C0000]      <1> 	mov	bl, [u.uno] ; process number	
  2583 00005D66 8AA3[43680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
  2584                              <1> sysmsg1:
  2585 00005D6C 8825[796C0000]      <1> 	mov	[u.ttyn], ah
  2586                              <1> sysmsg2:
  2587 00005D72 E898F5FFFF          <1> 	call	cpass
  2588 00005D77 7416                <1> 	jz	short sysmsg5
  2589 00005D79 AA                  <1> 	stosb
  2590 00005D7A 20C0                <1> 	and	al, al
  2591 00005D7C 75F4                <1> 	jnz	short sysmsg2
  2592                              <1> sysmsg3:
  2593 00005D7E 80FC07              <1> 	cmp	ah, 7 ; tty number
  2594 00005D81 7711                <1> 	ja	short sysmsg6 ; serial port
  2595 00005D83 E83E000000          <1> 	call	print_cmsg
  2596                              <1> sysmsg4:
  2597 00005D88 89EC                <1> 	mov	esp, ebp
  2598                              <1> sysmsg8: ; 11/12/2021	
  2599 00005D8A E9D8D3FFFF          <1> 	jmp	sysret
  2600                              <1> sysmsg5:
  2601 00005D8F C60700              <1> 	mov	byte [edi], 0
  2602 00005D92 EBEA                <1> 	jmp	short sysmsg3
  2603                              <1> sysmsg6:
  2604 00005D94 8A06                <1> 	mov	al, [esi]
  2605 00005D96 E82DFEFFFF          <1> 	call	sndc
  2606 00005D9B 72EB                <1> 	jc	short sysmsg4
  2607 00005D9D 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
  2608 00005DA0 76E6                <1> 	jna	short sysmsg4
  2609 00005DA2 46                  <1> 	inc 	esi
  2610 00005DA3 8A25[796C0000]      <1> 	mov	ah, [u.ttyn]
  2611 00005DA9 EBE9                <1> 	jmp	short sysmsg6
  2612                              <1> 
  2613                              <1> sysmsgk: ; Temporary (01/07/2015)
  2614                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
  2615                              <1> 	; (ECX -character count- will not be considered)
  2616 00005DAB 8B35[686C0000]      <1> 	mov	esi, [u.base]
  2617 00005DB1 8A25[36670000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
  2618 00005DB7 8825[796C0000]      <1> 	mov	[u.ttyn], ah
  2619 00005DBD C605[B66C0000]00    <1> 	mov	byte [u.kcall], 0
  2620 00005DC4 EBB8                <1> 	jmp	short sysmsg3
  2621                              <1> 	
  2622                              <1> print_cmsg: 
  2623                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
  2624                              <1> 	;
  2625                              <1> 	; print message (on user's console tty) 
  2626                              <1> 	;	with requested color
  2627                              <1> 	;
  2628                              <1> 	; INPUTS:
  2629                              <1> 	;	esi = message address
  2630                              <1> 	;	[u.ttyn] = tty number (0 to 7)
  2631                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
  2632                              <1> 	;
  2633 00005DC6 AC                  <1> 	lodsb
  2634                              <1> pcmsg1:
  2635 00005DC7 56                  <1> 	push 	esi
  2636 00005DC8 0FB61D[796C0000]    <1>         movzx   ebx, byte [u.ttyn]
  2637 00005DCF 8A25[37670000]      <1> 	mov	ah, [ccolor]
  2638 00005DD5 E8C0B4FFFF          <1> 	call 	write_tty
  2639 00005DDA 5E                  <1> 	pop	esi
  2640 00005DDB AC                  <1> 	lodsb
  2641 00005DDC 20C0                <1> 	and 	al, al  ; 0
  2642 00005DDE 75E7                <1> 	jnz 	short pcmsg1
  2643 00005DE0 C3                  <1> 	retn
  2644                              <1> 
  2645                              <1> sysgeterr:
  2646                              <1> 	; 16/02/2022 - Retro UNIX 386 v1.2
  2647                              <1> 	; 09/12/2015
  2648                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
  2649                              <1> 	; Get last error number or page fault count
  2650                              <1> 	; (for debugging)
  2651                              <1> 	;
  2652                              <1> 	; Input -> EBX = return type
  2653                              <1> 	;	   0 = last error code (which is in 'u.error')	
  2654                              <1> 	;	   FFFFFFFFh = page fault count for running process
  2655                              <1> 	;	   FFFFFFFEh = total page fault count
  2656                              <1> 	;	   1 .. FFFFFFFDh = undefined 
  2657                              <1> 	;
  2658                              <1> 	; Output -> EAX = last error number or page fault count
  2659                              <1> 	;	   (depending on EBX input)
  2660                              <1> 	; 	
  2661 00005DE1 21DB                <1> 	and 	ebx, ebx
  2662 00005DE3 750F                <1> 	jnz	short glerr_2
  2663                              <1> glerr_0:
  2664 00005DE5 A1[B86C0000]        <1> 	mov	eax, [u.error]
  2665                              <1> glerr_1:
  2666 00005DEA A3[446C0000]        <1> 	mov	[u.r0], eax
  2667                              <1> 	;retn
  2668                              <1>  	; 16/02/2022 (BugFix)
  2669 00005DEF E973D3FFFF          <1> 	jmp	sysret
  2670                              <1> glerr_2:
  2671 00005DF4 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
  2672 00005DF5 74FD                <1> 	jz	short glerr_2 ; page fault count for process
  2673 00005DF7 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
  2674 00005DF8 75EB                <1> 	jnz	short glerr_0
  2675 00005DFA A1[BC670000]        <1> 	mov	eax, [PF_Count] ; total page fault count
  2676 00005DFF EBE9                <1>         jmp     short glerr_1
  2677                              <1> glerr_3:
  2678 00005E01 A1[BC6C0000]        <1> 	mov 	eax, [u.pfcount]
  2679 00005E06 EBE2                <1> 	jmp	short glerr_1
  2680                              <1> 
  2681                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - PRINTER BIOS (Functions)		
  2682                              <1> 
  2683                              <1> ;;; IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985 ;;; 
  2684                              <1> ;
  2685                              <1> ;--- INT 17 H ------------------------------------------------------------------
  2686                              <1> ; PRINTER_IO								       :
  2687                              <1> ;	THIS ROUTINE PROVIDES COMMUNICATION WITH THE PRINTER		       :
  2688                              <1> ; INPUT 								       :
  2689                              <1> ;	(AH)= 00H  PRINT THE CHARACTER IN (AL)				       :
  2690                              <1> ;		    ON RETURN, (AH)= 1 IF CHARACTER NOT BE PRINTED (TIME OUT)  :
  2691                              <1> ;		    OTHER BITS SET AS ON NORMAL STATUS CALL		       :
  2692                              <1> ;	(AH)= 01H  INITIALIZE THE PRINTER PORT				       :
  2693                              <1> ;		    RETURNS WITH (AH) SET WITH PRINTER STATUS		       :
  2694                              <1> ;	(AH)= 02H  READ THE PRINTER STATUS INTO (AH)			       :
  2695                              <1> ;		   7	   6	   5	   4	   3	   2-1	   0	       :
  2696                              <1> ;		   |	   |	   |	   |	   |	   |	   |_TIME OUT  :
  2697                              <1> ;		   |	   |	   |	   |	   |	   |		       :
  2698                              <1> ;		   |	   |	   |	   |	   |	   |_ UNUSED	       :
  2699                              <1> ;		   |	   |	   |	   |	   |			       :
  2700                              <1> ;		   |	   |	   |	   |	   |_ 1 = I/O ERROR	       :
  2701                              <1> ;		   |	   |	   |	   |				       :
  2702                              <1> ;		   |	   |	   |	   |_ 1 = SELECTED		       :
  2703                              <1> ;		   |	   |	   |					       :
  2704                              <1> ;		   |	   |	   |_ 1 = OUT OF PAPER			       :
  2705                              <1> ;		   |	   |						       :
  2706                              <1> ;		   |	   |_ 1 = ACKNOWLEDGE				       :
  2707                              <1> ;		   |							       :
  2708                              <1> ;		   |_ 1 = NOT BUSY					       :
  2709                              <1> ;									       :
  2710                              <1> ;	(DX) = PRINTER TO BE USED (0,1,2) CORRESPONDING TO ACTUAL VALUES       :
  2711                              <1> ;		IN @PRINTER_BASE AREA					       :
  2712                              <1> ; DATA AREA @PRINTER_BASE CONTAINS THE BASE ADDRESS OF THE PRINTER CARD(S)     :
  2713                              <1> ; AVAILABLE (LOCATED AT BEGINNING OF DATA SEGMENT, 408H ABSOLUTE, 3 WORDS)     :
  2714                              <1> ;									       :
  2715                              <1> ; DATA AREA @PRINT_TIM_OUT (BYTE) MAY BE CHANGED TO CAUSE DIFFERENT	       :
  2716                              <1> ; TIME OUT WAITS. DEFAULT=20 * 4					       :
  2717                              <1> ;									       :
  2718                              <1> ; REGISTERS	(AH) IS MODIFIED WITH STATUS INFORMATION		       :
  2719                              <1> ;		ALL OTHERS UNCHANGED					       :
  2720                              <1> ;-------------------------------------------------------------------------------
  2721                              <1> 
  2722                              <1> int17h:
  2723                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
  2724                              <1> 	; (Derived from: IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985)
  2725                              <1> 	;
  2726                              <1> 	; (Default printer port: 378h) ; LPT1
  2727                              <1> 	; (Number of printers = 1)
  2728                              <1> 	
  2729                              <1> 	PRINTER_BASE equ 378h ; LPT1
  2730                              <1> 	;PRINT_TIM_OUT equ 4*80*65536 
  2731                              <1> 			; (Ref: IBM PC-AT BIOS v2 PRT.ASM)	 
  2732                              <1> 
  2733                              <1> 	PRINT_TIM_OUT equ 36000 ; WAIT_PRN_NBUSY
  2734                              <1> 			; (Ref: AWARD BIOS 1999 ATORGS.ASM)		
  2735                              <1> 
  2736                              <1> 	; INPUT:
  2737                              <1> 	;	ah = 0 -> print the character in AL 
  2738                              <1> 	;		 (sys write with write count >0)
  2739                              <1> 	;	ah = 1 -> initialize printer port
  2740                              <1> 	;		 (sys open)	
  2741                              <1> 	;	ah = 2 -> read the printer status 
  2742                              <1> 	;		 (sys write with write count = 0)
  2743                              <1> 	; OUTPUT:
  2744                              <1> 	;	ah = printer status
  2745                              <1> 
  2746                              <1> 	; Modified registers: eax, ecx, edx
  2747                              <1> 
  2748                              <1> PRINTER_IO_1:
  2749 00005E08 08E4                <1> 	or	ah, ah
  2750 00005E0A 7417                <1> 	jz	short _b20
  2751 00005E0C FECC                <1> 	dec	ah
  2752 00005E0E 7444                <1> 	jz	short _b80
  2753                              <1> 	;dec 	ah
  2754                              <1> 	;jz	short _b50
  2755                              <1> _b50:
  2756                              <1> 	;-----	PRINTER STATUS
  2757                              <1> B50:
  2758 00005E10 50                  <1> 	push	eax		; SAVE (AL) REGISTER
  2759                              <1> B60:
  2760 00005E11 66BA7903            <1> 	mov	dx, PRINTER_BASE+1
  2761                              <1> 				; GET PRINTER ATTACHMENT BASE ADDRESS
  2762                              <1> 				; POINT TO CONTROL PORT
  2763 00005E15 EC                  <1> 	in	al, dx		; PRE-CHARGE +BUSY LINE IF FLOATING
  2764 00005E16 EC                  <1> 	in	al, dx		; GET PRINTER STATUS HARDWARE BITS
  2765 00005E17 88C4                <1> 	mov	ah, al		; SAVE
  2766 00005E19 80E4F8              <1> 	and	ah, 0F8h	; TURN OFF UNUSED BITS
  2767                              <1> B70:
  2768 00005E1C 5A                  <1> 	pop	edx		; RECOVER (AL) REGISTER
  2769 00005E1D 88D0                <1> 	mov	al, dl		; MOVE CHARACTER INTO (AL)
  2770 00005E1F 80F448              <1> 	xor	ah, 48h		; FLIP A COUPLE OF BITS
  2771                              <1> B10:
  2772 00005E22 C3                  <1> 	retn			; RETURN FROM ROUTINE WITH STATUS IN AH
  2773                              <1> _b20:
  2774                              <1> 	;-----	PRINT THE CHARACTER IN (AL)
  2775 00005E23 B9A08C0000          <1> 	mov	ecx, PRINT_TIM_OUT ; (1 second)
  2776                              <1> B20:
  2777 00005E28 50                  <1> 	push	eax		; SAVE VALUE TO PRINT
  2778 00005E29 66BA7803            <1> 	mov	dx, PRINTER_BASE
  2779 00005E2D EE                  <1> 	out	dx, al		; OUTPUT CHARACTER TO DATA PORT
  2780 00005E2E FEC2                <1> 	inc	dl		; POINT TO STATUS PORT
  2781                              <1> 
  2782                              <1> 	;-----	CHECK FOR PRINTER BUSY
  2783                              <1> B25:
  2784                              <1> 	;-----	WAIT BUSY
  2785                              <1> B35:
  2786 00005E30 EC                  <1> 	in	al, dx		; GET STATUS
  2787 00005E31 88C4                <1> 	mov	ah, al		; STATUS TO (AH) ALSO
  2788 00005E33 A880                <1> 	test	al, 80h		; IS THE PRINTER CURRENTLY BUSY? (*)
  2789 00005E35 750F                <1> 	jnz	short B40	; GO TO OUTPUT STROBE
  2790 00005E37 E831000000          <1> 	call	WAIT_REFRESH	; (wait for 30 micro seconds)
  2791 00005E3C E2F2                <1> 	loop	B35		; LOOP IF YES (*)
  2792                              <1> 
  2793 00005E3E 80CC01              <1> 	or	ah, 1		; SET ERROR FLAG
  2794 00005E41 80E4F9              <1> 	and	ah, 0F9h	; TURN OFF THE UNUSED BITS
  2795 00005E44 EBD6                <1> 	jmp	short B70	; RETURN WITH ERROR FLAG SET
  2796                              <1> 
  2797                              <1> B40:				; SEND STROBE PULSE
  2798 00005E46 B00D                <1> 	mov	al, 0Dh		; SET THE STROBE LOW (BIT ON)
  2799 00005E48 6642                <1> 	inc	dx		; OUTPUT STROBE TO CONTROL PORT
  2800 00005E4A FA                  <1> 	cli			; PREVENT INTERRUPT PULSE STRETCHING
  2801 00005E4B EE                  <1> 	out	dx, al		; OUTPUT STROBE BIT > 1us < 5us
  2802                              <1> 	; IODELAY
  2803                              <1> 	;jmp	short $+2	; I/O DELAY TO ALLOW FOR LINE LOADING
  2804                              <1> 	;jmp	short $+2	; AND FOR CORRECT PULSE WIDTH
  2805                              <1> 	; NEWIODELAY
  2806 00005E4C E6EB                <1> 	out	0EBh, al
  2807                              <1> 
  2808 00005E4E B00C                <1> 	mov	al, 0Ch		; SET THE -STROBE HIGH
  2809 00005E50 EE                  <1> 	out	dx, al
  2810 00005E51 FB                  <1> 	sti			; INTERRUPTS BACK ON
  2811                              <1> 	;pop	eax		; RECOVER THE OUTPUT CHAR
  2812                              <1> 	;jmp	short B50
  2813 00005E52 EBBD                <1> 	jmp	short B60
  2814                              <1> 
  2815                              <1> _b80:
  2816                              <1> 	;-----	INITIALIZE THE PRINTER PORT
  2817                              <1> B80:
  2818 00005E54 50                  <1> 	push	eax		; SAVE (AL)
  2819 00005E55 66BA7A03            <1> 	mov	dx, PRINTER_BASE+2 ; POINT TO OUTPUT PORT
  2820 00005E59 B008                <1> 	mov	al, 8		; SET INIT LINE LOW
  2821 00005E5B EE                  <1> 	out	dx, al
  2822                              <1> 	;mov	eax, 1000*4	; ADJUST FOR INITIALIZATION DELAY LOOP
  2823 00005E5C B989080000          <1> 	mov	ecx, WAIT_PRN_INIT ; (65536 micro seconds)
  2824                              <1> B90:				; INIT_LOOP
  2825                              <1> 	;dec	eax		; LOOP FOR RESET TO TAKE
  2826                              <1> 	;jnz	short B90	; INIT_LOOP
  2827 00005E61 E807000000          <1> 	call	WAIT_REFRESH	; (wait for 30 micro seconds)
  2828 00005E66 E2F9                <1> 	loop	B90	
  2829 00005E68 B00C                <1> 	mov	al, 0Ch		; NO INTERRUPTS, NON AUTO LF, INIT HIGH
  2830 00005E6A EE                  <1> 	out	dx, al
  2831 00005E6B EBA4                <1> 	jmp	short B60	; EXIT THROUGH STATUS ROUTINE
  2832                              <1> 
  2833                              <1> 
  2834                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  2835                              <1> ; -------------------------------------------------------------------
  2836                              <1> ;
  2837                              <1> ;;Wait while printer initializes should be 65,536 microseconds.
  2838                              <1> ;;65536/30 = 2185
  2839                              <1> ;			PUBLIC	WAIT_PRN_INIT_LO
  2840                              <1> ;WAIT_PRN_INIT_LO	DW	2185
  2841                              <1> ;			PUBLIC	WAIT_PRN_INIT_HI
  2842                              <1> ;WAIT_PRN_INIT_HI	DW	0
  2843                              <1> ;
  2844                              <1> WAIT_PRN_INIT equ 2185 ; 12/06/2022
  2845                              <1> ;
  2846                              <1> ;;Wait for printer not busy should be 1,080,000 microseconds.
  2847                              <1> ;;Memory refresh =15 us, therefore memory refresh period = 30 Us.
  2848                              <1> ;;1,080,000 / 30 = 36,000
  2849                              <1> ;			PUBLIC	WAIT_PRN_NBUSY_LO
  2850                              <1> ;WAIT_PRN_NBUSY_LO	DW	36000
  2851                              <1> ;			PUBLIC	WAIT_PRN_NBUSY_HI
  2852                              <1> ;WAIT_PRN_NBUSY_HI	DB	0
  2853                              <1> ;
  2854                              <1> ;WAIT_PRN_NBUSY	equ 36000 ; 12/06/2022
  2855                              <1> 
  2856                              <1> ; AWARD BIOS - 1999 - ATORGS.ASM (27/5/1999)
  2857                              <1> ; ------------------------------------------
  2858                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  2859                              <1> ;   	INPUT: BX:CX = number of refresh periods to wait
  2860                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  2861                              <1> ;	OUTPUT: BX:CX destroyed.
  2862                              <1> ;
  2863                              <1> ;	SAVES:	AX (except when NO STACK)
  2864                              <1> ;
  2865                              <1> ;	NOTES:	This routine can be (and is) used with no stack. When
  2866                              <1> ;		used this way, AX is assumed to be destroyed.
  2867                              <1> 
  2868                              <1> WAIT_REFRESH:
  2869                              <1> 	; 12/06/2022
  2870                              <1> 	; Modified for Retro UNIX 386 v1.2
  2871                              <1> 	
  2872                              <1> 	; (wait for 30 micro seconds)
  2873                              <1> 
  2874                              <1> 	SYS1	equ 61h ; PORT_B
  2875                              <1> 
  2876                              <1> WR_SHORT:
  2877 00005E6D 50                  <1> 	push	eax
  2878                              <1> WR_STAT_0:
  2879 00005E6E E461                <1> 	in	al, SYS1	; wait for high to low
  2880 00005E70 A810                <1> 	test	al, 10h		; transition on memory
  2881 00005E72 75FA                <1> 	jnz	short WR_STAT_0 
  2882                              <1> WR_STAT_1:
  2883 00005E74 E461                <1> 	in	al, SYS1
  2884 00005E76 A810                <1> 	test	al, 10h
  2885 00005E78 74FA                <1> 	jz	short WR_STAT_1
  2886 00005E7A 58                  <1> 	pop	eax
  2887 00005E7B C3                  <1> 	retn
  2098                                  
  2099                                  ; 07/03/2015
  2100                                  ; Temporary Code
  2101                                  display_disks:
  2102 00005E7C 803D[2C620000]00        	cmp 	byte [fd0_type], 0
  2103 00005E83 7605                    	jna 	short ddsks1
  2104 00005E85 E87D000000              	call	pdskm
  2105                                  ddsks1:
  2106 00005E8A 803D[2D620000]00        	cmp	byte [fd1_type], 0
  2107 00005E91 760C                    	jna	short ddsks2
  2108 00005E93 C605[F3630000]31        	mov	byte [dskx], '1'
  2109 00005E9A E868000000              	call	pdskm
  2110                                  ddsks2:
  2111 00005E9F 803D[2E620000]00        	cmp	byte [hd0_type], 0
  2112 00005EA6 7654                    	jna	short ddsk6
  2113 00005EA8 66C705[F1630000]68-     	mov	word [dsktype], 'hd'
  2113 00005EB0 64                 
  2114 00005EB1 C605[F3630000]30        	mov	byte [dskx], '0'
  2115 00005EB8 E84A000000              	call	pdskm
  2116                                  ddsks3:
  2117 00005EBD 803D[2F620000]00        	cmp	byte [hd1_type], 0
  2118 00005EC4 7636                    	jna	short ddsk6
  2119 00005EC6 C605[F3630000]31        	mov	byte [dskx], '1'
  2120 00005ECD E835000000              	call	pdskm
  2121                                  ddsks4:
  2122 00005ED2 803D[30620000]00        	cmp	byte [hd2_type], 0
  2123 00005ED9 7621                    	jna	short ddsk6
  2124 00005EDB C605[F3630000]32        	mov	byte [dskx], '2'
  2125 00005EE2 E820000000              	call	pdskm
  2126                                  ddsks5:
  2127 00005EE7 803D[31620000]00        	cmp	byte [hd3_type], 0
  2128 00005EEE 760C                    	jna	short ddsk6
  2129 00005EF0 C605[F3630000]33        	mov	byte [dskx], '3'
  2130 00005EF7 E80B000000              	call	pdskm
  2131                                  ddsk6:
  2132 00005EFC BE[02640000]            	mov	esi, nextline
  2133 00005F01 E806000000              	call	pdskml
  2134                                  pdskm_ok:
  2135 00005F06 C3                      	retn
  2136                                  pdskm:
  2137 00005F07 BE[EF630000]            	mov	esi, dsk_ready_msg
  2138                                  pdskml:	
  2139 00005F0C AC                      	lodsb
  2140 00005F0D 08C0                    	or	al, al
  2141 00005F0F 74F5                    	jz	short pdskm_ok
  2142 00005F11 56                      	push	esi
  2143 00005F12 31DB                    	xor	ebx, ebx ; 0
  2144                                  			; Video page 0 (bl=0)
  2145 00005F14 B407                    	mov	ah, 07h ; Black background, 
  2146                                  			; light gray forecolor
  2147 00005F16 E87FB3FFFF              	call	write_tty
  2148 00005F1B 5E                      	pop	esi
  2149 00005F1C EBEE                    	jmp	short pdskml
  2150                                  
  2151 00005F1E 90<rep 2h>              align 16
  2152                                  
  2153                                  gdt:	; Global Descriptor Table
  2154                                  	; (30/07/2015, conforming cs)
  2155                                  	; (26/03/2015)
  2156                                  	; (24/03/2015, tss)
  2157                                  	; (19/03/2015)
  2158                                  	; (29/12/2013)
  2159                                  	;
  2160 00005F20 0000000000000000        	dw 0, 0, 0, 0	; NULL descriptor
  2161                                  	; 18/08/2014
  2162                                  			; 08h kernel code segment, base = 00000000h		
  2163 00005F28 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
  2164                                  			; 10h kernel data segment, base = 00000000h	
  2165 00005F30 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
  2166                                  			; 1Bh user code segment, base address = 400000h ; CORE
  2167 00005F38 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
  2168                                  			; 23h user data segment, base address = 400000h ; CORE
  2169 00005F40 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
  2170                                  			; Task State Segment
  2171 00005F48 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
  2172                                  			       ;  no IO permission in ring 3)
  2173                                  gdt_tss0:
  2174 00005F4A 0000                    	dw 0 ; TSS base address, bits 0-15 
  2175                                  gdt_tss1:
  2176 00005F4C 00                      	db 0 ; TSS base address, bits 16-23 
  2177                                  	      		; 49h	
  2178 00005F4D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
  2179 00005F4E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
  2180                                  gdt_tss2:
  2181 00005F4F 00                      	db 0 ; TSS base address, bits 24-31 
  2182                                  
  2183                                  gdt_end:
  2184                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2185                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2186                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2187                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2188                                  
  2189                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2190                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2191                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2192                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2193                                  		; W= Writeable, A= Accessed
  2194                                  	
  2195                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
  2196                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2197                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2198                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2199                                  
  2200                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
  2201                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2202                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2203                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2204                                  	
  2205                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
  2206                                  
  2207                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
  2208                                  		;	 = 100000h * 1000h (G=1) = 4GB
  2209                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
  2210                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
  2211                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
  2212                                  		; AVL= Available to programmers	
  2213                                  
  2214                                  gdtd:
  2215 00005F50 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
  2216 00005F52 [205F0000]                      dd gdt			; Address of the GDT
  2217                                  
  2218                                  	; 20/08/2014
  2219                                  idtd:
  2220 00005F56 FF01                            dw idt_end - idt - 1    ; Limit (size)
  2221 00005F58 [A0640000]                      dd idt			; Address of the IDT
  2222                                  
  2223                                  align 4
  2224                                  	; 21/08/2014
  2225                                  ilist:
  2226                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
  2227                                  	;
  2228                                  	; Exception list
  2229                                  	; 25/08/2014	
  2230 00005F5C [03080000]              	dd	exc0	; 0h,  Divide-by-zero Error
  2231 00005F60 [0A080000]              	dd	exc1	
  2232 00005F64 [11080000]              	dd 	exc2	
  2233 00005F68 [18080000]              	dd	exc3	
  2234 00005F6C [1C080000]              	dd	exc4	
  2235 00005F70 [20080000]              	dd	exc5	
  2236 00005F74 [24080000]              	dd 	exc6	; 06h,  Invalid Opcode
  2237 00005F78 [28080000]              	dd	exc7	
  2238 00005F7C [2C080000]              	dd	exc8	
  2239 00005F80 [30080000]              	dd	exc9	
  2240 00005F84 [34080000]              	dd 	exc10	
  2241 00005F88 [38080000]              	dd	exc11
  2242 00005F8C [3C080000]              	dd	exc12
  2243 00005F90 [40080000]              	dd	exc13	; 0Dh, General Protection Fault
  2244 00005F94 [44080000]              	dd 	exc14	; 0Eh, Page Fault
  2245 00005F98 [48080000]              	dd	exc15
  2246 00005F9C [4C080000]              	dd	exc16
  2247 00005FA0 [50080000]              	dd	exc17
  2248 00005FA4 [54080000]              	dd 	exc18
  2249 00005FA8 [58080000]              	dd	exc19
  2250 00005FAC [5C080000]              	dd 	exc20
  2251 00005FB0 [60080000]              	dd	exc21
  2252 00005FB4 [64080000]              	dd	exc22
  2253 00005FB8 [68080000]              	dd	exc23
  2254 00005FBC [6C080000]              	dd 	exc24
  2255 00005FC0 [70080000]              	dd	exc25
  2256 00005FC4 [74080000]              	dd	exc26
  2257 00005FC8 [78080000]              	dd	exc27
  2258 00005FCC [7C080000]              	dd 	exc28
  2259 00005FD0 [80080000]              	dd	exc29
  2260 00005FD4 [84080000]              	dd 	exc30
  2261 00005FD8 [88080000]              	dd	exc31
  2262                                  	; Interrupt list
  2263 00005FDC [3E060000]              	dd	timer_int	; INT 20h
  2264                                  		;dd	irq0	
  2265 00005FE0 [420B0000]              	dd	keyb_int	; 27/08/2014
  2266                                  		;dd	irq1
  2267 00005FE4 [5D070000]              	dd	irq2
  2268                                  		; COM2 int
  2269 00005FE8 [61070000]              	dd	irq3
  2270                                  		; COM1 int
  2271 00005FEC [6C070000]              	dd	irq4
  2272 00005FF0 [77070000]              	dd	irq5
  2273                                  ;DISKETTE_INT: ;06/02/2015
  2274 00005FF4 [AE1E0000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
  2275                                  		;dd	irq6
  2276                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2277                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2278 00005FF8 [F30A0000]              	dd	default_irq7	; 25/02/2015
  2279                                  		;dd	irq7
  2280                                  ; Real Time Clock Interrupt
  2281 00005FFC [91090000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
  2282                                  		;dd	irq8	; INT 28h
  2283 00006000 [87070000]              	dd	irq9
  2284 00006004 [8B070000]              	dd	irq10
  2285 00006008 [8F070000]              	dd	irq11
  2286 0000600C [93070000]              	dd	irq12
  2287 00006010 [97070000]              	dd	irq13
  2288                                  ;HDISK_INT1:  ;06/02/2015 	
  2289 00006014 [7E230000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
  2290                                  		;dd	irq14
  2291                                  ;HDISK_INT2:  ;06/02/2015
  2292 00006018 [A1230000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
  2293                                  		;dd	irq15	; INT 2Fh
  2294                                  		; 14/08/2015
  2295 0000601C [43300000]              	dd	sysent		; INT 30h (system calls)
  2296                                  	
  2297                                  	;dd	ignore_int
  2298 00006020 00000000                	dd	0
  2299                                  
  2300                                  ;;;
  2301                                  ;;; 11/03/2015
  2302                                  %include 'kybdata.s'	; KEYBOARD (BIOS) DATA
  2303                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - KYBDATA.INC
  2304                              <1> ; Last Modification: 11/06/2022
  2305                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
  2306                              <1> ;
  2307                              <1> ; ///////// KEYBOARD DATA ///////////////
  2308                              <1> 
  2309                              <1> ; 11/03/2015
  2310                              <1> ; 05/12/2014
  2311                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
  2312                              <1> ; 03/06/86  KEYBOARD BIOS
  2313                              <1> 
  2314                              <1> ;---------------------------------------------------------------------------------
  2315                              <1> ;	KEY IDENTIFICATION SCAN TABLES
  2316                              <1> ;---------------------------------------------------------------------------------
  2317                              <1> 
  2318                              <1> ;-----	TABLES FOR ALT CASE ------------
  2319                              <1> ;-----	ALT-INPUT-TABLE 
  2320 00006024 524F50514B          <1> K30:	db	82,79,80,81,75
  2321 00006029 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
  2322                              <1> ;-----	SUPER-SHIFT-TABLE 
  2323 0000602E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
  2324 00006034 161718191E1F        <1> 	db	22,23,24,25,30,31
  2325 0000603A 202122232425        <1> 	db	32,33,34,35,36,37
  2326 00006040 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
  2327 00006046 3132                <1> 	db	49,50
  2328                              <1> 
  2329                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
  2330                              <1> ;-----	KEY_TABLE 
  2331 00006048 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
  2332 00006049 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
  2333 0000604E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
  2334                              <1> _K6L    equ     $-_K6
  2335                              <1> 
  2336                              <1> ;-----	MASK_TABLE
  2337 00006050 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
  2338 00006051 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
  2339 00006056 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
  2340                              <1> 
  2341                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
  2342 00006058 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
  2343 0000605E 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
  2344                              <1> 	;db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
  2345 00006064 FF7F94111705        <1> 	db	-1,127,148,17,23,5 ; 11/06/2022
  2346 0000606A 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
  2347 00006070 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
  2348 00006076 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
  2349 0000607C 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
  2350 00006082 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
  2351 00006088 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
  2352 0000608E 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
  2353                              <1> 	;				;----- FUNCTIONS ------		
  2354 00006092 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
  2355 00006098 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
  2356 0000609E 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
  2357 000060A4 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
  2358 000060AA 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
  2359                              <1> 
  2360                              <1> ;-----	TABLES FOR LOWER CASE ----------
  2361 000060B0 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
  2361 000060B9 39302D3D0809        <1>
  2362 000060BF 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
  2362 000060C8 705B5D0DFF61736466- <1>
  2362 000060D1 67686A6B6C3B27      <1>
  2363 000060D8 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
  2363 000060E1 6D2C2E2FFF2AFF20FF  <1>
  2364                              <1> ;-----	LC TABLE SCAN
  2365 000060EA 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
  2366 000060EF 4041424344          <1> 	db	64,65,66,67,68
  2367 000060F4 FFFF                <1> 	db	-1,-1			; NL, SL
  2368                              <1> 
  2369                              <1> ;-----	KEYPAD TABLE
  2370 000060F6 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
  2371 000060FC 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
  2372 00006103 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
  2373                              <1> 
  2374                              <1> ;-----	TABLES FOR UPPER CASE ----------
  2375 00006108 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
  2375 00006111 28295F2B0800        <1>
  2376 00006117 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
  2376 00006120 507B7D0DFF41534446- <1>
  2376 00006129 47484A4B4C3A22      <1>
  2377 00006130 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
  2377 00006139 4D3C3E3FFF2AFF20FF  <1>
  2378                              <1> ;-----	UC TABLE SCAN
  2379 00006142 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
  2380 00006147 595A5B5C5D          <1> 	db	89,90,91,92,93
  2381 0000614C FFFF                <1> 	db	-1,-1			; NL, SL
  2382                              <1> 
  2383                              <1> ;-----	NUM STATE TABLE
  2384 0000614E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
  2384 00006157 3233302E            <1>
  2385                              <1> 	;
  2386 0000615B FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
  2387                              <1> 
  2388                              <1> Align	4
  2389                              <1> ;----------------------------------------
  2390                              <1> ;	VIDEO DISPLAY DATA AREA		;
  2391                              <1> ;----------------------------------------
  2392 00006160 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
  2393 00006161 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
  2394                              <1> 				; (29h default setting for video mode 3)
  2395                              <1> 				; Mode Select register Bits
  2396                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
  2397                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
  2398                              <1> 				;   BIT 2 - COLOR (0), BW (1)
  2399                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
  2400                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
  2401                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
  2402                              <1> 				;   BIT 6, 7 - Not Used
  2403                              <1> 
  2404                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
  2405                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
  2406                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
  2407                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
  2408                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
  2409                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
  2410                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
  2411                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
  2412                              <1> ; Mode & 37h = Video signal OFF
  2413                              <1> 			
  2414                              <1> 
  2415                              <1> ; 26/08/2014
  2416                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
  2417                              <1> ; Derived from IBM "pc-at" 
  2418                              <1> ; rombios source code (06/10/1985)
  2419                              <1> ; 'dseg.inc'
  2420                              <1> 
  2421                              <1> ;---------------------------------------;
  2422                              <1> ;	SYSTEM DATA AREA		;
  2423                              <1> ;----------------------------------------
  2424 00006162 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
  2425                              <1> 
  2426                              <1> ;----------------------------------------
  2427                              <1> ;	KEYBOARD DATA AREAS		;
  2428                              <1> ;----------------------------------------
  2429                              <1> 
  2430 00006163 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
  2431 00006164 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
  2432 00006165 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
  2433 00006166 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
  2434 00006167 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
  2435 00006168 [78610000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
  2436 0000616C [98610000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
  2437 00006170 [78610000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
  2438 00006174 [78610000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
  2439                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
  2440 00006178 0000<rep 10h>       <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
  2441                              <1> 
  2442                              <1> ; /// End Of KEYBOARD DATA ///
  2303                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
  2304                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.INC
  2305                              <1> ; Last Modification: 11/03/2015
  2306                              <1> ;		    (Data section for 'VIDEO.INC')	
  2307                              <1> ;
  2308                              <1> ; ///////// VIDEO DATA ///////////////
  2309                              <1> 
  2310                              <1> video_params:
  2311                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  2312                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
  2313                              <1> 	; VIDEO MODE 3
  2314 00006198 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
  2315 0000619F 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
  2316 000061A4 00000000            <1> 	db	0,0,0,0
  2317                              <1> 
  2318                              <1> ; /// End Of VIDEO DATA ///
  2304                                  %include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
  2305                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKBSS.INC
  2306                              <1> ; Last Modification: 12/07/2022 
  2307                              <1> ; *****************************************************************************
  2308                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
  2309                              <1> ; *****************************************************************************
  2310                              <1> ; Ref: Retro UNIX 386 v1 Kernel (v0.2.1.5) - DISKDATA.INC - 11/07/2022
  2311                              <1> 
  2312                              <1> ;----------------------------------------
  2313                              <1> ;	80286 INTERRUPT LOCATIONS	:
  2314                              <1> ;	REFERENCED BY POST & BIOS	:
  2315                              <1> ;----------------------------------------
  2316                              <1> 
  2317 000061A8 [0B620000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
  2318                              <1> 
  2319                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
  2320                              <1> ;----------------------------------------------------------------
  2321                              <1> ; DISK_BASE							:
  2322                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
  2323                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
  2324                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
  2325                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
  2326                              <1> ;----------------------------------------------------------------
  2327                              <1> 
  2328                              <1> ;DISK_BASE:	
  2329                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2330                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2331                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2332                              <1> ;	DB	2		; 512 BYTES/SECTOR
  2333                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
  2334                              <1> ;	db	18		; (EOT for 1.44MB diskette)
  2335                              <1> ;	DB	01BH		; GAP LENGTH
  2336                              <1> ;	DB	0FFH		; DTL
  2337                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
  2338                              <1> ;	db	06ch		; (for 1.44MB dsikette)
  2339                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
  2340                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
  2341                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
  2342                              <1> 
  2343                              <1> ;----------------------------------------
  2344                              <1> ;	ROM BIOS DATA AREAS		:
  2345                              <1> ;----------------------------------------
  2346                              <1> 
  2347                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
  2348                              <1> 
  2349                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
  2350                              <1> 
  2351                              <1> ;----------------------------------------
  2352                              <1> ;	DISKETTE DATA AREAS		:
  2353                              <1> ;----------------------------------------
  2354                              <1> 
  2355                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
  2356                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
  2357                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
  2358                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
  2359                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
  2360                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
  2361                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
  2362                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
  2363                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
  2364                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
  2365                              <1> 
  2366                              <1> ;----------------------------------------
  2367                              <1> ;	POST AND BIOS WORK DATA AREA	:
  2368                              <1> ;----------------------------------------
  2369                              <1> 
  2370                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
  2371                              <1> 
  2372                              <1> ;----------------------------------------
  2373                              <1> ;	TIMER DATA AREA 		:
  2374                              <1> ;----------------------------------------
  2375                              <1> 
  2376                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
  2377                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
  2378                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
  2379                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
  2380                              <1> 
  2381                              <1> ;----------------------------------------
  2382                              <1> ;	ADDITIONAL MEDIA DATA		:
  2383                              <1> ;----------------------------------------
  2384                              <1> 
  2385                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
  2386                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
  2387                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
  2388                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
  2389                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
  2390                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
  2391                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
  2392                              <1> 
  2393                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
  2394                              <1> 
  2395                              <1> ;--------------------------------------------------------
  2396                              <1> ;	DRIVE TYPE TABLE				:
  2397                              <1> ;--------------------------------------------------------
  2398                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
  2399                              <1> DR_TYPE:
  2400 000061AC 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
  2401                              <1>                 ;DW      MD_TBL1
  2402 000061AD [CA610000]          <1> 		dd	MD_TBL1
  2403 000061B1 82                  <1> 		DB	02+BIT7ON
  2404                              <1> 		;DW      MD_TBL2
  2405 000061B2 [D7610000]          <1>                 dd      MD_TBL2
  2406 000061B6 02                  <1> DR_DEFAULT:	DB	02
  2407                              <1>                 ;DW      MD_TBL3
  2408 000061B7 [E4610000]          <1> 		dd      MD_TBL3
  2409 000061BB 03                  <1> 		DB	03
  2410                              <1>                 ;DW      MD_TBL4
  2411 000061BC [F1610000]          <1> 		dd      MD_TBL4
  2412 000061C0 84                  <1> 		DB	04+BIT7ON
  2413                              <1>                 ;DW      MD_TBL5
  2414 000061C1 [FE610000]          <1> 		dd      MD_TBL5
  2415 000061C5 04                  <1> 		DB	04
  2416                              <1>                 ;DW      MD_TBL6
  2417 000061C6 [0B620000]          <1> 		dd      MD_TBL6
  2418                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
  2419                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
  2420                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
  2421                              <1> ;--------------------------------------------------------
  2422                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
  2423                              <1> ;--------------------------------------------------------
  2424                              <1> ;--------------------------------------------------------
  2425                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
  2426                              <1> ;--------------------------------------------------------
  2427                              <1> MD_TBL1:        
  2428 000061CA DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2429 000061CB 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2430 000061CC 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2431 000061CD 02                  <1> 	DB	2		; 512 BYTES/SECTOR
  2432 000061CE 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
  2433 000061CF 2A                  <1> 	DB	02AH		; GAP LENGTH
  2434 000061D0 FF                  <1> 	DB	0FFH		; DTL
  2435 000061D1 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
  2436 000061D2 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
  2437 000061D3 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
  2438 000061D4 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
  2439 000061D5 27                  <1> 	DB	39		; MAX. TRACK NUMBER
  2440 000061D6 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
  2441                              <1> ;--------------------------------------------------------
  2442                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
  2443                              <1> ;--------------------------------------------------------
  2444                              <1> MD_TBL2:        
  2445 000061D7 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2446 000061D8 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2447 000061D9 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2448 000061DA 02                  <1> 	DB	2		; 512 BYTES/SECTOR
  2449 000061DB 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
  2450 000061DC 2A                  <1> 	DB	02AH		; GAP LENGTH
  2451 000061DD FF                  <1> 	DB	0FFH		; DTL
  2452 000061DE 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
  2453 000061DF F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
  2454 000061E0 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
  2455 000061E1 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
  2456 000061E2 27                  <1> 	DB	39		; MAX. TRACK NUMBER
  2457 000061E3 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
  2458                              <1> ;--------------------------------------------------------
  2459                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
  2460                              <1> ;--------------------------------------------------------
  2461                              <1> MD_TBL3:
  2462 000061E4 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2463 000061E5 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2464 000061E6 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2465 000061E7 02                  <1> 	DB	2		; 512 BYTES/SECTOR
  2466 000061E8 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
  2467 000061E9 1B                  <1> 	DB	01BH		; GAP LENGTH
  2468 000061EA FF                  <1> 	DB	0FFH		; DTL
  2469 000061EB 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
  2470 000061EC F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
  2471 000061ED 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
  2472 000061EE 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
  2473 000061EF 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
  2474 000061F0 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
  2475                              <1> ;--------------------------------------------------------
  2476                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
  2477                              <1> ;--------------------------------------------------------
  2478                              <1> MD_TBL4:
  2479 000061F1 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2480 000061F2 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2481 000061F3 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2482 000061F4 02                  <1> 	DB	2		; 512 BYTES/SECTOR
  2483 000061F5 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
  2484 000061F6 2A                  <1> 	DB	02AH		; GAP LENGTH
  2485 000061F7 FF                  <1> 	DB	0FFH		; DTL
  2486 000061F8 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
  2487 000061F9 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
  2488 000061FA 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
  2489 000061FB 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
  2490 000061FC 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
  2491 000061FD 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
  2492                              <1> ;--------------------------------------------------------
  2493                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
  2494                              <1> ;--------------------------------------------------------
  2495                              <1> MD_TBL5:
  2496 000061FE DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2497 000061FF 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2498 00006200 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2499 00006201 02                  <1> 	DB	2		; 512 BYTES/SECTOR
  2500 00006202 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
  2501 00006203 2A                  <1> 	DB	02AH		; GAP LENGTH
  2502 00006204 FF                  <1> 	DB	0FFH		; DTL
  2503 00006205 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
  2504 00006206 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
  2505 00006207 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
  2506 00006208 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
  2507 00006209 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
  2508 0000620A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
  2509                              <1> ;--------------------------------------------------------
  2510                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
  2511                              <1> ;--------------------------------------------------------
  2512                              <1> MD_TBL6:
  2513 0000620B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
  2514 0000620C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  2515 0000620D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  2516 0000620E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
  2517 0000620F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
  2518 00006210 1B                  <1> 	DB	01BH		; GAP LENGTH
  2519 00006211 FF                  <1> 	DB	0FFH		; DTL
  2520 00006212 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
  2521 00006213 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
  2522 00006214 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
  2523 00006215 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
  2524 00006216 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
  2525 00006217 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
  2526                              <1> 
  2527                              <1> 
  2528                              <1> ; << diskette.inc >>
  2529                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2530                              <1> ;
  2531                              <1> ;----------------------------------------
  2532                              <1> ;	ROM BIOS DATA AREAS		:
  2533                              <1> ;----------------------------------------
  2534                              <1> 
  2535                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
  2536                              <1> 
  2537                              <1> ;----------------------------------------
  2538                              <1> ;	FIXED DISK DATA AREAS		:
  2539                              <1> ;----------------------------------------
  2540                              <1> 
  2541                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
  2542                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
  2543                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
  2544                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
  2545                              <1> 
  2546                              <1> ;----------------------------------------
  2547                              <1> ;	ADDITIONAL MEDIA DATA		:
  2548                              <1> ;----------------------------------------
  2549                              <1> 
  2550                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
  2551                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
  2552                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
  2553                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
  2554                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
  2555                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
  2556                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
  2557                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
  2558                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
  2559                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
  2560                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
  2561                              <1> 
  2562                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
  2563                              <1> ;
  2564                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2565                              <1> 
  2566                              <1> ERR_TBL:
  2567 00006218 E0                  <1> 	db	NO_ERR
  2568 00006219 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
  2569 0000621D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
  2570                              <1> 
  2571                              <1> ; 11/07/2022
  2572                              <1> ; 17/12/2014 (mov ax, [cfd])
  2573                              <1> ; 11/12/2014
  2574                              <1> ;cfd:		db 0			; current floppy drive (for GET_PARM)
  2575                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
  2576                              <1> ;pfd:		db 1			; previous floppy drive (for GET_PARM)
  2577                              <1> 					; (initial value of 'pfd 
  2578                              <1> 					; must be different then 'cfd' value
  2579                              <1> 					; to force updating/initializing
  2580                              <1> 					; current drive parameters) 
  2581                              <1> 
  2582                              <1> ;; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2583 00006221 FF                  <1> pfd:		db 0FFh
  2584                              <1> 
  2585                              <1> align 2
  2586                              <1> 
  2587 00006222 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
  2588                              <1> 			      ; (170h)
  2589 00006224 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
  2590                              <1> 
  2591                              <1> ; 05/01/2015 
  2592 00006226 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
  2593                              <1> 
  2594                              <1> ; *****************************************************************************
  2305                                  ;;;
  2306                                  
  2307 00006227 90                      align 2
  2308                                  
  2309                                  ; 12/11/2014 (Retro UNIX 386 v1)
  2310 00006228 00                      boot_drv:    db 0  ; boot drive number (physical)
  2311                                  ; 24/11/2014
  2312 00006229 00                      drv:	     db 0 
  2313 0000622A 00                      last_drv:    db 0  ; last hdd
  2314 0000622B 00                      hdc:         db 0  ; number of hard disk drives
  2315                                  		     ; (present/detected)
  2316                                  ;
  2317                                  ; 24/11/2014 (Retro UNIX 386 v1)
  2318                                  ; Physical drive type & flags
  2319 0000622C 00                      fd0_type:    db 0  ; floppy drive type
  2320 0000622D 00                      fd1_type:    db 0    ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
  2321                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
  2322                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
  2323                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
  2324                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
  2325 0000622E 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 - present flag)
  2326 0000622F 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 - present flag)
  2327 00006230 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 - present flag)
  2328 00006231 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 - present flag)
  2329                                  		     ; bit 0 - Fixed disk access subset supported
  2330                                  		     ; bit 1 - Drive locking and ejecting
  2331                                  		     ; bit 2 - Enhanced disk drive support
  2332                                  		     ; bit 3 - Reserved (64 bit EDD support)
  2333                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
  2334                                  		     ; will interpret it as 'LBA ready'!)		
  2335                                  
  2336                                  ; 12/07/2022
  2337                                  ; (drv.cylinders, drv.spt, drv.spt will not be used now on)
  2338                                  ; ('diskio.inc')
  2339                                  ; ((spt and heads and cylinder counts will be taken from DPT))
  2340                                  
  2341                                  ; 11/03/2015 - 10/07/2015
  2342                                  ;drv.cylinders: dw 0,0,0,0,0,0,0
  2343                                  ;drv.heads:     dw 0,0,0,0,0,0,0
  2344                                  ;drv.spt:       dw 0,0,0,0,0,0,0
  2345                                  ; 12/07/2022 - 11/03/2015
  2346 00006232 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
  2346 0000623B 000000000000000000-
  2346 00006244 000000000000000000-
  2346 0000624D 00                 
  2347 0000624E 00000000000000          drv.status:    db 0,0,0,0,0,0,0
  2348 00006255 00000000000000          drv.error:     db 0,0,0,0,0,0,0
  2349                                  ;
  2350                                  
  2351                                  ; 27/08/2014
  2352                                  scr_row:
  2353 0000625C E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
  2354                                  scr_col:
  2355 00006260 00000000                	dd 0
  2356                                  
  2357                                  ;; 14/08/2015
  2358                                  ;;msgPM:
  2359                                  ;;      db "Protected mode and paging are ENABLED ... ", 0
  2360                                  msgKVER:
  2361                                  	;;;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.0 [18/04/2022]", 0
  2362                                  	;;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.1 [08/06/2022]", 0
  2363                                  	;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.2 [14/06/2022]", 0
  2364 00006264 526574726F20554E49-     	db "Retro UNIX 386 v1.2 - Kernel v0.2.2.3 [24/07/2022]", 0
  2364 0000626D 58203338362076312E-
  2364 00006276 32202D204B65726E65-
  2364 0000627F 6C2076302E322E322E-
  2364 00006288 33205B32342F30372F-
  2364 00006291 323032325D00       
  2365                                  
  2366 00006297 90                      align 2
  2367                                  
  2368                                  ; 20/08/2014
  2369                                    ; /* This is the default interrupt "handler" :-) */ 
  2370                                    ; Linux v0.12 (head.s)
  2371                                  int_msg:
  2372 00006298 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
  2372 000062A1 6E7465727275707420-
  2372 000062AA 212000             
  2373                                  
  2374 000062AD 90                      align 2  
  2375                                  
  2376                                  ; 21/08/2014
  2377                                  timer_msg:
  2378 000062AE 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
  2378 000062B7 542032306829202120-
  2378 000062C0 54696D657220496E74-
  2378 000062C9 657272757074203A20 
  2379                                  tcountstr:
  2380 000062D2 303030303020            	db "00000 "
  2381 000062D8 00                      	db 0
  2382                                  
  2383 000062D9 90                      align 2
  2384                                  	; 21/08/2014
  2385                                  exc_msg:
  2386 000062DA 435055206578636570-     	db "CPU exception ! "
  2386 000062E3 74696F6E202120     
  2387                                  excnstr: 		; 25/08/2014
  2388 000062EA 3F3F68202045495020-     	db "??h", "  EIP : "
  2388 000062F3 3A20               
  2389                                  EIPstr: ; 29/08/2014
  2390 000062F5 00<rep Ch>              	times 12 db 0
  2391                                  rtc_msg:
  2392 00006301 5265616C2054696D65-     	db "Real Time Clock - "
  2392 0000630A 20436C6F636B202D20 
  2393                                  datestr:
  2394 00006313 30302F30302F303030-     	db "00/00/0000"
  2394 0000631C 30                 
  2395 0000631D 20                      	db " "
  2396                                  daystr:
  2397 0000631E 44415920                	db "DAY "
  2398                                  timestr:	
  2399 00006322 30303A30303A3030                db "00:00:00"
  2400 0000632A 20                      	db " "
  2401 0000632B 00                      	db 0 
  2402                                  
  2403                                  daytmp:
  2404                                  	; 28/02/2015
  2405 0000632C 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
  2405 00006335 4F4E20545545205745-
  2405 0000633E 442054485520465249-
  2405 00006347 2053415420         
  2406                                  
  2407 0000634C FF                      ptime_seconds: db 0FFh
  2408                                  
  2409                                  	; 23/02/2015
  2410                                  	; 25/08/2014
  2411                                  ;scounter:
  2412                                  ;	db 5
  2413                                  ;	db 19
  2414                                  
  2415                                  ; 28/11/2021
  2416                                  ;; 05/11/2014
  2417                                  ;msg_out_of_memory:
  2418                                  ;	db 	07h, 0Dh, 0Ah
  2419                                  ;	db	'Insufficient memory ! (Minimum 2 MB memory is needed.)'
  2420                                  ; 	db	0Dh, 0Ah, 0
  2421                                  	;
  2422                                  setup_error_msg:
  2423 0000634D 0D0A                    	db 0Dh, 0Ah
  2424 0000634F 4469736B2053657475-     	db 'Disk Setup Error!' 
  2424 00006358 70204572726F7221   
  2425 00006360 0D0A00                  	db 0Dh, 0Ah,0
  2426                                  
  2427                                  ; 02/09/2014 (Retro UNIX 386 v1)
  2428                                  ;crt_ulc: db 0 ; upper left column (for scroll) 
  2429                                  ;	  db 0 ; upper left row (for scroll)	
  2430                                  
  2431                                  ;crt_lrc: db 79 ; lower right column (for scroll) 
  2432                                  ;	  db 24 ; lower right row (for scroll)
  2433                                  
  2434                                  ; 06/11/2014 (Temporary Data)
  2435                                  ; Memory Information message
  2436                                  ; 14/08/2015
  2437                                  msg_memory_info:
  2438 00006363 07                      	db	07h
  2439 00006364 0D0A                    	db	0Dh, 0Ah
  2440                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
  2441 00006366 546F74616C206D656D-     	db	"Total memory : "
  2441 0000636F 6F7279203A20       
  2442                                  mem_total_b_str: ; 10 digits
  2443 00006375 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
  2443 0000637E 302062797465730D0A 
  2444 00006387 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2444 00006390 202020202020202020 
  2445                                  mem_total_p_str: ; 7 digits
  2446 00006399 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
  2446 000063A2 616765730D0A       
  2447 000063A8 0D0A                    	db 	0Dh, 0Ah
  2448 000063AA 46726565206D656D6F-     	db	"Free memory  : "
  2448 000063B3 727920203A20       
  2449                                  free_mem_b_str:  ; 10 digits
  2450 000063B9 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
  2450 000063C2 3F2062797465730D0A 
  2451 000063CB 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2451 000063D4 202020202020202020 
  2452                                  free_mem_p_str:  ; 7 digits
  2453 000063DD 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
  2453 000063E6 616765730D0A       
  2454 000063EC 0D0A00                  	db	0Dh, 0Ah, 0
  2455                                  
  2456                                  dsk_ready_msg:
  2457 000063EF 0D0A                    	db 	0Dh, 0Ah
  2458                                  dsktype:
  2459 000063F1 6664                    	db	'fd'
  2460                                  dskx:
  2461 000063F3 30                      	db	'0'
  2462 000063F4 20                      	db	20h
  2463 000063F5 697320524541445920-     	db 	'is READY ...'
  2463 000063FE 2E2E2E             
  2464 00006401 00                      	db 	0
  2465                                  nextline:
  2466 00006402 0D0A00                  	db 	0Dh, 0Ah, 0
  2467                                  
  2468                                  ; KERNEL - SYSINIT Messages
  2469                                  ; 24/08/2015
  2470                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
  2471                                  ; 14/07/2013
  2472                                  ;kernel_init_err_msg:
  2473                                  ;	db 0Dh, 0Ah
  2474                                  ;	db 07h
  2475                                  ;	db 'Kernel initialization ERROR !'
  2476                                  ;	db 0Dh, 0Ah, 0 
  2477                                  ; 24/08/2015
  2478                                  ;;; (temporary kernel init message has been removed
  2479                                  ;;;  from 'sys_init' code)
  2480                                  ;kernel_init_ok_msg: 
  2481                                  ;	db 0Dh, 0Ah
  2482                                  ;	db 07h
  2483                                  ;	db 'Welcome to Retro UNIX 386 v1.1 Operating System !'
  2484                                  ;	db 0Dh, 0Ah
  2485                                  ;       db 'by Erdogan Tan - 04/02/2016 (v0.2.1.0)'
  2486                                  ;	db 0Dh, 0Ah, 0
  2487                                  panic_msg:
  2488 00006405 0D0A07                  	db 0Dh, 0Ah, 07h
  2489 00006408 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
  2489 00006411 726E656C2050616E69-
  2489 0000641A 632021             
  2490 0000641D 0D0A00                  	db 0Dh, 0Ah, 0
  2491                                  etc_init_err_msg:
  2492 00006420 0D0A                    	db 0Dh, 0Ah
  2493 00006422 07                      	db 07h
  2494 00006423 4552524F523A202F65-     	db 'ERROR: /etc/init !?'
  2494 0000642C 74632F696E69742021-
  2494 00006435 3F                 
  2495 00006436 0D0A00                  	db 0Dh, 0Ah, 0
  2496                                  
  2497                                  ; 10/05/2015
  2498                                  badsys_msg:
  2499 00006439 0D0A                    	db 0Dh, 0Ah
  2500 0000643B 07                      	db 07h
  2501 0000643C 496E76616C69642053-     	db 'Invalid System Call !'
  2501 00006445 797374656D2043616C-
  2501 0000644E 6C2021             
  2502 00006451 0D0A                    	db 0Dh, 0Ah
  2503 00006453 4541583A20              	db 'EAX: '
  2504                                  bsys_msg_eax:
  2505 00006458 303030303030303068      	db '00000000h'
  2506 00006461 0D0A                    	db 0Dh, 0Ah
  2507 00006463 4549503A20              	db 'EIP: '
  2508                                  bsys_msg_eip:
  2509 00006468 303030303030303068      	db '00000000h' 
  2510 00006471 0D0A00                  	db 0Dh, 0Ah, 0
  2511                                  
  2512                                  BSYS_M_SIZE equ $ - badsys_msg
  2513                                  
  2514                                  align 2
  2515                                  
  2516                                  ; EPOCH Variables
  2517                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
  2518                                  ; 09/04/2013 epoch variables
  2519                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
  2520                                  ;
  2521 00006474 B207                    year: 	dw 1970
  2522                                  ;month: dw 1
  2523                                  ;day: 	dw 1
  2524                                  ;hour: 	dw 0
  2525                                  ;minute: dw 0
  2526                                  ;second: dw 0
  2527                                  ; 02/06/2022
  2528 00006476 01                      month:	db 1
  2529 00006477 01                      day:	db 1
  2530 00006478 01                      hour:	db 1
  2531 00006479 01                      minute: db 1
  2532 0000647A 01                      second:	db 1
  2533 0000647B 01                      	db 1
  2534                                  
  2535                                  DMonth:
  2536 0000647C 0000                    	dw 0
  2537 0000647E 1F00                    	dw 31
  2538 00006480 3B00                    	dw 59
  2539 00006482 5A00                    	dw 90
  2540 00006484 7800                    	dw 120
  2541 00006486 9700                    	dw 151
  2542 00006488 B500                    	dw 181
  2543 0000648A D400                    	dw 212
  2544 0000648C F300                    	dw 243
  2545 0000648E 1101                    	dw 273
  2546 00006490 3001                    	dw 304
  2547 00006492 4E01                    	dw 334
  2548                                  
  2549                                  ; 02/01/2022 (Retro UNIX 386 v1.2)
  2550                                  ; 04/11/2014 (Retro UNIX 386 v1)
  2551 00006494 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
  2552                                  		   ;   1 and 16 MB, max. 3C00h = 15 MB.
  2553 00006496 0000                    	     dw 0  ; 02/01/2022 (Retro UNIX 386 v1.2)
  2554 00006498 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
  2555                                  		   ;   between 16 MB and 4 GB.
  2556 0000649A 0000                    	     dw 0  ; 02/01/2022 (Retro UNIX 386 v1.2)
  2557                                  
  2558                                  ; 01/01/2022
  2559                                  KEND:
  2560                                  
  2561 0000649C 90<rep 4h>              align 16
  2562                                  
  2563                                  bss_start:
  2564                                  
  2565                                  ABSOLUTE bss_start
  2566                                  
  2567                                  	; 11/03/2015
  2568                                  	; Interrupt Descriptor Table (20/08/2014)
  2569                                  idt:
  2570 000064A0 <res 200h>              	resb	64*8 ; INT 0 to INT 3Fh
  2571                                  idt_end:
  2572                                  
  2573                                  ;alignb 4
  2574                                  
  2575                                  task_state_segment:
  2576                                  	; 24/03/2015
  2577 000066A0 ????                    tss.link:   resw 1
  2578 000066A2 ????                    	    resw 1
  2579                                  ; tss offset 4	
  2580 000066A4 ????????                tss.esp0:   resd 1
  2581 000066A8 ????                    tss.ss0:    resw 1
  2582 000066AA ????                    	    resw 1	
  2583 000066AC ????????                tss.esp1:   resd 1
  2584 000066B0 ????                    tss.ss1:    resw 1
  2585 000066B2 ????                    	    resw 1 	
  2586 000066B4 ????????                tss.esp2:   resd 1
  2587 000066B8 ????                    tss.ss2:    resw 1
  2588 000066BA ????                    	    resw 1
  2589                                  ; tss offset 28
  2590 000066BC ????????                tss.CR3:    resd 1
  2591 000066C0 ????????                tss.eip:    resd 1
  2592 000066C4 ????????                tss.eflags: resd 1
  2593                                  ; tss offset 40
  2594 000066C8 ????????                tss.eax:    resd 1		 		
  2595 000066CC ????????                tss.ecx:    resd 1
  2596 000066D0 ????????                tss.edx:    resd 1
  2597 000066D4 ????????                tss.ebx:    resd 1
  2598 000066D8 ????????                tss.esp:    resd 1
  2599 000066DC ????????                tss.ebp:    resd 1
  2600 000066E0 ????????                tss.esi:    resd 1
  2601 000066E4 ????????                tss.edi:    resd 1
  2602                                  ; tss offset 72
  2603 000066E8 ????                    tss.ES:     resw 1
  2604 000066EA ????                    	    resw 1	
  2605 000066EC ????                    tss.CS:	    resw 1
  2606 000066EE ????                    	    resw 1
  2607 000066F0 ????                    tss.SS:	    resw 1
  2608 000066F2 ????                    	    resw 1
  2609 000066F4 ????                    tss.DS:	    resw 1
  2610 000066F6 ????                    	    resw 1
  2611 000066F8 ????                    tss.FS:	    resw 1
  2612 000066FA ????                    	    resw 1
  2613 000066FC ????                    tss.GS:	    resw 1
  2614 000066FE ????                    	    resw 1		
  2615 00006700 ????                    tss.LDTR:   resw 1
  2616 00006702 ????                    	    resw 1
  2617                                  ; tss offset 100		
  2618 00006704 ????                    	    resw 1		
  2619 00006706 ????                    tss.IOPB:   resw 1
  2620                                  ; tss offset 104 
  2621                                  tss_end:
  2622                                  
  2623 00006708 ????????                k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
  2624                                  		    ;  (Physical address = Virtual address)	 	
  2625 0000670C ????????                memory_size: resd 1 ; memory size in pages
  2626 00006710 ????????                free_pages:  resd 1 ; number of free pages		
  2627 00006714 ????????                next_page:   resd 1 ; offset value in M.A.T. for
  2628                                  		    ;   first free page search
  2629 00006718 ????????                last_page:   resd 1 ; offset value in M.A.T. which
  2630                                  		    ;   next free page search will be
  2631                                  		    ;   stopped after it. (end of M.A.T.)
  2632 0000671C ????????                first_page:  resd 1 ;   offset value in M.A.T. which
  2633                                  		    ; first free page search
  2634                                  		    ;   will be started on it. (for user)
  2635 00006720 ????????                mat_size:    resd 1 ; Memory Allocation Table size in pages		
  2636                                  
  2637                                  ;;;
  2638                                  ; 02/09/2014 (Retro UNIX 386 v1)
  2639                                  ; 04/12/2013 (Retro UNIX 8086 v1)
  2640 00006724 ????                    CRT_START:   resw 1 	  ; starting address in regen buffer
  2641                                  			  ; NOTE: active page only
  2642 00006726 <res 10h>               cursor_posn: resw 8 	  ; cursor positions for video pages
  2643                                  active_page: 
  2644 00006736 ??                      ptty: 	     resb 1 	  ; current tty
  2645                                  ; 01/07/2015
  2646 00006737 ??                      ccolor:	     resb 1	  ; current color attributes ('sysmsg')	
  2647                                  ; 26/10/2015
  2648                                  ; 07/09/2014
  2649 00006738 <res 14h>               ttychr:      resw ntty+2  ; Character buffer (multiscreen)
  2650                                  
  2651                                  ; 21/08/2014
  2652 0000674C ????????                tcount:	     resd 1
  2653                                  
  2654                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
  2655 00006750 ????????                p_time:      resd 1     ; present time (for systime & sysmdate)
  2656                                  
  2657                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
  2658                                  ; (open mode locks for pseudo TTYs)
  2659                                  ; [ major tty locks (return error in any conflicts) ]
  2660 00006754 <res 14h>               ttyl:        resw ntty+2 ; opening locks for TTYs.
  2661                                  
  2662                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2663                                  ; 22/09/2013 (Retro UNIX 8086 v1)
  2664 00006768 <res Ah>                wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
  2665                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2666                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
  2667                                  ;; 0 means serial port is not available 
  2668                                  ;;comprm: ; 25/06/2014
  2669 00006772 ??                      com1p:       resb 1  ;;0E3h
  2670 00006773 ??                      com2p:       resb 1  ;;0E3h
  2671                                  
  2672                                  ; 17/11/2015
  2673                                  ; request for response (from the terminal)	
  2674 00006774 ????                    req_resp:    resw 1 			
  2675                                  ; 07/11/2015
  2676 00006776 ??                      ccomport:    resb 1 ; current COM (serial) port
  2677                                  		    ; (0= COM1, 1= COM2)
  2678                                  ; 09/11/2015
  2679 00006777 ??                      comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
  2680                                  ; 07/11/2015
  2681 00006778 ????                    rchar:	     resw 1 ; last received char for COM 1 and COM 2		
  2682 0000677A ????                    schar:	     resw 1 ; last sent char for COM 1 and COM 2
  2683                                  
  2684                                  ; 23/10/2015
  2685                                  ; SERIAL PORTS - COMMUNICATION MODES
  2686                                  ; (Retro UNIX 386 v1 feature only!)
  2687                                  ; 0 - command mode (default/initial mode)
  2688                                  ; 1 - terminal mode (Retro UNIX 386 v1 terminal, ascii chars)
  2689                                  ;;; communication modes for future versions:  
  2690                                  ; // 2 - keyboard mode (ascii+scancode input)
  2691                                  ; // 3 - mouse mode
  2692                                  ; // 4 - device control (output) mode
  2693                                  ; VALID COMMANDS for current version:
  2694                                  ; 	'LOGIN'
  2695                                  ;  Login request: db 0FFh, 'LOGIN', 0 
  2696                                  ;	 ("Retro UNIX 386 v1 terminal requests login")
  2697                                  ;  Login response: db 0FFh, 'login', 0
  2698                                  ;	 ("login request accepted, wait for login prompt") 
  2699                                  ; When a login requests is received and acknowledged (by
  2700                                  ; serial port interrupt handler (communication procedure),
  2701                                  ; Retro UNIX 386 v1 operating system will start terminal mode
  2702                                  ; (login procedure) by changing comm. mode to 1 (terminal mode)
  2703                                  ; and then running 'etc/getty' for tty8 (COM1) or tty9 (COM2)
  2704                                  ; 
  2705                                  ; 'sys connect' system call is used to change communication mode
  2706                                  ; except 'LOGIN' command which is used to start terminal mode
  2707                                  ; by using (COM port) terminal.
  2708                                  
  2709                                  ;com1own:     resb 1 ; COM1 owner (u.uno)
  2710                                  ;com2own:     resb 1 ; COM2 owner (u.uno)
  2711                                  ;com1mode:    resb 1 ; communication mode for COM1
  2712                                  ;com1com:     resb 1 ; communication command for COM1
  2713                                  ;com2mode:    resb 1 ; communication mode for COM1
  2714                                  ;com2com      resb 1 ; communication command for COM1
  2715                                  ;com1cbufp:   resb 8 ; COM1 command buffer char pointer	
  2716                                  ;com2cbufp:   resb 8 ; COM2 command buffer char pointer	
  2717                                  ;com1cbuf:    resb 8 ; COM2 command buffer
  2718                                  ;com2cbuf:    resb 8 ; COM2 command buffer
  2719                                  
  2720                                  ; 22/08/2014 (RTC)
  2721                                  ; (Packed BCD)
  2722 0000677C ??                      time_seconds: resb 1
  2723 0000677D ??                      time_minutes: resb 1
  2724 0000677E ??                      time_hours:   resb 1
  2725 0000677F ??                      date_wday:    resb 1
  2726 00006780 ??                      date_day:     resb 1
  2727 00006781 ??                      date_month:   resb 1			
  2728 00006782 ??                      date_year:    resb 1
  2729 00006783 ??                      date_century: resb 1
  2730                                  
  2731                                  %include 'diskbss.s' ; UNINITIALIZED DISK (BIOS) DATA
  2732                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKBSS.INC
  2733                              <1> ; Last Modification: 12/07/2022 
  2734                              <1> ; *****************************************************************************
  2735                              <1> ;	(Uninitialized Disk Parameters Data section for 'DISKIO.INC')
  2736                              <1> ; *****************************************************************************
  2737                              <1> ; Ref: Retro UNIX 386 v1 Kernel (v0.2.1.5) - DISKBSS.INC - 10/07/2022
  2738                              <1>  
  2739                              <1> 
  2740                              <1> alignb 2
  2741                              <1> 
  2742                              <1> ;----------------------------------------
  2743                              <1> ;	TIMER DATA AREA 		:
  2744                              <1> ;----------------------------------------
  2745                              <1> 
  2746                              <1> TIMER_LH:	; 16/02/205
  2747 00006784 ????                <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
  2748 00006786 ????                <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
  2749 00006788 ??                  <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
  2750                              <1> 
  2751                              <1> ;----------------------------------------
  2752                              <1> ;	DISKETTE DATA AREAS		:
  2753                              <1> ;----------------------------------------
  2754                              <1> 
  2755 00006789 ??                  <1> SEEK_STATUS:	resb	1
  2756 0000678A ??                  <1> MOTOR_STATUS:	resb	1
  2757 0000678B ??                  <1> MOTOR_COUNT:	resb	1
  2758 0000678C ??                  <1> DSKETTE_STATUS:	resb	1
  2759 0000678D ??????????????      <1> NEC_STATUS:	resb	7
  2760                              <1> 
  2761                              <1> ;----------------------------------------
  2762                              <1> ;	ADDITIONAL MEDIA DATA		:
  2763                              <1> ;----------------------------------------
  2764                              <1> 
  2765 00006794 ??                  <1> LASTRATE:	resb 	1
  2766 00006795 ??                  <1> HF_STATUS:	resb 	1
  2767                              <1> ;HF_ERROR:	resb 	1  ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)	
  2768 00006796 ??                  <1> HF_INT_FLAG:	resb	1
  2769                              <1> ;HF_CNTRL:	resb 	1  ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2770                              <1> ;DSK_STATE:	resb 	4
  2771 00006797 ????                <1> DSK_STATE:	resb 	2  ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  2772 00006799 ????                <1> DSK_TRK:	resb 	2
  2773                              <1> 
  2774                              <1> ;----------------------------------------
  2775                              <1> ;	FIXED DISK DATA AREAS		:
  2776                              <1> ;----------------------------------------
  2777                              <1> 
  2778 0000679B ??                  <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
  2779 0000679C ??                  <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
  2780 0000679D ??                  <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
  2781                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
  2782                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
  2783                              <1> ;port2_off	resb	1		; Hard disk controller 2 - port offset
  2784                              <1> 
  2785 0000679E ????                <1> alignb 4
  2786                              <1> 
  2787                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
  2788                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
  2789                              <1> HF_TBL_VEC: ; 22/12/2014	
  2790 000067A0 ????????            <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
  2791 000067A4 ????????            <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
  2792 000067A8 ????????            <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
  2793 000067AC ????????            <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
  2794                              <1> 
  2795                              <1> ; 03/01/2015
  2796 000067B0 ??                  <1> LBAMode:     	resb	1
  2797                              <1> 
  2798                              <1> ; *****************************************************************************
  2732                                  
  2733                                  ;;; Real Mode Data (10/07/2015 - BSS)
  2734                                  
  2735                                  ;alignb 2
  2736                                  
  2737                                  ; 02/01/2022
  2738                                  ;%include 'ux.s' ; 12/04/2015 (unix system/user/process data)
  2739                                  
  2740                                  ; 17/04/2021
  2741                                  ; (memory page swap parameters are disabled as temporary)
  2742                                  ;
  2743                                  ;; Memory (swap) Data (11/03/2015)
  2744                                  ; 09/03/2015
  2745                                  ;swpq_count: resw 1 ; count of pages on the swap que
  2746                                  ;swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
  2747                                  ;swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes).	
  2748                                  ;swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2749                                  ;swpd_next:  resd 1 ; next free page block
  2750                                  ;swpd_last:  resd 1 ; last swap page block	
  2751                                  
  2752 000067B1 ??????                  alignb 4
  2753                                  
  2754                                  ; 10/07/2015
  2755                                  ; 28/08/2014
  2756 000067B4 ????????                error_code:  resd 1
  2757                                  ; 29/08/2014
  2758 000067B8 ????????                FaultOffset: resd 1
  2759                                  ; 21/09/2015
  2760 000067BC ????????                PF_Count:    resd 1 ; total page fault count
  2761                                  		    ; (for debugging - page fault analyze)
  2762                                  		    ; 'page _fault_handler' (memory.s)
  2763                                  		    ; 'sysgeterr' (u9.s)
  2764                                  ; 23/02/2022
  2765 000067C0 ????????                rtc_ticks:  resd 1  ; (temporary! this rtc counter value may be used 
  2766                                  		    ;  for a system call in next retro unix 386 version)
  2767                                  		    ; -2 ticks per second-
  2768                                  ;; 21/08/2015
  2769                                  ;;buffer: resb (nbuf*520) ;; sysdefs.s, ux.s
  2770                                  
  2771                                  ; 02/01/2022
  2772                                  %include 'ux.s'	; 12/04/2015 (unix system/user/process data)
  2773                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2774                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2775                              <1> ; ****************************************************************************
  2776                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - ux.s 
  2777                              <1> ; Last Modification: 15/07/2022
  2778                              <1> ;
  2779                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
  2780                              <1> ; (Modified from 
  2781                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
  2782                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
  2783                              <1> ; ----------------------------------------------------------------------------
  2784                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
  2785                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
  2786                              <1> ; <Bell Laboratories (17/3/1972)>
  2787                              <1> ; <Preliminary Release of UNIX Implementation Document>
  2788                              <1> ; (Section E10 (17/3/1972) - ux.s)
  2789                              <1> ; ****************************************************************************
  2790                              <1> 
  2791                              <1> ; 15/07/2022
  2792                              <1> ; 08/06/2022
  2793                              <1> ; 15/05/2022
  2794                              <1> ; 21/03/2022
  2795                              <1> ; 27/02/2022
  2796                              <1> ; 12/01/2022
  2797                              <1> ; 22/11/2021 (Modification in Runix v1.1 'ux.s' for runix v2 fs compatibility)
  2798                              <1> ; 18/07/2021
  2799                              <1> ; 15/07/2021
  2800                              <1> ; 12/05/2021
  2801                              <1> ; 09/05/2021
  2802                              <1> ; 06/05/2021
  2803                              <1> ; 02/05/2021
  2804                              <1> ; 26/01/2020 (NASM version of SuperBlock structure in UNIXHDCP.ASM)
  2805                              <1> 
  2806                              <1> ; 21/12/2019 (UNIXCOPY.COM, UNIXCOPY.ASM, UNIXHDCP.COM, UNIXHDCP.ASM)
  2807                              <1> ; 19/12/2019 (UNIXHDFS.COM, RUFSHDI.ASM)
  2808                              <1> ; 01/09/2019 - Retro UNIX 386 v2 SuperBlock
  2809                              <1> 
  2810                              <1> ; 14/01/2020 - Super Block modification:
  2811                              <1> ;	     - Extended sections/divisions (consequental sectors)
  2812                              <1> ;	     - (for swapping, configuration, boot space etc.)	
  2813                              <1> 
  2814                              <1> ; 26/01/2020 (unix386.s, ux.s)
  2815                              <1> ; 14/01/2020
  2816                              <1> SB.HiddenSects	equ SB.BootSectAddr
  2817                              <1> SB.TotalSects	equ SB.VolumeSize
  2818                              <1> 
  2819                              <1> ; 11/05/2021 (Retro UNIX 386 v2)
  2820                              <1> ; Super block status byte (byte 0 of SB.status dword)
  2821                              <1> ; 	bit 0 - superblock modified flag
  2822                              <1> ; 	bit 1 - inode map modified flag
  2823                              <1> ; 	bit 2 - free blocks map modified flag
  2824                              <1> ; 	bit 3 - inode table modified flag
  2825                              <1> ;; 	bit 4 - boot sector modified flag ; 17/08/2021
  2826                              <1> ; 17/08/2021
  2827                              <1> ;	bit 4 - file data write error (for SB.LastInode)
  2828                              <1> ;	bit 5 - inode table write error (for SB.LastInode)
  2829                              <1> ;	bit 6 - inode map write error (for SB.LastInode)
  2830                              <1> ;	bit 7 - free blocks map write error (for SB.LastInode)
  2831                              <1> 	
  2832                              <1> ; 21/12/2019
  2833                              <1> ; 19/12/2019 - Retro UNIX 386 v2 HD (071h) partition boot sector 
  2834                              <1> ;	       (UNIXHDFS.ASM)
  2835                              <1> ; 04/12/2015 (14 byte file names - Retro UNIX 386 v1.1)
  2836                              <1> ; 14/07/2015 (8 byte file names - Retro UNIX 8086 v1 & Retro UNIX 386 v1.0)
  2837                              <1> 
  2838                              <1> bsFSystemID 	equ 2  ; db 'RUFS'	
  2839                              <1> bsVolumeSerial 	equ 6  ; dd 0 ; (4 bytes)
  2840                              <1> bsFDSign	equ 10 ; db 'fd'
  2841                              <1> bsDriveNumber 	equ 12 ; db 0 ; fd0 or fd1 (0 or 1)
  2842                              <1> bsReserved 	equ 13 ; db 0 ; (512 bytes per sector)	
  2843                              <1> bsSecPerTrack	equ 14 ; db 18 ; (9 or 15)	
  2844                              <1> bsHeads		equ 15 ; db  ; 2
  2845                              <1> bsTracks	equ 16 ; dw 80 ; bsCylinders
  2846                              <1> bs_bf_inode_number equ 18 ; dw 0 ; 0 or Boot/Startup File I-Number
  2847                              <1> bsInfoEndsign	equ 20 ; db '@'
  2848                              <1> ; 21/12/2019
  2849                              <1> bsMagic		equ 20 ; db '@'
  2850                              <1> bsPartitionID	equ 21 ; db 0 ; db 71h
  2851                              <1> bsHiddenSects	equ 22 ; dd 0 ; Hidden sectors (Boot Sector LBA)
  2852                              <1> 
  2853                              <1> ; 22/11/2021 - Retro UNIX v2 I-node Flags
  2854                              <1> ; ------------------------------------------------------------------
  2855                              <1> ; UINSTALL.ASM (included in UNIXFDFS.ASM) - 23/01/2020
  2856                              <1> ; ------------------------------------------------------------------
  2857                              <1> 
  2858                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
  2859                              <1> ; 1000000000000000b 	IFREG - 1 = regular file (8000h)
  2860                              <1> ; 0100000000000000b	IFDIR - 1 = directory (4000h)
  2861                              <1> ; 0010000000000000b	IRSVD - 0 = reserved bit (2000h) ; Mounted flag
  2862                              <1> ; 0001000000000000b	ILARG - large file addressing bit (1000h)
  2863                              <1> ; 0000100000000000b	ISUID - set user id on exec (800h)
  2864                              <1> ; 0000010000000000b	ISGID - set group id on exec (400h)
  2865                              <1> ; 0000001000000000b	IEXTT - 1 = use extents (200h)
  2866                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
  2867                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
  2868                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
  2869                              <1> ; 0000000000100000b	read, group (20h)
  2870                              <1> ; 0000000000010000b	write, group (10h)
  2871                              <1> ; 0000000000001000b	execute, group (08h)
  2872                              <1> ; 0000000000000100b	read, others (04h)
  2873                              <1> ; 0000000000000010b	write, others (02h)
  2874                              <1> ; 0000000000000001b	execute, others (01h)
  2875                              <1> 
  2876                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
  2877                              <1> ; 1000000000000000b 	IFREG - 0 = device file (8000h)
  2878                              <1> ; 0100000000000000b	IFBLK - 1 = block device (4000h)
  2879                              <1> ; 0010000000000000b	IFCHR - character special (2000h) -always 1-
  2880                              <1> ; 0001000000000000b	IFIFO - fifo special (1000h)
  2881                              <1> ; 0000100000000000b	IPIPE - pipe special (800h) ; 07/02/2020
  2882                              <1> ; 0000010000000000b	IREDIR - redirected (400h)  ; 07/02/2020
  2883                              <1> ; 0000001000000000b	IEXTR - 1 = external device driver (200h)
  2884                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
  2885                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
  2886                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
  2887                              <1> ; 0000000000100000b	read, group (20h)
  2888                              <1> ; 0000000000010000b	write, group (10h)
  2889                              <1> ; 0000000000001000b	execute, group (08h)
  2890                              <1> ; 0000000000000100b	read, others (04h)
  2891                              <1> ; 0000000000000010b	write, others (02h)
  2892                              <1> ; 0000000000000001b	execute, others (01h)
  2893                              <1> 
  2894                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
  2895                              <1> ; (SB structure has been moved from here to 'sysdefs.s'
  2896                              <1> ;	to overcome NASM's bss addressing bug !!!)
  2897                              <1> ; (('ux.s' bss section addresses are being overlapped
  2898                              <1> ;    when SB structure is defined in 'ux.s'))
  2899                              <1> 
  2900                              <1> %if 0
  2901                              <1> 
  2902                              <1> struc SB ; SuperBlock
  2903                              <1> 
  2904                              <1> .Header:	resd 1
  2905                              <1> ;.HiddenSects:
  2906                              <1> .BootSectAddr:	resd 1	; Hidden Sectors
  2907                              <1> ;.TotalSects:
  2908                              <1> .VolumeSize:	resd 1	; Entire Volume/Partition Size (includes ext. volume)
  2909                              <1> .Version:	resd 1	
  2910                              <1> .BlockSize:	resd 1	
  2911                              <1> .InodeCount:	resd 1	
  2912                              <1> .FreeMapAddr:	resd 1	
  2913                              <1> .FreeMapSize:	resd 1	
  2914                              <1> .InodeMapAddr:	resd 1	
  2915                              <1> .InodeMapSize:	resd 1	
  2916                              <1> .InodeTblAddr:	resd 1	
  2917                              <1> .InodeTblSize:	resd 1	
  2918                              <1> .FreeInodes:	resd 1	
  2919                              <1> .FirstFreeIno:	resd 1	
  2920                              <1> .FreeBlocks:	resd 1	
  2921                              <1> .FirstFreeBlk:	resd 1	
  2922                              <1> .BootSecParms:	resb 19	; v1
  2923                              <1> .BSExtension:	resb 5	; v2 HDFS
  2924                              <1> .Status:	resb 1	; 12/05/2021 (system modification status) (*)
  2925                              <1> .Pdrv:		resb 1  ; Physical disk number (index) ; 12/05/2021 (*) 
  2926                              <1> .Uno:		resw 1	; user/process number ; 12/05/2021 (*)
  2927                              <1> .ModifTime:	resd 1	; (last) modification time (*)
  2928                              <1> .ExtdVolTbl:	resd 1	; Extended Volume Start/Table Address
  2929                              <1> .ExtdVolSize:	resd 1	; Extended Volume (swap section etc.) Size	
  2930                              <1> .LBA_rw:	resb 1
  2931                              <1> .ClusterSize:	resb 1
  2932                              <1> .ReadOnly:	resb 1	; (SB will not be written to disk if bit 0 is 1)
  2933                              <1> .Mounted:	resb 1
  2934                              <1> .MountInode:	resd 1  ; double word
  2935                              <1> .DevMajor:	resb 1
  2936                              <1> .DevMinor:	resb 1
  2937                              <1> .LongName:	resb 1
  2938                              <1> .Direntry32:	resb 1
  2939                              <1> ; 18/07/2021
  2940                              <1> .FileBuffer:	resd 1
  2941                              <1> .ItabBuffer:	resd 1
  2942                              <1> .ImapBuffer:	resd 1
  2943                              <1> .FmapBuffer:	resd 1
  2944                              <1>  ; 15/07/2021
  2945                              <1> .LastInode:	resd 1
  2946                              <1> ; 02/05/2021
  2947                              <1> .FmapIndex:	resd 1
  2948                              <1> .ImapIndex:	resd 1
  2949                              <1> .ItableIndex:	resd 1
  2950                              <1> .Reserved:	resb 508-148 ; 18/07/2021
  2951                              <1> .Footer:	resd 1
  2952                              <1> 
  2953                              <1> endstruc
  2954                              <1> 
  2955                              <1> %endif
  2956                              <1> 
  2957                              <1> alignb 2
  2958                              <1> 
  2959                              <1> inode:
  2960                              <1> 	;; 11/03/2013. 
  2961                              <1> 	;;Derived from UNIX v1 source code 'inode' structure (ux).
  2962                              <1> 	;;i.
  2963                              <1> 	;
  2964                              <1> 	;i.flgs: resw 1
  2965                              <1> 	;i.nlks: resb 1
  2966                              <1> 	;i.uid:	 resb 1
  2967                              <1>         ;i.size: resw 1 ; size
  2968                              <1> 	;i.dskp: resw 8 ; 16 bytes
  2969                              <1> 	;i.ctim: resd 1
  2970                              <1> 	;i.mtim: resd 1
  2971                              <1> 	;i.rsvd: resw 1 ; Reserved (ZERO/Undefined word for UNIX v1)
  2972                              <1> 
  2973                              <1> 	; 26/01/2020
  2974                              <1> 	; Retro UNIX 386 v2.0 - Modified UNIX v7 inode model
  2975                              <1> 	;	(15/09/2029 .. 18/12/2019)
  2976                              <1> 
  2977 000067C4 ????                <1> 	i.flgs:   resw 1	; /* mode and type of file */
  2978 000067C6 ????                <1> 	i.nlks:	  resw 1	; /* number of links to file */
  2979 000067C8 ????                <1> 	i.uid:	  resw 1	; /* owner's user id */  - 0 to 65535 -
  2980 000067CA ??                  <1> 	i.gid:	  resb 1	; /* owner's group id */ - o to 255 -
  2981 000067CB ??                  <1> 	i.size_h: resb 1	; /* number of bytes in file */ ; byte 5
  2982 000067CC ????????            <1> 	i.size:	  resd 1 ; size	; /* number of bytes in file */
  2983 000067D0 <res 28h>           <1> 	i.dskp:	  resd 10 ; 40 bytes ; /* disk block addresses */
  2984 000067F8 ????????            <1> 	i.atim:	  resd 1	; /* time last accessed */
  2985 000067FC ????????            <1> 	i.mtim:	  resd 1	; /* time last modified */
  2986 00006800 ????????            <1> 	i.ctim:	  resd 1	; /* time created */
  2987                              <1> 
  2988                              <1> I_SIZE	equ $ - inode
  2989                              <1> 
  2990                              <1> process:
  2991                              <1> 	; 27/02/2022
  2992                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2) 
  2993                              <1> 	; 06/05/2015
  2994                              <1> 	; 11/03/2013 - 05/02/2014
  2995                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
  2996                              <1> 	;p.
  2997                              <1> 	
  2998 00006804 <res 20h>           <1>         p.pid:   resw nproc
  2999 00006824 <res 20h>           <1>         p.ppid:  resw nproc
  3000                              <1> 	;p.break: resw nproc ; 12/01/2022 (p.break is not used)
  3001 00006844 <res 10h>           <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
  3002                              <1> 	; 27/02/2022 (p.waitc is not used)
  3003                              <1> 	;p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
  3004 00006854 <res 10h>           <1> 	p.link:	 resb nproc
  3005 00006864 <res 10h>           <1> 	p.stat:	 resb nproc
  3006                              <1> 
  3007                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 feature only !) 
  3008 00006874 <res 40h>           <1> 	p.upage: resd nproc ; Physical address of the process's
  3009                              <1> 			    ; 'user' structure	
  3010                              <1> 
  3011                              <1> P_SIZE	equ $ - process
  3012                              <1> 
  3013                              <1> ; fsp table (original UNIX v1)
  3014                              <1> ;
  3015                              <1> ;Entry
  3016                              <1> ;          15                                      0
  3017                              <1> ;  1     |---|---------------------------------------|
  3018                              <1> ;        |r/w|       i-number of open file           |
  3019                              <1> ;        |---|---------------------------------------| 
  3020                              <1> ;        |               device number               |
  3021                              <1> ;        |-------------------------------------------|
  3022                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
  3023                              <1> ;        |-------------------------------------------| 
  3024                              <1> ;        |  flag that says    | number of processes  |
  3025                              <1> ;        |   file deleted     | that have file open  |
  3026                              <1> ;        |-------------------------------------------| 
  3027                              <1> ;  2     |                                           |
  3028                              <1> ;        |-------------------------------------------| 
  3029                              <1> ;        |                                           |
  3030                              <1> ;        |-------------------------------------------|
  3031                              <1> ;        |                                           |
  3032                              <1> ;        |-------------------------------------------|
  3033                              <1> ;        |                                           |
  3034                              <1> ;        |-------------------------------------------| 
  3035                              <1> ;  3     |                                           | 
  3036                              <1> ;        |                                           |  
  3037                              <1> ;
  3038                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
  3039                              <1> 
  3040                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
  3041                              <1> 
  3042                              <1> ;Entry
  3043                              <1> ;         15                    7                   0
  3044                              <1> ;  1     |-------------------------------------------|
  3045                              <1> ;        |   	     i-number of open file           |
  3046                              <1> ;        |-------------------------------------------| 
  3047                              <1> ;        |        high word of 32 bit i-number       |
  3048                              <1> ;        |-------------------------------------------|
  3049                              <1> ;        | open mode & status  |   device number     |
  3050                              <1> ;        |-------------------------------------------|
  3051                              <1> ;        |    reserved byte    |     open count      |
  3052                              <1> ;        |-------------------------------------------| 
  3053                              <1> ;        | offset pointer, i.e., r/w pointer to file |
  3054                              <1> ;        |-------------------------------------------|
  3055                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
  3056                              <1> ;        |-------------------------------------------|
  3057                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
  3058                              <1> ;        |-------------------------------------------|
  3059                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
  3060                              <1> ;        |-------------------------------------------|
  3061                              <1> ;  2     |                                           |
  3062                              <1> ;        |-------------------------------------------| 
  3063                              <1> ;        |                                           |
  3064                              <1> ;        |-------------------------------------------|
  3065                              <1> ;        |                                           |
  3066                              <1> ;        |-------------------------------------------|
  3067                              <1> ;        |                                           |
  3068                              <1> ;        |-------------------------------------------| 
  3069                              <1> ;        |                                           | 
  3070                              <1> 
  3071                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
  3072                              <1> ; (file structure has been moved from here to 'sysdefs.s'
  3073                              <1> ;	to overcome NASM's bss addressing bug !!!)
  3074                              <1> ; (('ux.s' bss section addresses are being overlapped
  3075                              <1> ;    when file file structure is defined in 'ux.s'))
  3076                              <1> 
  3077                              <1> %if 0
  3078                              <1> 
  3079                              <1> ; 22/11/2021
  3080                              <1> ; 21/07/2021 - Retro UNIX 386 v2 open file structure revision
  3081                              <1> 
  3082                              <1> struc file	; open files (fsp) structure
  3083                              <1>   .inode:  resw 1  ; inode number of open file (32 bit)
  3084                              <1>   .i32:	   resw 1  ; higher word of inode number (reserved)
  3085                              <1>   .drive:  resb 1  ; logical drive (disk) number
  3086                              <1>   .flags:  resb 1  ; open mode and status
  3087                              <1>   .count:  resb 1  ; number of processes that have file open
  3088                              <1>   ;.rsvd:  resb 1  ; reserved byte (for next versions)
  3089                              <1>   .mnt:    resb 1  ; mnttab index+1 (0 = not mounted)
  3090                              <1>   .offset: resd 1  ; file offset/pointer (64 bit) 
  3091                              <1>   .o64:	   resd 1  ; higher 32 bit of file offset
  3092                              <1>  .size:  ; = 16		
  3093                              <1> endstruc
  3094                              <1> 
  3095                              <1> %endif
  3096                              <1> 
  3097                              <1> ; 01/01/2022
  3098                              <1> ; 22/11/2021
  3099                              <1> ;fp.size equ file.size
  3100                              <1> 
  3101                              <1> ; 02/01/2022
  3102 000068B4 <res 320h>          <1> fsp:	resb nfiles*16 ; (NFILES*fp.size)
  3103                              <1> ; 01/01/2022
  3104                              <1> ; 22/11/2021 (16/05/2021)
  3105                              <1> ;fsp:	resb NFILES*16 ; (NFILES*fp.size)
  3106                              <1> ; 15/04/2015
  3107                              <1> ;fsp:	resb nfiles*10 ; 11/05/2015 (8 -> 10)
  3108                              <1> 
  3109 00006BD4 <res 48h>           <1> bufp:	resd (nbuf+2) ; will be initialized 
  3110 00006C1C ????????            <1> ii:	resd 1 ; 22/11/2021 ; 32 bit inode number (high word is 0)
  3111                              <1> ; 22/11/2021
  3112 00006C20 ??                  <1> idev:	resb 1 ; logical drive number of current inode, [ii]
  3113 00006C21 ??                  <1> cdev:	resb 1 ; current logical drive number for current user
  3114                              <1> 
  3115                              <1> ; 18/05/2015
  3116                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
  3117                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
  3118                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
  3119                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
  3120                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
  3121                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
  3122                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
  3123                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
  3124                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
  3125                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
  3126                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
  3127 00006C22 ??                  <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
  3128                              <1> 	        ; as above, for physical drives numbers in following table
  3129 00006C23 ??                  <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
  3130                              <1> ; 15/04/2015
  3131                              <1> ;active: resb 1 ; 15/07/2022
  3132                              <1> ;	 resb 1 ; 09/06/2015
  3133 00006C24 ????                <1> mpid:	 resw 1
  3134                              <1> ; 22/11/2021 (32 bit inode numbers)
  3135 00006C26 ????????            <1> rootdir: resd 1
  3136 00006C2A ????????            <1> mnti:	 resd 1
  3137                              <1> ; 15/05/2022 ; (parent dir inumber of [mnti])
  3138 00006C2E ????????            <1> mntp:	 resd 1 
  3139                              <1> 
  3140                              <1> ; 14/02/2014
  3141                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
  3142                              <1> ;		      Single level run queue
  3143                              <1> ;		      (in order to solve sleep/wakeup lock)
  3144 00006C32 ????                <1> runq:	resw 1
  3145 00006C34 ??                  <1> imod:	resb 1
  3146 00006C35 ??                  <1> imodx:	resb 1 ; 09/01/2022 - Retro UNIX 386 v1.2
  3147 00006C36 ??                  <1> smod:	resb 1
  3148 00006C37 ??                  <1> mmod:	resb 1
  3149                              <1> ;	resb 1 ; 09/01/2022 
  3150 00006C38 ??                  <1> sysflg:	resb 1
  3151                              <1> 
  3152 00006C39 ??????              <1> alignb 4
  3153                              <1> 
  3154                              <1> user:
  3155                              <1> 	; 01/01/2022
  3156                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
  3157                              <1> 	; 24/10/2021
  3158                              <1> 	; 18/10/2021
  3159                              <1> 	; 10/06/2021
  3160                              <1> 	; 30/05/2021
  3161                              <1> 	; 29/05/2021
  3162                              <1> 	; 21/05/2021
  3163                              <1> 	; 20/05/2021
  3164                              <1> 	; 16/05/2021
  3165                              <1> 	; 01/05/2021
  3166                              <1> 	; 27/03/2021
  3167                              <1> 	; 17/04/2020, 28/04/2020
  3168                              <1> 	; 25/03/2020, 28/03/2020
  3169                              <1> 	; 20/03/2020, 22/03/2020, 23/03/2020
  3170                              <1> 	; 05/03/2020, 08/03/2020, 14/03/2020
  3171                              <1> 	; 07/02/2020 - Retro UNIX 386 v2
  3172                              <1> 	;
  3173                              <1> 	; 27/02/2017 - TRDOS 386
  3174                              <1> 	; 13/01/2017 - TRDOS 386
  3175                              <1> 	; 10/01/2017 - TRDOS 386
  3176                              <1> 	; 19/12/2016 - TRDOS 386	
  3177                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0) 
  3178                              <1> 	; 	       [u.pri] usage method modification
  3179                              <1> 	;
  3180                              <1> 	; 04/12/2015 - Retro UNIX 386 v1.1 (14 byte file/directory names)
  3181                              <1> 	; 18/10/2015
  3182                              <1> 	; 12/10/2015
  3183                              <1> 	; 21/09/2015
  3184                              <1> 	; 24/07/2015
  3185                              <1> 	; 16/06/2015
  3186                              <1> 	; 09/06/2015
  3187                              <1> 	; 11/05/2015
  3188                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
  3189                              <1> 	; 10/10/2013
  3190                              <1> 	; 11/03/2013. 
  3191                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
  3192                              <1> 	;u.
  3193                              <1> 
  3194 00006C3C ????????            <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
  3195 00006C40 ????????            <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
  3196 00006C44 ????????            <1> 	u.r0:	  resd 1 ; eax
  3197 00006C48 ????                <1> 	u.cdir:	  resw 1
  3198 00006C4A ????                <1> 		  resw 1 ; 28/03/2020 - reserved for 32 bit inode number
  3199                              <1> 	;u.cdrv:  resw 1 ; 17/04/2020 (dword alignment) 
  3200 00006C4C ??                  <1> 	u.cdrv:   resb 1 ; 01/05/2021
  3201 00006C4D ??                  <1> 		  resb 1 ; 01/05/2021 (dword alignment)
  3202 00006C4E <res Ah>            <1> 	u.fp:	  resb 10 ; Retro UNIX 386 v1
  3203                              <1> 	;u.fp:	  resb OPENFILES ; Retro UNIX 386 v2 ; 28/03/2020 
  3204                              <1> 	u.fsp:	  ; 16/05/2021
  3205 00006C58 ????????            <1> 	u.fofp:	  resd 1 ; 16/05/2021 (pointer to fsp entry)
  3206 00006C5C ????????            <1> 	u.dirp:	  resd 1
  3207 00006C60 ????????            <1> 	u.namep:  resd 1
  3208 00006C64 ????????            <1> 	u.off:	  resd 1
  3209                              <1> 	;	  resd 1 ; 08/03/2020 - Retro UNIX 386 v2 - 64 bit fptr
  3210 00006C68 ????????            <1> 	u.base:	  resd 1
  3211 00006C6C ????????            <1> 	u.count:  resd 1
  3212 00006C70 ????????            <1> 	u.nread:  resd 1
  3213 00006C74 ????????            <1> 	u.break:  resd 1 ; break
  3214                              <1> 	; 16/05/2021 (Retro UNIX 386 v2)
  3215 00006C78 ??                  <1> 	u.mode:   resb 1 ; 16/05/2021 (sysread, syswrite, 'rdwr' file mode)
  3216                              <1> 	; 10/01/2017 (TRDOS 386, relocation and dword alignment)
  3217                              <1> 	; tty number (rtty, rcvt, wtty)
  3218 00006C79 ??                  <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
  3219 00006C7A ????                <1> 	u.ttyp:	  resw 1 
  3220 00006C7C <res 10h>           <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
  3221                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
  3222 00006C8C ??                  <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
  3223 00006C8D ??                  <1> 		  resb 1 ; 17/04/2020
  3224 00006C8E ??                  <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
  3225 00006C8F ??                  <1> 		  resb 1 ; 17/04/2020
  3226                              <1> 	; 10/06/2021
  3227                              <1> 	;u.signal: resw 1 ; 21/05/2021 - Retro UNIX 386 v2
  3228                              <1> 	;	  resw 1 ; reserved ; 21/05/2021	
  3229 00006C90 ????                <1> 	u.intr:	  resw 1
  3230 00006C92 ????                <1> 	u.quit:	  resw 1
  3231                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
  3232                              <1> 	;u.ilgins: resw 1 ; 10/01/2017
  3233                              <1> 	;u.cdrv:  resw 1 ; cdev ; 17/04/2020 (moved to up)
  3234                              <1> 	;u.uid:	  resb 1 ; uid
  3235                              <1> 	;u.ruid:  resb 1
  3236 00006C94 ??                  <1> 	u.bsys:	  resb 1
  3237 00006C95 ??                  <1> 	u.uno:	  resb 1
  3238 00006C96 ????                <1>         u.uid:	  resw 1 ; uid	; 27/03/2021 - Retro UNIX 386 v2
  3239 00006C98 ????                <1> 	u.ruid:	  resw 1	; 16 bit uid
  3240 00006C9A ??                  <1> 	u.gid:	  resb 1 ; gid 	; 27/03/2021 - Retro UNIX 386 v2
  3241 00006C9B ??                  <1> 	u.rgid:	  resb 1
  3242                              <1> 	; 20/05/2021 - Retro UNIX 386 v2
  3243 00006C9C ????????            <1> 	u.procp:  resd 1 ; /* pointer to proc structure */		
  3244 00006CA0 ????????            <1> 	u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
  3245 00006CA4 ????????            <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
  3246 00006CA8 ????????            <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
  3247 00006CAC ????????            <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
  3248                              <1> 		; 24/10/2021 (32 bit value for Retro UNIX 386 v2)
  3249 00006CB0 ????????            <1> 	u.pcount: resd 1 ; 20/05/2015 (byte -transfer- count for page)
  3250                              <1> 	;u.pncount: resw 1 
  3251                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
  3252                              <1> 	;u.pnbase:  resd 1 
  3253                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
  3254 00006CB4 ????                <1> 	u.rsvd:	  resw 1 ; 04/12/2021 (dword alignment)
  3255                              <1> 			 ; 09/06/2015
  3256 00006CB6 ??                  <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign
  3257                              <1> 		; 08/03/2020 (block device read/write flag for 'sioreg')		
  3258 00006CB7 ??                  <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
  3259                              <1> 			 ; 24/07/2015 - 24/06/2015
  3260                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
  3261                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
  3262                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
  3263                              <1>  			 ; 24/06/2015	  	
  3264                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
  3265                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
  3266                              <1> 	; last error number
  3267 00006CB8 ????????            <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
  3268                              <1> 			; Retro UNIX 8086/386 v1 feature only!
  3269                              <1> 			; 21/09/2015 (debugging - page fault analyze)
  3270 00006CBC ????????            <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
  3271                              <1> 		; 29/05/2021 - Retro UNIX 386 v2, 2021 (sleep, psig)
  3272                              <1> ;	u.signal: resd 1 ; unix signal recognition (enabling, accepting) bits	
  3273                              <1> ;	u.srb:	  resb 1 ; signal handling/responding method
  3274                              <1> ;	u.snum:	  resb 1 ; signal number (last signal number)
  3275                              <1> ;	u.exit:	  resb 1 ; exit code ; 30/05/2021 - Retro UNIX 386 v2
  3276                              <1> ;	u.s_lock: resb 1 ; signal handling (phase) lock	
  3277                              <1> ;	u.s_addr: resd 1 ; Signal Response Byte or signal handler (callback) address
  3278                              <1> ;	u.s_time: resd 1 ; signal time in unix epoch format		
  3279                              <1> 		; 19/12/2016 (TRDOS 386)	
  3280                              <1> ;	u.tcb:	  resd 1 ; Timer callback address/flag which will be used by timer int
  3281                              <1> 		; 13/01/2017 (TRDOS 386)
  3282                              <1> ;	u.t_lock: resb 1 ; Timer interrupt (callback) lock (unlocked by 'sysrele')
  3283                              <1> ;	u.t_mode: resb 1 ; running mode during timer interrupt (0= system, 0FFh= user)
  3284                              <1> 		; 26/02/2017 (TRDOS 386)
  3285                              <1> ;	u.irqc:	  resb 1  ; Count of IRQ callback services (IRQs in use)
  3286                              <1> 		; 28/02/2017 (TRDOS 386) 
  3287                              <1> ;	u.irqwait: resb 1 ; IRQ waiting for callback service flag (IRQ number, If > 0)
  3288                              <1> ;	u.r_lock:  resb 1 ; 'IRQ callback service is in progress' flag (IRQ lock)
  3289                              <1> ;	u.r_mode:  resb 1 ; running mode during hardware interrupt
  3290                              <1> 		; 07/02/2020 - Retro UNIX 386 v2
  3291                              <1> ;	u.redir:  resb 1 ; device func redirection permitted by user (if u.redir > 0)
  3292                              <1> 		; 26/02/2020 - Retro UNIX 386 v2
  3293                              <1> ;	u.rwm:	  resb 1  ; read & write mode for devices/drives, 0 = direct, 1 = fs r/w 
  3294                              <1> 		; 24/02/2020 - Retro UNIX 386 v2
  3295                              <1> 		; 24/10/2021 (32 bit value)
  3296                              <1> ;	u.scount: resd 1 ; sub byte count ; 22/03/2020 
  3297                              <1> 		; 07/03/2020 - Retro UNIX 386 v2
  3298                              <1> ;	u.bps:	  resw 1 ; u.bps = bytes per sector, for readi and writei
  3299                              <1> ;		  resw 1 ; 24/10/2021 (32 bit value for using with 32 bit registers)	
  3300                              <1> 		; 23/03/2020 - Retro UNIX 386 v2
  3301                              <1> ;	u.timeout: resw 1 ; timeout setting (seconds) -for 'sleep'-
  3302                              <1> 		; 28/04/2020 - Retro UNIX 386 v2
  3303                              <1> ;	u.lock:	  resb 1 ; Device lock flag (bit 0 is for device/disk read/write)
  3304                              <1> 		; 24/04/2020
  3305                              <1> 		; 17/04/2020 - Retro UNIX 386 v2
  3306                              <1> ;	u.ifs:	  resb 1 ; (current) installable file system driver index number
  3307                              <1> 		; 25/03/2020
  3308                              <1> 		; 20/03/2020
  3309                              <1> 	;u.lcount: resd 1 ; last byte count for 'writei' (for restoring write count)	
  3310                              <1> 
  3311                              <1> 		; 08/03/2020 - Retro UNIX 386 v2 ('sioreg, 'readi')
  3312                              <1> 	;u.limit: resd 1  ; disk/file size limit for block device read/write ('sioreg')			
  3313                              <1> 	;	  resd 1  ; 08/03/2020 - 64 bit limit (disk size in bytes)
  3314                              <1> 	;	; 26/02/2020 - Retro UNIX 386 v2
  3315                              <1> 	;u.sector: resd 1  ; current sector (for readi and writei, device r/w)  		
  3316                              <1> 	;u.buffer: resd 1  ; current buffer (for readi and writei, device r/w) 
  3317                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
  3318                              <1> 	;u.devmm: resw 1 ; device major (hb) and minor (lb) numbers
  3319                              <1> 	;u.zero:  resw 1 ; 14/03/2020 - Must be ZERO for current version
  3320                              <1> 		; 22/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
  3321                              <1> ;	u.device: resd 1 ; (blk, chr) device description table (entry) address 	
  3322                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
  3323                              <1> ;	u.function: resd 1 ; device function (read, write)
  3324                              <1> 		; 22/03/2020 - Retro UNIX 386 v2, 2020 (readi, writei)
  3325                              <1> ;	u.buffer: resd 1  ; for saving buffer header address for 'poke'
  3326                              <1> ;	u.inode:  resw 1  ; for saving inode number of current (device) inode
  3327                              <1> ;		  resw 1  ; 18/10/2021 Retro UNIX 386 v2 - 32 bit inode number			
  3328                              <1> ;	u.idev:	  resb 1  ; for saving logical drv number of current (dev) inode
  3329                              <1> 		; 04/12/2021
  3330                              <1> ;	u.rsvd2:  resw 1  ; (for dword alignment)	
  3331                              <1> 		; 27/02/2017 (TRDOS 386) 
  3332                              <1> ;; 31/12/2021 - temporary !
  3333                              <1> ;	u.fpsave: resb 1  ; TRDOS 386, 'save/restore FPU registers' flag
  3334                              <1> alignb 4
  3335                              <1> 	; !! wrong sizing in TRDOS 386 v2.0.4 (in 'ubss.s', 28/02/2017) !! 
  3336                              <1> 	;u.fpregs: resb 94 ; 94 byte area for saving and restoring FPU registers
  3337                              <1> 	; 30/05/2021 - Retro UNIX 386 v2
  3338                              <1> ;	u.fpregs: resb 108 ; 108 byte area for saving and restoring FPU registers	
  3339                              <1> alignb 4
  3340                              <1> 
  3341                              <1> U_SIZE	equ $ - user
  3342                              <1> 
  3343                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
  3344 00006CC0 ????????            <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
  3345 00006CC4 ????????            <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
  3346 00006CC8 ????????            <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
  3347                              <1> ;ncount: resw 1 ; remain byte count in page for 'namei' & 'sysexec'
  3348                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'ncount')
  3349 00006CCC ????????            <1> ncount: resd 1	; remain byte count in page for 'namei' & 'sysexec'
  3350                              <1> ;argc:	resw 1	; argument count for 'sysexec'
  3351                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'argc')
  3352 00006CD0 ????????            <1> argc:	resd 1	; argument count for 'sysexec'
  3353 00006CD4 ????????            <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
  3354                              <1> 
  3355                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
  3356                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
  3357 00006CD8 ??                  <1> rw: 	 resb 1 ;; Read/Write sign (iget)
  3358 00006CD9 ??                  <1> rwdsk:	 resb 1 ;; Read/Write function number (diskio) - 16/06/2015
  3359 00006CDA ??                  <1> mget_rw: resb 1 ; 22/11/2021 
  3360 00006CDB ??                  <1> retry_count: resb 1 ; Disk I/O retry count - 11/06/2015
  3361                              <1> 
  3362                              <1> ; 08/06/2022 - (BugFix) ! (level: resd 0) !
  3363                              <1> ; 22/11/2021 - Retro UNIX 386 v2 compatibility
  3364 00006CDC ????????            <1> level:	resd 1  ; level, level+1, level+2, level+3  ; for 'mget' procedure
  3365                              <1> 
  3366                              <1> ; (02/01/2022)
  3367                              <1> ; 27/11/2021
  3368                              <1> ; these are will be used for disk block allocation ('alloc' proc)
  3369                              <1> free_map_offset: 
  3370 00006CE0 ????????            <1> 		resd 1
  3371 00006CE4 ????????            <1> free_map_index:	resd 1
  3372                              <1> free_map_sector:
  3373 00006CE8 ????????            <1> 		resd 1
  3374                              <1> ;free_map_buffer:
  3375                              <1> ;		resd 1
  3376                              <1> 
  3377                              <1> ; 12/01/2022
  3378                              <1> ; 27/11/2021 - temporary !
  3379                              <1> ;s.time:	resd 1
  3380                              <1> 
  3381                              <1> ;alignb 4
  3382                              <1> 
  3383                              <1> ; (02/01/2022)
  3384                              <1> ; 22/08/2015
  3385                              <1> ;buffer: resb nbuf * 520
  3386                              <1> 
  3387 00006CEC ????????????????    <1> sb0:	resd 2
  3388                              <1> ;s:
  3389                              <1> ; (root disk) super block buffer
  3390                              <1> systm:
  3391                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatible super block
  3392                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
  3393                              <1> 	; 11/03/2013. 
  3394                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
  3395                              <1> 	;s.
  3396                              <1> 
  3397                              <1> 	;resw 1
  3398                              <1> 	;resb 360 ; 2880 sectors ; original UNIX v1 value: 128
  3399                              <1> 	;resw 1
  3400                              <1> 	;resb 32 ; 256+40 inodes ; original UNIX v1 value: 64
  3401                              <1> 	;s.time: resd 1
  3402                              <1> 	;s.syst: resd 1
  3403                              <1>         ;s.wait_: resd 1 ; wait
  3404                              <1> 	;s.idlet: resd 1
  3405                              <1> 	;s.chrgt: resd 1
  3406                              <1> 	;s.drerr: resw 1
  3407                              <1> 
  3408                              <1> 	; 27/11/2021
  3409 00006CF4 <res 200h>          <1> 	resb 512	
  3410                              <1> 
  3411                              <1> ;S_SIZE	equ $ - systm
  3412                              <1> 
  3413                              <1> 	;resb 512-S_SIZE ; 03/06/2015
  3414                              <1> 
  3415 00006EF4 ????????????????    <1> sb1:	resd 2
  3416                              <1> ; (mounted disk) super block buffer
  3417                              <1> mount:	
  3418 00006EFC <res 200h>          <1> 	resb 512  ; 03/06/2015
  3419                              <1> 
  3420                              <1> ; 21/03/2022
  3421                              <1> ; hard disk masterboot sector buffer
  3422 000070FC ????????????????    <1> mbrbuf: resd 2
  3423 00007104 <res 200h>          <1> 	resb 512
  3424                              <1> 
  3425                              <1> ; 10/01/2022
  3426 00007304 <res 200h>          <1> dbli_buf: resb 512  ; double indir ptr buff for 'itrunc', 'tloop'
  3427 00007504 <res 200h>          <1> trpi_buf: resb 512  ; triple indir ptr buff for 'itrunc', 'tloop'
  3428                              <1> 
  3429                              <1> ;/ ux -- unix
  3430                              <1> ;
  3431                              <1> ;systm:
  3432                              <1> ;
  3433                              <1> ;	.=.+2
  3434                              <1> ;	.=.+128.
  3435                              <1> ;	.=.+2
  3436                              <1> ;	.=.+64.
  3437                              <1> ;	s.time: .=.+4
  3438                              <1> ;	s.syst: .=.+4
  3439                              <1> ;	s.wait: .=.+4
  3440                              <1> ;	s.idlet:.=.+4
  3441                              <1> ;	s.chrgt:.=.+4
  3442                              <1> ;	s.drerr:.=.+2
  3443                              <1> ;inode:
  3444                              <1> ;	i.flgs: .=.+2
  3445                              <1> ;	i.nlks: .=.+1
  3446                              <1> ;	i.uid:  .=.+1
  3447                              <1> ;	i.size: .=.+2
  3448                              <1> ;	i.dskp: .=.+16.
  3449                              <1> ;	i.ctim: .=.+4
  3450                              <1> ;	i.mtim: .=.+4
  3451                              <1> ;	. = inode+32.
  3452                              <1> ;mount:	.=.+1024.
  3453                              <1> ;proc:
  3454                              <1> ;	p.pid:  .=.+[2*nproc]
  3455                              <1> ;	p.dska: .=.+[2*nproc]
  3456                              <1> ;	p.ppid: .=.+[2*nproc]
  3457                              <1> ;	p.break:.=.+[2*nproc]
  3458                              <1> ;	p.link: .=.+nproc
  3459                              <1> ;	p.stat: .=.+nproc
  3460                              <1> ;tty:
  3461                              <1> ;	. = .+[ntty*8.]
  3462                              <1> ;fsp:	.=.+[nfiles*8.]
  3463                              <1> ;bufp:	.=.+[nbuf*2]+6
  3464                              <1> ;sb0:	.=.+8
  3465                              <1> ;sb1:	.=.+8
  3466                              <1> ;swp:	.=.+8
  3467                              <1> ;ii:	.=.+2
  3468                              <1> ;idev:	.=.+2
  3469                              <1> ;cdev:	.=.+2
  3470                              <1> ;deverr: .=.+12.
  3471                              <1> ;active: .=.+2
  3472                              <1> ;rfap:	.=.+2
  3473                              <1> ;rkap:	.=.+2
  3474                              <1> ;tcap:	.=.+2
  3475                              <1> ;tcstate:.=.+2
  3476                              <1> ;tcerrc: .=.+2
  3477                              <1> ;mnti:	.=.+2
  3478                              <1> ;mntd:	.=.+2
  3479                              <1> ;mpid:	.=.+2
  3480                              <1> ;clockp: .=.+2
  3481                              <1> ;rootdir:.=.+2
  3482                              <1> ;toutt:	.=.+16.
  3483                              <1> ;touts: .=.+32.
  3484                              <1> ;runq:	.=.+6
  3485                              <1> ;
  3486                              <1> ;wlist:	.=.+40.
  3487                              <1> ;cc:	.=.+30.
  3488                              <1> ;cf:	.=.+31.
  3489                              <1> ;cl:	.=.+31.
  3490                              <1> ;clist:	.=.+510.
  3491                              <1> ;imod:	.=.+1
  3492                              <1> ;smod:	.=.+1
  3493                              <1> ;mmod:	.=.+1
  3494                              <1> ;uquant: .=.+1
  3495                              <1> ;sysflg: .=.+1
  3496                              <1> ;pptiflg:.=.+1
  3497                              <1> ;ttyoch: .=.+1
  3498                              <1> ; .even
  3499                              <1> ; .=.+100.; sstack:
  3500                              <1> ;buffer: .=.+[ntty*140.]
  3501                              <1> ;	.=.+[nbuf*520.]
  3502                              <1> ;
  3503                              <1> ; . = core-64.
  3504                              <1> ;user:
  3505                              <1> ;	u.sp:    .=.+2
  3506                              <1> ;	u.usp:   .=.+2
  3507                              <1> ;	u.r0:    .=.+2
  3508                              <1> ;	u.cdir:  .=.+2
  3509                              <1> ;	u.fp:    .=.+10.
  3510                              <1> ;	u.fofp:  .=.+2
  3511                              <1> ;	u.dirp:  .=.+2
  3512                              <1> ;	u.namep: .=.+2
  3513                              <1> ;	u.off:   .=.+2
  3514                              <1> ;	u.base:  .=.+2
  3515                              <1> ;	u.count: .=.+2
  3516                              <1> ;	u.nread: .=.+2
  3517                              <1> ;	u.break: .=.+2
  3518                              <1> ;	u.ttyp:  .=.+2
  3519                              <1> ;	u.dirbuf:.=.+10.
  3520                              <1> ;	u.pri:   .=.+2
  3521                              <1> ;	u.intr:  .=.+2
  3522                              <1> ;	u.quit:  .=.+2
  3523                              <1> ;	u.emt:   .=.+2
  3524                              <1> ;	u.ilgins:.=.+2
  3525                              <1> ;	u.cdev:  .=.+2
  3526                              <1> ;	u.uid:   .=.+1
  3527                              <1> ;	u.ruid:  .=.+1
  3528                              <1> ;	u.bsys:  .=.+1
  3529                              <1> ;	u.uno:   .=.+1
  3530                              <1> ;. = core
  2773                                  
  2774                                  ; 27/12/2021
  2775 00007704 <res 2080h>             buffer:	resb (nbuf*520)
  2776                                  
  2777                                  bss_end:
  2778                                  
  2779                                  ; 12/12/2021
  2780                                  BSS_SIZE equ bss_end - bss_start
  2781                                  
  2782                                  ; 27/12/2013
  2783                                  _end: ; end of kernel code (and read only data, just before bss)
