     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.4
     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: 27/12/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[8862]              	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[F464]              	mov	[mem_1m_1k], cx
   175 00000017 8916[F864]              	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 !'
   208 00000042 656E74206D656D6F72-
   209 0000004B 792021             
   210 0000004E 0D0A                    	db	0Dh, 0Ah
   211                                  _int13h_48h_buffer: ; 07/07/2016
   212 00000050 284D696E696D756D20-     	db	'(Minimum 2MB memory is needed.)'
   213 00000059 324D42206D656D6F72-
   214 00000062 79206973206E656564-
   215 0000006B 65642E29           
   216 0000006F 0D0A00                   	db	0Dh, 0Ah, 0
   217                                  
   218                                  L0:
   219                                  %include 'diskinit.s' ; 07/03/2015
   220                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
   221                              <1> ; (re-write kernel for test by using previous version without a major defect)
   222                              <1> ; ****************************************************************************
   223                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKINIT.INC
   224                              <1> ; Last Modification: 08/08/2022 (Previous: 12/07/2022)
   225                              <1> 
   226                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
   227                              <1> 
   228                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
   229                              <1> 
   230                              <1> 	; 08/08/2022
   231                              <1> 	; 14/07/2022 (TRDOS 386 v2.0.5)
   232                              <1> 	; 12/07/2022
   233                              <1> 	; 02/01/2022 (Retro UNIX 386 v1.2)
   234                              <1> 	; 29/08/2020
   235                              <1> 	; 17/07/2020
   236                              <1> 	; 14/07/2020 (TRDOS 386 v2.0.2)
   237                              <1> 	; 06/02/2015 (Retro UNIX 386 v1)
   238                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
   239                              <1> ;L0:
   240                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
   241                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
   242 00000072 BA7F00              <1> 	mov	dx, 7Fh
   243                              <1> L1:	
   244 00000075 FEC2                <1> 	inc	dl
   245 00000077 B441                <1> 	mov	ah, 41h ; Check extensions present
   246                              <1> 			; Phoenix EDD v1.1 - EDD v3
   247 00000079 BBAA55              <1> 	mov	bx, 55AAh
   248 0000007C CD13                <1> 	int 	13h
   249 0000007E 721A                <1> 	jc	short L2
   250                              <1> 
   251 00000080 81FB55AA            <1> 	cmp	bx, 0AA55h
   252 00000084 7514                <1> 	jne	short L2
   253 00000086 FE06[8B62]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   254 0000008A 8816[8A62]          <1>         mov     [last_drv], dl  ; last hard disk number
   255 0000008E BB[0E62]            <1> 	mov	bx, hd0_type - 80h
   256 00000091 01D3                <1> 	add	bx, dx	 
   257 00000093 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
   258                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
   259                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
   260                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
   261                              <1>                          ;            (EDD) ready (DPTE ready)
   262                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
   263                              <1>                          ;            (EDD-3)
   264                              <1> 			 ; Bit 4 to 15 - 0, Reserved
   265 00000095 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
   266 00000098 72DB                <1> 	jb	short L1
   267                              <1> L2:
   268                              <1> 	; 23/11/2014
   269                              <1> 	; 19/11/2014
   270 0000009A 30D2                <1> 	xor	dl, dl  ; 0
   271                              <1> 	; 04/02/2016 (esi -> si)
   272 0000009C BE[8C62]            <1> 	mov	si, fd0_type
   273                              <1> L3:
   274                              <1> 	; 14/01/2015
   275 0000009F 8816[8962]          <1> 	mov	[drv], dl
   276                              <1> 	;
   277 000000A3 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   278 000000A5 CD13                <1> 	int	13h	
   279 000000A7 7210                <1> 	jc	short L4
   280                              <1> 		; BL = drive type (for floppy drives)
   281                              <1> 		; DL = number of floppy drives
   282                              <1> 		;		
   283                              <1> 		; ES:DI = Address of DPT from BIOS
   284                              <1> 		;
   285 000000A9 881C                <1> 	mov	[si], bl ;  Drive type
   286                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
   287                              <1> 	; 14/01/2015
   288 000000AB E8DC01              <1> 	call	set_disk_parms
   289                              <1> 	; 10/12/2014
   290 000000AE 81FE[8C62]          <1> 	cmp	si, fd0_type
   291 000000B2 7705                <1> 	ja	short L4
   292 000000B4 46                  <1> 	inc	si ; fd1_type
   293 000000B5 B201                <1> 	mov	dl, 1
   294 000000B7 EBE6                <1> 	jmp	short L3
   295                              <1> L4:
   296 000000B9 B27F                <1> 	mov	dl, 7Fh
   297                              <1> 	; 24/12/2014
   298 000000BB 803E[8B62]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
   299                              <1> 	;ja	L10	  ; yes, all fixed disk operations
   300                              <1> 			  ; will be performed according to
   301                              <1> 			  ; present EDD specification
   302                              <1> 	; 14/07/2022
   303 000000C0 7603                <1> 	jna	short L5
   304 000000C2 E98800              <1> 	jmp	L10
   305                              <1> 
   306                              <1> L5:
   307                              <1> 	; 17/07/2020
   308                              <1> 	; Note: Virtual CPU will not come here while 
   309                              <1> 	; running in QEMU, Bochs, VirtualBox emulators !!!
   310                              <1> 	
   311                              <1> 	; 17/07/2020
   312                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   313                              <1> 
   314 000000C5 FEC2                <1> 	inc 	dl
   315 000000C7 8816[8962]          <1>         mov     [drv], dl
   316 000000CB 8816[8A62]          <1>         mov     [last_drv], dl ; 14/01/2015
   317 000000CF B408                <1> 	mov 	ah, 08h ; Return drive parameters
   318 000000D1 CD13                <1> 	int	13h	; (conventional function)
   319                              <1> 	;jc	L13	; fixed disk drive not ready
   320                              <1> 	; 14/07/2022
   321 000000D3 7303                <1> 	jnc	short L6
   322 000000D5 E9A401              <1> 	jmp	L13
   323                              <1> L6:
   324 000000D8 8816[8B62]          <1>         mov     [hdc], dl ; number of drives
   325                              <1> 	;; 14/01/2013
   326                              <1> 	;;push	cx
   327 000000DC E8AB01              <1> 	call	set_disk_parms
   328                              <1> 	;;pop	cx
   329                              <1> 	;
   330                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   331 000000DF 8A16[8962]          <1>         mov     dl, [drv]
   332 000000E3 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   333 000000E6 80FA80              <1> 	cmp	dl, 80h
   334 000000E9 7603                <1> 	jna	short L7
   335 000000EB 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   336                              <1> L7:	
   337 000000EE 31C0                <1> 	xor	ax, ax
   338 000000F0 8ED8                <1> 	mov	ds, ax
   339 000000F2 8B37                <1>         mov     si, [bx]
   340 000000F4 8B4702              <1>         mov     ax, [bx+2] 
   341 000000F7 8ED8                <1> 	mov	ds, ax
   342 000000F9 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   343                              <1> 	;jne	L12 ; invalid FDPT
   344                              <1> 	; 14/07/2022
   345 000000FC 7403                <1> 	je	short L7_8
   346 000000FE E97701              <1> 	jmp	L12
   347                              <1> L7_8:
   348 00000101 BF0000              <1> 	mov	di, HD0_DPT
   349 00000104 80FA80              <1> 	cmp	dl, 80h
   350 00000107 7603                <1> 	jna	short L8
   351 00000109 BF2000              <1> 	mov	di, HD1_DPT 
   352                              <1> L8:
   353                              <1> 	; 30/12/2014
   354 0000010C B80090              <1> 	mov	ax, DPT_SEGM
   355 0000010F 8EC0                <1> 	mov	es, ax
   356                              <1> 	; 24/12/2014
   357 00000111 B90800              <1> 	mov	cx, 8
   358 00000114 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   359 00000116 8CC8                <1> 	mov	ax, cs
   360 00000118 8ED8                <1> 	mov	ds, ax
   361                              <1> 
   362                              <1> 	; 02/02/2015
   363                              <1> 	;mov	cl, [drv]
   364                              <1> 	;mov	bl, cl
   365                              <1> 	;mov	ax, 1F0h
   366                              <1> 	;and	bl, 1
   367                              <1> 	;jz	short L9
   368                              <1> 	;shl	bl, 4
   369                              <1> 	;sub	ax, 1F0h-170h
   370                              <1> 
   371                              <1> 	; 17/07/2020 
   372                              <1> 	; (Only 1F0h port address must be valid for old ROM BIOSes)
   373 0000011A B8F001              <1> 	mov	ax, 1F0h
   374 0000011D B3A0                <1> 	mov	bl, 0A0h
   375 0000011F 80FA80              <1> 	cmp	dl, 80h
   376 00000122 7603                <1> 	jna	short L9
   377                              <1> 	; dl = 81h
   378 00000124 80C310              <1> 	add	bl, 10h  ; slave disk
   379                              <1> 	;sub	ax, 1F0h-170h
   380                              <1> L9:
   381 00000127 AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   382 00000128 050602              <1> 	add	ax, 206h
   383 0000012B AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   384 0000012C 88D8                <1> 	mov	al, bl  ; bit 4, master/slave disk bit
   385                              <1> 	;add	al, 0A0h ; 17/07/2020
   386 0000012E AA                  <1> 	stosb	; Device/Head Register upper nibble
   387                              <1> 	;
   388 0000012F FE06[8962]          <1> 	inc	byte [drv]
   389 00000133 BB[0E62]            <1> 	mov	bx, hd0_type - 80h
   390 00000136 01CB                <1> 	add	bx, cx
   391 00000138 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   392 0000013B A0[8B62]            <1> 	mov	al, [hdc]
   393 0000013E FEC8                <1> 	dec	al
   394                              <1> 	;jz	L13
   395                              <1> 	; 14/07/2022
   396 00000140 7408                <1> 	jz	short L9_10
   397 00000142 80FA80              <1> 	cmp	dl, 80h
   398                              <1>         ;jna	L5 ; Max. 2 hard disks  ; 17/07/2020
   399                              <1> 	; 14/07/2022
   400 00000145 7703                <1> 	ja	short L9_10
   401 00000147 E97BFF              <1> 	jmp	L5
   402                              <1> L9_10:
   403 0000014A E92F01              <1>         jmp     L13
   404                              <1> L10:
   405 0000014D FEC2                <1> 	inc 	dl
   406                              <1> 	; 25/12/2014
   407 0000014F 8816[8962]          <1> 	mov	[drv], dl
   408 00000153 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   409 00000155 CD13                <1> 	int	13h	; (conventional function)
   410                              <1> 	;jc	L13
   411                              <1> 	; 14/07/2022
   412 00000157 72F1                <1> 	jc	short L9_10
   413                              <1> 	; 14/01/2015
   414 00000159 8A16[8962]          <1> 	mov	dl, [drv]
   415 0000015D 52                  <1> 	push	dx
   416 0000015E 51                  <1> 	push	cx
   417 0000015F E82801              <1> 	call	set_disk_parms
   418 00000162 59                  <1> 	pop	cx
   419 00000163 5A                  <1> 	pop	dx
   420                              <1> 	; 06/07/2016 (BugFix for >64K kernel files)
   421                              <1> 	; 04/02/2016 (esi -> si)
   422                              <1> 	;mov	si, _end ; 30 byte temporary buffer address 	
   423                              <1> 	;		 ; at the '_end' of kernel.
   424                              <1> 	;mov	word [si], 30
   425                              <1> 	; 06/07/2016
   426 00000164 BE[5000]            <1> 	mov	si, _int13h_48h_buffer
   427                              <1> 	; 09/07/2016
   428 00000167 B81E00              <1> 	mov	ax, 001Eh
   429 0000016A 8824                <1> 	mov	[si], ah ; 0
   430 0000016C 46                  <1> 	inc	si
   431 0000016D 8904                <1> 	mov	word [si], ax
   432                              <1>  	; word [si] = 30
   433                              <1> 	;
   434 0000016F B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   435 00000171 CD13                <1> 	int	13h
   436                              <1> 	;jc	L13
   437                              <1> 	; 14/07/2022
   438 00000173 72D5                <1> 	jc	short L9_10
   439                              <1> 
   440                              <1> 	; 29/08/2020
   441                              <1> 	; 04/02/2016 (ebx -> bx)
   442                              <1> 	; 14/01/2015
   443 00000175 28FF                <1> 	sub	bh, bh
   444 00000177 88D3                <1> 	mov	bl, dl
   445                              <1> 	;sub	bl, 80h
   446                              <1> 	; 29/08/2020
   447 00000179 81C3[0E62]          <1> 	add	bx, (hd0_type - 80h)
   448                              <1> 	;mov 	al, [bx]
   449 0000017D 8A07                <1> 	mov	al, [bx]
   450 0000017F 0C80                <1> 	or	al, 80h
   451 00000181 8807                <1> 	mov 	[bx], al	
   452 00000183 81EB[8C62]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   453                              <1> 	;add	bx, drv.status
   454                              <1> 	;mov	[bx], al
   455                              <1> 	; 29/08/2020
   456 00000187 8887[AE62]          <1> 	mov	[bx+drv.status], al
   457                              <1> 	; 04/02/2016 (eax -> ax)
   458                              <1> 	;mov	ax, [si+16]
   459                              <1> 	; 14/07/2020
   460                              <1> 	;mov	di, [si+18] 
   461                              <1> 	;;test	ax, [si+18]
   462                              <1> 	;test	ax, di ; 14/07/2020
   463                              <1> 	;jz	short L10_A0h ; (!) ; 17/07/2020
   464                              <1> 			; 'CHS only' disks on EDD system 
   465                              <1> 			;  are reported with ZERO disk size
   466                              <1> 			; (if so, we must not overwrite
   467                              <1> 			; calculated disk size in 'set_disk_parms')
   468                              <1> 	; 29/08/2020
   469 0000018B 8B4410              <1> 	mov	ax, [si+16]
   470 0000018E 8B7C12              <1> 	mov	di, [si+18]
   471 00000191 09C0                <1> 	or	ax, ax
   472 00000193 7504                <1> 	jnz	short L10_LBA
   473 00000195 09FF                <1> 	or	di, di
   474 00000197 740B                <1> 	jz	short L10_A0h
   475                              <1> L10_LBA:
   476                              <1> 	;sub	bx, drv.status
   477 00000199 C1E302              <1> 	shl	bx, 2
   478                              <1> 	;add	bx, drv.size ; disk size (in sectors)
   479                              <1> 	;mov	[bx], ax
   480                              <1> 	; 29/08/2020
   481 0000019C 8987[9262]          <1> 	mov	[bx+drv.size], ax
   482                              <1> 	;mov	ax, [si+18]
   483                              <1> 	;;mov	[bx], ax
   484                              <1> 	;mov	[bx+2], ax ; BugFix ; 15/07/2020
   485                              <1> 	; 14/07/2020
   486                              <1> 	;mov	[bx+2], di ; 15/07/2020
   487                              <1> 	; 29/08/2020
   488 000001A0 89BF[9462]          <1> 	mov	[bx+drv.size+2], di
   489                              <1> L10_A0h: 
   490                              <1> 	; 17/07/2020
   491                              <1> 	; Note: Virtual CPU will jump here from above (!) test
   492                              <1> 	;	while running in QEMU
   493                              <1> 
   494                              <1> 	; Jump here to fix a ZERO (LBA) disk size problem 
   495                              <1> 	; for CHS disks (28/02/2015)
   496                              <1> 	
   497                              <1> 	; 30/12/2014
   498 000001A4 BF0000              <1> 	mov	di, HD0_DPT
   499 000001A7 88D0                <1> 	mov	al, dl
   500 000001A9 83E003              <1> 	and 	ax, 3
   501 000001AC C0E005              <1> 	shl	al, 5 ; * 32
   502 000001AF 01C7                <1> 	add 	di, ax
   503 000001B1 B80090              <1> 	mov	ax, DPT_SEGM
   504 000001B4 8EC0                <1> 	mov	es, ax
   505                              <1> 	;
   506 000001B6 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   507 000001B8 88CC                <1> 	mov	ah, cl	
   508 000001BA C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   509 000001BD 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   510 000001BE AB                  <1> 	stosw		
   511 000001BF 88F0                <1> 	mov	al, dh	; max. head number
   512                              <1> 	;
   513 000001C1 30F6                <1> 	xor	dh, dh  ; 29/08/2020 (dh = 0 is needed here)
   514                              <1> 	;
   515 000001C3 FEC0                <1> 	inc	al
   516 000001C5 AA                  <1> 	stosb		; logical heads (limits 256)
   517 000001C6 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   518 000001C8 AA                  <1> 	stosb
   519 000001C9 8A440C              <1> 	mov	al, [si+12]
   520 000001CC AA                  <1> 	stosb		 ; physical sectors per track
   521 000001CD 31C0                <1>  	xor	ax, ax
   522                              <1> 	;dec	ax	 ; 02/01/2015 
   523 000001CF AB                  <1> 	stosw		 ; precompensation (obsolete)
   524                              <1> 	;xor	al, al	 ; 02/01/2015	
   525 000001D0 AA                  <1> 	stosb		 ; reserved
   526 000001D1 B008                <1> 	mov	al, 8	 ; drive control byte
   527                              <1> 		         ; (do not disable retries, 
   528                              <1> 			 ; more than 8 heads)
   529 000001D3 AA                  <1> 	stosb
   530 000001D4 8B4404              <1> 	mov	ax, [si+4]
   531 000001D7 AB                  <1> 	stosw		 ; physical number of cylinders	
   532                              <1> 	;push	ax	 ; 02/01/2015
   533 000001D8 8A4408              <1> 	mov	al, [si+8]
   534 000001DB AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   535 000001DC 29C0                <1> 	sub 	ax, ax
   536                              <1> 	;pop	ax	 ; 02/01/2015	
   537 000001DE AB                  <1> 	stosw		 ; landing zone (obsolete)
   538 000001DF 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   539 000001E1 243F                <1> 	and 	al, 3Fh	
   540 000001E3 AA                  <1> 	stosb
   541                              <1> 	;sub	al, al	 ; checksum
   542                              <1> 	;stosb
   543                              <1> 	;
   544 000001E4 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   545 000001E7 AD                  <1> 	lodsw
   546 000001E8 50                  <1> 	push	ax ; *	 ; (BIOS) DPTE offset
   547 000001E9 AD                  <1> 	lodsw
   548 000001EA 50                  <1> 	push	ax ; **	 ; (BIOS) DPTE segment
   549                              <1> 	;
   550                              <1> 	; checksum calculation
   551 000001EB 89FE                <1> 	mov	si, di
   552 000001ED 06                  <1> 	push	es
   553 000001EE 1F                  <1> 	pop	ds
   554                              <1> 	;mov	cx, 16
   555 000001EF B90F00              <1> 	mov 	cx, 15
   556 000001F2 29CE                <1> 	sub	si, cx
   557 000001F4 30E4                <1> 	xor	ah, ah
   558                              <1> 	;del	cl
   559                              <1> L11:		
   560 000001F6 AC                  <1> 	lodsb
   561 000001F7 00C4                <1> 	add	ah, al
   562 000001F9 E2FB                <1> 	loop	L11
   563                              <1> 	;
   564 000001FB 88E0                <1> 	mov	al, ah
   565 000001FD F6D8                <1> 	neg	al	; -x+x = 0
   566 000001FF AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   567                              <1> 	;
   568 00000200 1F                  <1> 	pop	ds ; **	; (BIOS) DPTE segment
   569 00000201 5E                  <1> 	pop	si ; *	; (BIOS) DPTE offset	
   570                              <1> 
   571                              <1> 	; 08/08/2022 (TRDOS 386 v2.0.5)
   572                              <1> 	; (Recent version of Retro UNIX 386 v1 'diskinit.s' file
   573                              <1> 	; -12/07/2022- does not contain following 2020 code) (*)
   574                              <1> 
   575                              <1> 	; 14/07/2020 (TRDOS 386 v2.0.2)
   576                              <1> 	; 0FFFFh:0FFFFh = invalid DPTE address
   577 00000202 8B0C                <1> 	mov	cx, [si]
   578 00000204 8B4402              <1> 	mov	ax, [si+2]
   579 00000207 21C1                <1> 	and	cx, ax
   580 00000209 41                  <1> 	inc	cx 
   581 0000020A 7404                <1> 	jz	short L11c ; 0FFFFh:0FFFFh
   582 0000020C 0B04                <1> 	or	ax, [si]
   583 0000020E 752A                <1> 	jnz	short L11e ; <> 0
   584                              <1> L11c:
   585                              <1> 	; 17/07/2020
   586                              <1> 	; TRDOS 386 v2 DRVINIT assumptions:
   587                              <1> 	; (also by regarding QEMU, Bochs and VirtualBox settings)
   588                              <1> 	;	Hard disk 0 port address: 1F0h
   589                              <1> 	;	Hard disk 1 port address: 1F0h
   590                              <1> 	;	Hard disk 2 port address: 170h
   591                              <1> 	;	Hard disk 3 port address: 170h
   592                              <1> 
   593                              <1> 	; in QEMU, hda=hd0 (1F0h) and hdb=hd1 (1F0h) -IRQ14-
   594                              <1> 	;      and hdc=hd2 (170h) and hdd=hd3 (170h) -IRQ15-
   595                              <1> 
   596 00000210 B8F001              <1> 	mov	ax, 1F0h
   597                              <1> 
   598                              <1> 	; 15/07/2020
   599                              <1> 	; 14/07/2020
   600                              <1> 	; Invalid DPTE address...
   601                              <1> 	; Default DPTE parms must be set for DISK_IO_CONT
   602                              <1> 	; (diskio.s)
   603                              <1> 	; 17/07/2020
   604                              <1> 
   605                              <1> 	;mov	bl, dl
   606                              <1> 	;and	bl, 1
   607                              <1> 	;jz	short L11d
   608                              <1> 
   609 00000213 B3A0                <1> 	mov	bl, 0A0h
   610                              <1> 
   611 00000215 F6C201              <1> 	test	dl, 1
   612 00000218 7403                <1> 	jz	short L11g  ; Master (as default, for 80h & 82h))
   613                              <1> 	;shl	bl, 4 ; bl = 16 (bit 4 = 1 -> slave)
   614 0000021A 80C310              <1> 	add	bl, 10h  ; Slave (as default, for 81h & 83h)
   615                              <1> L11g:
   616                              <1> 	; 17/07/2020
   617 0000021D 80FA82              <1> 	cmp	dl, 82h	; Hard disk 3 or 4 ?
   618 00000220 7203                <1> 	jb	short L11d ; Primary ATA channel (hd0, hd1)
   619                              <1> 			   ; (port address = 1F0h)
   620                              <1> 	
   621                              <1> 	; Secondary ATA channel (hd2, hd3)
   622                              <1> 	; (port address = 170h)
   623                              <1> 
   624 00000222 2D8000              <1> 	sub	ax, 1F0h-170h
   625                              <1> L11d:
   626                              <1> 	; 14/07/2020
   627 00000225 AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   628 00000226 050602              <1> 	add	ax, 206h
   629 00000229 AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   630 0000022A 88D8                <1> 	mov	al, bl  ; Master/Slave bit (0 = Master)
   631                              <1> 	; 17/07/2020
   632                              <1> 	;or	al, 0A0h ; CHS (LBA enable bit = 0)
   633                              <1> 			 ; (Bits 5&7, reserved bits  =  1)
   634 0000022C 30E4                <1> 	xor	ah, ah
   635                              <1> 	;stosb	; Device/Head Register upper nibble
   636 0000022E AB                  <1> 	stosw
   637 0000022F 30C0                <1> 	xor	al, al
   638 00000231 B90500              <1> 	mov	cx, 5
   639 00000234 F3AB                <1> 	rep	stosw ; clear remain part of the (fake) DPTE
   640 00000236 0E                  <1> 	push	cs
   641 00000237 1F                  <1> 	pop	ds
   642 00000238 EB2E                <1> 	jmp	short L11f
   643                              <1> 
   644                              <1> 	; 08/08/2022 (TRDOS 386 v2.0.5)
   645                              <1> 	; (Recent version of Retro UNIX 386 v1 'diskinit.s' file
   646                              <1> 	; -12/07/2022- does not contain above 2020 code) (*)
   647                              <1> L11e:
   648                              <1> 	; 23/02/2015
   649 0000023A 57                  <1> 	push	di
   650                              <1> 	; ES:DI points to DPTE (FDPTE) location
   651                              <1> 	;;mov	cx, 8
   652                              <1> 	;mov	cl, 8
   653 0000023B B90800              <1> 	mov	cx, 8 ; 14/07/2020
   654 0000023E F3A5                <1> 	rep	movsw	
   655                              <1> 	;
   656                              <1> 	; 23/02/2015
   657                              <1> 	; (P)ATA drive and LBA validation
   658                              <1> 	; (invalidating SATA drives and setting
   659                              <1> 	; CHS type I/O for old type fixed disks)
   660 00000240 5B                  <1> 	pop	bx
   661 00000241 8CC8                <1> 	mov	ax, cs
   662 00000243 8ED8                <1> 	mov	ds, ax
   663 00000245 268B07              <1> 	mov	ax, [es:bx]
   664 00000248 3DF001              <1> 	cmp	ax, 1F0h
   665 0000024B 7413                <1> 	je	short L11a
   666 0000024D 3D7001              <1> 	cmp	ax, 170h
   667 00000250 740E                <1> 	je	short L11a
   668                              <1> 	; invalidation 
   669                              <1> 	; (because base port address is not 1F0h or 170h)
   670                              <1> 	;xor	bh, bh
   671                              <1> 	;mov	bl, dl
   672                              <1> 	; 29/08/2020
   673                              <1> 	;xor	dh, dh ; 0
   674 00000252 89D3                <1> 	mov	bx, dx
   675                              <1> 	;sub	bl, 80h
   676                              <1> 	;mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   677                              <1>         ;or	byte [bx+drv.status+2], 0F0h ; (failure sign)
   678                              <1> 	; 29/08/2020
   679 00000254 C687[0E62]00        <1> 	mov	byte [bx+hd0_type-80h], 0
   680 00000259 808F[3062]F0        <1> 	or	byte [bx+drv.status-7Eh], 0F0h
   681 0000025E EB0F                <1> 	jmp	short L11b
   682                              <1> L11a:	
   683                              <1> 	; LBA validation
   684 00000260 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   685 00000264 A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   686 00000266 7507                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   687                              <1> L11f:
   688                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   689                              <1> 	;sub	bh, bh
   690                              <1> 	;mov	bl, dl
   691                              <1> 	; 29/08/2020
   692                              <1> 	;xor	dh, dh ; 0
   693 00000268 89D3                <1> 	mov	bx, dx
   694                              <1> 	;sub	bl, 80h ; 26/02/2015
   695                              <1>         ;and	byte [bx+drv.status+2], 0FEh ; clear bit 0
   696                              <1> 				; bit 0 = LBA ready bit
   697                              <1> 	; 29/08/2020
   698 0000026A 80A7[3062]FE        <1> 	and	byte [bx+drv.status-7Eh], 0FEh
   699                              <1> 	; 'diskio' procedure will check this bit !
   700                              <1> L11b:
   701 0000026F 3A16[8A62]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   702 00000273 7307                <1>         jnb     short L13
   703 00000275 E9D5FE              <1>         jmp     L10
   704                              <1> 
   705                              <1> L12:
   706                              <1> 	; Restore data registers
   707 00000278 8CC8                <1> 	mov	ax, cs
   708 0000027A 8ED8                <1> 	mov	ds, ax	
   709                              <1> L13:
   710                              <1> 	; 13/12/2014
   711 0000027C 0E                  <1> 	push	cs
   712 0000027D 07                  <1> 	pop	es
   713                              <1> L14:
   714                              <1> 	; clear keyboard buffer
   715 0000027E B411                <1> 	mov 	ah, 11h
   716 00000280 CD16                <1> 	int 	16h
   717 00000282 7440                <1> 	jz 	short L16 ; no keys in keyboard buffer
   718 00000284 B010                <1> 	mov	al, 10h
   719 00000286 CD16                <1> 	int 	16h
   720 00000288 EBF4                <1> 	jmp 	short L14
   721                              <1> 
   722                              <1> set_disk_parms:
   723                              <1> 	; 08/08/2022
   724                              <1> 	; 09/05/2022 - Retro UNIX 386 v1.2
   725                              <1> 	; 29/08/2020 - TRDOS 386 v2.0.2
   726                              <1> 	; 04/02/2016 (ebx -> bx)
   727                              <1> 	; 10/07/2015
   728                              <1> 	; 14/01/2015
   729                              <1> 	;push	bx
   730 0000028A 28FF                <1> 	sub	bh, bh
   731 0000028C 8A1E[8962]          <1> 	mov	bl, [drv]
   732 00000290 80FB80              <1> 	cmp	bl, 80h
   733 00000293 7203                <1> 	jb	short sdp0
   734 00000295 80EB7E              <1> 	sub	bl, 7Eh
   735                              <1> sdp0:	
   736                              <1> 	;add	bx, drv.status
   737                              <1>   	;mov	byte [bx], 80h ; 'Present' flag
   738                              <1> 	; 29/08/2020
   739 00000298 C687[AE62]80        <1> 	mov	byte [bx+drv.status], 80h
   740                              <1> 	;
   741 0000029D 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   742 0000029F 88CC                <1> 	mov	ah, cl ; 
   743 000002A1 C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   744                              <1> 	;sub	bx, drv.status
   745 000002A4 D0E3                <1> 	shl	bl, 1
   746                              <1> 	;add	bx, drv.cylinders
   747 000002A6 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   748                              <1> 	;mov	[bx], ax
   749                              <1> 	; 08/08/2022
   750                              <1> 	; 29/08/2020
   751                              <1> 	;mov	[bx+drv.cylinders], ax
   752                              <1> 	;
   753 000002A7 50                  <1> 	push	ax ; ** cylinders
   754                              <1> 	;sub	bx, drv.cylinders
   755                              <1> 	;add	bx, drv.heads
   756 000002A8 30E4                <1> 	xor	ah, ah
   757 000002AA 88F0                <1> 	mov	al, dh ; heads
   758 000002AC 40                  <1> 	inc	ax
   759                              <1> 	;mov	[bx], ax
   760                              <1> 	; 08/08/2022
   761                              <1> 	; 29/08/2020
   762                              <1> 	;mov	[bx+drv.heads], ax
   763                              <1> 	;sub	bx, drv.heads
   764                              <1>         ;add	bx, drv.spt
   765 000002AD 30ED                <1> 	xor	ch, ch
   766 000002AF 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   767                              <1> 	;mov	[bx], cx
   768                              <1>         ; 08/08/2022
   769                              <1> 	; 29/08/2020
   770                              <1> 	;mov	[bx+drv.spt], cx
   771                              <1> 	;sub	bx, drv.spt
   772 000002B2 D1E3                <1> 	shl	bx, 1
   773                              <1> 	;add	bx, drv.size ; disk size (in sectors)
   774                              <1> 	; LBA size = cylinders * heads * secpertrack
   775 000002B4 F7E1                <1> 	mul	cx 
   776 000002B6 89C2                <1> 	mov	dx, ax	; heads*spt					
   777 000002B8 58                  <1> 	pop	ax ; ** cylinders
   778                              <1> 	; 09/05/2022 (fd0&fd1 drv.size = cyls*spt*heads)
   779                              <1> 	;dec	ax ; 1 cylinder reserved (!?) ; (*)
   780 000002B9 F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   781                              <1> 	;mov	[bx], ax
   782                              <1> 	;mov	[bx+2], dx
   783                              <1> 	; 29/08/2020
   784 000002BB 8987[9262]          <1> 	mov	[bx+drv.size], ax
   785 000002BF 8997[9462]          <1> 	mov	[bx+drv.size+2], dx
   786                              <1> 	;
   787                              <1> 	;pop	bx
   788 000002C3 C3                  <1> 	retn
   789                              <1> 
   790                              <1> ;align 2
   791                              <1> 
   792                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   793                              <1> ;heads     :  dw 0, 0, 0, 0, 0, 0
   794                              <1> ;spt       :  dw 0, 0, 0, 0, 0, 0
   795                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   796                              <1> 
   797                              <1> ;last_drv:
   798                              <1> ;	db  0
   799                              <1> ;drv_status:
   800                              <1> ;	db  0,0,0,0,0,0
   801                              <1> ;	db 0
   802                              <1> 
   803                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   804                              <1> 
   805                              <1> L16:
   806                                  _L0:	
   807                                  	; 10/11/2014
   808 000002C4 FA                           	cli	; Disable interrupts (clear interrupt flag)
   809                                  		; Reset Interrupt MASK Registers (Master&Slave)
   810                                  	;mov	al, 0FFh	; mask off all interrupts
   811                                  	;out	21h, al		; on master PIC (8259)
   812                                  	;jmp 	$+2  ; (delay)
   813                                  	;out	0A1h, al	; on slave PIC (8259)
   814                                  	;
   815                                  	; Disable NMI 
   816 000002C5 B080                    	mov   	al, 80h 
   817 000002C7 E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   818                                  	; 23/02/2015
   819 000002C9 90                      	nop			;
   820                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   821                                  				; for preventing unknown state (!?)
   822                                  
   823                                  	; 01/01/2022 (Retro UNIX 386 v1.2)
   824                                  	%define KERNELFSIZE KEND-KSTART 
   825                                  	;
   826                                   	; 20/08/2014
   827                                  	; Moving the kernel 64 KB back (to physical address 0)
   828                                  	; DS = CS = 1000h
   829                                  	; 05/11/2014
   830 000002CA 31C0                    	xor	ax, ax
   831 000002CC 8EC0                    	mov	es, ax ; ES = 0
   832                                  	;
   833                                  	;;mov	cx, (KEND - KLOAD)/4
   834                                  	;mov	cx, (KERNELFSIZE+3)/4 ; 01/01/2022
   835 000002CE B97E32                  	mov	cx, (KERNELFSIZE+1)/2 ; 02/01/2022
   836 000002D1 31F6                    	xor	si, si
   837 000002D3 31FF                    	xor	di, di
   838                                  	;rep	movsd
   839 000002D5 F3A5                    	rep	movsw ; 02/01/2022
   840                                  	;
   841 000002D7 06                      	push	es ; 0
   842 000002D8 68[DC02]                	push	L17
   843 000002DB CB                      	retf
   844                                  	;
   845                                  L17:
   846                                  	; Turn off the floppy drive motor
   847 000002DC BAF203                          mov     dx, 3F2h
   848 000002DF EE                              out     dx, al ; 0 ; 31/12/2013
   849                                  
   850                                  	; Enable access to memory above one megabyte
   851                                  L18:
   852 000002E0 E464                    	in	al, 64h
   853 000002E2 A802                    	test	al, 2
   854 000002E4 75FA                            jnz     short L18
   855 000002E6 B0D1                    	mov	al, 0D1h	; Write output port
   856 000002E8 E664                    	out	64h, al
   857                                  L19:
   858 000002EA E464                    	in	al, 64h
   859 000002EC A802                    	test	al, 2
   860 000002EE 75FA                            jnz     short L19
   861 000002F0 B0DF                    	mov	al, 0DFh	; Enable A20 line
   862 000002F2 E660                    	out	60h, al
   863                                  ;L20:
   864                                  	;
   865                                  	; Load global descriptor table register
   866                                  
   867                                          ;mov	ax, cs
   868                                          ;mov	ds, ax
   869                                  
   870 000002F4 2E0F0116[B05F]                  lgdt    [cs:gdtd]
   871                                  
   872 000002FA 0F20C0                          mov     eax, cr0
   873                                  	;or 	eax, 1
   874 000002FD 40                      	inc     ax
   875 000002FE 0F22C0                  	mov     cr0, eax
   876                                  
   877                                  	; Jump to 32 bit code
   878                                  	
   879 00000301 66                      	db	66h 		; Prefix for 32-bit
   880 00000302 EA                      	db	0EAh 		; Opcode for far jump
   881 00000303 [09030000]              	dd	StartPM 	; Offset to start, 32-bit
   882                                  				; (1000h:StartPM = StartPM + 10000h)
   883 00000307 0800                    	dw	KCODE		; This is the selector for CODE32_DESCRIPTOR,
   884                                  				; assuming that StartPM resides in code32
   885                                  
   886                                  [BITS 32] 
   887                                  
   888                                  StartPM:
   889                                  	; Kernel Base Address = 0 ; 30/12/2013
   890 00000309 66B81000                	mov	ax, KDATA	; Save data segment identifier
   891 0000030D 8ED8                            mov	ds, ax		; Move a valid data segment into DS register
   892 0000030F 8EC0                           	mov	es, ax		; Move data segment into ES register
   893 00000311 8EE0                           	mov	fs, ax		; Move data segment into FS register
   894 00000313 8EE8                          	mov	gs, ax		; Move data segment into GS register
   895 00000315 8ED0                            mov	ss, ax		; Move data segment into SS register
   896 00000317 BC00000900                      mov	esp, 90000h	; Move the stack pointer to 090000h
   897                                  
   898                                  clear_bss: ; Clear uninitialized data area
   899                                  	; 11/03/2015
   900 0000031C 31C0                    	xor	eax, eax ; 0
   901                                  	;mov	ecx, (bss_end - bss_start)/4
   902                                  	;;shr	ecx, 2 ; bss section is already aligned for double words
   903                                  	; 12/12/2021
   904 0000031E B9B90C0000              	mov	ecx, BSS_SIZE/4
   905 00000323 BF[00650000]            	mov	edi, bss_start	
   906 00000328 F3AB                    	rep	stosd  		
   907                                  
   908                                  memory_init:
   909                                  	; Initialize memory allocation table and page tables
   910                                  	;
   911                                  	; 02/01/2022 (Retro UNIX 386 v1.2)
   912                                  	; 16/11/2014
   913                                  	; 15/11/2014
   914                                  	; 07/11/2014
   915                                  	; 06/11/2014
   916                                  	; 05/11/2014
   917                                  	; 04/11/2014
   918                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   919                                  	;
   920                                  ;	xor	eax, eax
   921                                  ;	xor 	ecx, ecx
   922 0000032A B108                    	mov	cl, 8
   923 0000032C BF00001000              	mov	edi, MEM_ALLOC_TBL	
   924 00000331 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   925                                  				   ; for the first 1 MB memory
   926                                  	;
   927 00000333 8B0D[F4640000]          	mov	ecx, [mem_1m_1k]   ; 02/01/2022	
   928                                  	;mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   929                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   930                                  	;shr	cx, 2		   ; convert 1 KB count to 4 KB count
   931 00000339 C1E902                  	shr	ecx, 2	; 02/01/2022
   932 0000033C 890D[70670000]          	mov	[free_pages], ecx
   933 00000342 8B15[F8640000]          	mov	edx, [mem_16m_64k] ; 02/01/2022
   934                                  	;mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   935                                  				   ; between 16 MB and 4 GB.
   936                                  	;or	dx, dx
   937 00000348 09D2                    	or	edx, edx ; 02/01/2022
   938 0000034A 7412                    	jz	short mi_0
   939                                  	;
   940                                  	;mov	ax, dx
   941 0000034C 89D0                    	mov	eax, edx ; 02/01/2022
   942 0000034E C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   943 00000351 0105[70670000]          	add	[free_pages], eax
   944 00000357 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   945 0000035C EB06                    	jmp	short mi_1
   946                                  mi_0:
   947                                  	;mov	ax, cx
   948 0000035E 89C8                    	mov	eax, ecx ; 02/01/2022	 
   949 00000360 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB
   950                                  mi_1:
   951 00000364 A3[6C670000]            	mov	[memory_size], eax ; Total available memory in pages
   952                                  				   ; 1 alloc. tbl. bit = 1 memory page
   953                                  				   ; 32 allocation bits = 32 mem. pages
   954                                  	;
   955 00000369 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page
   956 0000036E C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   957                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   958                                  				   ;  --> x M.A.T. pages, if y = 0
   959                                  	;mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages
   960 00000371 A3[80670000]            	mov	[mat_size], eax ; 02/01/2022
   961 00000376 C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   962                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   963 00000379 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   964                                  	; Set/Calculate Kernel's Page Directory Address
   965 0000037B 81C300001000            	add	ebx, MEM_ALLOC_TBL
   966 00000381 891D[68670000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   967                                  				   ; just after the last M.A.T. page
   968                                  	;
   969 00000387 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   970 0000038A A3[78670000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   971                                  	;			   ; (allocation status search must be
   972                                  				   ; stopped after here)
   973 0000038F 31C0                    	xor	eax, eax
   974 00000391 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)
   975                                  	;push	cx
   976 00000392 51                      	push	ecx ; 02/01/2022 
   977 00000393 C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to
   978                                  				   ; count of 32 allocation bits
   979 00000396 F3AB                    	rep	stosd
   980                                  	;pop	cx
   981 00000398 59                      	pop	ecx ; 02/01/2022
   982 00000399 40                      	inc	eax		   ; 0
   983 0000039A 80E11F                  	and	cl, 31		   ; remain bits
   984 0000039D 7412                    	jz	short mi_4
   985 0000039F 8907                    	mov	[edi], eax	   ; reset
   986                                  mi_2:
   987 000003A1 0FAB07                  	bts	[edi], eax	   ; 06/11/2014
   988 000003A4 FEC9                    	dec	cl
   989 000003A6 7404                    	jz	short mi_3
   990 000003A8 FEC0                    	inc	al
   991 000003AA EBF5                    	jmp	short mi_2
   992                                  mi_3:
   993 000003AC 28C0                    	sub	al, al	   	   ; 0
   994 000003AE 83C704                  	add	edi, 4		   ; 15/11/2014
   995                                  mi_4:
   996 000003B1 09D2                    	or	edx, edx ; 02/01/2022
   997                                  	;or	dx, dx		  ; check 16M to 4G memory space
   998 000003B3 741F                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   999                                  	;	
  1000 000003B5 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
  1001                                  	;	
  1002 000003BA 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
  1003 000003BC 7405                    	jz	short mi_5	  ; jump if EDI points to 
  1004                                  				  ;         end of first 16 MB	
  1005                                  	;shr	ecx, 1		  ; convert to dword count
  1006                                  	;shr	ecx, 1		  ; (shift 2 bits right) 
  1007 000003BE C1E902                  	shr	ecx, 2	; 02/01/2022
  1008 000003C1 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
  1009                                  				  ; (memory hole under 16 MB)
  1010                                  mi_5:
  1011 000003C3 89D1                    	mov	ecx, edx ; 02/01/2022
  1012                                  	;mov	cx, dx		  ; count of 64 KB memory blocks
  1013 000003C5 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
  1014 000003C7 9C                      	pushf			  ; 16/11/2014		
  1015 000003C8 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
  1016 000003C9 F3AB                    	rep	stosd
  1017 000003CB 40                      	inc	eax		  ; 0
  1018 000003CC 9D                      	popf			  ; 16/11/2014
  1019 000003CD 7305                    	jnc	short mi_6
  1020 000003CF 6648                    	dec	ax		  ; eax = 0000FFFFh
  1021 000003D1 AB                      	stosd
  1022 000003D2 6640                    	inc	ax		  ; 0		
  1023                                  mi_6:
  1024 000003D4 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
  1025 000003D6 7309                    	jnb	short mi_7	  ; end of memory allocation table
  1026                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
  1027 000003D8 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
  1028 000003DA 29F9                    	sub	ecx, edi	  ; convert displacement/offset
  1029                                  	;shr	ecx, 1		  ; to dword count
  1030                                  	;shr	ecx, 1		  ; (shift 2 bits right) 
  1031 000003DC C1E902                  	shr	ecx, 2 ; 02/01/2022	
  1032 000003DF F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
  1033                                  mi_7:
  1034                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
  1035 000003E1 BA00001000              	mov	edx, MEM_ALLOC_TBL
  1036                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
  1037                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
  1038 000003E6 8B0D[80670000]          	mov	ecx, [mat_size] ; 02/01/2022
  1039                                  	;mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
  1040 000003EC 89D7                    	mov	edi, edx
  1041 000003EE C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
  1042                                  				  ; byte offset in M.A.T.
  1043                                  				  ; (1 M.A.T. byte points to 
  1044                                  				  ;	      32768 bytes)
  1045                                  				  ; Note: MEM_ALLOC_TBL address 
  1046                                  				  ; must be aligned on 128 KB 
  1047                                  				  ; boundary!
  1048 000003F1 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
  1049                                  	; eax = 0
  1050 000003F3 290D[70670000]          	sub	[free_pages], ecx ; 07/11/2014
  1051                                  mi_8:
  1052 000003F9 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
  1053                                  	;dec	bl
  1054 000003FC FEC9                    	dec	cl
  1055 000003FE 7404                    	jz	short mi_9
  1056 00000400 FEC0                    	inc	al
  1057 00000402 EBF5                    	jmp	short mi_8
  1058                                  mi_9:
  1059                                  	;
  1060                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
  1061                                  	;		(allocate pages for system page tables)
  1062                                  
  1063                                  	; edx = MEM_ALLOC_TBL
  1064 00000404 8B0D[6C670000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
  1065 0000040A 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)
  1066 00000410 C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
  1067                                  				 ; page table count (PDE count)
  1068                                  	;
  1069 00000413 51                      	push	ecx		 ; (**) PDE count (<= 1024)
  1070                                  	;
  1071 00000414 41                      	inc	ecx		 ; +1 for kernel page directory	
  1072                                  	;
  1073 00000415 290D[70670000]          	sub	[free_pages], ecx ; 07/11/2014
  1074                                  	;
  1075 0000041B 8B35[68670000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
  1076 00000421 C1EE0C                  	shr	esi, 12		 ; convert to page number
  1077                                  mi_10:
  1078 00000424 89F0                    	mov	eax, esi	 ; allocation bit offset
  1079 00000426 89C3                    	mov	ebx, eax
  1080 00000428 C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
  1081 0000042B 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
  1082                                  				 ;   to align on dword boundary
  1083 0000042E 83E01F                  	and	eax, 31		 ; set allocation bit position 
  1084                                  				 ;  (bit 0 to bit 31)
  1085                                  	;
  1086 00000431 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
  1087                                  	;
  1088 00000433 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
  1089                                  	;
  1090 00000436 46                      	inc	esi		 ; next page table
  1091 00000437 E2EB                    	loop	mi_10		 ; allocate next kernel page table 
  1092                                  				 ; (ecx = page table count + 1)
  1093                                  	;
  1094 00000439 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
  1095                                  	;
  1096                                  	; Initialize Kernel Page Directory and Kernel Page Tables
  1097                                  	;
  1098                                  	; Initialize Kernel's Page Directory
  1099 0000043A 8B3D[68670000]          	mov	edi, [k_page_dir]
  1100 00000440 89F8                    	mov	eax, edi
  1101 00000442 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
  1102                                  		     	      ; supervisor + read&write + present
  1103 00000444 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)
  1104                                  mi_11:
  1105 00000446 0500100000              	add	eax, 4096	; Add page size (PGSZ)
  1106                                  			        ; EAX points to next page table
  1107 0000044B AB                      	stosd
  1108 0000044C E2F8                    	loop	mi_11
  1109 0000044E 29C0                    	sub	eax, eax	; Empty PDE
  1110                                  	;mov	cx, 1024	; Entry count (PGSZ/4)
  1111                                  	; 02/01/2022
  1112 00000450 B504                    	mov	ch, 4 ; cx = 4*256 = 1024
  1113 00000452 29D1                    	sub	ecx, edx
  1114 00000454 7402                    	jz	short mi_12
  1115 00000456 F3AB                    	rep	stosd 		; clear remain (empty) PDEs
  1116                                  	;
  1117                                  	; Initialization of Kernel's Page Directory is OK, here.
  1118                                  mi_12:
  1119                                  	; Initialize Kernel's Page Tables
  1120                                  	;
  1121                                  	; (EDI points to address of page table 0)
  1122                                  	; eax = 0
  1123 00000458 8B0D[6C670000]          	mov	ecx, [memory_size] ; memory size in pages
  1124 0000045E 89CA                    	mov	edx, ecx	; (***)
  1125 00000460 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
  1126                                  			     ; supervisor + read&write + present
  1127                                  mi_13:
  1128 00000462 AB                      	stosd
  1129 00000463 0500100000              	add	eax, 4096	
  1130 00000468 E2F8                    	loop	mi_13
  1131                                  	; 02/01/2022
  1132 0000046A 66B9FF03                	mov	cx, 1023
  1133 0000046E 21CA                    	and	edx, ecx
  1134                                  	;and	dx, 1023	; (***)
  1135 00000470 7407                    	jz	short mi_14
  1136                                  	;mov	cx, 1024	
  1137                                  	; 02/01/2022
  1138                                  	;mov	ch, 4 ; cx = 4*256 = 1024
  1139 00000472 41                      	inc	ecx ; ecx = 1024
  1140 00000473 29D1                    	sub	ecx, edx
  1141                                  	;sub	cx, dx		; from dx (<= 1023) to 1024
  1142 00000475 31C0                    	xor	eax, eax
  1143 00000477 F3AB                    	rep	stosd		; clear remain (empty) PTEs 
  1144                                  				; of the last page table
  1145                                  mi_14:
  1146                                  	;  Initialization of Kernel's Page Tables is OK, here.
  1147                                  	;
  1148 00000479 89F8                    	mov	eax, edi	; end of the last page table page
  1149                                  			        ; (beginging of user space pages)
  1150 0000047B C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
  1151 0000047E 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
  1152                                  				; aligning on dword boundary
  1153                                  	 
  1154 00000480 A3[7C670000]            	mov	[first_page], eax
  1155 00000485 A3[74670000]            	mov	[next_page], eax ; The first free page pointer
  1156                                  				 ; for user programs
  1157                                  				 ; (Offset in Mem. Alloc. Tbl.)	
  1158                                  	;
  1159                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
  1160                                  	;
  1161                                  	
  1162                                  	; Enable paging
  1163                                  	;
  1164 0000048A A1[68670000]                    mov     eax, [k_page_dir]
  1165 0000048F 0F22D8                  	mov	cr3, eax
  1166 00000492 0F20C0                  	mov	eax, cr0
  1167 00000495 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
  1168 0000049A 0F22C0                  	mov	cr0, eax
  1169                                          ;jmp    KCODE:StartPMP
  1170                                  
  1171 0000049D EA                      	db 0EAh 		; Opcode for far jump
  1172 0000049E [A4040000]                      dd StartPMP		; 32 bit offset
  1173 000004A2 0800                    	dw KCODE		; kernel code segment descriptor
  1174                                  
  1175                                  StartPMP:
  1176                                  	; 06/11//2014
  1177                                  	; Clear video page 0
  1178                                  	;
  1179                                  	; Temporary Code
  1180                                  	;
  1181                                  	;mov	ecx, 80*25/2
  1182 000004A4 66B9E803                	mov	cx, (80*25)/2 ; 02/01/2022
  1183 000004A8 BF00800B00              	mov	edi, 0B8000h
  1184 000004AD 57                      	push	edi ; * ; 02/01/2022
  1185 000004AE 31C0                    	xor	eax, eax	; black background, black fore color
  1186 000004B0 F3AB                    	rep	stosd
  1187                                  	
  1188                                  	; 19/08/2014
  1189                                  	; Kernel Base Address = 0
  1190                                  	; It is mapped to (physically) 0 in the page table.
  1191                                  	; So, here is exactly 'StartPMP' address.
  1192                                  	;
  1193                                  	;;mov	ah, 4Eh	; Red background, yellow forecolor
  1194                                  	;;mov	esi, msgPM
  1195                                  	;; 14/08/2015 (kernel version message will appear
  1196                                  	;;	       when protected mode and paging is enabled)
  1197 000004B2 B40B                    	mov	ah, 0Bh ; Black background, light cyan forecolor
  1198 000004B4 BE[C4620000]            	mov	esi, msgKVER
  1199 000004B9 5F                      	pop	edi ; * ; 02/01/2022
  1200                                  	;mov	edi, 0B8000h ; 27/08/2014
  1201                                  	; 20/08/2014
  1202 000004BA E88F010000              	call	printk
  1203                                  
  1204                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
  1205                                  	; // Set IRQ offsets
  1206                                  	;
  1207                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
  1208                                  	;
  1209                                  					;; ICW1
  1210 000004BF B011                    	mov	al, 11h			; Initialization sequence
  1211 000004C1 E620                    	out	20h, al			; 	8259A-1
  1212                                  	; jmp 	$+2
  1213 000004C3 E6A0                    	out	0A0h, al		; 	8259A-2
  1214                                  					;; ICW2
  1215 000004C5 B020                    	mov	al, 20h			; Start of hardware ints (20h)
  1216 000004C7 E621                    	out	21h, al			;	for 8259A-1
  1217                                  	; jmp 	$+2
  1218 000004C9 B028                    	mov	al, 28h			; Start of hardware ints (28h)
  1219 000004CB E6A1                    	out	0A1h, al		; 	for 8259A-2
  1220                                  					;
  1221 000004CD B004                    	mov	al, 04h			;; ICW3
  1222 000004CF E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
  1223                                  	; jmp 	$+2
  1224 000004D1 B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
  1225 000004D3 E6A1                    	out	0A1h, al		;
  1226                                  					;; ICW4
  1227 000004D5 B001                    	mov	al, 01h	 		;
  1228 000004D7 E621                    	out	21h, al			; 	8086 mode, normal EOI	
  1229                                  	; jmp 	$+2
  1230 000004D9 E6A1                    	out	0A1h, al		;	for both chips.
  1231                                  
  1232                                  	;mov	al, 0FFh	; mask off all interrupts for now
  1233                                  	;out	21h, al
  1234                                  	;; jmp 	$+2
  1235                                  	;out	0A1h, al
  1236                                  
  1237                                  	; 02/04/2015
  1238                                  	; 26/03/2015 System call (INT 30h) modification
  1239                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
  1240                                  	;
  1241                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
  1242                                  	;  setup_idt:
  1243                                  	;
  1244                                          ;; 16/02/2015
  1245                                  	;;mov	dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1246                                  	; 21/08/2014 (timer_int)
  1247 000004DB BE[BC5F0000]            	mov	esi, ilist
  1248 000004E0 8D3D[00650000]          	lea	edi, [idt]
  1249                                  	; 26/03/2015
  1250                                  	;mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
  1251                                  	; 02/01/2022
  1252 000004E6 B130                    	mov	cl, 48 ; ecx = 48
  1253                                  	; 02/04/2015
  1254 000004E8 BB00000800              	mov	ebx, 80000h
  1255                                  rp_sidt1:
  1256 000004ED AD                      	lodsd
  1257 000004EE 89C2                    	mov	edx, eax
  1258 000004F0 66BA008E                	mov	dx, 8E00h
  1259 000004F4 6689C3                  	mov	bx, ax
  1260 000004F7 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
  1261                                         			        ; /* interrupt gate - dpl=0, present */
  1262 000004F9 AB                      	stosd	; selector & offset bits 0-15 	
  1263 000004FA 89D0                    	mov	eax, edx
  1264 000004FC AB                      	stosd	; attributes & offset bits 16-23
  1265 000004FD E2EE                    	loop	rp_sidt1
  1266 000004FF B110                    	mov	cl, 16		; 16 software interrupts (INT 30h to INT 3Fh)
  1267                                  rp_sidt2:
  1268 00000501 AD                      	lodsd
  1269 00000502 21C0                    	and	eax, eax
  1270 00000504 7413                    	jz	short rp_sidt3
  1271 00000506 89C2                    	mov	edx, eax
  1272 00000508 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1273 0000050C 6689C3                  	mov	bx, ax
  1274 0000050F 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1275 00000511 AB                      	stosd
  1276 00000512 89D0                    	mov	eax, edx
  1277 00000514 AB                      	stosd
  1278 00000515 E2EA                    	loop	rp_sidt2
  1279 00000517 EB16                    	jmp	short sidt_OK
  1280                                  rp_sidt3:
  1281 00000519 B8[72090000]            	mov	eax, ignore_int
  1282 0000051E 89C2                    	mov	edx, eax
  1283 00000520 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1284 00000524 6689C3                  	mov	bx, ax
  1285 00000527 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1286                                  rp_sidt4:
  1287 00000529 AB                      	stosd
  1288 0000052A 92                      	xchg	eax, edx
  1289 0000052B AB                      	stosd
  1290 0000052C 92                      	xchg	edx, eax
  1291 0000052D E2FA                    	loop	rp_sidt4
  1292                                  sidt_OK: 
  1293 0000052F 0F011D[B65F0000]        	lidt 	[idtd]
  1294                                  	;
  1295                                  	; TSS descriptor setup ; 24/03/2015
  1296 00000536 B8[00670000]            	mov	eax, task_state_segment
  1297 0000053B 66A3[AA5F0000]          	mov	[gdt_tss0], ax
  1298 00000541 C1C010                  	rol	eax, 16
  1299 00000544 A2[AC5F0000]            	mov	[gdt_tss1], al
  1300 00000549 8825[AF5F0000]          	mov	[gdt_tss2], ah
  1301 0000054F 66C705[66670000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
  1302 00000557 00                 
  1303                                  		; 
  1304                                  		; IO Map Base address (When this address points
  1305                                  		; to end of the TSS, CPU does not use IO port 
  1306                                  		; permission bit map for RING 3 IO permissions, 
  1307                                  		; access to any IO ports in ring 3 will be forbidden.)
  1308                                   		;
  1309                                  	;mov	[tss.esp0], esp ; TSS offset 4
  1310                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
  1311 00000558 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
  1312                                  			 ; occurs (or a system call -software INT- is requested)
  1313                                  			 ; while cpu running in ring 3 (in user mode).				
  1314                                  			 ; (Kernel stack pointer and segment will be loaded
  1315                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
  1316 0000055C 0F00D8                  	ltr	ax  ; Load task register
  1317                                  	;
  1318                                  esp0_set0:
  1319                                  	; 30/07/2015
  1320 0000055F 8B0D[6C670000]          	mov 	ecx, [memory_size] ; memory size in pages
  1321 00000565 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
  1322 00000568 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
  1323                                  			  ; (kernel mode virtual address)
  1324 0000056E 7605                    	jna	short esp0_set1
  1325                                  	;
  1326                                  	; If available memory > CORE (end of the 1st 4 MB)
  1327                                  	; set stack pointer to CORE
  1328                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
  1329                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
  1330 00000570 B900004000              	mov	ecx, CORE
  1331                                  esp0_set1:
  1332 00000575 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
  1333                                  esp0_set_ok:
  1334                                  	; 30/07/2015 (**tss.esp0**) 
  1335 00000577 8925[04670000]          	mov	[tss.esp0], esp
  1336 0000057D 66C705[08670000]10-             mov     word [tss.ss0], KDATA
  1337 00000585 00                 
  1338                                  	; 14/08/2015
  1339                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
  1340                                  	;
  1341                                  	;cli	; Disable interrupts (for CPU)
  1342                                  	;    (CPU will not handle hardware interrupts, except NMI!)
  1343                                  	;
  1344 00000586 30C0                    	xor	al, al		; Enable all hardware interrupts!
  1345 00000588 E621                    	out	21h, al		; (IBM PC-AT compatibility)
  1346 0000058A EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
  1347 0000058C E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
  1348                                  				; (Even if related hardware component
  1349                                  				;  does not exist!)
  1350                                  	; Enable NMI 
  1351 0000058E B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
  1352 00000590 E670                    	out  	70h, al
  1353                                  	; 23/02/2015
  1354 00000592 90                      	nop
  1355 00000593 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
  1356                                  				; for preventing unknown state (!?)
  1357                                  	;
  1358                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
  1359                                  	;
  1360                                  	; 02/09/2014
  1361 00000595 6631DB                  	xor	bx, bx
  1362 00000598 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
  1363 0000059C E81D0E0000              	call	set_cpos
  1364                                  	;
  1365                                  	; 06/11/2014
  1366                                  	; Temporary Code
  1367                                  	;
  1368 000005A1 E8920F0000              	call	memory_info
  1369                                  	; 14/08/2015
  1370                                  	;call	getch ; 28/02/2015
  1371                                  drv_init:
  1372 000005A6 FB                      	sti	; Enable Interrupts 
  1373                                  	; 06/02/2015
  1374 000005A7 8B15[8E620000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1375 000005AD 668B1D[8C620000]        	mov	bx, [fd0_type] ; fd0, fd1
  1376                                  	; 22/02/2015
  1377 000005B4 6621DB                  	and	bx, bx
  1378 000005B7 751B                    	jnz	short di1
  1379                                  	;
  1380 000005B9 09D2                    	or 	edx, edx
  1381 000005BB 7529                    	jnz	short di2
  1382                                  	;
  1383                                  setup_error:
  1384 000005BD BE[AD630000]            	mov 	esi, setup_error_msg
  1385                                  psem:	
  1386 000005C2 AC                      	lodsb
  1387 000005C3 08C0                    	or	al, al
  1388                                  	;jz	short haltx ; 22/02/2015
  1389 000005C5 7426                    	jz	short di3
  1390 000005C7 56                      	push	esi
  1391 000005C8 31DB                    	xor	ebx, ebx ; 0
  1392                                  			; Video page 0 (bl=0)
  1393 000005CA B407                    	mov	ah, 07h ; Black background, 
  1394                                  			; light gray forecolor
  1395 000005CC E8E30C0000              	call	write_tty
  1396 000005D1 5E                      	pop	esi
  1397 000005D2 EBEE                    	jmp	short psem
  1398                                  
  1399                                  di1:
  1400                                  	; supress 'jmp short T6'
  1401                                  	;  (activate fdc motor control code)
  1402 000005D4 66C705[CF060000]90-     	mov	word [T5], 9090h ; nop
  1403 000005DC 90                 
  1404                                  	;
  1405                                  	;mov	ax, int_0Eh	; IRQ 6 handler
  1406                                  	;mov	di, 0Eh*4	; IRQ 6 vector
  1407                                  	;stosw
  1408                                  	;mov 	ax, cs
  1409                                  	;stosw
  1410                                  	;; 16/02/2015
  1411                                          ;;mov	dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1412                                  	;
  1413 000005DD E8FC180000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
  1414                                  	;
  1415 000005E2 09D2                    	or	edx, edx
  1416 000005E4 7407                            jz      short di3
  1417                                  di2:
  1418 000005E6 E825190000              	call   	DISK_SETUP	; Initialize Fixed Disks
  1419 000005EB 72D0                            jc      short setup_error
  1420                                  di3:
  1421 000005ED E81A0F0000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
  1422                                  	;
  1423 000005F2 E8DD580000              	call	display_disks ; 07/03/2015  (Temporary)
  1424                                  ;haltx:
  1425                                  	; 14/08/2015
  1426                                  	;call	getch ; 22/02/2015
  1427 000005F7 FB                      	sti	; Enable interrupts (for CPU)
  1428                                  	; 14/08/2015
  1429                                  	;mov 	ecx, 0FFFFFFFh
  1430                                  	; 22/11/2021
  1431 000005F8 B9FFFF2F00              	mov 	ecx, 02FFFFFh
  1432                                  md_info_msg_wait:
  1433 000005FD 51                      	push 	ecx
  1434 000005FE B001                    	mov	al, 1
  1435 00000600 8A25[96670000]          	mov 	ah, [ptty] ; active (current) video page
  1436 00000606 E864550000              	call	getc_n
  1437 0000060B 59                      	pop	ecx
  1438 0000060C 7502                    	jnz	short md_info_msg_ok
  1439 0000060E E2ED                    	loop	md_info_msg_wait
  1440                                  md_info_msg_ok:
  1441                                  	; 30/06/2015
  1442 00000610 E8BF220000              	call	sys_init
  1443                                  	;
  1444                                  	;jmp 	cpu_reset ; 22/02/2015
  1445                                  hang:
  1446                                  	; 04/12/2021
  1447 00000615 29C0                    	sub	eax, eax
  1448                                  _hang:	
  1449                                  	; 23/02/2015
  1450                                  	;sti			; Enable interrupts
  1451 00000617 F4                      	hlt
  1452                                  	;
  1453                                  	;nop
  1454                                  	;; 03/12/2014
  1455                                  	;; 28/08/2014
  1456                                  	;mov	ah, 11h
  1457                                  	;call	getc
  1458                                  	;jz     _c8
  1459                                  	;
  1460                                  	; 23/02/2015
  1461                                  	; 06/02/2015
  1462                                  	; 07/09/2014
  1463 00000618 31DB                    	xor	ebx, ebx
  1464 0000061A 8A1D[96670000]          	mov	bl, [ptty]	; active_page
  1465 00000620 89DE                    	mov	esi, ebx
  1466                                  	;shl 	si, 1
  1467                                  	; 17/07/2022
  1468 00000622 D1E6                    	shl	esi, 1
  1469 00000624 81C6[98670000]          	add	esi, ttychr
  1470 0000062A 668B06                  	mov	ax, [esi]
  1471                                  	;and	ax, ax
  1472                                  	;;jz	short _c8
  1473                                  	;jz	short hang
  1474                                  	; 04/12/2021
  1475 0000062D 21C0                    	and	eax, eax
  1476 0000062F 74E6                    	jz	short _hang
  1477 00000631 66C7060000              	mov	word [esi], 0
  1478 00000636 80FB03                  	cmp	bl, 3		; Video page 3
  1479                                  	;jb	short _c8
  1480 00000639 72DA                    	jb	short hang
  1481                                  	;	
  1482                                  	; 02/09/2014
  1483 0000063B B40E                    	mov	ah, 0Eh		; Yellow character 
  1484                                  				; on black background
  1485                                  	; 30/11/2021 (32 bit reg push-pop)
  1486                                  	; 07/09/2014
  1487                                  nxtl:
  1488 0000063D 53                      	push	ebx
  1489                                  	;
  1490                                  	;xor	ebx, ebx	; bl = 0 (video page 0)
  1491                                  				; bh = 0 (video mode)
  1492                                  				; Retro UNIX 386 v1 - Video Mode 0
  1493                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
  1494 0000063E 50                      	push	eax
  1495 0000063F E8700C0000              	call 	write_tty
  1496 00000644 58                      	pop	eax
  1497                                  	;pop	bx
  1498 00000645 5B                      	pop	ebx
  1499 00000646 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
  1500                                  	;jne	short _c8
  1501 00000648 75CB                    	jne	short hang
  1502 0000064A B00A                    	mov	al, 0Ah		; next line
  1503 0000064C EBEF                    	jmp	short nxtl
  1504                                  	
  1505                                  ;_c8:
  1506                                  ;	; 25/08/2014
  1507                                  ;	cli			; Disable interrupts
  1508                                  ;	mov	al, [scounter + 1]
  1509                                  ;	and	al, al
  1510                                  ;	jnz	hang
  1511                                  ;	call	rtc_p
  1512                                  ;	jmp     hang
  1513                                  
  1514                                  
  1515                                  	; 27/08/2014
  1516                                  	; 20/08/2014
  1517                                  printk:
  1518                                          ;mov    edi, [scr_row]
  1519                                  pkl:
  1520 0000064E AC                      	lodsb
  1521 0000064F 08C0                    	or 	al, al
  1522 00000651 7404                    	jz	short pkr
  1523 00000653 66AB                    	stosw
  1524 00000655 EBF7                    	jmp	short pkl
  1525                                  pkr:
  1526 00000657 C3                      	retn
  1527                                  
  1528                                  ; 25/07/2015
  1529                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
  1530                                  ; 17/02/2015
  1531                                  ; 06/02/2015 (unix386.s)
  1532                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
  1533                                  ;
  1534                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
  1535                                  ;
  1536                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
  1537                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
  1538                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
  1539                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
  1540                                  ;									       :
  1541                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
  1542                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
  1543                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
  1544                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
  1545                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
  1546                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
  1547                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
  1548                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
  1549                                  ;-------------------------------------------------------------------------------
  1550                                  ;
  1551                                  
  1552                                  timer_int:	; IRQ 0
  1553                                  ;int_08h:	; Timer
  1554                                  	; 14/10/2015
  1555                                  	; Here, we are simulating system call entry (for task switch)
  1556                                  	; (If multitasking is enabled, 
  1557                                  	; 'clock' procedure may jump to 'sysrelease')
  1558 00000658 1E                      	push	ds
  1559 00000659 06                      	push	es
  1560 0000065A 0FA0                    	push	fs
  1561 0000065C 0FA8                    	push	gs
  1562 0000065E 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1563 0000065F 66B91000                	mov     cx, KDATA
  1564 00000663 8ED9                            mov     ds, cx
  1565 00000665 8EC1                            mov     es, cx
  1566 00000667 8EE1                            mov     fs, cx
  1567 00000669 8EE9                            mov     gs, cx
  1568                                  	;
  1569 0000066B 0F20D9                  	mov	ecx, cr3
  1570 0000066E 890D[11070000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1571                                  	;
  1572 00000674 3B0D[68670000]          	cmp 	ecx, [k_page_dir]
  1573 0000067A 741F                    	je	short T3
  1574                                  	;
  1575                                  	; timer interrupt has been occurred while OS is in user mode
  1576 0000067C A3[A46C0000]            	mov 	[u.r0], eax
  1577 00000681 89E1                    	mov	ecx, esp
  1578 00000683 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1579 00000686 890D[9C6C0000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1580 0000068C 8925[A06C0000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1581                                  	;
  1582 00000692 8B0D[68670000]          	mov	ecx, [k_page_dir]
  1583 00000698 0F22D9                  	mov	cr3, ecx
  1584                                  T3:
  1585 0000069B FB                      	sti				; INTERRUPTS BACK ON
  1586 0000069C 66FF05[E4670000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1587 000006A3 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1588 000006A5 66FF05[E6670000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1589                                  T4:					; TEST_DAY
  1590 000006AC 66833D[E6670000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
  1591 000006B4 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1592 000006B6 66813D[E4670000]B0-     	CMP	word [TIMER_LOW],0B0H
  1593 000006BE 00                 
  1594 000006BF 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1595                                  
  1596                                  ;-----	TIMER HAS GONE 24 HOURS
  1597                                  	;;SUB	AX,AX
  1598                                  	;MOV	[TIMER_HIGH],AX
  1599                                  	;MOV	[TIMER_LOW],AX
  1600 000006C1 29C0                    	sub	eax, eax
  1601 000006C3 A3[E4670000]            	mov	[TIMER_LH], eax
  1602                                  	;	
  1603 000006C8 C605[E8670000]01        	MOV	byte [TIMER_OFL],1
  1604                                  
  1605                                  ;-----	TEST FOR DISKETTE TIME OUT
  1606                                  
  1607                                  T5:
  1608                                  	; 23/12/2014
  1609 000006CF EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1610                                  					; (9090h) if a floppy disk
  1611                                  					; is detected.
  1612                                  	;mov	al,[CS:MOTOR_COUNT]
  1613 000006D1 A0[EB670000]            	mov	al, [MOTOR_COUNT]
  1614 000006D6 FEC8                    	dec	al
  1615                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1616 000006D8 A2[EB670000]            	mov	[MOTOR_COUNT], al
  1617                                  	;mov	[ORG_MOTOR_COUNT], al
  1618 000006DD 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1619 000006DF B0F0                    	mov 	al,0F0h
  1620                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1621 000006E1 2005[EA670000]          	and	[MOTOR_STATUS], al
  1622                                  	;and	[ORG_MOTOR_STATUS], al
  1623 000006E7 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1624                                  					; bit 2 = enable controller
  1625                                  					;	1 = normal operation
  1626                                  					;	0 = reset	
  1627                                  					; bit 0, 1 = drive select
  1628                                  					; bit 4-7 = motor running bits 
  1629 000006E9 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1630 000006ED EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1631                                  T6:	
  1632                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1633                                  					; TIMER TICK INTERRUPT
  1634                                  	;;inc	word [wait_count] ;;27/02/2015
  1635                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1636                                  	;;;;cli
  1637                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1638 000006EE FF15[09070000]          	call	[x_timer] ; 14/05/2015
  1639                                  T7:
  1640                                  	; 14/10/2015
  1641 000006F4 B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1642 000006F6 FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1643 000006F7 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1644                                  	;
  1645 000006F9 A1[11070000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1646 000006FE 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1647                                  	;
  1648 00000701 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1649                                  	;
  1650 00000702 0FA9                    	pop	gs
  1651 00000704 0FA1                    	pop	fs
  1652 00000706 07                      	pop	es
  1653 00000707 1F                      	pop	ds
  1654 00000708 CF                      	iretd	; return from interrupt
  1655                                  
  1656                                  
  1657                                  ; ////////////////
  1658                                  
  1659                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1660                                  x_timer:
  1661 00000709 [15070000]              	dd 	u_timer	; (temporary demo code)	; 14/05/2015
  1662                                  	;dd	clock
  1663                                  
  1664                                  ; 23/02/2022 - Real time clock (digital) output demo (sys emt)
  1665                                  x_rtci:
  1666 0000070D [4B0A0000]              	dd	rtc_p	; (temporary demo code)	; 23/02/2022
  1667                                  
  1668                                  ; 14/10/2015
  1669 00000711 00000000                cr3reg: dd 0
  1670                                  
  1671                                  	; 04/12/2021 - Retro UNIX 386 v1.2
  1672                                  	; 06/02/2015
  1673                                  	; 07/09/2014
  1674                                  	; 21/08/2014
  1675                                  u_timer:
  1676                                  ;timer_int:	; IRQ 0
  1677                                  	; 06/02/2015
  1678                                  	;push	eax
  1679                                  	;push	edx
  1680                                  	;push	ecx
  1681                                  	;push	ebx
  1682                                  	;push	ds
  1683                                  	;push	es
  1684                                  	;mov	eax, KDATA
  1685                                  	;mov	ds, ax
  1686                                  	;mov	es, ax
  1687 00000715 FF05[AC670000]          	inc	dword [tcount]
  1688 0000071B BB[36630000]            	mov	ebx, tcountstr + 4
  1689                                  	;mov	ax, [tcount]
  1690                                  	; 04/12/2021
  1691 00000720 A1[AC670000]            	mov	eax, [tcount]
  1692 00000725 B90A000000              	mov	ecx, 10
  1693                                  rp_divtcnt:
  1694 0000072A 31D2                    	xor	edx, edx
  1695 0000072C F7F1                    	div	ecx
  1696 0000072E 80C230                  	add	dl, 30h
  1697 00000731 8813                    	mov	[ebx], dl
  1698                                  	;or	ax, ax
  1699                                  	; 04/12/2021
  1700 00000733 09C0                    	or	eax, eax
  1701 00000735 7403                    	jz	short print_lzero
  1702 00000737 4B                      	dec	ebx
  1703 00000738 EBF0                    	jmp	short rp_divtcnt
  1704                                  print_lzero:
  1705 0000073A 81FB[32630000]          	cmp	ebx, tcountstr
  1706 00000740 7606                    	jna	short print_tcount
  1707 00000742 4B                      	dec	ebx
  1708 00000743 C60330                   	mov	byte [ebx], 30h
  1709 00000746 EBF2                    	jmp	short print_lzero
  1710                                  print_tcount:
  1711 00000748 56                      	push	esi
  1712 00000749 57                      	push	edi
  1713 0000074A BE[0E630000]            	mov	esi, timer_msg ; Timer interrupt message
  1714                                  	; 07/09/2014
  1715                                  	;mov	bx, 1	; Video page 1
  1716                                  	; 04/12/2021
  1717 0000074F 29DB                    	sub	ebx, ebx
  1718                                  	;inc	bl ; ebx = 1
  1719                                  	; 02/01/2022
  1720 00000751 B306                    	mov	bl, 6	; Video page 6
  1721                                  ptmsg:
  1722 00000753 AC                      	lodsb
  1723 00000754 08C0                    	or	al, al
  1724 00000756 740D                    	jz	short ptmsg_ok
  1725 00000758 56                      	push	esi
  1726                                  	;push	bx
  1727                                  	; 04/12/2021
  1728 00000759 53                              push	ebx
  1729 0000075A B42F                    	mov     ah, 2Fh ; Green background, white forecolor
  1730 0000075C E8530B0000              	call 	write_tty
  1731                                  	;pop	bx
  1732                                  	; 04/12/2021
  1733 00000761 5B                      	pop	ebx
  1734 00000762 5E                      	pop	esi
  1735 00000763 EBEE                    	jmp	short ptmsg
  1736                                  	;; 27/08/2014
  1737                                  	;mov	edi, 0B8000h + 0A0h ; Row 1
  1738                                  	;call	printk
  1739                                  	;
  1740                                  ptmsg_ok:
  1741                                  	; 07/09/2014
  1742                                  	;xor	dx, dx		; column 0, row 0
  1743                                  	; 04/12/2021
  1744 00000765 31D2                    	xor	edx, edx
  1745 00000767 E8520C0000              	call	set_cpos	; set cursor position to 0,0 
  1746                                  	; 23/02/2015
  1747                                  	; 25/08/2014
  1748                                  	;mov	ebx, scounter		; (seconds counter)
  1749                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1750                                  ;	dec	byte [scounter+1]
  1751                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1752                                  ;	jns	short u_timer_retn
  1753                                  	; 26/02/2015
  1754                                  ;	call	rtc_p
  1755                                  ;	mov	ebx, scounter		; (seconds counter)
  1756                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1757                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1758                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1759                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1760                                  ;	mov	byte [ebx], 5
  1761                                  ;	inc	byte [ebx+1] ; 19
  1762                                  ;;timer_eoi:
  1763                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1764                                  ;;	out	20h, al	; 8259 PORT
  1765                                  	;
  1766                                  ;u_timer_retn:  ; 06/02/2015
  1767 0000076C 5F                      	pop	edi
  1768 0000076D 5E                      	pop	esi
  1769                                  	;pop	es
  1770                                  	;pop	ds
  1771                                  	;pop	ebx
  1772                                  	;pop	ecx
  1773                                  	;pop	edx
  1774                                  	;pop	eax
  1775                                  	;iret
  1776 0000076E C3                      	retn	; 06/02/2015
  1777                                  
  1778                                  	; 28/08/2014
  1779                                  irq0:
  1780 0000076F 6A00                            push 	dword 0
  1781 00000771 EB48                    	jmp	short which_irq
  1782                                  irq1:
  1783 00000773 6A01                            push 	dword 1
  1784 00000775 EB44                    	jmp	short which_irq
  1785                                  irq2:
  1786 00000777 6A02                            push 	dword 2
  1787 00000779 EB40                    	jmp	short which_irq
  1788                                  irq3:
  1789                                  	; 20/11/2015
  1790                                  	; 24/10/2015
  1791 0000077B 2EFF15[58300000]        	call	dword [cs:com2_irq3]
  1792 00000782 6A03                    	push 	dword 3
  1793 00000784 EB35                    	jmp	short which_irq
  1794                                  irq4:
  1795                                  	; 20/11/2015
  1796                                  	; 24/10/2015
  1797 00000786 2EFF15[54300000]        	call	dword [cs:com1_irq4]
  1798 0000078D 6A04                            push 	dword 4
  1799 0000078F EB2A                    	jmp	short which_irq
  1800                                  irq5:
  1801 00000791 6A05                            push 	dword 5
  1802 00000793 EB26                    	jmp	short which_irq
  1803                                  irq6:
  1804 00000795 6A06                            push 	dword 6
  1805 00000797 EB22                    	jmp	short which_irq
  1806                                  irq7:
  1807 00000799 6A07                            push 	dword 7
  1808 0000079B EB1E                    	jmp	short which_irq
  1809                                  irq8:
  1810 0000079D 6A08                            push 	dword 8
  1811 0000079F EB1A                    	jmp	short which_irq
  1812                                  irq9:
  1813 000007A1 6A09                            push 	dword 9
  1814 000007A3 EB16                    	jmp	short which_irq
  1815                                  irq10:
  1816 000007A5 6A0A                            push 	dword 10
  1817 000007A7 EB12                    	jmp	short which_irq
  1818                                  irq11:
  1819 000007A9 6A0B                            push 	dword 11
  1820 000007AB EB0E                    	jmp	short which_irq
  1821                                  irq12:
  1822 000007AD 6A0C                            push 	dword 12
  1823 000007AF EB0A                    	jmp	short which_irq
  1824                                  irq13:
  1825 000007B1 6A0D                            push 	dword 13
  1826 000007B3 EB06                    	jmp	short which_irq
  1827                                  irq14:
  1828 000007B5 6A0E                            push 	dword 14
  1829 000007B7 EB02                    	jmp	short which_irq
  1830                                  irq15:
  1831 000007B9 6A0F                            push 	dword 15
  1832                                  	;jmp	short which_irq
  1833                                  
  1834                                  	; 19/10/2015
  1835                                  	; 29/08/2014
  1836                                  	; 21/08/2014
  1837                                  which_irq:
  1838 000007BB 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1839 000007BE 53                      	push	ebx
  1840 000007BF 56                      	push	esi
  1841 000007C0 57                      	push	edi
  1842 000007C1 1E                      	push 	ds
  1843 000007C2 06                      	push 	es
  1844                                  	;
  1845 000007C3 88C3                    	mov	bl, al
  1846                                  	;
  1847 000007C5 B810000000              	mov	eax, KDATA
  1848 000007CA 8ED8                    	mov	ds, ax
  1849 000007CC 8EC0                    	mov	es, ax
  1850                                  	; 19/10/2015
  1851 000007CE FC                      	cld
  1852                                          ; 27/08/2014
  1853 000007CF 8105[BC620000]A000-             add     dword [scr_row], 0A0h
  1854 000007D7 0000               
  1855                                  	;
  1856 000007D9 B417                    	mov	ah, 17h	; blue (1) background, 
  1857                                  			; light gray (7) forecolor
  1858 000007DB 8B3D[BC620000]                  mov     edi, [scr_row]
  1859 000007E1 B049                    	mov	al, 'I'
  1860 000007E3 66AB                    	stosw
  1861 000007E5 B052                    	mov	al, 'R'
  1862 000007E7 66AB                    	stosw
  1863 000007E9 B051                    	mov	al, 'Q'
  1864 000007EB 66AB                    	stosw
  1865 000007ED B020                    	mov	al, ' '
  1866 000007EF 66AB                    	stosw
  1867 000007F1 88D8                    	mov	al, bl
  1868 000007F3 3C0A                    	cmp	al, 10
  1869 000007F5 7208                    	jb	short iix
  1870 000007F7 B031                    	mov	al, '1'
  1871 000007F9 66AB                    	stosw
  1872 000007FB 88D8                    	mov	al, bl
  1873 000007FD 2C0A                    	sub	al, 10
  1874                                  iix:
  1875 000007FF 0430                    	add	al, '0'
  1876 00000801 66AB                    	stosw
  1877 00000803 B020                    	mov	al, ' '
  1878 00000805 66AB                    	stosw
  1879 00000807 B021                    	mov	al, '!'
  1880 00000809 66AB                    	stosw
  1881 0000080B B020                    	mov	al, ' '
  1882 0000080D 66AB                    	stosw
  1883                                  	; 23/02/2015
  1884 0000080F 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1885                                  	;jna	iiret
  1886                                  	; 04/12/2021
  1887 00000812 7604                    	jna	short iiz
  1888                                  iiy:
  1889 00000814 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1890 00000816 E6A0                    	out	0A0h, al ; the 2nd 8259
  1891                                  iiz:
  1892 00000818 E983010000              	jmp     iiret
  1893                                  	;
  1894                                  	; 22/08/2014
  1895                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1896                                  	;out	20h, al	; 8259 PORT
  1897                                  	;
  1898                                  	;pop	es
  1899                                  	;pop	ds
  1900                                  	;pop	edi
  1901                                  	;pop	esi
  1902                                  	;pop	ebx
  1903                                  	;pop 	eax
  1904                                  	;iret
  1905                                  
  1906                                  	; 02/04/2015
  1907                                  	; 25/08/2014
  1908                                  exc0:
  1909 0000081D 6A00                            push 	dword 0
  1910 0000081F E990000000                      jmp     cpu_except
  1911                                  exc1:
  1912 00000824 6A01                            push 	dword 1
  1913 00000826 E989000000                      jmp     cpu_except
  1914                                  exc2:
  1915 0000082B 6A02                            push 	dword 2
  1916 0000082D E982000000                      jmp     cpu_except
  1917                                  exc3:
  1918 00000832 6A03                            push 	dword 3
  1919 00000834 EB7E                            jmp     cpu_except
  1920                                  exc4:
  1921 00000836 6A04                            push 	dword 4
  1922 00000838 EB7A                            jmp     cpu_except
  1923                                  exc5:
  1924 0000083A 6A05                            push 	dword 5
  1925 0000083C EB76                            jmp     cpu_except
  1926                                  exc6:
  1927 0000083E 6A06                            push 	dword 6
  1928 00000840 EB72                            jmp     cpu_except
  1929                                  exc7:
  1930 00000842 6A07                            push 	dword 7
  1931 00000844 EB6E                            jmp     cpu_except
  1932                                  exc8:
  1933                                  	; [esp] = Error code
  1934 00000846 6A08                            push 	dword 8
  1935 00000848 EB5C                            jmp     cpu_except_en
  1936                                  exc9:
  1937 0000084A 6A09                            push 	dword 9
  1938 0000084C EB66                            jmp     cpu_except
  1939                                  exc10:
  1940                                  	; [esp] = Error code
  1941 0000084E 6A0A                            push 	dword 10
  1942 00000850 EB54                            jmp     cpu_except_en
  1943                                  exc11:
  1944                                  	; [esp] = Error code
  1945 00000852 6A0B                            push 	dword 11
  1946 00000854 EB50                            jmp     cpu_except_en
  1947                                  exc12:
  1948                                  	; [esp] = Error code
  1949 00000856 6A0C                            push 	dword 12
  1950 00000858 EB4C                            jmp     cpu_except_en
  1951                                  exc13:
  1952                                  	; [esp] = Error code
  1953 0000085A 6A0D                            push 	dword 13
  1954 0000085C EB48                            jmp     cpu_except_en
  1955                                  exc14:
  1956                                  	; [esp] = Error code
  1957 0000085E 6A0E                            push 	dword 14
  1958 00000860 EB44                    	jmp	short cpu_except_en
  1959                                  exc15:
  1960 00000862 6A0F                            push 	dword 15
  1961 00000864 EB4E                            jmp     cpu_except
  1962                                  exc16:
  1963 00000866 6A10                            push 	dword 16
  1964 00000868 EB4A                            jmp     cpu_except
  1965                                  exc17:
  1966                                  	; [esp] = Error code
  1967 0000086A 6A11                            push 	dword 17
  1968 0000086C EB38                    	jmp	short cpu_except_en
  1969                                  exc18:
  1970 0000086E 6A12                            push 	dword 18
  1971 00000870 EB42                    	jmp	short cpu_except
  1972                                  exc19:
  1973 00000872 6A13                            push 	dword 19
  1974 00000874 EB3E                    	jmp	short cpu_except
  1975                                  exc20:
  1976 00000876 6A14                            push 	dword 20
  1977 00000878 EB3A                    	jmp	short cpu_except
  1978                                  exc21:
  1979 0000087A 6A15                            push 	dword 21
  1980 0000087C EB36                    	jmp	short cpu_except
  1981                                  exc22:
  1982 0000087E 6A16                            push 	dword 22
  1983 00000880 EB32                    	jmp	short cpu_except
  1984                                  exc23:
  1985 00000882 6A17                            push 	dword 23
  1986 00000884 EB2E                    	jmp	short cpu_except
  1987                                  exc24:
  1988 00000886 6A18                            push 	dword 24
  1989 00000888 EB2A                    	jmp	short cpu_except
  1990                                  exc25:
  1991 0000088A 6A19                            push 	dword 25
  1992 0000088C EB26                    	jmp	short cpu_except
  1993                                  exc26:
  1994 0000088E 6A1A                            push 	dword 26
  1995 00000890 EB22                    	jmp	short cpu_except
  1996                                  exc27:
  1997 00000892 6A1B                            push 	dword 27
  1998 00000894 EB1E                    	jmp	short cpu_except
  1999                                  exc28:
  2000 00000896 6A1C                            push 	dword 28
  2001 00000898 EB1A                    	jmp	short cpu_except
  2002                                  exc29:
  2003 0000089A 6A1D                            push 	dword 29
  2004 0000089C EB16                    	jmp	short cpu_except
  2005                                  exc30:
  2006 0000089E 6A1E                            push 	dword 30
  2007 000008A0 EB04                    	jmp	short cpu_except_en
  2008                                  exc31:
  2009 000008A2 6A1F                            push 	dword 31
  2010 000008A4 EB0E                            jmp     short cpu_except
  2011                                  
  2012                                  	; 02/01/2022 (Retro UNIX 386 v1.2)
  2013                                  	; 19/10/2015
  2014                                  	; 19/09/2015
  2015                                  	; 01/09/2015
  2016                                  	; 28/08/2015
  2017                                  	; 28/08/2014
  2018                                  cpu_except_en:
  2019 000008A6 87442404                	xchg	eax, [esp+4] ; Error code
  2020 000008AA 36A3[14680000]          	mov	[ss:error_code], eax
  2021 000008B0 58                      	pop	eax  ; Exception number
  2022 000008B1 870424                  	xchg	eax, [esp]
  2023                                  		; eax = eax before exception
  2024                                  		; [esp] -> exception number
  2025                                  		; [esp+4] -> EIP to return
  2026                                  	; 19/10/2015
  2027                                  	; 19/09/2015
  2028                                  	; 01/09/2015
  2029                                  	; 28/08/2015
  2030                                  	; 29/08/2014
  2031                                  	; 28/08/2014
  2032                                  	; 25/08/2014
  2033                                  	; 21/08/2014
  2034                                  cpu_except:	; CPU Exceptions
  2035 000008B4 FC                      	cld
  2036 000008B5 870424                  	xchg	eax, [esp] 
  2037                                  		; eax = Exception number
  2038                                  		; [esp] = eax (before exception)
  2039 000008B8 53                      	push	ebx
  2040 000008B9 56                      	push	esi
  2041 000008BA 57                      	push	edi
  2042 000008BB 1E                      	push 	ds
  2043 000008BC 06                      	push 	es
  2044                                  	; 28/08/2015
  2045 000008BD 66BB1000                	mov	bx, KDATA
  2046 000008C1 8EDB                    	mov	ds, bx
  2047 000008C3 8EC3                    	mov	es, bx
  2048 000008C5 0F20DB                  	mov	ebx, cr3
  2049 000008C8 53                      	push	ebx ; (*) page directory
  2050                                  	; 19/10/2015
  2051 000008C9 FC                      	cld
  2052                                  	; 25/03/2015
  2053 000008CA 8B1D[68670000]          	mov	ebx, [k_page_dir]
  2054 000008D0 0F22DB                  	mov	cr3, ebx
  2055                                  	; 28/08/2015
  2056 000008D3 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT
  2057 000008D6 7513                    	jne	short cpu_except_nfp
  2058 000008D8 E8B31D0000              	call	page_fault_handler
  2059 000008DD 21C0                    	and 	eax, eax
  2060                                  	;jz	iiretp ; 01/09/2015
  2061                                  	; 02/01/2022
  2062 000008DF 7505                    	jnz	short cpu_except_pf
  2063 000008E1 E9B6000000              	jmp	iiretp
  2064                                  cpu_except_pf:
  2065 000008E6 B80E000000              	mov	eax, 0Eh ; 14
  2066                                  cpu_except_nfp:
  2067                                  	; 02/04/2015
  2068 000008EB BB[15060000]            	mov	ebx, hang
  2069 000008F0 875C241C                	xchg	ebx, [esp+28]
  2070                                  		; EIP (points to instruction which faults)
  2071                                  	  	; New EIP (hang)
  2072 000008F4 891D[18680000]          	mov	[FaultOffset], ebx
  2073 000008FA C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  2074 00000902 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  2075                                  	;
  2076 0000090A 88C4                    	mov	ah, al
  2077 0000090C 240F                    	and	al, 0Fh
  2078 0000090E 3C09                    	cmp	al, 9
  2079 00000910 7602                    	jna	short h1ok
  2080 00000912 0407                    	add	al, 'A'-':'
  2081                                  h1ok:
  2082 00000914 D0EC                    	shr	ah, 1
  2083 00000916 D0EC                    	shr	ah, 1
  2084 00000918 D0EC                    	shr	ah, 1
  2085 0000091A D0EC                    	shr	ah, 1
  2086 0000091C 80FC09                  	cmp	ah, 9
  2087 0000091F 7603                    	jna	short h2ok
  2088 00000921 80C407                  	add	ah, 'A'-':'
  2089                                  h2ok:	
  2090 00000924 86E0                    	xchg 	ah, al	
  2091 00000926 66053030                	add	ax, '00'
  2092 0000092A 66A3[4A630000]          	mov	[excnstr], ax
  2093                                  	;
  2094                                  	; 29/08/2014
  2095 00000930 A1[18680000]            	mov	eax, [FaultOffset]
  2096 00000935 51                      	push	ecx
  2097 00000936 52                      	push	edx
  2098 00000937 89E3                    	mov	ebx, esp
  2099                                  	; 28/08/2015
  2100 00000939 B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  2101                                  			  ; to hexadecimal string
  2102                                  	;mov	ecx, 10	    ; divisor to convert
  2103                                  			    ; binary number to decimal string
  2104                                  b2d1:
  2105 0000093E 31D2                    	xor	edx, edx
  2106 00000940 F7F1                    	div	ecx
  2107                                  	;push	dx
  2108                                  	; 02/01/2022
  2109 00000942 52                      	push	edx
  2110 00000943 39C8                    	cmp	eax, ecx
  2111 00000945 73F7                    	jnb	short b2d1
  2112 00000947 BF[55630000]            	mov	edi, EIPstr ; EIP value
  2113                                  			    ; points to instruction which faults
  2114                                  	; 28/08/2015
  2115 0000094C 89C2                    	mov	edx, eax
  2116                                  b2d2:
  2117                                  	;add	al, '0'
  2118 0000094E 8A82[F0150000]          	mov	al, [edx+hexchrs]
  2119 00000954 AA                      	stosb		    ; write hexadecimal digit to its place
  2120 00000955 39E3                    	cmp	ebx, esp
  2121 00000957 7605                    	jna	short b2d3
  2122                                  	; 02/01/2022
  2123 00000959 58                      	pop	eax
  2124                                  	;pop	ax
  2125 0000095A 88C2                    	mov	dl, al
  2126 0000095C EBF0                    	jmp	short b2d2
  2127                                  b2d3:
  2128 0000095E B068                    	mov 	al, 'h' ; 28/08/2015
  2129 00000960 AA                      	stosb
  2130 00000961 B020                    	mov	al, 20h	    ; space
  2131 00000963 AA                      	stosb
  2132 00000964 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  2133 00000966 AA                      	stosb
  2134                                  	;
  2135 00000967 5A                      	pop	edx
  2136 00000968 59                      	pop	ecx
  2137                                  	;
  2138 00000969 B44F                    	mov	ah, 4Fh	; red (4) background, 
  2139                                  			; white (F) forecolor
  2140 0000096B BE[3A630000]            	mov	esi, exc_msg ; message offset
  2141                                  	;
  2142 00000970 EB11                    	jmp	short piemsg
  2143                                  	;
  2144                                          ;add    dword [scr_row], 0A0h
  2145                                          ;mov    edi, [scr_row]
  2146                                          ;
  2147                                  	;call 	printk
  2148                                  	;
  2149                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2150                                  	;out	20h, al	; 8259 PORT
  2151                                  	;
  2152                                  	;pop	es
  2153                                  	;pop	ds
  2154                                  	;pop	edi
  2155                                  	;pop	esi
  2156                                  	;pop 	eax
  2157                                  	;iret
  2158                                  	
  2159                                  	; 28/08/2015
  2160                                  	; 23/02/2015
  2161                                  	; 20/08/2014
  2162                                  ignore_int:
  2163 00000972 50                      	push	eax
  2164 00000973 53                      	push	ebx ; 23/02/2015
  2165 00000974 56                      	push	esi
  2166 00000975 57                      	push	edi
  2167 00000976 1E                      	push 	ds
  2168 00000977 06                      	push 	es
  2169                                  	; 28/08/2015
  2170 00000978 0F20D8                  	mov	eax, cr3
  2171 0000097B 50                      	push	eax ; (*) page directory
  2172                                  	;
  2173 0000097C B467                    	mov	ah, 67h	; brown (6) background, 
  2174                                  			; light gray (7) forecolor
  2175 0000097E BE[F8620000]            	mov	esi, int_msg ; message offset
  2176                                  piemsg:
  2177                                          ; 27/08/2014
  2178 00000983 8105[BC620000]A000-             add     dword [scr_row], 0A0h
  2179 0000098B 0000               
  2180 0000098D 8B3D[BC620000]                  mov     edi, [scr_row]
  2181                                          ;
  2182 00000993 E8B6FCFFFF              	call 	printk
  2183                                  	;
  2184                                  	; 23/02/2015
  2185 00000998 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2186 0000099A E6A0                    	out	0A0h, al ; the 2nd 8259
  2187                                  iiretp: ; 01/09/2015
  2188                                  	; 28/08/2015
  2189 0000099C 58                      	pop	eax ; (*) page directory
  2190 0000099D 0F22D8                  	mov	cr3, eax
  2191                                  	;
  2192                                  iiret:
  2193                                  	; 22/08/2014
  2194 000009A0 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2195 000009A2 E620                    	out	20h, al	; 8259 PORT
  2196                                  	;
  2197 000009A4 07                      	pop	es
  2198 000009A5 1F                      	pop	ds
  2199 000009A6 5F                      	pop	edi
  2200 000009A7 5E                      	pop	esi
  2201 000009A8 5B                      	pop	ebx ; 29/08/2014
  2202 000009A9 58                      	pop 	eax
  2203 000009AA CF                      	iretd
  2204                                  
  2205                                  	; 23/02/2022
  2206                                  	; 26/02/2015
  2207                                  	; 07/09/2014
  2208                                  	; 25/08/2014
  2209                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  2210                                  	; 22/08/2014
  2211 000009AB 50                      	push	eax
  2212 000009AC 53                      	push	ebx ; 29/08/2014
  2213 000009AD 56                      	push	esi
  2214 000009AE 57                      	push	edi
  2215 000009AF 1E                      	push 	ds
  2216 000009B0 06                      	push 	es
  2217                                  	;
  2218 000009B1 B810000000              	mov	eax, KDATA
  2219 000009B6 8ED8                    	mov	ds, ax
  2220 000009B8 8EC0                    	mov	es, ax
  2221                                  	;
  2222                                  	; 25/08/2014
  2223                                  	;call	rtc_p
  2224                                  	; 23/02/2022
  2225 000009BA FF15[0D070000]          	call	[x_rtci]
  2226                                  	;
  2227                                  	; 22/02/2015 - dsectpm.s
  2228                                  	; [ source: http://wiki.osdev.org/RTC ]
  2229                                  	; read status register C to complete procedure
  2230                                  	;(it is needed to get a next IRQ 8) 
  2231 000009C0 B00C                    	mov	al, 0Ch ; 
  2232 000009C2 E670                    	out	70h, al ; select register C
  2233 000009C4 90                      	nop
  2234 000009C5 E471                    	in	al, 71h ; just throw away contents
  2235                                  	; 22/02/2015
  2236 000009C7 B020                    	MOV	AL,EOI		; END OF INTERRUPT
  2237 000009C9 E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  2238                                  	;
  2239 000009CB EBD3                    	jmp	short iiret	
  2240                                  
  2241                                  	; 22/08/2014
  2242                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  2243                                  	; (INT 1Ah)
  2244                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  2245                                  time_of_day:
  2246 000009CD E866010000              	call	UPD_IPR		; WAIT TILL UPDATE NOT IN PROGRESS
  2247 000009D2 726F                            jc      short rtc_retn 
  2248 000009D4 B000                    	mov	al, CMOS_SECONDS
  2249 000009D6 E847010000              	call	CMOS_READ
  2250 000009DB A2[DC670000]            	mov	[time_seconds], al 
  2251 000009E0 B002                    	mov	al, CMOS_MINUTES
  2252 000009E2 E83B010000              	call	CMOS_READ
  2253 000009E7 A2[DD670000]            	mov	[time_minutes], al 
  2254 000009EC B004                    	mov	al, CMOS_HOURS
  2255 000009EE E82F010000              	call	CMOS_READ
  2256 000009F3 A2[DE670000]                    mov     [time_hours], al
  2257 000009F8 B006                    	mov	al, CMOS_DAY_WEEK 
  2258 000009FA E823010000              	call	CMOS_READ
  2259 000009FF A2[DF670000]            	mov	[date_wday], al
  2260 00000A04 B007                     	mov	al, CMOS_DAY_MONTH
  2261 00000A06 E817010000              	call	CMOS_READ
  2262 00000A0B A2[E0670000]            	mov	[date_day], al
  2263 00000A10 B008                    	mov	al, CMOS_MONTH
  2264 00000A12 E80B010000              	call	CMOS_READ
  2265 00000A17 A2[E1670000]            	mov	[date_month], al
  2266 00000A1C B009                    	mov	al, CMOS_YEAR
  2267 00000A1E E8FF000000              	call	CMOS_READ
  2268 00000A23 A2[E2670000]            	mov	[date_year], al
  2269 00000A28 B032                    	mov	al, CMOS_CENTURY
  2270 00000A2A E8F3000000              	call	CMOS_READ
  2271 00000A2F A2[E3670000]            	mov	[date_century], al
  2272                                  	;
  2273 00000A34 B000                    	mov	al, CMOS_SECONDS
  2274 00000A36 E8E7000000              	call 	CMOS_READ
  2275 00000A3B 3A05[DC670000]          	cmp	al, [time_seconds]
  2276 00000A41 758A                    	jne	short time_of_day
  2277                                  
  2278                                  rtc_retn:
  2279 00000A43 C3                      	retn
  2280                                  
  2281                                  rtci_default:
  2282                                  	; 23/02/2022 (Temporary!)
  2283                                  	; (default real time clock handler in multitasking mode)
  2284                                  	; ((2 rtc ticks per second after 'setup_rtc_int'))
  2285 00000A44 FF05[20680000]          	inc	dword [rtc_ticks] ; real time clock counter
  2286                                  			; (not used in anywhere of kernel for now!)
  2287 00000A4A C3                      	retn
  2288                                  
  2289                                  rtc_p:
  2290                                  	; 27/12/2021 (Retro UNIX 386 v1.2)
  2291                                  	; 07/09/2014
  2292                                  	; 29/08/2014
  2293                                  	; 27/08/2014
  2294                                  	; 25/08/2014
  2295                                   	; Print Real Time Clock content
  2296                                  	;
  2297                                  	;
  2298 00000A4B E87DFFFFFF              	call	time_of_day
  2299 00000A50 72F1                    	jc	short rtc_retn
  2300                                  	;
  2301 00000A52 3A05[AC630000]          	cmp	al, [ptime_seconds]
  2302 00000A58 74E9                            je      short rtc_retn ; 29/08/2014
  2303                                  	;
  2304 00000A5A A2[AC630000]            	mov	[ptime_seconds], al
  2305                                  	;
  2306 00000A5F A0[E3670000]            	mov	al, [date_century]
  2307 00000A64 E8EA000000              	call	bcd_to_ascii
  2308 00000A69 66A3[79630000]          	mov	[datestr+6], ax
  2309 00000A6F A0[E2670000]            	mov	al, [date_year]
  2310 00000A74 E8DA000000              	call	bcd_to_ascii
  2311 00000A79 66A3[7B630000]          	mov	[datestr+8], ax
  2312 00000A7F A0[E1670000]            	mov	al, [date_month]
  2313 00000A84 E8CA000000              	call	bcd_to_ascii
  2314 00000A89 66A3[76630000]          	mov	[datestr+3], ax
  2315 00000A8F A0[E0670000]            	mov	al, [date_day]
  2316 00000A94 E8BA000000              	call	bcd_to_ascii
  2317 00000A99 66A3[73630000]          	mov	[datestr], ax
  2318                                  	;
  2319 00000A9F 0FB61D[DF670000]        	movzx	ebx, byte [date_wday]
  2320 00000AA6 C0E302                  	shl 	bl, 2
  2321 00000AA9 81C3[8C630000]          	add	ebx, daytmp
  2322 00000AAF 8B03                    	mov	eax, [ebx]
  2323 00000AB1 A3[7E630000]            	mov	[daystr], eax
  2324                                  	;
  2325 00000AB6 A0[DE670000]            	mov	al, [time_hours]
  2326 00000ABB E893000000              	call	bcd_to_ascii
  2327 00000AC0 66A3[82630000]          	mov	[timestr], ax
  2328 00000AC6 A0[DD670000]            	mov	al, [time_minutes]
  2329 00000ACB E883000000              	call	bcd_to_ascii
  2330 00000AD0 66A3[85630000]          	mov	[timestr+3], ax
  2331 00000AD6 A0[DC670000]            	mov	al, [time_seconds]
  2332 00000ADB E873000000              	call	bcd_to_ascii
  2333 00000AE0 66A3[88630000]          	mov	[timestr+6], ax
  2334                                  	;		
  2335 00000AE6 BE[61630000]            	mov	esi, rtc_msg ; message offset
  2336                                  	; 23/02/2015
  2337 00000AEB 52                      	push	edx
  2338 00000AEC 51                      	push	ecx
  2339                                  	; 07/09/2014
  2340                                  	;mov	bx, 2	; Video page 2
  2341                                  	; 27/12/2021
  2342 00000AED 29DB                    	sub	ebx, ebx
  2343                                  	;mov	bl, 2
  2344                                  	; 15/02/2022
  2345 00000AEF B307                    	mov	bl, 7	; Video page 7
  2346                                  prtmsg:
  2347 00000AF1 AC                      	lodsb
  2348 00000AF2 08C0                    	or	al, al
  2349 00000AF4 740D                    	jz	short prtmsg_ok
  2350 00000AF6 56                      	push	esi
  2351                                  	;push	bx
  2352 00000AF7 53                              push	ebx ; 27/12/2021
  2353 00000AF8 B43F                    	mov	ah, 3Fh	; cyan (6) background, 
  2354                                  			; white (F) forecolor
  2355 00000AFA E8B5070000              	call 	write_tty
  2356                                  	;pop	bx
  2357 00000AFF 5B                      	pop	ebx ; 27/12/2021
  2358 00000B00 5E                      	pop	esi
  2359 00000B01 EBEE                    	jmp	short prtmsg
  2360                                  	;
  2361                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  2362                                  	;call	printk
  2363                                  prtmsg_ok:
  2364                                  	; 07/09/2014
  2365                                  	;xor	dx, dx		; column 0, row 0
  2366                                  	; 27/12/2021
  2367 00000B03 31D2                    	xor	edx, edx
  2368 00000B05 E8B4080000              	call	set_cpos	; set curspor position to 0,0 
  2369                                  	; 23/02/2015
  2370 00000B0A 59                      	pop	ecx
  2371 00000B0B 5A                      	pop	edx
  2372 00000B0C C3                      	retn
  2373                                  
  2374                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2375                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2376                                  default_irq7:
  2377                                  	; 04/12/2021
  2378                                  	;push	ax
  2379 00000B0D 50                      	push	eax
  2380 00000B0E B00B                    	mov	al, 0Bh  ; In-Service register
  2381 00000B10 E620                    	out	20h, al
  2382 00000B12 EB00                            jmp short $+2
  2383 00000B14 EB00                    	jmp short $+2
  2384 00000B16 E420                    	in	al, 20h
  2385 00000B18 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  2386 00000B1A 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  2387 00000B1C B020                            mov     al, 20h ; EOI
  2388 00000B1E E620                    	out	20h, al 
  2389                                  irq7_iret:
  2390                                  	;pop	ax
  2391                                  	; 04/12/2021
  2392 00000B20 58                      	pop	eax
  2393 00000B21 CF                      	iretd
  2394                                  	
  2395                                  	; 04/12/2021
  2396                                  	; 22/08/2014
  2397                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
  2398                                  CMOS_READ:
  2399 00000B22 9C                      	pushf		; SAVE INTERRUPT ENABLE STATUS AND FLAGS
  2400 00000B23 D0C0                    	rol	al, 1	; MOVE NMI BIT TO LOW POSITION
  2401 00000B25 F9                      	stc		; FORCE NMI BIT ON IN CARRY FLAG
  2402 00000B26 D0D8                    	rcr	al, 1	; HIGH BIT ON TO DISABLE NMI - OLD IN CY
  2403 00000B28 FA                      	cli		; DISABLE INTERRUPTS
  2404 00000B29 E670                    	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
  2405 00000B2B 90                      	nop		; I/O DELAY
  2406 00000B2C E471                    	in	al, CMOS_DATA	; READ THE REQUESTED CMOS LOCATION
  2407                                  	;push	ax	; SAVE (AH) REGISTER VALUE AND CMOS BYTE
  2408                                  	; 04/12/2021
  2409 00000B2E 50                      	push	eax
  2410                                  	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
  2411                                  		     ; ----- 10/06/85 (test4.asm)
  2412 00000B2F B01E                    	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
  2413                                  	;mov	al, CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
  2414 00000B31 D0D8                    	rcr	al, 1	; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
  2415 00000B33 E670                    	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
  2416                                  	;pop	ax	; RESTORE (AH) AND (AL), CMOS BYTE
  2417                                  	; 04/12/2021
  2418 00000B35 58                      	pop	eax
  2419 00000B36 9D                      	popf	
  2420 00000B37 C3                      	retn		; RETURN WITH FLAGS RESTORED
  2421                                  
  2422                                  	; 22/08/2014
  2423                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
  2424                                  UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
  2425 00000B38 51                      	push	ecx
  2426 00000B39 B9FFFF0000              	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
  2427                                  		; mov cx, 800	
  2428                                  UPD_10:
  2429 00000B3E B00A                    	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
  2430 00000B40 FA                      	cli				; NO TIMER INTERRUPTS DURING UPDATES
  2431 00000B41 E8DCFFFFFF              	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
  2432 00000B46 A880                    	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
  2433 00000B48 7406                    	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
  2434 00000B4A FB                      	sti				; ALLOW INTERRUPTS WHILE WAITING
  2435 00000B4B E2F1                    	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
  2436 00000B4D 31C0                    	xor	eax, eax		; CLEAR RESULTS IF ERROR
  2437                                  		; xor ax, ax
  2438 00000B4F F9                      	stc				; SET CARRY FOR ERROR
  2439                                  UPD_90:
  2440 00000B50 59                      	pop	ecx			; RESTORE CALLERS REGISTER
  2441 00000B51 FA                      	cli				; INTERRUPTS OFF DURING SET
  2442 00000B52 C3                      	retn				; RETURN WITH CY FLAG SET
  2443                                  
  2444                                  bcd_to_ascii:
  2445                                  	; 25/08/2014
  2446                                  	; INPUT ->
  2447                                  	;	al = Packed BCD number
  2448                                  	; OUTPUT ->
  2449                                  	;	ax  = ASCII word/number
  2450                                  	;
  2451                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  2452                                  	;
  2453 00000B53 D410                    	db	0D4h, 10h		; Undocumented inst. AAM
  2454                                  					; AH = AL / 10h
  2455                                  					; AL = AL MOD 10h
  2456 00000B55 660D3030                	or	ax, '00'		; Make it ASCII based
  2457                                  
  2458 00000B59 86E0                            xchg	ah, al 
  2459                                  	
  2460 00000B5B C3                      	retn	
  2461                                  	
  2462                                  
  2463                                  %include 'keyboard.s' ; 07/03/2015
  2464                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2465                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2466                              <1> ; ****************************************************************************
  2467                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - KEYBOARD.INC
  2468                              <1> ; Last Modification: 24/07/2022
  2469                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
  2470                              <1> ;
  2471                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
  2472                              <1> 
  2473                              <1> ; 24/07/2022
  2474                              <1> ;	(Retro UNIX 386 v1.2, Kernel v0.2.2.3)	
  2475                              <1> ;	(Retro UNIX 386 v1.1, Kernel v0.2.1.6)
  2476                              <1> ;	(Retro UNIX 386 v1.0, Kernel v0.2.0.22)
  2477                              <1> ; 23/02/2022
  2478                              <1> ; 05/12/2021 (Retro UNIX 386 v1.2)
  2479                              <1> ; 30/06/2015
  2480                              <1> ; 11/03/2015
  2481                              <1> ; 28/02/2015
  2482                              <1> ; 25/02/2015
  2483                              <1> ; 20/02/2015
  2484                              <1> ; 18/02/2015
  2485                              <1> ; 03/12/2014
  2486                              <1> ; 07/09/2014
  2487                              <1> ; KEYBOARD INTERRUPT HANDLER
  2488                              <1> ; (kb_int - Retro UNIX 8086 v1 - U0.ASM, 30/06/2014)
  2489                              <1> 
  2490                              <1> ;getch:
  2491                              <1> ;	; 18/02/2015
  2492                              <1> ;	; This routine will be replaced with Retro UNIX 386
  2493                              <1> ;	; version of Retro UNIX 8086 getch (tty input)
  2494                              <1> ;	; routine, later... (multi tasking ability)
  2495                              <1> ;	; 28/02/2015
  2496                              <1> ;	sti	; enable interrupts
  2497                              <1> ;	;
  2498                              <1> ;	;push	esi
  2499                              <1> ;	;push	ebx
  2500                              <1> ;	;xor	ebx, ebx
  2501                              <1> ;	;mov	bl, [ptty]  ; active_page
  2502                              <1> ;	;mov	esi, ebx
  2503                              <1> ;	;shl 	si, 1
  2504                              <1> ;	;add	esi, ttychr
  2505                              <1> ;getch_1:
  2506                              <1> ;	;mov	ax, [esi]
  2507                              <1> ;	mov	ax, [ttychr] ; video page 0 (tty0)
  2508                              <1> ;	and	ax, ax
  2509                              <1> ;	jz	short getch_2
  2510                              <1> ;	mov	word [ttychr], 0
  2511                              <1> ;	;mov	word [esi], 0
  2512                              <1> ;	;pop	ebx
  2513                              <1> ;	;pop	esi
  2514                              <1> ;	retn
  2515                              <1> ;getch_2:
  2516                              <1> ;	hlt	; not proper for multi tasking!
  2517                              <1> ;		; (temporary halt for now)
  2518                              <1> ;		; 'sleep' on tty 
  2519                              <1> ;		; will (must) be located here		
  2520                              <1> ;	nop
  2521                              <1> ;	jmp	short getch_1
  2522                              <1> 
  2523                              <1> keyb_int:
  2524                              <1> 	; 24/07/2022
  2525                              <1> 	; 23/02/2022
  2526                              <1> 	; 30/06/2015
  2527                              <1> 	; 25/02/2015
  2528                              <1> 	; 20/02/2015
  2529                              <1> 	; 03/12/2014 (getc_int - INT 16h modifications)
  2530                              <1> 	; 07/09/2014 - Retro UNIX 386 v1
  2531                              <1> 	; 30/06/2014
  2532                              <1> 	; 10/05/2013	
  2533                              <1>       	; Retro Unix 8086 v1 feature only!
  2534                              <1> 	; 03/03/2014
  2535                              <1> 	
  2536 00000B5C 1E                  <1> 	push	ds
  2537 00000B5D 53                  <1> 	push	ebx
  2538 00000B5E 50                  <1> 	push	eax
  2539                              <1> 	;
  2540                              <1> 	; 23/02/2022
  2541 00000B5F 9C                  <1> 	pushfd
  2542 00000B60 0E                  <1> 	push	cs
  2543                              <1> 	;mov	ax, KDATA
  2544 00000B61 31C0                <1> 	xor	eax, eax
  2545 00000B63 B010                <1> 	mov	al, KDATA
  2546 00000B65 8ED8                <1> 	mov	ds, ax
  2547                              <1> 	;
  2548                              <1> 	;pushfd
  2549                              <1> 	;push	cs
  2550 00000B67 E80A010000          <1> 	call	kb_int   ; int_09h
  2551                              <1> 	;
  2552                              <1> 	;mov	ah, 11h	 ; 03/12/2014	
  2553 00000B6C B401                <1> 	mov	ah, 1 ; 24/07/2022
  2554                              <1> 	;call	getc
  2555 00000B6E E854000000          <1> 	call	int_16h  ; 30/06/2015
  2556 00000B73 744E                <1> 	jz	short keyb_int4
  2557                              <1> 	;
  2558                              <1> 	;mov	ah, 10h	 ; 03/12/2014
  2559 00000B75 B400                <1> 	mov	ah, 0 ; 24/07/2022
  2560                              <1> 	;call	getc
  2561 00000B77 E84B000000          <1> 	call	int_16h  ; 30/06/2015
  2562                              <1> 	;
  2563                              <1> 	; 20/02/2015
  2564 00000B7C 0FB61D[96670000]    <1>         movzx   ebx, byte [ptty]  ; active_page
  2565                              <1> 	;
  2566 00000B83 20C0                <1> 	and 	al, al
  2567 00000B85 751D                <1> 	jnz	short keyb_int1
  2568                              <1> 	;
  2569 00000B87 80FC68              <1> 	cmp	ah, 68h	 ; ALT + F1 key
  2570 00000B8A 7218                <1> 	jb	short keyb_int1
  2571 00000B8C 80FC6F              <1> 	cmp	ah, 6Fh  ; ALT + F8 key	
  2572 00000B8F 7713                <1> 	ja	short keyb_int1
  2573                              <1> 	;
  2574 00000B91 88D8                <1> 	mov	al, bl
  2575 00000B93 0468                <1> 	add	al, 68h
  2576 00000B95 38E0                <1> 	cmp	al, ah
  2577 00000B97 7409                <1> 	je	short keyb_int0
  2578 00000B99 88E0                <1> 	mov	al, ah
  2579 00000B9B 2C68                <1> 	sub	al, 68h
  2580 00000B9D E831090000          <1> 	call	tty_sw
  2581                              <1> 	;movzx	ebx, [ptty]  ; active_page
  2582                              <1> keyb_int0: ; 30/06/2015
  2583                              <1> 	;xor	ax, ax
  2584                              <1> 	; 23/02/2022
  2585 00000BA2 31C0                <1> 	xor	eax, eax
  2586                              <1> keyb_int1:
  2587 00000BA4 D0E3                <1> 	shl	bl, 1
  2588 00000BA6 81C3[98670000]      <1> 	add	ebx, ttychr
  2589                              <1> 	;
  2590                              <1> 	;23/02/2022
  2591 00000BAC 09C0                <1> 	or	eax, eax
  2592                              <1> 	;or	ax, ax
  2593 00000BAE 7406                <1> 	jz	short keyb_int2
  2594                              <1> 	;
  2595 00000BB0 66833B00            <1> 	cmp 	word [ebx], 0
  2596 00000BB4 7703                <1>         ja      short keyb_int3 
  2597                              <1> keyb_int2:
  2598 00000BB6 668903              <1>         mov	[ebx], ax  ; Save ascii code
  2599                              <1> 			   ; and scan code of the character
  2600                              <1> 			   ; for current tty (or last tty
  2601                              <1> 			   ; just before tty switch).
  2602                              <1> keyb_int3:
  2603 00000BB9 A0[96670000]        <1>         mov     al, [ptty]
  2604 00000BBE E88F3B0000          <1> 	call	wakeup
  2605                              <1> 	;
  2606                              <1> keyb_int4:
  2607 00000BC3 58                  <1> 	pop	eax
  2608 00000BC4 5B                  <1> 	pop	ebx
  2609 00000BC5 1F                  <1> 	pop	ds
  2610 00000BC6 CF                  <1> 	iret
  2611                              <1> 
  2612                              <1> ; 18/02/2015
  2613                              <1> ; REMINDER: Only 'keyb_int' (IRQ 9) must call getc.
  2614                              <1> ; 'keyb_int' always handles 'getc' at 1st and puts the
  2615                              <1> ; scancode and ascii code of the character 
  2616                              <1> ; in the tty input (ttychr) buffer. 
  2617                              <1> ; Test procedures must call 'getch' for tty input
  2618                              <1> ; otherwise, 'getc' will not be able to return to the caller
  2619                              <1> ; due to infinite (key press) waiting loop.
  2620                              <1> ; 
  2621                              <1> ; 03/12/2014
  2622                              <1> ; 26/08/2014
  2623                              <1> ; KEYBOARD I/O
  2624                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
  2625                              <1> 
  2626                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
  2627                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
  2628                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
  2629                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
  2630                              <1> 
  2631                              <1> ; 24/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
  2632                              <1> ;int_16h: ; 30/06/2015
  2633                              <1> ;;getc:
  2634                              <1> ;	pushfd	; 28/08/2014
  2635                              <1> ;	push 	cs
  2636                              <1> ;	call 	getc_int
  2637                              <1> ;	retn
  2638                              <1> 
  2639                              <1> 	; 24/07/2022
  2640                              <1> %if 0
  2641                              <1> ; 24/12/2021
  2642                              <1> 
  2643                              <1> 	;-----	SHIFT STATUS
  2644                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
  2645                              <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2646                              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2647                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2648                              <1> 	;shl	ah, cl			; BIT 7 POSITION
  2649                              <1>         shl	ah, 5
  2650                              <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2651                              <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2652                              <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2653                              <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2654                              <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2655                              <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2656                              <1> _K3:
  2657                              <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2658                              <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2659                              <1> 
  2660                              <1> %endif
  2661                              <1> 
  2662                              <1> int_16h:
  2663                              <1> 	; 24/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
  2664                              <1> 	; 24/07/2022 - (near call return instead of interrupt return)
  2665                              <1> 	
  2666                              <1> 	; INPUT:
  2667                              <1> 	;	AL = Function (0 or 1)
  2668                              <1> 	;	     0 = Read Character
  2669                              <1> 	;	     1 = Get Keyboard Buffer Status
  2670                              <1> 	; OUTPUT:
  2671                              <1> 	;	Function 0 - AX = ASCII (AL) and SCAN CODE (AH)
  2672                              <1> 	;			  of the character (enterrd from the keyboard) 
  2673                              <1> 	;	Function 1 - If ZF = 0
  2674                              <1> 	;			AX = ASCII (AL) and SCAN CODE (AH) of the character
  2675                              <1> 	;			(which is waiting in keyboard buffer)
  2676                              <1> 	;		     If ZF = 1
  2677                              <1> 	;			there is not a character in the keyboard buffer
  2678                              <1> 	;
  2679                              <1> 	; Modified registers: eax, ebx
  2680                              <1> 	
  2681                              <1> getc_int:
  2682                              <1> 	; 24/07/2022 (Retro UNIX 386 v1.1 - Kernel v0.2.1.6)
  2683                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
  2684                              <1> 	; 28/02/2015
  2685                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2686                              <1> 	;	      instead of pc-at bios - 1985-)
  2687                              <1> 	; 28/08/2014 (_k1d)
  2688                              <1> 	; 30/06/2014
  2689                              <1> 	; 03/03/2014
  2690                              <1> 	; 28/02/2014
  2691                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
  2692                              <1> 	; rombios source code (21/04/1986)
  2693                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
  2694                              <1> 	;
  2695                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
  2696                              <1> 	;
  2697                              <1> 	;--- INT 16 H -----------------------------------------------------------------
  2698                              <1> 	; KEYBOARD I/O								      :
  2699                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
  2700                              <1> 	; INPUT									      :
  2701                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
  2702                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
  2703                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
  2704                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
  2705                              <1> 	;-----------------------------------------------------------------------------:
  2706                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
  2707                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
  2708                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
  2709                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
  2710                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
  2711                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
  2712                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
  2713                              <1> 	;-----------------------------------------------------------------------------:	
  2714                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
  2715                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
  2716                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
  2717                              <1> 	;-----------------------------------------------------------------------------:	
  2718                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
  2719                              <1> 	;	      (AL) = 05H                                                      :
  2720                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
  2721                              <1> 	;		       							      :
  2722                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
  2723                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
  2724                              <1> 	;                     --------------------------------------------            :
  2725                              <1> 	;			00H        30.0        10H        7.5                 :
  2726                              <1> 	;			01H        26.7        11H        6.7                 :
  2727                              <1> 	;			02H        24.0        12H        6.0                 :
  2728                              <1> 	;			03H        21.8        13H        5.5                 :
  2729                              <1> 	;			04H        20.0        14H        5.0                 :
  2730                              <1> 	;			05H        18.5        15H        4.6                 :
  2731                              <1> 	;			06H        17.1        16H        4.3                 :
  2732                              <1> 	;			07H        16.0        17H        4.0                 :
  2733                              <1> 	;			08H        15.0        18H        3.7                 :
  2734                              <1> 	;			09H        13.3        19H        3.3                 :
  2735                              <1> 	;			0AH        12.0        1AH        3.0                 :
  2736                              <1> 	;			0BH        10.9        1BH        2.7                 :
  2737                              <1>         ;			0CH        10.0        1CH        2.5                 :
  2738                              <1> 	;			0DH         9.2        1DH        2.3                 :
  2739                              <1> 	;			0EH         8.6        1EH        2.1                 :
  2740                              <1> 	;			0FH         8.0        1FH        2.0                 :
  2741                              <1> 	;									      :
  2742                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
  2743                              <1> 	;		       							      :
  2744                              <1> 	;                     REGISTER     DELAY                                      :
  2745                              <1> 	;                      VALUE       VALUE                                      :
  2746                              <1> 	;                     ------------------                                      :
  2747                              <1> 	;			00H        250 ms                                     :
  2748                              <1> 	;			01H        500 ms                                     :
  2749                              <1> 	;			02H        750 ms                                     :
  2750                              <1> 	;			03H       1000 ms                                     :
  2751                              <1> 	;-----------------------------------------------------------------------------:
  2752                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
  2753                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
  2754                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
  2755                              <1> 	;		           (CH) = SCAN CODE                                   :
  2756                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
  2757                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
  2758                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
  2759                              <1> 	;-----------------------------------------------------------------------------:		
  2760                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
  2761                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
  2762                              <1> 	;-----------------------------------------------------------------------------:
  2763                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
  2764                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
  2765                              <1> 	;-----------------------------------------------------------------------------:	
  2766                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
  2767                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
  2768                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
  2769                              <1> 	; OUTPUT					                              :
  2770                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
  2771                              <1> 	;	ALL REGISTERS RETAINED		                                      :
  2772                              <1> 	;------------------------------------------------------------------------------
  2773                              <1> 	
  2774 00000BC7 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2775                              <1> 
  2776                              <1> 	; 24/07/2022
  2777                              <1> 	;push	ds			; SAVE CURRENT DS
  2778                              <1> 	;push	ebx			; SAVE BX TEMPORARILY
  2779                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
  2780                              <1>         ;mov	bx, KDATA 
  2781                              <1> 	;mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
  2782                              <1> 
  2783                              <1> 	;or	ah, ah			; CHECK FOR (AH)= 00H
  2784                              <1> 	;jz	short _K1		; ASCII_READ
  2785                              <1> 	;dec	ah                      ; CHECK FOR (AH)= 01H
  2786                              <1> 	;jz	short _K2               ; ASCII_STATUS
  2787                              <1> 	;dec	ah			; CHECK FOR (AH)= 02H
  2788                              <1> 	;jz	short _K3               ; SHIFT STATUS
  2789                              <1> 	;dec	ah			; CHECK FOR (AH)= 03H	
  2790                              <1> 	;jz	short _K300             ; SET TYPAMATIC RATE/DELAY
  2791                              <1> 	;sub	ah, 2			; CHECK FOR (AH)= 05H	
  2792                              <1> 	;jz	short _K500             ; KEYBOARD WRITE         
  2793                              <1> ;_KIO1:	
  2794                              <1> 	;sub	ah, 11			; AH =  10H
  2795                              <1> 	;jz	short _K1E		; EXTENDED ASCII READ
  2796                              <1> 	;dec	ah			; CHECK FOR (AH)= 11H
  2797                              <1> 	;jz	short _K2E		; EXTENDED_ASCII_STATUS
  2798                              <1> 	;dec	ah			; CHECK FOR (AH)= 12H
  2799                              <1> 	;jz	short _K3E		; EXTENDED_SHIFT_STATUS
  2800                              <1> 
  2801                              <1> ;_KIO_EXIT:
  2802                              <1> 	;pop	ecx			; RECOVER REGISTER
  2803                              <1> 	;pop	ebx			; RECOVER REGISTER
  2804                              <1> 	; 24/07/2022
  2805                              <1> 	;retn
  2806                              <1> 	;pop	ds			; RECOVER SEGMENT
  2807                              <1> 	;iretd				; INVALID COMMAND, EXIT
  2808                              <1> 
  2809 00000BC8 08E4                <1> 	or	ah, ah
  2810 00000BCA 7507                <1> 	jnz	short _K2
  2811                              <1> 
  2812                              <1> 	;-----	ASCII CHARACTER
  2813                              <1> _K1:
  2814                              <1> _K1E:	
  2815 00000BCC E81C000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
  2816                              <1> 	;call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2817                              <1> 	;;jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
  2818                              <1> 	; 24/07/2022
  2819                              <1> 	;retn
  2820 00000BD1 EB0F                <1> 	jmp	short _KIO_E_XLAT
  2821                              <1> ;_K1:	
  2822                              <1> 	;call	_K1S			; GET A CHARACTER FROM THE BUFFER
  2823                              <1> 	;call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2824                              <1> 	;jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
  2825                              <1> ;_K1A:
  2826                              <1> 	;jmp	short _KIO_EXIT         ; RETURN TO CALLER
  2827                              <1> 	; 24/07/2022
  2828                              <1> 	;retn
  2829                              <1> 
  2830                              <1> 	;-----	ASCII STATUS
  2831                              <1> _K2:
  2832                              <1> _K2E:	
  2833 00000BD3 E860000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
  2834 00000BD8 7407                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2835 00000BDA 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2836 00000BDB E802000000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2837                              <1> 	;jmp	short _K2A	        ; GIVE IT TO THE CALLER
  2838                              <1> 	; 24/07/2022
  2839 00000BE0 9D                  <1> 	popf
  2840                              <1> _K2B:
  2841 00000BE1 C3                  <1> 	retn
  2842                              <1> ;_K2:	
  2843                              <1> 	;call	_K2S			; TEST FOR CHARACTER IN BUFFER
  2844                              <1> 	;jz	short _K2B		; RETURN IF BUFFER EMPTY
  2845                              <1> 	;pushf				; SAVE ZF FROM TEST
  2846                              <1> 	;call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2847                              <1> 	;jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
  2848                              <1> 	;popf				; INVALID CODE FOR THIS TYPE OF CALL
  2849                              <1> 	;call	_K1S			; THROW THE CHARACTER AWAY
  2850                              <1> 	;jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
  2851                              <1> ;_K2A:
  2852                              <1> 	;popf				; RESTORE ZF FROM TEST
  2853                              <1> ;_K2B:
  2854                              <1> 	;;pop	ecx			; RECOVER REGISTER
  2855                              <1> 	;pop	ebx			; RECOVER REGISTER
  2856                              <1> 	;pop	ds			; RECOVER SEGMENT
  2857                              <1> 	;retf	4			; THROW AWAY (E)FLAGS
  2858                              <1> 
  2859                              <1> ; 24/12/2021
  2860                              <1> ;	;-----	SHIFT STATUS
  2861                              <1> ;_K3E:                                  ; GET THE EXTENDED SHIFT STATUS FLAGS
  2862                              <1> ;	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2863                              <1> ;	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2864                              <1> ;	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2865                              <1> ;	;shl	ah, cl			; BIT 7 POSITION
  2866                              <1> ;       shl	ah, 5
  2867                              <1> ;	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2868                              <1> ;	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2869                              <1> ;	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2870                              <1> ;	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2871                              <1> ;	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2872                              <1> ;	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2873                              <1> ;_K3:
  2874                              <1> ;	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2875                              <1> ;	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2876                              <1> 
  2877                              <1> 	; 24/07/2022
  2878                              <1> %if 0
  2879                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
  2880                              <1> _K300:
  2881                              <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
  2882                              <1> 	jne	short _KIO_EXIT		; NO, RETURN
  2883                              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
  2884                              <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2885                              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
  2886                              <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2887                              <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
  2888                              <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2889                              <1> 	;mov	cx, 5			; SHIFT COUNT
  2890                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
  2891                              <1> 	shl	bh, 5
  2892                              <1> 	mov	al, bl			; PUT IN RATE
  2893                              <1> 	or	al, bh			; AND DELAY
  2894                              <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2895                              <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
  2896                              <1> 
  2897                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
  2898                              <1> _K500:
  2899                              <1> 	push	esi			; SAVE SI (esi)
  2900                              <1> 	cli				; 
  2901                              <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
  2902                              <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
  2903                              <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
  2904                              <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
  2905                              <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
  2906                              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
  2907                              <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
  2908                              <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
  2909                              <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
  2910                              <1> _K502:
  2911                              <1> 	mov	al, 01h			; BUFFER FULL INDICATION
  2912                              <1> _K504:
  2913                              <1> 	sti				
  2914                              <1> 	pop	esi			; RECOVER SI (esi)
  2915                              <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
  2916                              <1> %endif
  2917                              <1> 
  2918                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
  2919                              <1> _KIO_E_XLAT:
  2920 00000BE2 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2921 00000BE4 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
  2922 00000BE6 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
  2923 00000BE8 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
  2924 00000BEA 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
  2925                              <1> _KIO_E_RET:				
  2926 00000BEC C3                  <1> 	retn				; GO BACK
  2927                              <1> 
  2928                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
  2929                              <1> _K1S:
  2930 00000BED FA                  <1> 	cli	; 03/12/2014
  2931 00000BEE 8B1D[D0610000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2932 00000BF4 3B1D[D4610000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2933                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
  2934 00000BFA 750F                <1> 	jne	short _k1x ; 03/12/2014
  2935                              <1> 	;
  2936                              <1> 	; 03/12/2014
  2937                              <1> 	; 28/08/2014
  2938                              <1> 	; PERFORM OTHER FUNCTION ?? here !
  2939                              <1> 	;;mov	ax, 9002h		; MOVE IN WAIT CODE & TYPE
  2940                              <1> 	;;int	15h			; PERFORM OTHER FUNCTION
  2941                              <1> _K1T:                                   ; ASCII READ
  2942 00000BFC FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
  2943 00000BFD 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
  2944                              <1> _K1U:	
  2945 00000BFE FA                  <1> 	cli				; INTERRUPTS BACK OFF
  2946 00000BFF 8B1D[D0610000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2947 00000C05 3B1D[D4610000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2948                              <1> _k1x:
  2949 00000C0B 53                  <1> 	push	ebx			; SAVE ADDRESS		
  2950 00000C0C 9C                  <1> 	pushf				; SAVE FLAGS
  2951 00000C0D E895060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2952 00000C12 8A1D[C5610000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2953 00000C18 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2954 00000C1A 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
  2955 00000C1D 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
  2956 00000C1F E82F060000          <1> 	call	SND_LED1
  2957 00000C24 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2958                              <1> _K1V:
  2959 00000C25 9D                  <1> 	popf				; RESTORE FLAGS
  2960 00000C26 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2961 00000C27 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
  2962                              <1> 	;
  2963 00000C29 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
  2964 00000C2C E834000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
  2965 00000C31 891D[D0610000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
  2966 00000C37 C3                  <1> 	retn				; RETURN
  2967                              <1> 
  2968                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
  2969                              <1> _K2S:
  2970 00000C38 FA                  <1> 	cli				; INTERRUPTS OFF
  2971 00000C39 8B1D[D0610000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2972 00000C3F 3B1D[D4610000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
  2973 00000C45 668B03              <1> 	mov	ax, [ebx]
  2974 00000C48 9C                  <1> 	pushf				; SAVE FLAGS
  2975                              <1> 	;push	ax			; SAVE CODE
  2976                              <1> 	; 24/12/2021
  2977 00000C49 50                  <1> 	push	eax
  2978 00000C4A E858060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2979 00000C4F 8A1D[C5610000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2980 00000C55 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2981 00000C57 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
  2982 00000C5A 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
  2983 00000C5C E8DB050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2984                              <1> _K2T:
  2985                              <1> 	;pop	ax			; RESTORE CODE
  2986                              <1> 	; 24/12/2021
  2987 00000C61 58                  <1> 	pop	eax
  2988 00000C62 9D                  <1> 	popf				; RESTORE FLAGS
  2989 00000C63 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2990 00000C64 C3                  <1> 	retn				; RETURN
  2991                              <1> 
  2992                              <1> 	; 24/07/2022
  2993                              <1> %if 0
  2994                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
  2995                              <1> _KIO_S_XLAT:
  2996                              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
  2997                              <1> 	jne	short _KIO_S2		; NO, CONTINUE
  2998                              <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
  2999                              <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
  3000                              <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
  3001                              <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
  3002                              <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
  3003                              <1> _kio_ret: ; 03/12/2014
  3004                              <1> 	clc
  3005                              <1> 	retn
  3006                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  3007                              <1> _KIO_S1:				
  3008                              <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
  3009                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  3010                              <1> 	retn
  3011                              <1> _KIO_S2:		
  3012                              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
  3013                              <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
  3014                              <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  3015                              <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
  3016                              <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  3017                              <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
  3018                              <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
  3019                              <1> _KIO_S3:
  3020                              <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
  3021                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
  3022                              <1> 	jne	short _kio_ret
  3023                              <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  3024                              <1>         jz	short _KIO_USE		; JUMP IF AH = 0
  3025                              <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
  3026                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
  3027                              <1> _KIO_USE:
  3028                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
  3029                              <1> 	retn				; RETURN	
  3030                              <1> _KIO_DIS:
  3031                              <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
  3032                              <1> 	retn				; RETURN
  3033                              <1> 
  3034                              <1> %endif
  3035                              <1> 
  3036                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
  3037                              <1> _K4:    
  3038 00000C65 43                  <1> 	inc     ebx
  3039 00000C66 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
  3040 00000C67 3B1D[CC610000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
  3041                              <1>         ;jne    short _K5               ; NO, CONTINUE
  3042 00000C6D 7206                <1> 	jb	short _K5
  3043 00000C6F 8B1D[C8610000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
  3044                              <1> _K5:
  3045 00000C75 C3                  <1> 	retn
  3046                              <1> 
  3047                              <1> ; 20/02/2015
  3048                              <1> ; 05/12/2014
  3049                              <1> ; 26/08/2014
  3050                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
  3051                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
  3052                              <1> ;
  3053                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
  3054                              <1> ; rombios source code (06/10/1985)
  3055                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
  3056                              <1> 
  3057                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
  3058                              <1> ENA_KBD		equ	0AEh	; ENABLE KEYBOARD COMMAND
  3059                              <1> DIS_KBD		equ	0ADh	; DISABLE KEYBOARD COMMAND
  3060                              <1> SHUT_CMD	equ	0FEh	; CAUSE A SHUTDOWN COMMAND
  3061                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  3062                              <1> STATUS_PORT	equ	064h	; 8042 STATUS PORT
  3063                              <1> INPT_BUF_FULL	equ	00000010b ; 1 = +INPUT BUFFER FULL
  3064                              <1> PORT_A		equ	060h	; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  3065                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
  3066                              <1> KB_ACK		equ	0FAh	; ACKNOWLEDGE PROM TRANSMISSION
  3067                              <1> KB_RESEND	equ	0FEh	; RESEND REQUEST
  3068                              <1> KB_OVER_RUN	equ	0FFh	; OVER RUN SCAN CODE
  3069                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
  3070                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
  3071                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
  3072                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
  3073                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
  3074                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
  3075                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
  3076                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
  3077                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
  3078                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
  3079                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
  3080                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
  3081                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
  3082                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
  3083                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
  3084                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
  3085                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
  3086                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
  3087                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
  3088                              <1> F11_M		equ	87		; F11 KEY MAKE
  3089                              <1> F12_M		equ	88		; F12 KEY MAKE
  3090                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
  3091                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
  3092                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
  3093                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
  3094                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
  3095                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
  3096                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
  3097                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
  3098                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
  3099                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
  3100                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
  3101                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
  3102                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
  3103                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
  3104                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
  3105                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
  3106                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
  3107                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
  3108                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
  3109                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
  3110                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
  3111                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
  3112                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
  3113                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
  3114                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
  3115                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
  3116                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
  3117                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
  3118                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
  3119                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
  3120                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
  3121                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
  3122                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
  3123                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
  3124                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
  3125                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
  3126                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
  3127                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
  3128                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
  3129                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
  3130                              <1> ;
  3131                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
  3132                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
  3133                              <1> INTA00		equ	020h		; 8259 PORT
  3134                              <1> 
  3135                              <1> 
  3136                              <1> kb_int:
  3137                              <1> 
  3138                              <1> ; 11/06/2022
  3139                              <1> ; 05/12/2021 (Retro UNIX 386 v1.2)
  3140                              <1> ; 17/10/2015 ('ctrlbrk') 
  3141                              <1> ; 05/12/2014
  3142                              <1> ; 04/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  3143                              <1> ;	      instead of pc-at bios - 1985-)
  3144                              <1> ; 26/08/2014
  3145                              <1> ;
  3146                              <1> ; 03/06/86  KEYBOARD BIOS
  3147                              <1> ;
  3148                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
  3149                              <1> ;										;
  3150                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
  3151                              <1> ;										;
  3152                              <1> ;--------------------------------------------------------------------------------
  3153                              <1> 
  3154                              <1> KB_INT_1:
  3155 00000C76 FB                  <1> 	sti				; ENABLE INTERRUPTS
  3156                              <1> 	;push	ebp
  3157 00000C77 50                  <1> 	push	eax
  3158 00000C78 53                  <1> 	push	ebx
  3159 00000C79 51                  <1> 	push	ecx
  3160 00000C7A 52                  <1> 	push	edx
  3161 00000C7B 56                  <1> 	push	esi
  3162 00000C7C 57                  <1> 	push	edi
  3163 00000C7D 1E                  <1> 	push	ds
  3164 00000C7E 06                  <1> 	push	es
  3165 00000C7F FC                  <1> 	cld				; FORWARD DIRECTION
  3166 00000C80 66B81000            <1> 	mov	ax, KDATA
  3167 00000C84 8ED8                <1> 	mov	ds, ax
  3168 00000C86 8EC0                <1> 	mov	es, ax
  3169                              <1> 	;
  3170                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
  3171 00000C88 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
  3172 00000C8A E852050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
  3173 00000C8F FA                  <1> 	cli				; DISABLE INTERRUPTS
  3174 00000C90 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
  3175                              <1> KB_INT_01:
  3176 00000C95 E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
  3177 00000C97 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
  3178 00000C99 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
  3179                              <1> 	;
  3180                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
  3181 00000C9B E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
  3182                              <1> 	;
  3183                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
  3184                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
  3185                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
  3186                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
  3187                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
  3188                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
  3189                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
  3190                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
  3191                              <1> 	;
  3192                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
  3193                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
  3194 00000C9D FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3195 00000C9E 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
  3196 00000CA0 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
  3197                              <1> 	;
  3198                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
  3199 00000CA2 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
  3200 00000CA4 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
  3201                              <1> 	;
  3202                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
  3203 00000CA6 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3204 00000CA7 800D[C5610000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
  3205 00000CAE E963020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
  3206                              <1> 	;
  3207                              <1> 	;-----	RESEND THE LAST BYTE
  3208                              <1> KB_INT_4:
  3209 00000CB3 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3210 00000CB4 800D[C5610000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
  3211 00000CBB E956020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
  3212                              <1> 	;
  3213                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
  3214                              <1> KB_INT_2:
  3215                              <1> 	;push 	ax			; SAVE DATA IN
  3216                              <1> 	; 05/12/2021
  3217 00000CC0 50                  <1> 	push	eax
  3218 00000CC1 E8E1050000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  3219 00000CC6 8A1D[C5610000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  3220 00000CCC 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  3221 00000CCE 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
  3222 00000CD1 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
  3223 00000CD3 E864050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  3224                              <1> UP0:
  3225                              <1> 	;pop	ax			; RESTORE DATA IN
  3226                              <1> 	; 05/12/2021
  3227 00000CD8 58                  <1> 	pop	eax
  3228                              <1> ;------------------------------------------------------------------------
  3229                              <1> ;	START OF KEY PROCESSING						;
  3230                              <1> ;------------------------------------------------------------------------
  3231 00000CD9 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
  3232                              <1> 	;
  3233                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
  3234 00000CDB 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
  3235                              <1>         ;je	K62			; BUFFER_FULL_BEEP
  3236                              <1> 	; 05/12/2021
  3237 00000CDD 7505                <1> 	jne	short K16
  3238 00000CDF E9E9040000          <1> 	jmp	K62
  3239                              <1> K16:	
  3240 00000CE4 8A3D[C6610000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
  3241                              <1> 	;
  3242                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
  3243 00000CEA F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
  3244 00000CED 7442                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
  3245 00000CEF 7914                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
  3246 00000CF1 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
  3247 00000CF3 7507                <1> 	jne	short RST_RD_ID
  3248 00000CF5 800D[C6610000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  3249                              <1> RST_RD_ID:
  3250 00000CFC 8025[C6610000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
  3251 00000D03 EB27                <1>         jmp    short ID_EX		; AND EXIT
  3252                              <1> 	; 05/12/2021
  3253                              <1> 	;jmp	K26
  3254                              <1> 	;
  3255                              <1> TST_ID_2:
  3256 00000D05 8025[C6610000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
  3257 00000D0C 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
  3258 00000D0E 7415                <1>         je	short KX_BIT		; JUMP IF SO
  3259 00000D10 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
  3260 00000D12 7518                <1>         jne	short ID_EX		; LEAVE IF NOT
  3261                              <1> 	; 05/12/2021
  3262                              <1> 	;jne	K26
  3263                              <1> 	;
  3264                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
  3265 00000D14 F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
  3266 00000D17 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
  3267 00000D19 800D[C3610000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
  3268 00000D20 E817050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
  3269                              <1> KX_BIT:
  3270 00000D25 800D[C6610000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
  3271 00000D2C E9E5010000          <1> ID_EX:	jmp     K26			; EXIT
  3272                              <1> 	;
  3273                              <1> NOT_ID:
  3274 00000D31 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
  3275 00000D33 750E                <1> 	jne	short TEST_E1
  3276 00000D35 800D[C6610000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
  3277 00000D3C EB10                <1> 	jmp	short EXIT		; THROW AWAY THIS CODE
  3278                              <1> 	; 05/12/2021
  3279 00000D3E E9DA010000          <1> 	jmp	K26A	
  3280                              <1> TEST_E1:	
  3281 00000D43 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
  3282 00000D45 750C                <1> 	jne	short NOT_HC
  3283 00000D47 800D[C6610000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
  3284 00000D4E E9CA010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
  3285                              <1> 	;
  3286                              <1> NOT_HC:
  3287 00000D53 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
  3288 00000D55 F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
  3289 00000D58 740D                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
  3290                              <1> 	;
  3291 00000D5A BF[AE600000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
  3292 00000D5F AE                  <1> 	scasb
  3293                              <1> 	;je	K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
  3294                              <1> 	; 05/12/2021
  3295 00000D60 7458                <1> 	je	short K16B
  3296 00000D62 AE                  <1> 	scasb
  3297 00000D63 756A                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
  3298 00000D65 EB53                <1> 	jmp	short K16B		; YES, THROW AWAY & RESET FLAG
  3299                              <1> 	; 05/12/2021
  3300                              <1> 	;jmp	K26
  3301                              <1> 	;
  3302                              <1> NOT_LC_E0:
  3303 00000D67 F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
  3304 00000D6A 7425                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
  3305 00000D6C B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
  3306 00000D71 BF[AC600000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
  3307 00000D76 F2AE                <1> 	repne	scasb			; CHECK IT
  3308 00000D78 74D4                <1> 	je	short EXIT		; THROW AWAY IF SO
  3309                              <1> 	; 05/12/2021
  3310                              <1> 	;je	K26A			
  3311                              <1> 	;
  3312 00000D7A 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
  3313 00000D7C 753C                <1> 	jne	short K16B		; NO, THROW AWAY & RESET FLAG
  3314                              <1> 	; 05/12/2021
  3315                              <1> 	;jne	K26
  3316 00000D7E F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
  3317 00000D81 7537                <1> 	jnz	short K16B		; YES, THROW THIS AWAY, TOO	
  3318                              <1> 	; 05/12/2021
  3319                              <1> 	;jnz	K26
  3320                              <1>         ; 20/02/2015 
  3321 00000D83 F605[C4610000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ; NO, ARE WE PAUSED ALREADY?
  3322 00000D8A 752E                <1> 	jnz	short K16B		; YES, THROW AWAY
  3323                              <1> 	; 05/12/2021
  3324                              <1> 	;jnz	K26
  3325 00000D8C E9D2020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
  3326                              <1> 	;
  3327                              <1> 	;-----	TEST FOR SYSTEM KEY
  3328                              <1> T_SYS_KEY:
  3329 00000D91 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
  3330 00000D93 753A                <1> 	jnz	short K16A		; CONTINUE IF NOT
  3331                              <1> 	;
  3332 00000D95 F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
  3333 00000D98 7525                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
  3334                              <1> 	;
  3335 00000D9A F605[C4610000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
  3336 00000DA1 7517                <1> 	jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
  3337                              <1> 	;jnz	K26			
  3338                              <1> 	;
  3339 00000DA3 800D[C4610000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
  3340 00000DAA B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3341 00000DAC E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3342                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3343 00000DAE B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3344 00000DB0 E82C040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3345                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
  3346                              <1> 	;mov	al, 8500h		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
  3347                              <1> 	;sti				; MAKE SURE INTERRUPTS ENABLED
  3348                              <1> 	;int	15h			; USER INTERRUPT	
  3349 00000DB5 E96F010000          <1>         jmp     K27A                    ; END PROCESSING
  3350                              <1> 	;
  3351 00000DBA E957010000          <1> K16B:	jmp	K26			; IGNORE SYSTEM KEY
  3352                              <1> 	;
  3353                              <1> K16C:
  3354 00000DBF 8025[C4610000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
  3355 00000DC6 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3356 00000DC8 E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
  3357                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3358                              <1> 	;mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3359                              <1> 	;call	SHIP_IT			; EXECUTE ENABLE
  3360                              <1> 	;
  3361                              <1> 	;mov	ax, 8501h		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
  3362                              <1> 	;sti				; MAKE SURE INTERRUPTS ENABLED
  3363                              <1> 	;int	15h			; USER INTERRUPT
  3364                              <1> 	;jmp	K27A			; IGNORE SYSTEM KEY
  3365                              <1> 	;
  3366 00000DCA E953010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
  3367                              <1> 	;
  3368                              <1> 	;-----	TEST FOR SHIFT KEYS
  3369                              <1> K16A:
  3370 00000DCF 8A1D[C3610000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  3371 00000DD5 BF[A8600000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
  3372 00000DDA B908000000          <1> 	mov	ecx, _K6L		; LENGTH
  3373 00000DDF F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
  3374 00000DE1 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
  3375                              <1>         ;jne    K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
  3376                              <1> 	; 05/12/2021
  3377 00000DE3 7405                <1> 	je	short K17
  3378 00000DE5 E914010000          <1> 	jmp	K25
  3379                              <1> 	;
  3380                              <1> 	;------	SHIFT KEY FOUND
  3381                              <1> K17:
  3382 00000DEA 81EF[A9600000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  3383 00000DF0 8AA7[B0600000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
  3384 00000DF6 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
  3385 00000DF8 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
  3386                              <1>         ;jnz	K23                     ; JUMP OF BREAK
  3387                              <1> 	; 05/12/2021
  3388 00000DFA 7405                <1> 	jz	short K17C
  3389 00000DFC E999000000          <1> 	jmp	K23
  3390                              <1> 	;
  3391                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
  3392                              <1> K17C:
  3393 00000E01 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
  3394 00000E04 732C                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
  3395                              <1> 	;
  3396                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
  3397 00000E06 0825[C3610000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
  3398 00000E0C A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
  3399 00000E0E 7505                <1> 	jnz	short K17D		; YES, MORE FLAGS TO SET
  3400                              <1> 	;jz	K26			; NO, INTERRUPT RETURN
  3401                              <1> 	; 05/12/2021
  3402 00000E10 E901010000          <1> 	jmp	K26
  3403                              <1> K17D:
  3404 00000E15 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
  3405 00000E18 740B                <1> 	jz 	short K17E		; NO, JUMP
  3406 00000E1A 0825[C6610000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
  3407 00000E20 E9F1000000          <1> 	jmp	K26			; INTERRUPT RETURN
  3408                              <1> K17E:
  3409 00000E25 D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
  3410 00000E27 0825[C4610000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
  3411 00000E2D E9E4000000          <1> 	jmp	K26
  3412                              <1> 	;
  3413                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
  3414                              <1> K18:					; SHIFT-TOGGLE
  3415 00000E32 F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
  3416 00000E35 7405                <1>         jz    	short K18A              ; JUMP IF NOT CTL STATE
  3417                              <1>         ;jnz	K25                     ; JUMP IF CTL STATE
  3418                              <1> 	; 05/12/2021
  3419 00000E37 E9C2000000          <1> 	jmp	K25
  3420                              <1> K18A:
  3421 00000E3C 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
  3422 00000E3E 7525                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
  3423 00000E40 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
  3424 00000E43 7405                <1>       	jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
  3425                              <1> 	;jnz	K25                     ; JUMP IF ALTERNATE SHIFT
  3426                              <1> 	; 05/12/2021
  3427 00000E45 E9B4000000          <1> 	jmp	K25
  3428                              <1> K18B:
  3429 00000E4A F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
  3430 00000E4D 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
  3431                              <1> K19:	
  3432 00000E4F F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
  3433 00000E52 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
  3434 00000E54 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
  3435 00000E57 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
  3436                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
  3437 00000E59 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
  3438 00000E5B E99E000000          <1>         jmp	K25               	; NUMERAL '0', STNDRD. PROCESSING
  3439                              <1> K21:					; MIGHT BE NUMERIC
  3440 00000E60 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
  3441 00000E63 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
  3442                              <1> 	;
  3443                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
  3444 00000E65 8425[C4610000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
  3445                              <1> 	;jnz	K26
  3446                              <1> 	; 05/12/2021
  3447 00000E6B 7405                <1> 	jz	short K22A
  3448 00000E6D E9A4000000          <1> 	jmp	K26			; JUMP IF KEY ALREADY DEPRESSED
  3449                              <1> K22A:
  3450 00000E72 0825[C4610000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  3451 00000E78 3025[C3610000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
  3452                              <1> 	;
  3453                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
  3454 00000E7E F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
  3455 00000E81 7407                <1> 	jz	short K22B		; GO IF NOT
  3456                              <1> 	;
  3457                              <1> 	; 05/12/2021
  3458                              <1> 	;push	ax			; SAVE SCAN CODE AND SHIFT MASK
  3459 00000E83 50                  <1> 	push	eax
  3460 00000E84 E8B3030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
  3461                              <1> 	;pop	ax			; RESTORE SCAN CODE
  3462 00000E89 58                  <1> 	pop	eax
  3463                              <1> K22B:
  3464 00000E8A 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
  3465                              <1>         ;jne	K26			; JUMP IF NOT INSERT KEY
  3466                              <1> 	; 05/12/2021
  3467 00000E8C 7405                <1> 	je	short K22C
  3468 00000E8E E983000000          <1> 	jmp	K26			; JUMP IF NOT INSERT KEY
  3469                              <1> K22C:
  3470 00000E93 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
  3471 00000E95 E999000000          <1>         jmp	K28			; FLAGS UPDATED, PROC. FOR BUFFER
  3472                              <1> 	;
  3473                              <1> 	;-----	BREAK SHIFT FOUND
  3474                              <1> K23:					; BREAK-SHIFT-FOUND
  3475 00000E9A 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
  3476 00000E9D F6D4                <1> 	not	ah			; INVERT MASK
  3477 00000E9F 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
  3478 00000EA1 2025[C3610000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
  3479 00000EA7 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
  3480 00000EAA 7730                <1> 	ja	short K23D		; NO, ALL DONE
  3481                              <1> 	;
  3482 00000EAC F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
  3483 00000EAF 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
  3484 00000EB1 2025[C6610000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
  3485 00000EB7 EB08                <1> 	jmp	short K23B		; CONTINUE
  3486                              <1> K23A:
  3487 00000EB9 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
  3488 00000EBB 2025[C4610000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
  3489                              <1> K23B:
  3490 00000EC1 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
  3491 00000EC3 A0[C6610000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
  3492 00000EC8 D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
  3493 00000ECA 0A05[C4610000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
  3494 00000ED0 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
  3495 00000ED2 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
  3496 00000ED4 0805[C3610000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
  3497 00000EDA 88E0                <1> 	mov	al, ah
  3498                              <1> K23D:
  3499 00000EDC 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
  3500 00000EDE 7536                <1> 	jne	short K26		; INTERRUPT RETURN
  3501                              <1> 	;	
  3502                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
  3503 00000EE0 A0[C7610000]        <1> 	mov	al, [ALT_INPUT]
  3504 00000EE5 B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  3505 00000EE7 8825[C7610000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
  3506 00000EED 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
  3507 00000EEF 7425                <1> 	je	short K26		; INTERRUPT_RETURN
  3508 00000EF1 E9B4020000          <1>         jmp     K61                     ; IT WASN'T, SO PUT IN BUFFER
  3509                              <1> 	;
  3510                              <1> K24:					; BREAK-TOGGLE
  3511 00000EF6 2025[C4610000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
  3512 00000EFC EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
  3513                              <1> 	;
  3514                              <1> 	;-----	TEST FOR HOLD STATE
  3515                              <1> 					; AL, AH = SCAN CODE
  3516                              <1> K25:					; NO-SHIFT-FOUND
  3517 00000EFE 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
  3518 00000F00 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
  3519 00000F02 F605[C4610000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
  3520 00000F09 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
  3521 00000F0B 3C45                <1> 	cmp	al, NUM_KEY
  3522 00000F0D 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
  3523 00000F0F 8025[C4610000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  3524                              <1> 	;
  3525                              <1> K26:
  3526 00000F16 8025[C6610000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3527                              <1> K26A:					; INTERRUPT-RETURN
  3528 00000F1D FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3529 00000F1E B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3530 00000F20 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3531                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
  3532 00000F22 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3533 00000F24 E8B8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3534                              <1> K27A:
  3535 00000F29 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3536 00000F2A 07                  <1> 	pop	es			; RESTORE REGISTERS
  3537 00000F2B 1F                  <1> 	pop	ds
  3538 00000F2C 5F                  <1> 	pop	edi
  3539 00000F2D 5E                  <1> 	pop	esi
  3540 00000F2E 5A                  <1> 	pop	edx
  3541 00000F2F 59                  <1> 	pop	ecx
  3542 00000F30 5B                  <1> 	pop	ebx
  3543 00000F31 58                  <1> 	pop	eax
  3544                              <1> 	;pop	ebp
  3545 00000F32 CF                  <1> 	iret				; RETURN
  3546                              <1> 
  3547                              <1> 	;-----	NOT IN	HOLD STATE
  3548                              <1> K28:					; NO-HOLD-STATE
  3549 00000F33 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
  3550 00000F35 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
  3551                              <1> 	;
  3552 00000F37 F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
  3553 00000F3A 740E                <1>         jz	short K28A		; IF NOT ALTERNATE
  3554                              <1>         ; 05/12/2021
  3555                              <1> 	;jz      K38
  3556                              <1> 	;
  3557 00000F3C F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
  3558 00000F3F 740E                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3559                              <1> 	; 28/02/2015
  3560 00000F41 F605[C4610000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
  3561 00000F48 7405                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3562                              <1> 	; 05/12/2021
  3563                              <1> 	;jnz	K38			; YES, THIS IS PHONY ALT STATE 
  3564                              <1>         ;				; DUE TO PRESSING SYSREQ	
  3565 00000F4A E9CD000000          <1> K28A:	jmp	K38
  3566                              <1> 	;
  3567                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
  3568                              <1> K29:					; TEST-RESET
  3569 00000F4F F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
  3570 00000F52 740B                <1> 	jz	short K31		; NO_RESET
  3571 00000F54 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
  3572 00000F56 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
  3573                              <1> 	;
  3574                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
  3575                              <1>  	; 26/08/2014
  3576                              <1> cpu_reset:
  3577                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
  3578                              <1> 	; Send FEh (system reset command) to the keyboard controller.
  3579 00000F58 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
  3580 00000F5A E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
  3581                              <1> khere:
  3582 00000F5C F4                  <1> 	hlt				; WAIT FOR 80286 RESET
  3583 00000F5D EBFD                <1> 	jmp 	short khere		; INSURE HALT
  3584                              <1> 
  3585                              <1> 	;
  3586                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
  3587                              <1> K31:					; NO-RESET
  3588 00000F5F 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
  3589 00000F61 7507                <1> 	jne	short K311		; NOT THERE
  3590 00000F63 B020                <1> 	mov	al, ' '			; SET SPACE CHAR
  3591 00000F65 E932020000          <1>         jmp     K57                     ; BUFFER_FILL
  3592                              <1> K311:
  3593 00000F6A 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
  3594 00000F6C 7509                <1> 	jne	short K312		; NOT THERE
  3595 00000F6E 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
  3596 00000F72 E925020000          <1>         jmp     K57                     ; BUFFER_FILL
  3597                              <1> K312:
  3598 00000F77 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
  3599 00000F79 7471                <1>         je	short K37B              ; GO PROCESS
  3600 00000F7B 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
  3601 00000F7D 746D                <1>         je	short K37B              ; GO PROCESS
  3602                              <1> 	;
  3603                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
  3604                              <1> K32:					; ALT-KEY-PAD
  3605 00000F7F BF[84600000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
  3606 00000F84 B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
  3607 00000F89 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
  3608 00000F8B 7523                <1> 	jne	short K33		; NO_ALT_KEYPAD
  3609 00000F8D F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
  3610                              <1>         ;jnz	short K37C		; YES, JUMP, NOT NUMPAD KEY
  3611                              <1> 	; 05/12/2021
  3612 00000F90 751C                <1> 	jnz	short K32B
  3613 00000F92 81EF[85600000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3614 00000F98 A0[C7610000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
  3615 00000F9D B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
  3616 00000F9F F6E4                <1> 	mul	ah
  3617 00000FA1 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
  3618 00000FA4 A2[C7610000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
  3619                              <1> K32A:
  3620 00000FA9 E968FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
  3621                              <1> K32B:
  3622                              <1> 	; 05/12/2021
  3623 00000FAE EB66                <1> 	jmp	K37C
  3624                              <1> 	;
  3625                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
  3626                              <1> K33:					; NO-ALT-KEYPAD
  3627 00000FB0 C605[C7610000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
  3628 00000FB7 B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
  3629 00000FBC F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
  3630 00000FBE 744F                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
  3631                              <1> 	;
  3632                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
  3633                              <1> K34:					; ALT-TOP-ROW
  3634 00000FC0 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
  3635 00000FC2 7228                <1> 	jb	short K37B		; MUST BE ESCAPE
  3636 00000FC4 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
  3637 00000FC6 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
  3638 00000FC8 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
  3639 00000FCB EB42                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3640                              <1> 	;
  3641                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
  3642                              <1> K35:					; ALT-FUNCTION
  3643 00000FCD 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
  3644 00000FCF 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
  3645 00000FD1 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
  3646 00000FD3 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
  3647 00000FD5 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
  3648 00000FD8 EB35                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3649                              <1> K35A:
  3650 00000FDA F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  3651 00000FDD 7425                <1> 	jz	short K37		; NO, JUMP
  3652 00000FDF 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  3653 00000FE1 7510                <1>         jne     short K35B              ; NOT THERE
  3654 00000FE3 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  3655 00000FE7 E9B0010000          <1> 	jmp	K57			; BUFFER FILL
  3656                              <1> K37B:
  3657 00000FEC B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  3658 00000FEE E9A9010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  3659                              <1> K35B:
  3660 00000FF3 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  3661 00000FF5 741F                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  3662 00000FF7 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  3663 00000FF9 75AE                <1> 	jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  3664                              <1>         ; 05/12/2021
  3665                              <1> 	;jne	K26
  3666 00000FFB 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  3667 00000FFF E998010000          <1> 	jmp	K57			; BUFFER FILL
  3668                              <1> K37:
  3669 00001004 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  3670 00001006 72E4                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  3671 00001008 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  3672 0000100A 779D                <1>         ja	short K32A		; IF SO, IGNORE
  3673                              <1> 	; 11/06/2022
  3674                              <1> 	;ja      K26
  3675 0000100C 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  3676                              <1> K37A:
  3677 0000100F B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  3678 00001011 E986010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  3679                              <1> K37C:
  3680 00001016 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  3681 00001018 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  3682 0000101A EBF3                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  3683                              <1> 	;
  3684                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  3685                              <1> K38:					; NOT-ALT-SHIFT
  3686                              <1> 					; BL STILL HAS SHIFT FLAGS
  3687 0000101C F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  3688 0000101F 7505                <1> 	jnz	short K38A		; YES, START PROCESSING	
  3689                              <1>         ;jz	K44                     ; NOT-CTL-SHIFT
  3690                              <1> 	; 05/12/2021
  3691 00001021 E9AB000000          <1> 	jmp	K44
  3692                              <1> 	;
  3693                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  3694                              <1> 	;-----	TEST FOR BREAK
  3695                              <1> K38A:
  3696 00001026 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  3697 00001028 7530                <1> 	jne	short K39		; JUMP, NO-BREAK
  3698 0000102A F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3699 0000102D 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  3700 0000102F F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3701 00001032 7426                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  3702                              <1> K38B:
  3703 00001034 8B1D[D0610000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3704 0000103A 891D[D4610000]      <1> 	mov	[BUFFER_TAIL], ebx
  3705 00001040 C605[C2610000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  3706                              <1> 	;
  3707                              <1> 	;-----	ENABLE KEYBOARD
  3708 00001047 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3709 00001049 E893010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3710                              <1> 	;
  3711                              <1> 	; CTRL+BREAK code here !!!
  3712                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  3713                              <1> 	; 17/10/2015	
  3714 0000104E E892190000          <1> 	call	ctrlbrk ; control+break subroutine
  3715                              <1> 	;
  3716                              <1> 	;sub	ax, ax			; PUT OUT DUMMY CHARACTER
  3717                              <1> 	; 05/12/2021
  3718 00001053 29C0                <1> 	sub	eax, eax
  3719 00001055 E942010000          <1> 	jmp     K57                     ; BUFFER_FILL
  3720                              <1> 	;
  3721                              <1> 	;-----	TEST FOR PAUSE
  3722                              <1> K39:					; NO_BREAK
  3723 0000105A F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3724 0000105D 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  3725 0000105F 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  3726 00001061 7533                <1> 	jne	short K41		; NO-PAUSE
  3727                              <1> K39P:
  3728 00001063 800D[C4610000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  3729                              <1> 	;
  3730                              <1> 	;-----	ENABLE KEYBOARD
  3731 0000106A B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3732 0000106C E870010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3733                              <1> K39A:
  3734 00001071 B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  3735 00001073 E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  3736                              <1> 	;
  3737                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  3738 00001075 803D[C0610000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  3739 0000107C 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  3740 0000107E 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  3741 00001082 A0[C1610000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  3742 00001087 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  3743                              <1> 	;
  3744                              <1> K40:					; PAUSE-LOOP
  3745 00001088 F605[C4610000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  3746 0000108F 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  3747                              <1> 	;
  3748 00001091 E98CFEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  3749                              <1>         ;
  3750                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  3751                              <1> K41:					; NO-PAUSE
  3752 00001096 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  3753 00001098 7513                <1> 	jne	short K42		; NOT-KEY-55
  3754 0000109A F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3755 0000109D 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  3756 0000109F F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3757 000010A2 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  3758                              <1> K41A:	
  3759 000010A4 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  3760 000010A8 E9EF000000          <1>         jmp     K57                     ; BUFFER_FILL
  3761                              <1> 	;
  3762                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  3763                              <1> K42:					; NOT-KEY-55
  3764 000010AD 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  3765 000010AF 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  3766 000010B1 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  3767 000010B3 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  3768 000010B5 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  3769 000010B8 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  3770 000010BA 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  3771 000010BE E9D9000000          <1> 	jmp	K57			; BUFFER FILL	
  3772                              <1> K42A:
  3773                              <1> 	;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3774 000010C3 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  3775                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  3776                              <1> 	;;jb	K56 ; 20/02/2015
  3777                              <1> 	;;jmp	K64 ; 20/02/2015
  3778                              <1> K42B:
  3779 000010C5 BB[B8600000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3780                              <1> 	;;jmp	K64
  3781                              <1> 	;jb	K56 ;; 20/02/2015	
  3782                              <1> 	; 05/12/2021
  3783 000010CA 7267                <1> 	jb	short K45F
  3784 000010CC E9B9000000          <1> 	jmp	K64	
  3785                              <1>         ;
  3786                              <1> 	;-----	NOT IN CONTROL SHIFT
  3787                              <1> K44:					; NOT-CTL-SHIFT
  3788 000010D1 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  3789 000010D3 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  3790 000010D5 F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  3791 000010D8 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  3792 000010DA F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  3793 000010DD 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  3794 000010DF EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3795                              <1> K44A:
  3796 000010E1 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  3797 000010E4 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3798                              <1> 	;
  3799                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  3800                              <1> K44B:
  3801 000010E6 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3802 000010E8 E8F4000000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3803 000010ED B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  3804 000010EF E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  3805                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  3806                              <1> 	;PUSH 	BP			; SAVE POINTER
  3807                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  3808                              <1> 	;POP	BP			; RESTORE POINTER
  3809 000010F1 8025[C6610000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  3810 000010F8 E925FEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  3811                              <1> 	;
  3812                              <1> 	;-----	HANDLE IN-CORE KEYS
  3813                              <1> K45:					; NOT-PRINT-SCREEN
  3814 000010FD 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  3815 000010FF 7734                <1> 	ja	short K46		; JUMP IF NOT
  3816 00001101 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  3817 00001103 7505                <1> 	jne	short K45A		; NO, JUMP
  3818 00001105 F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  3819 00001108 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  3820                              <1> K45A:
  3821 0000110A B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  3822 0000110F BF[8E600000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  3823 00001114 F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  3824                              <1> 		; 20/02/2015
  3825 00001116 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  3826                              <1> 	;
  3827 00001118 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  3828 0000111B 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  3829                              <1> K45B:
  3830 0000111D F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3831 00001120 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  3832                              <1> 					; NO, LOWERCASE
  3833                              <1> K45C:
  3834 00001122 BB[10610000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  3835 00001127 EB51                <1> 	jmp	short K56	
  3836                              <1> K45D:					; ALMOST-CAPS-STATE
  3837 00001129 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  3838 0000112C 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  3839                              <1> K45E:
  3840 0000112E BB[68610000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  3841 00001133 EB45                <1> K45F:	jmp	short K56
  3842                              <1> 	;
  3843                              <1> 	;-----	TEST FOR KEYS F1 - F10
  3844                              <1> K46:					; NOT IN-CORE AREA
  3845 00001135 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  3846                              <1> 	;ja	short K47		; JUMP IF NOT
  3847                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  3848 00001137 7635                <1> 	jna	short K53		
  3849                              <1> 	;
  3850                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  3851                              <1> K47:					; NOT F1 - F10
  3852 00001139 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  3853 0000113B 772D                <1> 	ja	short K52		; JUMP IF NOT
  3854                              <1> 	;
  3855                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  3856                              <1> K48:
  3857 0000113D 3C4A                <1> 	cmp	al, 74			; SPECIAL CASE FOR MINUS
  3858 0000113F 74ED                <1> 	je	short K45E		; GO TRANSLATE
  3859 00001141 3C4E                <1> 	cmp	al, 78			; SPECIAL CASE FOR PLUS
  3860 00001143 74E9                <1> 	je	short K45E		; GO TRANSLATE
  3861 00001145 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  3862 00001148 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  3863                              <1> 	;		
  3864 0000114A F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  3865 0000114D 7514                <1> 	jnz	short K50		; TEST FOR SURE
  3866 0000114F F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3867                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  3868 00001152 75DA                <1> 	jnz	short K45E
  3869                              <1> 	;
  3870                              <1> 	;-----	BASE CASE FOR KEYPAD
  3871                              <1> K49:					
  3872 00001154 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  3873 00001156 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  3874 00001158 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  3875 0000115A EB40                <1> 	jmp	short K57		; BUFFER FILL
  3876                              <1> K49A:
  3877 0000115C BB[10610000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  3878 00001161 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  3879                              <1> 	;
  3880                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  3881                              <1> K50:					; ALMOST-NUM-STATE
  3882 00001163 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  3883 00001166 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  3884 00001168 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  3885                              <1> 	;
  3886                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  3887                              <1> K52:					; NOT A NUMPAD KEY
  3888 0000116A 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  3889                              <1> 	;jne	short K53		; JUMP IF NOT
  3890                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  3891 0000116C 74AF                <1> 	je	short K45B		
  3892                              <1> 	;
  3893                              <1> 	;-----	MUST BE F11 OR F12 
  3894                              <1> K53:					; F1 - F10 COME HERE, TOO
  3895 0000116E F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  3896 00001171 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  3897                              <1> 		; 20/02/2015 
  3898 00001173 BB[68610000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  3899 00001178 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  3900                              <1> 	;
  3901                              <1> 	;-----	TRANSLATE THE CHARACTER
  3902                              <1> K56:					; TRANSLATE-CHAR
  3903 0000117A FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3904 0000117C D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  3905 0000117D F605[C6610000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3906 00001184 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3907 00001186 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  3908 00001188 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  3909                              <1> 	;
  3910                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  3911                              <1> K64:					; TRANSLATE-SCAN-ORGD
  3912 0000118A FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3913 0000118C D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  3914 0000118D 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  3915 0000118F B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  3916 00001191 F605[C6610000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3917 00001198 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3918 0000119A B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  3919                              <1> 	;
  3920                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  3921                              <1> K57:					; BUFFER_FILL
  3922 0000119C 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  3923 0000119E 7405                <1>         je	short K59		; YES, DO NOTHING WITH IT
  3924                              <1> 	; 05/12/2021
  3925                              <1> 	;je	K26			; YES, DO NOTHING WITH IT
  3926 000011A0 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  3927                              <1> 	; 05/12/2021
  3928 000011A3 7505                <1>         jne	short K61		; NEAR_INTERRUPT_RETURN
  3929                              <1> 	;je	K26			; INTERRUPT_RETURN
  3930                              <1> K59:					; NEAR_INTERRUPT_RETURN
  3931 000011A5 E96CFDFFFF          <1> 	jmp	K26			; INTERRUPT_RETURN
  3932                              <1> K61:					; NOT-CAPS-STATE
  3933 000011AA 8B1D[D4610000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  3934 000011B0 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  3935 000011B2 E8AEFAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  3936 000011B7 3B1D[D0610000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  3937 000011BD 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  3938 000011BF 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  3939 000011C2 891D[D4610000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  3940 000011C8 E949FDFFFF          <1> 	jmp	K26
  3941                              <1> 	;;cli				; TURN OFF INTERRUPTS
  3942                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  3943                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  3944                              <1> 	;mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3945                              <1> 	;call	SHIP_IT			; EXECUTE ENABLE
  3946                              <1> 	;mov	ax, 9102h		; MOVE IN POST CODE & TYPE
  3947                              <1> 	;int	15h			; PERFORM OTHER FUNCTION
  3948                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3949                              <1> 	;jmp	K27A			; INTERRUPT_RETURN
  3950                              <1> 	;;jmp   K27                    
  3951                              <1> 	;
  3952                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  3953                              <1> K62:
  3954 000011CD B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  3955 000011CF E620                <1> 	out	INTA00, al
  3956 000011D1 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  3957 000011D5 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  3958 000011D7 E883010000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  3959 000011DC E941FDFFFF          <1> 	jmp     K27			; EXIT   
  3960                              <1> 
  3961                              <1> SHIP_IT:
  3962                              <1> 	;---------------------------------------------------------------------------------
  3963                              <1> 	; SHIP_IT
  3964                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3965                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  3966                              <1> 	;---------------------------------------------------------------------------------
  3967                              <1> 	;
  3968                              <1> 	;push	ax			; SAVE DATA TO SEND
  3969                              <1> 	; 05/12/2021
  3970 000011E1 50                  <1> 	push	eax
  3971                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  3972 000011E2 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  3973                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  3974 000011E3 B900000100          <1> 	mov	ecx, 10000h			
  3975                              <1> S10:
  3976 000011E8 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  3977 000011EA A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  3978 000011EC E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  3979                              <1> 
  3980                              <1> 	;pop	ax			; GET DATA TO SEND
  3981                              <1> 	; 05/12/2021
  3982 000011EE 58                  <1> 	pop	eax
  3983 000011EF E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  3984 000011F1 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3985 000011F2 C3                  <1> 	retn				; RETURN TO CALLER
  3986                              <1> 
  3987                              <1> SND_DATA:
  3988                              <1> 	; ---------------------------------------------------------------------------------
  3989                              <1> 	; SND_DATA
  3990                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3991                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  3992                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  3993                              <1> 	; ---------------------------------------------------------------------------------
  3994                              <1> 	;
  3995                              <1> 	;push	ax			; SAVE REGISTERS
  3996                              <1> 	;push	bx
  3997                              <1> 	; 05/12/2021
  3998 000011F3 50                  <1> 	push	eax
  3999 000011F4 53                  <1> 	push	ebx
  4000 000011F5 51                  <1> 	push	ecx
  4001 000011F6 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  4002 000011F8 B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  4003                              <1> SD0:
  4004 000011FA FA                  <1> 	cli				; DISABLE INTERRUPTS
  4005 000011FB 8025[C5610000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  4006                              <1> 	;
  4007                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  4008 00001202 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  4009                              <1> SD5:
  4010 00001207 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  4011 00001209 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  4012 0000120B E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  4013                              <1> 	;
  4014 0000120D 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  4015 0000120F E660                <1> 	out	PORT_A, al		; SEND BYTE
  4016 00001211 FB                  <1> 	sti				; ENABLE INTERRUPTS
  4017                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  4018 00001212 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  4019                              <1> SD1:
  4020 00001217 F605[C5610000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  4021 0000121E 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  4022 00001220 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  4023                              <1> SD2:
  4024 00001222 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  4025 00001224 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  4026 00001226 800D[C5610000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  4027 0000122D EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  4028                              <1> SD3:
  4029 0000122F F605[C5610000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  4030 00001236 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  4031                              <1> SD4:	
  4032 00001238 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  4033                              <1> 	;pop	bx
  4034                              <1> 	;pop	ax
  4035                              <1> 	; 05/12/2021
  4036 00001239 5B                  <1> 	pop	ebx
  4037 0000123A 58                  <1> 	pop	eax
  4038 0000123B C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  4039                              <1> 
  4040                              <1> SND_LED:
  4041                              <1> 	; ---------------------------------------------------------------------------------
  4042                              <1> 	; SND_LED
  4043                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  4044                              <1> 	;
  4045                              <1> 	;----------------------------------------------------------------------------------
  4046                              <1> 	;
  4047 0000123C FA                  <1> 	cli				; TURN OFF INTERRUPTS
  4048 0000123D F605[C5610000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  4049 00001244 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  4050                              <1> 	;
  4051 00001246 800D[C5610000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  4052 0000124D B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  4053 0000124F E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  4054 00001251 EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  4055                              <1> SND_LED1:
  4056 00001253 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  4057 00001254 F605[C5610000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  4058 0000125B 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  4059                              <1> 	;
  4060 0000125D 800D[C5610000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  4061                              <1> SL0:
  4062 00001264 B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  4063 00001266 E888FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  4064 0000126B FA                  <1> 	cli
  4065 0000126C E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  4066 00001271 8025[C5610000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  4067 00001278 0805[C5610000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  4068 0000127E F605[C5610000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  4069 00001285 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  4070                              <1> 	;
  4071 00001287 E867FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  4072 0000128C FA                  <1> 	cli				; TURN OFF INTERRUPTS
  4073 0000128D F605[C5610000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  4074 00001294 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  4075                              <1> SL2:
  4076 00001296 B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  4077 00001298 E856FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  4078 0000129D FA                  <1> 	cli				; TURN OFF INTERRUPTS
  4079                              <1> SL3:
  4080 0000129E 8025[C5610000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  4081                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  4082 000012A5 FB                  <1> 	sti				; ENABLE INTERRUPTS
  4083 000012A6 C3                  <1> 	retn				; RETURN TO CALLER
  4084                              <1> 
  4085                              <1> MAKE_LED:
  4086                              <1> 	;---------------------------------------------------------------------------------
  4087                              <1> 	; MAKE_LED
  4088                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  4089                              <1> 	;	THE MODE INDICATORS.
  4090                              <1> 	;---------------------------------------------------------------------------------
  4091                              <1> 	;
  4092                              <1> 	;push 	cx			; SAVE CX
  4093 000012A7 A0[C3610000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  4094 000012AC 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  4095                              <1> 	;mov	cl, 4			; SHIFT COUNT
  4096                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  4097 000012AE C0C004              <1> 	rol	al, 4 ; 20/02/2015
  4098 000012B1 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  4099                              <1> 	;pop	cx
  4100 000012B3 C3                  <1> 	retn				; RETURN TO CALLER
  4101                              <1> 
  4102                              <1> ; % include 'kybdata.inc'   ; KEYBOARD DATA ; 11/03/2015
  4103                              <1> 
  4104                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  4105                                  
  4106                                  %include 'video.s' ; 07/03/2015
  4107                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  4108                              <1> ; (re-write kernel for test by using previous version without a major defect)
  4109                              <1> ; ****************************************************************************
  4110                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - VIDEO.INC
  4111                              <1> ; Last Modification: 14/06/2022
  4112                              <1> ;		  (Video Data is in 'VIDATA.INC')
  4113                              <1> ;
  4114                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
  4115                              <1> 
  4116                              <1> ; 27/02/2022
  4117                              <1> ; 23/02/2022
  4118                              <1> ; 21/02/2022 (Retro UNIX 386 v1.2)
  4119                              <1> ; 07/02/2022 (Retro UNIX 386 V1&v1.1)
  4120                              <1> ; 02/02/2022 (simplified scroll up)
  4121                              <1> ; 16/01/2016
  4122                              <1> ; 30/06/2015
  4123                              <1> ; 27/06/2015
  4124                              <1> ; 11/03/2015
  4125                              <1> ; 02/09/2014
  4126                              <1> ; 30/08/2014
  4127                              <1> ; VIDEO FUNCTIONS
  4128                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  4129                              <1> 
  4130                              <1> write_tty:
  4131                              <1> 	; 02/02/2022
  4132                              <1> 	; 13/08/2015
  4133                              <1> 	; 02/09/2014
  4134                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4135                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  4136                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  4137                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  4138                              <1> 	;
  4139                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  4140                              <1> 	;	   AL = Character to be written
  4141                              <1> 	;	   EBX = Video Page (0 to 7)
  4142                              <1> 	;	   (BH = 0 --> Video Mode 3)
  4143                              <1> 
  4144                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  4145                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  4146                              <1> 
  4147                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  4148                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  4149                              <1> ;
  4150                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  4151                              <1> ;
  4152                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  4153                              <1> ;										:
  4154                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  4155                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  4156                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  4157                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  4158                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  4159                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  4160                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  4161                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  4162                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  4163                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  4164                              <1> ;   THE 0 COLOR IS USED.							:
  4165                              <1> ;   ENTRY --									:
  4166                              <1> ;     (AH) = CURRENT CRT MODE							:
  4167                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  4168                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  4169                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  4170                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  4171                              <1> ;   EXIT -- 									:
  4172                              <1> ;     ALL REGISTERS SAVED							:
  4173                              <1> ;--------------------------------------------------------------------------------
  4174                              <1> 
  4175 000012B4 FA                  <1> 	cli
  4176                              <1> 	;
  4177                              <1> 	; READ CURSOR (04/12/2013)
  4178                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  4179 000012B5 08FF                <1> 	or	bh, bh
  4180                              <1> 	;jnz	beeper
  4181                              <1> 	; 02/02/2022
  4182 000012B7 7405                <1> 	jz	short u14
  4183 000012B9 E992000000          <1> 	jmp	beeper
  4184                              <1> u14:
  4185                              <1> 	; 02/02/2022
  4186                              <1> 	;; 01/09/2014
  4187                              <1> 	;cmp	byte [CRT_MODE], 3
  4188                              <1> 	;je	short m3
  4189                              <1> 	;;
  4190                              <1> 	;call	set_mode
  4191                              <1> m3:
  4192 000012BE 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  4193                              <1> 	;shl	si, 1
  4194                              <1> 	; 02/02/2022
  4195 000012C0 D1E6                <1> 	shl	esi, 1
  4196 000012C2 81C6[86670000]      <1> 	add	esi, cursor_posn
  4197 000012C8 668B16              <1> 	mov	dx, [esi]
  4198                              <1> 	;
  4199                              <1> 	; dx now has the current cursor position
  4200                              <1> 	;
  4201 000012CB 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  4202 000012CD 7647                <1> 	jbe	short u8
  4203                              <1> 	;
  4204                              <1> 	; write the char to the screen
  4205                              <1> u0:	
  4206                              <1> 	; ah = attribute/color
  4207                              <1> 	; al = character
  4208                              <1> 	; bl = video page number (0 to 7)
  4209                              <1> 	; bh = 0
  4210                              <1> 	;
  4211 000012CF E8D2010000          <1> 	call	write_c_current
  4212                              <1> 	;
  4213                              <1> 	; position the cursor for next char
  4214 000012D4 FEC2                <1> 	inc	dl		; next column
  4215                              <1> 	;cmp	dl, [CRT_COLS]
  4216 000012D6 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  4217                              <1>         ;jne	set_cpos
  4218                              <1> 	; 02/02/2022
  4219 000012D9 7405                <1> 	je	short u13
  4220 000012DB E9DE000000          <1> 	jmp	set_cpos
  4221                              <1> u13:
  4222 000012E0 B200                <1> 	mov	dl, 0		; column = 0
  4223                              <1> u10:				; (line feed found)
  4224 000012E2 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  4225 000012E5 7228                <1> 	jb 	short u6
  4226                              <1> 	;
  4227                              <1> 	; scroll required
  4228                              <1> u1:	
  4229                              <1> 	; SET CURSOR POSITION (04/12/2013)
  4230 000012E7 E8D2000000          <1> 	call	set_cpos
  4231                              <1> 	;
  4232                              <1> 	; determine value to fill with during scroll
  4233                              <1> u2:
  4234                              <1> 	; READ_AC_CURRENT		:
  4235                              <1> 	;   THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER
  4236                              <1> 	;    AT THE CURRENT CURSOR POSITION
  4237                              <1> 	;
  4238                              <1> 	; INPUT				
  4239                              <1> 	;	(AH) = CURRENT CRT MODE
  4240                              <1> 	;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )
  4241                              <1> 	;	(DS) = DATA SEGMENT
  4242                              <1> 	;	(ES) = REGEN SEGMENT
  4243                              <1> 	; OUTPUT			
  4244                              <1> 	;	(AL) = CHARACTER READ
  4245                              <1> 	;	(AH) = ATTRIBUTE READ
  4246                              <1> 	;
  4247                              <1> 	; mov	ah, [CRT_MODE] ; move current mode into ah
  4248                              <1> 	;
  4249                              <1> 	; bl = video page number
  4250                              <1> 	;
  4251 000012EC E829010000          <1> 	call	find_position	; get regen location and port address
  4252                              <1> 	; dx = status port
  4253                              <1> 	; esi = cursor location/address
  4254                              <1> p11:
  4255 000012F1 FB                  <1> 	sti			; enable interrupts
  4256 000012F2 90                  <1> 	nop			; allow for small interupts window
  4257 000012F3 FA                  <1> 	cli			; blocks interrupts for single loop
  4258 000012F4 EC                  <1> 	in	al, dx		; get status from adapter
  4259 000012F5 A801                <1> 	test	al, RHRZ	; is horizontal retrace low
  4260 000012F7 75F8                <1> 	jnz	short p11	; wait until it is
  4261                              <1> p12:				; now wait for either retrace high
  4262 000012F9 EC                  <1> 	in	al, dx		; get status
  4263 000012FA A809                <1> 	test	al, RVRT+RHRZ	; is horizontal or vertical retrace high
  4264 000012FC 74FB                <1> 	jz	short p12	; wait until either is active	
  4265                              <1> p13:
  4266 000012FE 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
  4267 00001304 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
  4268                              <1> 	;
  4269                              <1> 	; al = character, ah = attribute
  4270                              <1> 	;
  4271 00001307 FB                  <1> 	sti
  4272                              <1> 	; bl = video page number 	
  4273                              <1> u3:
  4274                              <1> 	;;mov	ax, 0601h 	; scroll one line
  4275                              <1> 	;;sub	cx, cx		; upper left corner
  4276                              <1> 	;;mov	dh, 25-1 	; lower right row
  4277                              <1> 	;;;mov	dl, [CRT_COLS]
  4278                              <1> 	;mov	dl, 80		; lower right column	
  4279                              <1> 	;;dec	dl
  4280                              <1> 	;;mov	dl, 79
  4281                              <1> 
  4282                              <1> 	;;call	scroll_up	; 04/12/2013
  4283                              <1> 	;;; 11/03/2015
  4284                              <1> 	; 02/09/2014
  4285                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  4286                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  4287                              <1> 	; 11/03/2015
  4288                              <1> 	;sub	cx, cx
  4289                              <1> 	;mov	dx, 184Fh ; dl= 79 (column), dh = 24 (row)
  4290                              <1> 	;
  4291                              <1> 	; 02/02/2022 (simplied scroll up)
  4292                              <1> 	; ((retro unix 8086 v1 'scroll_up' in 'u9.s'))
  4293                              <1> 	;
  4294 00001308 B001                <1> 	mov	al, 1		; scroll 1 line up
  4295                              <1> 		; ah = attribute
  4296 0000130A E935010000          <1> 	jmp	scroll_up
  4297                              <1> ;u4:
  4298                              <1> 	;;int	10h		; video-call return
  4299                              <1> 				; scroll up the screen
  4300                              <1> 				; tty return
  4301                              <1> ;u5:
  4302                              <1> 	;retn			; return to the caller
  4303                              <1> 
  4304                              <1> u6:				; set-cursor-inc
  4305 0000130F FEC6                <1> 	inc	dh		; next row
  4306                              <1> 				; set cursor
  4307                              <1> ;u7:					
  4308                              <1> 	;;mov	ah, 02h
  4309                              <1> 	;;jmp	short u4 	; establish the new cursor
  4310                              <1> 	;call	set_cpos
  4311                              <1> 	;jmp 	short u5
  4312 00001311 E9A8000000          <1> 	jmp     set_cpos
  4313                              <1> 
  4314                              <1> 	; check for control characters
  4315                              <1> u8:
  4316 00001316 7434                <1> 	je	short u9
  4317 00001318 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  4318 0000131A 74C6                <1> 	je	short u10
  4319 0000131C 3C07                <1> 	cmp	al, 07h 	; is it a bell
  4320 0000131E 7430                <1> 	je	short u11
  4321 00001320 3C08                <1> 	cmp	al, 08h		; is it a backspace
  4322                              <1> 	;jne	short u0
  4323 00001322 7420                <1> 	je	short bs	; 12/12/2013
  4324                              <1> 	; 12/12/2013 (tab stop)
  4325 00001324 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  4326 00001326 75A7                <1> 	jne	short u0
  4327 00001328 88D0                <1> 	mov	al, dl
  4328 0000132A 6698                <1> 	cbw
  4329 0000132C B108                <1> 	mov	cl, 8
  4330 0000132E F6F1                <1> 	div	cl
  4331 00001330 28E1                <1> 	sub	cl, ah
  4332                              <1> ts:
  4333                              <1> 	; 02/09/2014
  4334                              <1> 	; 01/09/2014
  4335 00001332 B020                <1> 	mov	al, 20h
  4336                              <1> tsloop:
  4337                              <1> 	;push	cx
  4338                              <1> 	;push	ax
  4339                              <1> 	; 02/02/2022
  4340 00001334 51                  <1> 	push	ecx
  4341 00001335 50                  <1> 	push	eax
  4342 00001336 30FF                <1> 	xor 	bh, bh
  4343                              <1> 	;mov	bl, [active_page]
  4344 00001338 E881FFFFFF          <1> 	call	m3
  4345                              <1> 	; 02/02/2022
  4346 0000133D 58                  <1> 	pop	eax
  4347 0000133E 59                  <1>  	pop	ecx
  4348                              <1> 	;pop	ax  ; ah = attribute/color
  4349                              <1> 	;pop	cx
  4350 0000133F FEC9                <1> 	dec	cl
  4351 00001341 75F1                <1> 	jnz	short tsloop
  4352 00001343 C3                  <1> 	retn
  4353                              <1> bs:	
  4354                              <1> 	; back space found
  4355 00001344 08D2                <1> 	or	dl, dl 		; is it already at start of line
  4356                              <1> 	;je	short u7 	; set_cursor
  4357 00001346 7476                <1> 	jz	short set_cpos
  4358                              <1> 	;dec	dx     		; no -- just move it back
  4359                              <1> 	; 02/02/2022
  4360 00001348 FECA                <1> 	dec	dl
  4361                              <1> 	;jmp	short u7
  4362 0000134A EB72                <1> 	jmp	short set_cpos
  4363                              <1> 
  4364                              <1> 	; carriage return found
  4365                              <1> u9:
  4366 0000134C B200                <1> 	mov	dl, 0 		; move to first column
  4367                              <1> 	;jmp	short u7
  4368 0000134E EB6E                <1> 	jmp	short set_cpos
  4369                              <1> 
  4370                              <1> 	; line feed found
  4371                              <1> ;u10:
  4372                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  4373                              <1> ;	jne	short u6 	; no, just set the cursor
  4374                              <1> ;       jmp     u1              ; yes, scroll the screen
  4375                              <1> 
  4376                              <1> beeper: 
  4377                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4378                              <1> 	; 18/01/2014
  4379                              <1> 	; 03/12/2013
  4380                              <1> 	; bell found
  4381                              <1> u11:
  4382 00001350 FB                  <1> 	sti
  4383 00001351 3A1D[96670000]      <1> 	cmp	bl, [active_page]
  4384 00001357 7551                <1> 	jne	short u12	; Do not sound the beep 
  4385                              <1> 				; if it is not written on the active page
  4386 00001359 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  4387 0000135D B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  4388                              <1> 	;call	beep		; sound the pod bell
  4389                              <1> 	;jmp	short u5 	; tty_return
  4390                              <1> 	;retn
  4391                              <1> 	
  4392                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  4393                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  4394                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  4395                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  4396                              <1> 
  4397                              <1> beep:
  4398                              <1> 	; 07/02/2015
  4399                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4400                              <1> 	; 18/01/2014
  4401                              <1> 	; 03/12/2013
  4402                              <1> 	;
  4403                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  4404                              <1> 	;
  4405                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  4406                              <1> 	;
  4407                              <1> 	; ENTRY:
  4408                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  4409                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  4410                              <1> 	; EXIT:			:
  4411                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  4412                              <1> 
  4413 0000135F 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  4414 00001360 FA                  <1> 	cli			; block interrupts during update
  4415 00001361 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  4416 00001363 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  4417 00001365 EB00                <1> 	jmp	$+2		; I/O delay
  4418 00001367 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  4419 00001369 E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  4420 0000136B EB00                <1> 	jmp	$+2		; I/O delay
  4421 0000136D 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  4422 0000136F E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  4423 00001371 E461                <1> 	in	al, PORT_B	; get current setting of port
  4424 00001373 88C4                <1> 	mov	ah, al		; save that setting
  4425 00001375 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  4426 00001377 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  4427                              <1> 	;popf	; 18/01/2014
  4428 00001379 FB                  <1> 	sti
  4429                              <1> g7:				; 1/64 second per count (bl)
  4430 0000137A B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  4431 0000137F E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  4432 00001384 FECB                <1> 	dec	bl		; (bl) length count expired?
  4433 00001386 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  4434                              <1> 	;
  4435                              <1> 	;pushf			; save interrupt status
  4436 00001388 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  4437 00001389 E461                <1> 	in	al, PORT_B	; get current port value
  4438                              <1>         ;or	al, not (GATE2+SPK2) ; isolate current speaker bits in case
  4439 0000138B 0CFC                <1>         or      al, ~(GATE2+SPK2)
  4440 0000138D 20C4                <1>         and	ah, al		; someone turned them off during beep
  4441 0000138F 88E0                <1> 	mov	al, ah		; recover value of port
  4442                              <1>         ;or	al, not (GATE2+SPK2) ; force speaker data off
  4443 00001391 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  4444 00001393 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  4445                              <1> 	;popf			; restore interrupt flag state
  4446 00001395 FB                  <1> 	sti
  4447 00001396 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  4448 0000139B E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  4449                              <1> 	;pushf			; save interrupt status
  4450 000013A0 FA                  <1> 	cli			; block interrupts during update
  4451 000013A1 E461                <1> 	in	al, PORT_B	; get current port value in case	
  4452 000013A3 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  4453 000013A5 08E0                <1> 	or	al, ah		; recover value of port_b
  4454 000013A7 E661                <1> 	out	PORT_B, al	; restore speaker status
  4455 000013A9 9D                  <1> 	popf			; restore interrupt flag state
  4456                              <1> u12:	
  4457 000013AA C3                  <1> 	retn
  4458                              <1> 
  4459                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  4460                              <1> 
  4461                              <1> WAITF:
  4462                              <1> waitf:
  4463                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4464                              <1> 	; 03/12/2013
  4465                              <1> 	;
  4466                              <1> ;	push	ax		; save work register (ah)	
  4467                              <1> ;waitf1:
  4468                              <1> 				; use timer 1 output bits
  4469                              <1> ;	in	al, PORT_B	; read current counter output status
  4470                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  4471                              <1> ;	cmp	al, ah		; did it just change
  4472                              <1> ;	je	short waitf1	; wait for a change in output line
  4473                              <1> ;	;
  4474                              <1> ;	mov	ah, al		; save new lflag state
  4475                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  4476                              <1> ;	;
  4477                              <1> ;	pop	ax		; restore (ah)
  4478                              <1> ;	retn			; return (cx)=0
  4479                              <1> 
  4480                              <1> ; 02/02/2022
  4481                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  4482                              <1> ; 17/12/2014 (dsectrm2.s)
  4483                              <1> ; WAITF
  4484                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  4485                              <1> ;
  4486                              <1> ;---WAITF-----------------------------------------------------------------------
  4487                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  4488                              <1> ; ENTRY:
  4489                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  4490                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  4491                              <1> ; EXIT:
  4492                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  4493                              <1> ;	(CX) = 0	
  4494                              <1> ;-------------------------------------------------------------------------------
  4495                              <1> 
  4496                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  4497                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  4498                              <1> 
  4499                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  4500 000013AB 50                  <1> 	push	eax ; 02/02/2022	; SAVE WORK REGISTER (AH)
  4501                              <1> 	;push	ax
  4502                              <1> 	; 16/12/2014
  4503                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  4504 000013AC D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  4505                              <1> ;17/12/2014	
  4506                              <1> ;WAITF1:
  4507                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  4508                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  4509                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  4510                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  4511                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  4512                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  4513                              <1> 	;
  4514                              <1> 	; 17/12/2014
  4515                              <1> 	;
  4516                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  4517                              <1> 	;
  4518                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  4519                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  4520                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  4521                              <1> WR_STATE_0:
  4522 000013AE E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4523 000013B0 A810                <1> 	TEST	AL,010H
  4524 000013B2 74FA                <1> 	JZ	SHORT WR_STATE_0
  4525                              <1> WR_STATE_1:
  4526 000013B4 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4527 000013B6 A810                <1> 	TEST	AL,010H
  4528 000013B8 75FA                <1> 	JNZ	SHORT WR_STATE_1
  4529 000013BA E2F2                <1>         LOOP    WR_STATE_0
  4530                              <1> 	;
  4531                              <1> 	;pop	ax
  4532 000013BC 58                  <1> 	pop	eax ; 02/02/2022	; RESTORE (AH)
  4533 000013BD C3                  <1> 	RETn				; (CX) = 0
  4534                              <1> 
  4535                              <1> set_cpos:
  4536                              <1> 	; 14/06/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.2)
  4537                              <1> 	; 27/02/2022
  4538                              <1> 	; 23/02/2022
  4539                              <1> 	; 02/02/2022
  4540                              <1> 	; 27/06/2015
  4541                              <1> 	; 01/09/2014
  4542                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4543                              <1> 	;
  4544                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  4545                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  4546                              <1> 	;
  4547                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4548                              <1> 	;
  4549                              <1> 	; SET_CPOS
  4550                              <1> 	;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  4551                              <1> 	;	NEW X-Y VALUES PASSED
  4552                              <1> 	; INPUT
  4553                              <1> 	;	DX - ROW,COLUMN OF NEW CURSOR
  4554                              <1> 	;	BH - DISPLAY PAGE OF CURSOR
  4555                              <1> 	; OUTPUT
  4556                              <1> 	;	CURSOR IS SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  4557                              <1> 	;
  4558 000013BE 0FB6C3              <1>         movzx   eax, bl	; BL = video page number ; 27/06/2015 (movzx)
  4559 000013C1 D0E0                <1>         shl     al, 1   ; word offset
  4560 000013C3 BE[86670000]        <1> 	mov	esi, cursor_posn
  4561 000013C8 01C6                <1>         add     esi, eax
  4562 000013CA 668916              <1> 	mov	[esi], dx ; save the pointer
  4563 000013CD 381D[96670000]      <1> 	cmp	[active_page], bl
  4564 000013D3 7531                <1> 	jne	short m17
  4565                              <1> 
  4566                              <1> 	; 14/06/2022
  4567                              <1> 	;cli	; 27/02/2022
  4568                              <1> 
  4569                              <1> 	;call	m18	; CURSOR SET
  4570                              <1> ;m17:			; SET_CPOS_RETURN
  4571                              <1> 	; 01/09/2014
  4572                              <1> ;	retn
  4573                              <1> 		; DX = row/column
  4574                              <1> m18:
  4575 000013D5 E832000000          <1> 	call	position ; determine location in regen buffer	
  4576                              <1> 	;mov	cx, [CRT_START]
  4577                              <1> 	; 23/02/2022
  4578 000013DA 0FB70D[84670000]    <1> 	movzx	ecx, word [CRT_START]
  4579 000013E1 01C1                <1> 	add	ecx, eax
  4580                              <1> 	;add	cx, ax  ; add char position in regen buffer
  4581                              <1> 			; to the start address (offset) for this page
  4582                              <1> 	;shr	cx, 1	; divide by 2 for char only count
  4583                              <1> 	; 23/02/2022
  4584 000013E3 D1E9                <1> 	shr	ecx, 1
  4585 000013E5 B40E                <1> 	mov	ah, 14	; register number for cursor
  4586                              <1> 	
  4587                              <1> 	; 14/06/2022
  4588                              <1> 	;call	m16	; output value to the 6845
  4589                              <1> 	;sti	; 27/02/2022
  4590                              <1> 	;retn
  4591                              <1> 
  4592                              <1> 	; 14/06/2022
  4593                              <1> 	; 27/02/2022
  4594                              <1> 	; 02/02/2022
  4595                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  4596                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  4597                              <1> m16:
  4598                              <1> 	; 14/06/2022
  4599 000013E7 FA                  <1> 	cli	; 27/02/2022
  4600                              <1> 	;mov	dx, [addr_6845] ; address register
  4601 000013E8 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  4602 000013EC 88E0                <1> 	mov	al, ah	; get value
  4603 000013EE EE                  <1> 	out	dx, al	; register set
  4604                              <1> 	;inc	dx	; data register
  4605                              <1> 	; 02/02/2022
  4606 000013EF FEC2                <1> 	inc	dl
  4607 000013F1 EB00                <1> 	jmp	$+2	; i/o delay
  4608 000013F3 88E8                <1> 	mov	al, ch	; data
  4609 000013F5 EE                  <1> 	out	dx, al	
  4610                              <1> 	;dec	dx
  4611                              <1> 	; 02/02/2022	
  4612 000013F6 FECA                <1> 	dec	dl
  4613 000013F8 88E0                <1> 	mov	al, ah
  4614 000013FA FEC0                <1> 	inc	al	; point to other data register
  4615 000013FC EE                  <1> 	out	dx, al	; set for second register
  4616                              <1> 	;inc	dx
  4617                              <1> 	; 02/02/2022
  4618 000013FD FEC2                <1> 	inc	dl
  4619 000013FF EB00                <1> 	jmp	$+2	; i/o delay
  4620 00001401 88C8                <1> 	mov	al, cl	; second data value
  4621 00001403 EE                  <1> 	out	dx, al
  4622                              <1> 	; 14/06/2022
  4623 00001404 FB                  <1> 	sti	; 27/02/2022
  4624                              <1> ;m17:
  4625 00001405 C3                  <1> 	retn
  4626                              <1> m17:
  4627                              <1> 	; 14/06/2022
  4628                              <1> 	; ('write_tty' must not return to 'putc' with cf)
  4629 00001406 F8                  <1> 	clc
  4630 00001407 C3                  <1> 	retn
  4631                              <1> 
  4632                              <1> set_ctype:
  4633                              <1> 	; 07/02/2022
  4634                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4635                              <1> 	;
  4636                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4637                              <1> 
  4638                              <1> ;	CH) = BITS 4-0 = START LINE FOR CURSOR
  4639                              <1> ;       ** HARDWARE WILL ALWAYS CAUSE BLINK
  4640                              <1> ;       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  4641                              <1> ;          OR NO CURSOR AT ALL
  4642                              <1> ;	(CL) = BITS 4-0 = END LINE FOR CURSOR
  4643                              <1> 
  4644                              <1> ;------------------------------------------------
  4645                              <1> ; SET_CTYPE
  4646                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  4647                              <1> ; INPUT
  4648                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  4649                              <1> ; OUTPUT	
  4650                              <1> ;	NONE
  4651                              <1> ;------------------------------------------------
  4652                              <1> 
  4653 00001408 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  4654                              <1> 	;mov	[CURSOR_MODE], cx ; save in data area
  4655                              <1> 	;call	m16	; output cx register
  4656                              <1> 	;retn
  4657                              <1> 	; 07/02/2022
  4658 0000140A EBDB                <1> 	jmp	short m16
  4659                              <1> 
  4660                              <1> position:
  4661                              <1> 	; 23/02/2022
  4662                              <1> 	; 02/02/2022
  4663                              <1> 	; 27/06/2015
  4664                              <1> 	; 02/09/2014
  4665                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4666                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  4667                              <1> 	;
  4668                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4669                              <1> 	;
  4670                              <1> 	; POSITION
  4671                              <1> 	;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  4672                              <1> 	;	OF A CHARACTER IN THE ALPHA MODE
  4673                              <1> 	; INPUT
  4674                              <1> 	;	AX = ROW, COLUMN POSITION
  4675                              <1> 	; OUTPUT
  4676                              <1> 	;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  4677                              <1> 
  4678                              <1> 		; DX = ROW, COLUMN POSITION
  4679                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
  4680 0000140C 31C0                <1> 	xor	eax, eax ; 02/09/2014
  4681 0000140E B050                <1> 	mov	al, 80	; determine bytes to row	
  4682 00001410 F6E6                <1> 	mul	dh	; row value
  4683                              <1> 	;xor	dh, dh	; 0
  4684                              <1> 	;add	ax, dx	; add column value to the result
  4685                              <1> 	; 23/02/2022
  4686 00001412 00D0                <1> 	add	al, dl
  4687 00001414 80D400              <1> 	adc	ah, 0	
  4688                              <1> 	;shl	ax, 1	; * 2 for attribute bytes
  4689                              <1> 	; 02/02/2022
  4690 00001417 D1E0                <1> 	shl	eax, 1
  4691                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  4692 00001419 C3                  <1> 	retn
  4693                              <1> 
  4694                              <1> find_position:
  4695                              <1> 	; 02/02/2022
  4696                              <1> 	; 27/06/2015
  4697                              <1> 	; 07/09/2014
  4698                              <1> 	; 02/09/2014
  4699                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4700                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4701 0000141A 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
  4702 0000141D 89CE                <1> 	mov	esi, ecx
  4703                              <1> 	;shl	si, 1
  4704                              <1> 	; 02/02/2022
  4705 0000141F D1E6                <1> 	shl	esi, 1
  4706 00001421 668B96[86670000]    <1> 	mov	dx, [esi+cursor_posn]
  4707 00001428 7409                <1> 	jz	short p21
  4708                              <1> 	;xor	si, si
  4709                              <1> 	; 02/02/2022
  4710 0000142A 31F6                <1> 	xor	esi, esi
  4711                              <1> p20:
  4712                              <1> 	;add	si, [CRT_LEN]
  4713 0000142C 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
  4714 00001431 E2F9                <1> 	loop	p20
  4715                              <1> p21:
  4716 00001433 6621D2              <1> 	and	dx, dx
  4717 00001436 7407                <1> 	jz	short p22
  4718 00001438 E8CFFFFFFF          <1> 	call 	position ; determine location in regen in page
  4719 0000143D 01C6                <1> 	add	esi, eax ; add location to start of regen page
  4720                              <1> p22:	
  4721                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  4722                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  4723                              <1> 	;add	dx, 6	; point at status port
  4724 0000143F 66BADA03            <1> 	mov	dx, 03DAh ; status port
  4725                              <1> 	; cx = 0
  4726 00001443 C3                  <1> 	retn
  4727                              <1> 
  4728                              <1> scroll_up:
  4729                              <1> 	; 02/02/2022 (simplified scroll up)
  4730                              <1> 	;	((retro unix 8086 v1 'scroll_up' in 'u9.s'))
  4731                              <1> 	; 16/01/2016
  4732                              <1> 	; 07/09/2014
  4733                              <1> 	; 02/09/2014
  4734                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  4735                              <1> 	; 04/04/2014
  4736                              <1> 	; 04/12/2013
  4737                              <1> 	;
  4738                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4739                              <1> 	;
  4740                              <1> 	; SCROLL UP
  4741                              <1> 	;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  4742                              <1> 	;	ON THE SCREEN
  4743                              <1> 	; INPUT
  4744                              <1> 	;	(AH) = CURRENT CRT MODE
  4745                              <1> 	;	(AL) = NUMBER OF ROWS TO SCROLL
  4746                              <1> 	;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  4747                              <1> 	;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  4748                              <1> 	;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  4749                              <1> 	;	(DS) = DATA SEGMENT
  4750                              <1> 	;	(ES) = REGEN BUFFER SEGMENT
  4751                              <1> 	; OUTPUT
  4752                              <1> 	;	NONE -- THE REGEN BUFFER IS MODIFIED
  4753                              <1> 	;
  4754                              <1> 	;	bh = 0  (02/09/2014)
  4755                              <1> 	;
  4756                              <1> 	; ((ah = 3))
  4757                              <1> 	; cl = left upper column
  4758                              <1> 	; ch = left upper row
  4759                              <1> 	; dl = right lower column
  4760                              <1> 	; dh = right lower row
  4761                              <1> 	;
  4762                              <1> 	; al = line count 
  4763                              <1> 	; ah = attribute to be used on blanked line
  4764                              <1> 	; bl = video page number (0 to 7)
  4765                              <1> 	; 
  4766                              <1> 
  4767                              <1> 	; 02/02/2022 'scroll_up' code
  4768                              <1> 	; ------------------------------------------------------
  4769                              <1> 	; (ref: Retro UNIX 8086 v1 'scroll_up' code in 'u9.asm')
  4770                              <1> 
  4771                              <1> 	; INPUT:
  4772                              <1> 	;		
  4773                              <1> 	; al = line count 
  4774                              <1> 	;	(0 or 1) .. 0 -> clear video page
  4775                              <1> 	; ah = attribute to be used on blanked line
  4776                              <1> 	; bl = video page number (0 to 7)
  4777                              <1> 
  4778                              <1> 	;cli
  4779 00001444 31C9                <1> 	xor	ecx, ecx
  4780 00001446 88C1                <1> 	mov	cl, al ; line count (cl)
  4781 00001448 BE00800B00          <1> 	mov	esi, 0B8000h
  4782 0000144D 3A1D[96670000]      <1> 	cmp	bl, [active_page]
  4783 00001453 7411                <1> 	je	short n1
  4784 00001455 20DB                <1> 	and	bl, bl
  4785 00001457 7422                <1> 	jz	short n3
  4786 00001459 88DD                <1> 	mov	ch, bl ; video page number
  4787                              <1> n0:
  4788 0000145B 6681C6A00F          <1> 	add	si, 25*80*2
  4789 00001460 FECD                <1> 	dec	ch
  4790 00001462 75F7                <1> 	jnz	short n0
  4791 00001464 EB15                <1> 	jmp	short n3
  4792                              <1> n1:
  4793 00001466 660335[84670000]    <1> 	add	si, [CRT_START]
  4794                              <1> 	;
  4795 0000146D 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here
  4796                              <1> n2:			 ; wait_display_enable
  4797 00001471 EC                  <1> 	in	al, dx	 ; get port
  4798 00001472 A808                <1> 	test	al, RVRT ; wait for vertical retrace
  4799 00001474 74FB                <1> 	jz	short n2 ; wait_display_enable
  4800 00001476 B025                <1> 	mov	al, 25h
  4801 00001478 B2D8                <1> 	mov	dl, 0D8h ; address control port
  4802 0000147A EE                  <1> 	out	dx, al	 ; turn off video during vertical retrace
  4803                              <1> n3:
  4804                              <1> 	; cl = line count
  4805                              <1> 	; ah = attribute/color
  4806 0000147B 89F7                <1> 	mov	edi, esi
  4807 0000147D 20C9                <1> 	and	cl, cl
  4808 0000147F 741F                <1> 	jz	short n6
  4809 00001481 6681C6A000          <1> 	add	si, 80*2 ; + 160 bytes
  4810 00001486 66B98007            <1> 	mov	cx, 24*80 ; 24 rows/lines
  4811 0000148A F366A5              <1> 	rep	movsw
  4812 0000148D B150                <1> 	mov	cl, 80 ; 1 row (will be cleared)
  4813                              <1> n4:
  4814                              <1> 	; ah = character attribute/cocor
  4815 0000148F B020                <1> 	mov	al, 20h ; fill with blanks
  4816 00001491 F366AB              <1> 	rep	stosw
  4817                              <1> 
  4818 00001494 3A1D[96670000]      <1> 	cmp	bl, [active_page]
  4819 0000149A 7503                <1> 	jne	short n5
  4820                              <1> 
  4821                              <1> 	;mov	al, [crt_mode_set] ; get the value of mode set
  4822 0000149C B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3
  4823                              <1> 	;mov	dx, 03D8h ; always set color card port
  4824 0000149E EE                  <1> 	out	dx, al
  4825                              <1> n5:
  4826 0000149F C3                  <1> 	retn
  4827                              <1> n6:
  4828                              <1> 	; clear video page
  4829 000014A0 66B9D007            <1> 	mov	cx, 25*80 ; 25 rows/lines
  4830 000014A4 EBE9                <1> 	jmp	short n4
  4831                              <1> 
  4832                              <1> 	; 23/02/2022
  4833                              <1> %if 0	; 16/01/2016 'scroll_up' code
  4834                              <1> 	; ------------------------------------------------------
  4835                              <1> 
  4836                              <1> 	; Test	Line Count
  4837                              <1> 	or	al, al
  4838                              <1> 	jz	short al_set
  4839                              <1> 	mov	bh, dh	; subtract lower row from upper row
  4840                              <1> 	sub	bh, ch
  4841                              <1> 	inc	bh	; adjust difference by 1
  4842                              <1> 	cmp	bh, al 	; line count = amount of rows in window?
  4843                              <1> 	jne	short al_set ; if not the we're all set
  4844                              <1> 	xor	al, al	; otherwise set al to zero
  4845                              <1> al_set:
  4846                              <1> 	xor	bh, bh	; 0
  4847                              <1> 	;push	ax
  4848                              <1> 	push	eax ; 23/02/2022
  4849                              <1> 	;mov 	esi, [crt_base]
  4850                              <1>         mov     esi, 0B8000h  
  4851                              <1>         cmp     bl, [active_page]
  4852                              <1> 	jne	short n0
  4853                              <1> 	;
  4854                              <1>         mov     ax, [CRT_START]
  4855                              <1>         add     si, ax
  4856                              <1>         jmp     short n1
  4857                              <1> n0:
  4858                              <1>         and     bl, bl
  4859                              <1> 	jz	short n1
  4860                              <1> 	mov	al, bl
  4861                              <1> n0x:
  4862                              <1>         ;add    si, [CRT_LEN]
  4863                              <1>         ;add    esi, 80*25*2 
  4864                              <1>         add     si, 80*25*2
  4865                              <1>         dec	al
  4866                              <1> 	jnz	short n0x
  4867                              <1> n1:	
  4868                              <1>         ; Scroll position
  4869                              <1> 	;push	dx ; 23/02/2022
  4870                              <1> 	mov	dx, cx	; now, upper left position in DX
  4871                              <1> 	call	position
  4872                              <1> 	add	esi, eax
  4873                              <1> 	mov	edi, esi
  4874                              <1> 	;pop	dx	; lower right position in DX
  4875                              <1> 	sub	dx, cx
  4876                              <1> 	inc	dh	; dh = #rows 
  4877                              <1> 	inc	dl	; dl = #cols in block
  4878                              <1> 	;pop	ax	; al = line count, ah = attribute
  4879                              <1> 	pop	eax ; 23/02/2022
  4880                              <1> 	xor	ecx, ecx
  4881                              <1> 	mov	cx, ax
  4882                              <1> 	;mov	ah, [CRT_COLS]
  4883                              <1> 	mov	ah, 80
  4884                              <1> 	mul	ah	; determine offset to from address
  4885                              <1> 	add	ax, ax  ; *2 for attribute byte
  4886                              <1> 	;
  4887                              <1> 	;push	ax	; offset 
  4888                              <1> 	;push	dx
  4889                              <1> 	; 23/02/2022
  4890                              <1> 	push	eax
  4891                              <1> 	push	edx
  4892                              <1> 	;
  4893                              <1> 	; 04/04/2014
  4894                              <1> 	mov	dx, 3DAh ; guaranteed to be color card here
  4895                              <1> n8:                      ; wait_display_enable
  4896                              <1>         in      al, dx   ; get port
  4897                              <1> 	test	al, RVRT ; wait for vertical retrace
  4898                              <1> 	jz	short n8 ; wait_display_enable
  4899                              <1> 	mov	al, 25h
  4900                              <1> 	mov	dl, 0D8h ; address control port
  4901                              <1> 	out	dx, al	; turn off video during vertical retrace
  4902                              <1> 	;pop	dx	; #rows, #cols
  4903                              <1>        	;pop	ax	; offset
  4904                              <1> 	; 23/02/2022
  4905                              <1> 	pop	edx
  4906                              <1> 	pop	eax
  4907                              <1> 	xchg	ax, cx	; 
  4908                              <1> 	; ecx = offset, al = line count, ah = attribute
  4909                              <1> ;n9:
  4910                              <1> 	or	al, al
  4911                              <1>         jz      short n3 
  4912                              <1>         add     esi, ecx ; from address for scroll
  4913                              <1> 	mov	bh, dh  ; #rows in block
  4914                              <1> 	sub	bh, al	; #rows to be moved
  4915                              <1> n2:
  4916                              <1> 	; Move rows
  4917                              <1> 	mov	cl, dl	; get # of cols to move
  4918                              <1> 	push	esi
  4919                              <1> 	push	edi	; save start address
  4920                              <1> n10:
  4921                              <1> 	movsw		; move that line on screen
  4922                              <1> 	dec	cl
  4923                              <1>         jnz     short n10
  4924                              <1> 	pop	edi
  4925                              <1> 	pop	esi	; recover addresses
  4926                              <1>         ;mov    cl, [CRT_COLS] 
  4927                              <1> 	;add	cl, cl
  4928                              <1>         ;mov    ecx, 80*2
  4929                              <1>         mov     cx, 80*2
  4930                              <1>         add     esi, ecx  ; next line
  4931                              <1>         add     edi, ecx
  4932                              <1> 	dec	bh	 ; count of lines to move
  4933                              <1> 	jnz	short n2 ; row loop
  4934                              <1> 	; bh = 0
  4935                              <1> 	mov	dh, al	 ; #rows	
  4936                              <1> n3:
  4937                              <1> 	; attribute in ah
  4938                              <1> 	mov	al, ' '	 ; fill with blanks
  4939                              <1> n3x:
  4940                              <1> 	; Clear rows
  4941                              <1>                 ; dh =  #rows
  4942                              <1>         mov	cl, dl	; get # of cols to clear
  4943                              <1>         push    edi     ; save address
  4944                              <1> n11:
  4945                              <1>         stosw           ; store fill character
  4946                              <1> 	dec	cl
  4947                              <1>         jnz     short n11
  4948                              <1>         pop     edi     ; recover address
  4949                              <1> 	;mov	cl, [CRT_COLS]
  4950                              <1> 	;add	cl, cl
  4951                              <1>         ;mov    ecx, 80*2
  4952                              <1>         mov	cl, 80*2
  4953                              <1>         add     edi, ecx
  4954                              <1> 	dec	dh
  4955                              <1> 	jnz	short n3x ; 16/01/2016
  4956                              <1> 	;
  4957                              <1> 	cmp	bl, [active_page]
  4958                              <1> 	jne	short n6
  4959                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  4960                              <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3
  4961                              <1> 	mov	dx, 03D8h ; always set color card port
  4962                              <1> 	out	dx, al
  4963                              <1> n6:
  4964                              <1> 	retn
  4965                              <1> 
  4966                              <1> %endif
  4967                              <1> 
  4968                              <1> write_c_current:
  4969                              <1> 	; 02/02/2022
  4970                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4971                              <1> 	; 18/01/2014
  4972                              <1> 	; 04/12/2013
  4973                              <1> 	;
  4974                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4975                              <1> 	;
  4976                              <1> 	; WRITE_C_CURRENT
  4977                              <1> 	;	THIS ROUTINE WRITES THE CHARACTER AT
  4978                              <1> 	;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
  4979                              <1> 	; INPUT	
  4980                              <1> 	;	(AH) = CURRENT CRT MODE
  4981                              <1> 	;	(BH) = DISPLAY PAGE
  4982                              <1> 	;	(CX) = COUNT OF CHARACTERS TO WRITE
  4983                              <1> 	;	(AL) = CHAR TO WRITE
  4984                              <1> 	;	(DS) = DATA SEGMENT
  4985                              <1> 	;	(ES) = REGEN SEGMENT
  4986                              <1> 	; OUTPUT
  4987                              <1> 	;	DISPLAY REGEN BUFFER UPDATED
  4988                              <1> 
  4989 000014A6 FA                  <1> 	cli		
  4990                              <1> 	; bl = video page
  4991                              <1> 	; al = character
  4992                              <1> 	; ah = color/attribute
  4993                              <1> 	;push	dx
  4994                              <1> 	;push	ax	; save character & attribute/color
  4995                              <1> 	; 02/02/2022
  4996 000014A7 52                  <1> 	push	edx
  4997 000014A8 50                  <1> 	push	eax
  4998 000014A9 E86CFFFFFF          <1> 	call 	find_position  ; get regen location and port address
  4999                              <1> 	; esi = regen location
  5000                              <1> 	; dx = status port
  5001                              <1> 	;
  5002                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  5003                              <1> 	;
  5004                              <1> p41:			; wait for horizontal retrace is low or vertical
  5005 000014AE FB                  <1> 	sti		; enable interrupts first
  5006 000014AF 3A1D[96670000]      <1>         cmp     bl, [active_page]
  5007 000014B5 7510                <1> 	jne	short p44 
  5008 000014B7 FA                  <1> 	cli 		; block interrupts for single loop
  5009 000014B8 EC                  <1> 	in	al, dx	; get status from the adapter
  5010 000014B9 A808                <1> 	test	al, RVRT ; check for vertical retrace first
  5011 000014BB 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  5012 000014BD A801                <1> 	test	al, RHRZ  ; is horizontal retrace low
  5013 000014BF 75ED                <1> 	jnz	short p41 ; wait until it is
  5014                              <1> p42:			; wait for either retrace high
  5015 000014C1 EC                  <1> 	in	al, dx	; get status again
  5016 000014C2 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  5017 000014C4 74FB                <1> 	jz	short p42 ; wait until either retrace active
  5018                              <1> p43:	
  5019 000014C6 FB                  <1> 	sti
  5020                              <1> p44:
  5021                              <1> 	;pop	ax	; restore the character (al) & attribute (ah)
  5022                              <1> 	; 02/02/2022
  5023 000014C7 58                  <1> 	pop	eax
  5024 000014C8 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  5025                              <1> 			; Retro UNIX 386 v1 feature only!
  5026 000014CE 668906              <1> 	mov	[esi], ax
  5027                              <1> 	;pop	dx
  5028                              <1> 	; 02/02/2022
  5029 000014D1 5A                  <1> 	pop	edx
  5030 000014D2 C3                  <1> 	retn
  5031                              <1> 
  5032                              <1> %if 0	; 02/02/2022
  5033                              <1> 
  5034                              <1> set_mode:
  5035                              <1> 	; 02/02/2022
  5036                              <1> 	; 16/01/2016
  5037                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  5038                              <1> 	;
  5039                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  5040                              <1> 
  5041                              <1> ;------------------------------------------------------
  5042                              <1> ; SET MODE					      :
  5043                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  5044                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  5045                              <1> ; INPUT						      :
  5046                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  5047                              <1> ; OUTPUT					      :
  5048                              <1> ;	NONE					      :
  5049                              <1> ;------------------------------------------------------
  5050                              <1> 
  5051                              <1> 	push	edi ; 16/01/2016
  5052                              <1> 	push	ebx
  5053                              <1> 	push	edx
  5054                              <1> 	push	ecx ; 16/01/2016
  5055                              <1>         push    eax
  5056                              <1> 
  5057                              <1> 	;mov	dx, 03D4h 	; address or color card
  5058                              <1> 	mov	al, 3
  5059                              <1> ;M8:
  5060                              <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  5061                              <1> 	mov	al, 29h
  5062                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
  5063                              <1> 	and	al, 037h	; video off, save high resolution bit	
  5064                              <1> 	;push	dx  		; save port value
  5065                              <1> 	;add	dx, 4		; point to control register
  5066                              <1> 	mov	dx, 3D8h
  5067                              <1> 	out	dx, al		; reset video to off to suppress rolling
  5068                              <1> 	;pop	dx
  5069                              <1> ;M9:
  5070                              <1> 	mov	ebx, video_params ; initialization table
  5071                              <1> 	;mov	ax, [ebx+10]      ; get the cursor mode from the table	
  5072                              <1> 	;xchg 	ah, al
  5073                              <1> 	;mov	[CURSOR_MODE], ax ; save cursor mode
  5074                              <1> 	xor	ah, ah		  ; ah is register number during loop 
  5075                              <1> 	
  5076                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
  5077                              <1> 	; 02/02/2022
  5078                              <1> 	; dx = 3D8h
  5079                              <1> 	xor	ecx, ecx
  5080                              <1> 	mov	cl, 16
  5081                              <1> 	;mov	ecx, 16 ; 16/01/2016
  5082                              <1> M10:			;  initialization loop
  5083                              <1> 	mov	al, ah 	; get 6845 register number
  5084                              <1> 	out	dx, al
  5085                              <1> 	;inc	dx      ; point to data port
  5086                              <1> 	; 02/02/2022
  5087                              <1> 	inc	dl ; 3D9h
  5088                              <1> 	inc	ah	; next register value
  5089                              <1> 	mov	al, [ebx] ; get table value
  5090                              <1> 	out	dx, al	; out to chip
  5091                              <1> 	inc	ebx	; next in table
  5092                              <1> 	;dec	dx	; back to pointer register
  5093                              <1> 	; 02/02/2022
  5094                              <1> 	dec	dl ; 3D8h
  5095                              <1> 	loop	M10	; do the whole table
  5096                              <1> 	
  5097                              <1> ;-----	FILL REGEN AREA WITH BLANK
  5098                              <1> 	;xor	ax, ax  
  5099                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
  5100                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
  5101                              <1> 	;mov	ecx, 8192 ; number of words in color card
  5102                              <1> 	; black background, light gray characeter color, space character
  5103                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
  5104                              <1> ;M13:			  ; clear buffer
  5105                              <1> 	;add	edi, 0B8000h ; [crt_base]
  5106                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  5107                              <1> 
  5108                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
  5109                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
  5110                              <1> 			 ; prepare to output to video enable port
  5111                              <1> 	;;add	dx, 4	 ; point to the mode control gerister
  5112                              <1> 	; 02/02/2022
  5113                              <1> 	;mov	dx, 3D8h
  5114                              <1> 	; 
  5115                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
  5116                              <1> 	mov	al, 29h
  5117                              <1> 	out	dx, al	 ; set video enable port
  5118                              <1> 
  5119                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
  5120                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
  5121                              <1> 	;
  5122                              <1> 	;mov byte [CRT_COLS], 80h ; initialize number of columns count
  5123                              <1> 	;
  5124                              <1> ;-----	SET CURSOR POSITIONS
  5125                              <1> 	;push	edi
  5126                              <1> 	;mov	word [CRT_LEN], 80*25*2
  5127                              <1> 	mov	edi, cursor_posn
  5128                              <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
  5129                              <1> 	xor	eax, eax
  5130                              <1> 	rep 	stosd	; fill with zeroes
  5131                              <1> 	;pop	edi
  5132                              <1> 
  5133                              <1> ;-----	SET UP OVERSCAN REGISTER
  5134                              <1> 	inc	dx	; set overscan port to a default
  5135                              <1> 	mov	al, 30h	; 30H valuye for all modes except 640X200 bw
  5136                              <1> ;M14:
  5137                              <1> 	out	dx, al	; output the correct value to 3D9 port
  5138                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
  5139                              <1> 
  5140                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  5141                              <1> 	;
  5142                              <1> 	pop	eax
  5143                              <1> 	pop	ecx ; 16/01/2016
  5144                              <1> 	pop	edx
  5145                              <1> 	pop	ebx
  5146                              <1> 	pop	edi ; 16/01/2016
  5147                              <1> 	retn
  5148                              <1> 
  5149                              <1> %endif
  5150                              <1> 	
  5151                              <1> tty_sw:
  5152                              <1> 	; 02/02/2022
  5153                              <1> 	; 30/06/2015
  5154                              <1> 	; 27/06/2015 
  5155                              <1> 	; 07/09/2014
  5156                              <1> 	; 02/09/2014 (Retro UNIX 386 v1 - beginning)
  5157                              <1> 	;
  5158                              <1> 	; (Modified registers : EAX)
  5159                              <1> 	;
  5160                              <1>         ;mov     byte [u.quant], 0  ; 04/03/2014
  5161                              <1> 	;
  5162                              <1> ;act_disp_page:
  5163                              <1> 	; 30/06/2015
  5164                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  5165                              <1> 	; 10/12/2013
  5166                              <1> 	; 04/12/2013
  5167                              <1> 	;
  5168                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  5169                              <1> 	;
  5170                              <1> 	; ACT_DISP_PAGE
  5171                              <1> 	;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  5172                              <1> 	;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  5173                              <1> 	; INPUT
  5174                              <1> 	;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  5175                              <1> 	; OUTPUT
  5176                              <1> 	;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  5177                              <1> 
  5178                              <1> 	;cli
  5179                              <1> 
  5180 000014D3 53                  <1> 	push	ebx
  5181                              <1> 	;push	cx
  5182                              <1> 	;push	dx
  5183                              <1> 	; 02/02/2022
  5184 000014D4 51                  <1> 	push	ecx
  5185 000014D5 52                  <1> 	push	edx
  5186                              <1> 	;
  5187 000014D6 A2[96670000]        <1> 	mov	[active_page], al ; save active page value ; [ptty]
  5188                              <1> 	;;mov	cx, [CRT_LEN] ; get saved length of regen buffer
  5189                              <1> 	;mov	cx, 25*80*2
  5190                              <1> 	; 02/02/2022
  5191 000014DB B9A00F0000          <1> 	mov	ecx, 25*80*2
  5192                              <1> 	; 27/06/2015
  5193 000014E0 0FB6D8              <1> 	movzx	ebx, al
  5194                              <1> 	; 02/02/2022
  5195 000014E3 89D8                <1> 	mov	eax, ebx
  5196                              <1> 	;
  5197                              <1> 	;cbw	; 07/09/2014 (ah=0)
  5198                              <1> 	;mul 	cx	; display page times regen length
  5199                              <1> 	; 02/02/2022
  5200 000014E5 F7E1                <1> 	mul	ecx	
  5201                              <1> 	; 10/12/2013
  5202 000014E7 66A3[84670000]      <1> 	mov	[CRT_START], ax ; save start address for later
  5203                              <1> 	;mov	cx, ax	; start address to cx
  5204                              <1> 	; 02/02/2022
  5205 000014ED 89C1                <1> 	mov	ecx, eax
  5206                              <1> 	;;sar	cx, 1
  5207                              <1> 	;shr	cx, 1	; divide by 2 for 6845 handling
  5208                              <1> 	; 02/02/2022
  5209 000014EF D1E9                <1> 	shr	ecx, 1
  5210 000014F1 B40C                <1> 	mov	ah, 12	; 6845 register for start address
  5211 000014F3 E8EFFEFFFF          <1> 	call	m16
  5212                              <1> 	;sal	bx, 1
  5213                              <1> 	; 01/09/2014
  5214 000014F8 D0E3                <1> 	shl	bl, 1	; * 2 for word offset
  5215 000014FA 81C3[86670000]      <1> 	add	ebx, cursor_posn
  5216 00001500 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  5217 00001503 E8CDFEFFFF          <1> 	call	m18
  5218                              <1> 	;
  5219                              <1> 	;pop	dx
  5220                              <1> 	;pop	cx
  5221                              <1> 	; 02/02/2022
  5222 00001508 5A                  <1> 	pop	edx
  5223 00001509 59                  <1> 	pop	ecx
  5224 0000150A 5B                  <1> 	pop	ebx
  5225                              <1> 	;
  5226                              <1> 	;sti
  5227                              <1> 	;
  5228 0000150B C3                  <1> 	retn
  5229                              <1> 
  5230                              <1> ; %include 'vidata.inc' ; VIDEO DATA ; 11/03/2015
  5231                              <1> 
  5232                              <1> ; /// End Of VIDEO FUNCTIONS ///
  5233                                  
  5234                                  setup_rtc_int:
  5235                                  ; source: http://wiki.osdev.org/RTC
  5236 0000150C FA                      	cli		; disable interrupts
  5237                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  5238                                  	; in order to change this ...
  5239                                  	; frequency = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  5240                                  	; (rate must be above 2 and not over 15)
  5241                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  5242 0000150D B08A                    	mov	al, 8Ah 
  5243 0000150F E670                    	out	70h, al ; set index to register A, disable NMI
  5244 00001511 90                      	nop
  5245 00001512 E471                    	in	al, 71h ; get initial value of register A
  5246 00001514 88C4                    	mov 	ah, al
  5247 00001516 80E4F0                  	and	ah, 0F0h
  5248 00001519 B08A                    	mov	al, 8Ah 
  5249 0000151B E670                    	out	70h, al ; reset index to register A
  5250 0000151D 88E0                    	mov	al, ah
  5251 0000151F 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  5252 00001521 E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  5253                                  	; enable RTC interrupt
  5254 00001523 B08B                    	mov	al, 8Bh ;
  5255 00001525 E670                    	out	70h, al ; select register B and disable NMI
  5256 00001527 90                      	nop
  5257 00001528 E471                    	in	al, 71h ; read the current value of register B
  5258 0000152A 88C4                    	mov	ah, al  ;
  5259 0000152C B08B                    	mov 	al, 8Bh ;
  5260 0000152E E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  5261 00001530 88E0                    	mov	al, ah  ;
  5262 00001532 0C40                    	or	al, 40h ;
  5263 00001534 E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  5264 00001536 FB                      	sti
  5265 00001537 C3                      	retn
  5266                                  
  5267                                  ; Write memory information
  5268                                  ; Temporary Code
  5269                                  ; 06/11/2014
  5270                                  ; 14/08/2015 
  5271                                  memory_info:	
  5272 00001538 A1[6C670000]            	mov	eax, [memory_size] ; in pages
  5273 0000153D 50                      	push	eax
  5274 0000153E C1E00C                  	shl	eax, 12		   ; in bytes
  5275 00001541 BB0A000000              	mov	ebx, 10
  5276 00001546 89D9                    	mov	ecx, ebx	   ; 10
  5277 00001548 BE[D5630000]            	mov	esi, mem_total_b_str	
  5278 0000154D E8AE000000              	call	bintdstr
  5279 00001552 58                      	pop	eax
  5280 00001553 B107                    	mov	cl, 7
  5281 00001555 BE[F9630000]            	mov	esi, mem_total_p_str
  5282 0000155A E8A1000000              	call	bintdstr	
  5283                                  	; 14/08/2015
  5284 0000155F E8B9000000              	call	calc_free_mem
  5285                                  	; edx = calculated free pages
  5286                                  	; ecx = 0
  5287 00001564 A1[70670000]            	mov 	eax, [free_pages]
  5288 00001569 39D0                    	cmp	eax, edx ; calculated free mem value 
  5289                                  		; and initial free mem value are same or not?
  5290 0000156B 751D                    	jne 	short pmim ; print mem info with '?' if not
  5291 0000156D 52                      	push 	edx ; free memory in pages	
  5292                                  	;mov 	eax, edx
  5293 0000156E C1E00C                  	shl	eax, 12 ; convert page count
  5294                                  			; to byte count
  5295 00001571 B10A                    	mov	cl, 10
  5296 00001573 BE[19640000]            	mov	esi, free_mem_b_str
  5297 00001578 E883000000              	call	bintdstr
  5298 0000157D 58                      	pop	eax
  5299 0000157E B107                    	mov	cl, 7
  5300 00001580 BE[3D640000]            	mov	esi, free_mem_p_str
  5301 00001585 E876000000              	call	bintdstr
  5302                                  pmim:
  5303 0000158A BE[C3630000]            	mov	esi, msg_memory_info
  5304                                  pmim_nb:	
  5305 0000158F AC                      	lodsb
  5306 00001590 08C0                    	or	al, al
  5307 00001592 740D                    	jz	short pmim_ok
  5308 00001594 56                      	push	esi
  5309 00001595 31DB                    	xor	ebx, ebx ; 0
  5310                                  			; Video page 0 (bl=0)
  5311 00001597 B407                    	mov	ah, 07h ; Black background, 
  5312                                  			; light gray forecolor
  5313 00001599 E816FDFFFF              	call	write_tty
  5314 0000159E 5E                      	pop	esi
  5315 0000159F EBEE                    	jmp	short pmim_nb
  5316                                  pmim_ok:
  5317 000015A1 C3                      	retn
  5318                                  
  5319                                  ; Convert binary number to hexadecimal string
  5320                                  ; 10/05/2015  
  5321                                  ; dsectpm.s (28/02/2015)
  5322                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  5323                                  ; 01/12/2014
  5324                                  ; 25/11/2014
  5325                                  ;
  5326                                  bytetohex:
  5327                                  	; INPUT ->
  5328                                  	; 	AL = byte (binary number)
  5329                                  	; OUTPUT ->
  5330                                  	;	AX = hexadecimal string
  5331                                  	;
  5332 000015A2 53                      	push	ebx
  5333 000015A3 31DB                    	xor	ebx, ebx
  5334 000015A5 88C3                    	mov	bl, al
  5335 000015A7 C0EB04                  	shr	bl, 4
  5336 000015AA 8A9B[F0150000]          	mov	bl, [ebx+hexchrs]
  5337 000015B0 86D8                    	xchg	bl, al
  5338 000015B2 80E30F                  	and	bl, 0Fh
  5339 000015B5 8AA3[F0150000]          	mov	ah, [ebx+hexchrs]
  5340 000015BB 5B                      	pop	ebx	
  5341 000015BC C3                      	retn
  5342                                  
  5343                                  wordtohex:
  5344                                  	; INPUT ->
  5345                                  	; 	AX = word (binary number)
  5346                                  	; OUTPUT ->
  5347                                  	;	EAX = hexadecimal string
  5348                                  	;
  5349 000015BD 53                      	push	ebx
  5350 000015BE 31DB                    	xor	ebx, ebx
  5351 000015C0 86E0                    	xchg	ah, al
  5352 000015C2 6650                    	push	ax
  5353 000015C4 88E3                    	mov	bl, ah
  5354 000015C6 C0EB04                  	shr	bl, 4
  5355 000015C9 8A83[F0150000]          	mov	al, [ebx+hexchrs]
  5356 000015CF 88E3                    	mov	bl, ah
  5357 000015D1 80E30F                  	and	bl, 0Fh
  5358 000015D4 8AA3[F0150000]          	mov	ah, [ebx+hexchrs]
  5359 000015DA C1E010                  	shl	eax, 16
  5360 000015DD 6658                    	pop	ax
  5361 000015DF 5B                      	pop	ebx
  5362 000015E0 EBC0                    	jmp	short bytetohex
  5363                                  	;mov	bl, al
  5364                                  	;shr	bl, 4
  5365                                  	;mov	bl, [ebx+hexchrs]
  5366                                  	;xchg	bl, al	 	
  5367                                  	;and	bl, 0Fh
  5368                                  	;mov	ah, [ebx+hexchrs]
  5369                                  	;pop	ebx	
  5370                                  	;retn
  5371                                  
  5372                                  dwordtohex:
  5373                                  	; INPUT ->
  5374                                  	; 	EAX = dword (binary number)
  5375                                  	; OUTPUT ->
  5376                                  	;	EDX:EAX = hexadecimal string
  5377                                  	;
  5378 000015E2 50                      	push	eax
  5379 000015E3 C1E810                  	shr	eax, 16
  5380 000015E6 E8D2FFFFFF              	call	wordtohex
  5381 000015EB 89C2                    	mov	edx, eax
  5382 000015ED 58                      	pop	eax
  5383                                  	;call	wordtohex
  5384                                  	;retn
  5385                                  	; 02/01/2022
  5386 000015EE EBCD                    	jmp	short wordtohex
  5387                                  
  5388                                  ; 10/05/2015
  5389                                  hex_digits:
  5390                                  hexchrs:
  5391 000015F0 303132333435363738-     	db '0123456789ABCDEF'
  5392 000015F9 39414243444546     
  5393                                  
  5394                                  ; Convert binary number to decimal/numeric string
  5395                                  ; 06/11/2014
  5396                                  ; Temporary Code
  5397                                  ;
  5398                                  
  5399                                  bintdstr:
  5400                                  	; EAX = binary number
  5401                                  	; ESI = decimal/numeric string address
  5402                                  	; EBX = divisor (10)
  5403                                  	; ECX = string length (<=10)
  5404 00001600 01CE                    	add	esi, ecx
  5405                                  btdstr0:
  5406 00001602 4E                      	dec	esi
  5407 00001603 31D2                    	xor	edx, edx
  5408 00001605 F7F3                    	div	ebx
  5409 00001607 80C230                  	add	dl, 30h
  5410 0000160A 8816                    	mov	[esi], dl
  5411 0000160C FEC9                    	dec	cl
  5412 0000160E 740C                    	jz	short btdstr2 ; 02/01/2022 (short jump)
  5413 00001610 09C0                    	or	eax, eax
  5414 00001612 75EE                    	jnz	short btdstr0
  5415                                  btdstr1:
  5416 00001614 4E                      	dec	esi
  5417 00001615 C60620                          mov     byte [esi], 20h ; blank space
  5418 00001618 FEC9                    	dec	cl
  5419 0000161A 75F8                    	jnz	short btdstr1
  5420                                  btdstr2:
  5421 0000161C C3                      	retn
  5422                                  
  5423                                  ; Calculate free memory pages on M.A.T.
  5424                                  ; 06/11/2014
  5425                                  ; Temporary Code
  5426                                  ;
  5427                                  
  5428                                  calc_free_mem:
  5429 0000161D 31D2                    	xor	edx, edx
  5430                                  	;xor	ecx, ecx
  5431                                  	;mov	cx, [mat_size] ; in pages
  5432                                  	; 02/01/2022
  5433 0000161F 8B0D[80670000]          	mov	ecx, [mat_size] ; in pages
  5434 00001625 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  5435 00001628 BE00001000              	mov	esi, MEM_ALLOC_TBL
  5436                                  cfm0:
  5437 0000162D AD                      	lodsd
  5438 0000162E 51                      	push	ecx
  5439 0000162F B920000000              	mov	ecx, 32
  5440                                  cfm1:
  5441 00001634 D1E8                    	shr	eax, 1
  5442 00001636 7301                    	jnc	short cfm2
  5443 00001638 42                      	inc	edx
  5444                                  cfm2:
  5445 00001639 E2F9                    	loop	cfm1
  5446 0000163B 59                      	pop	ecx
  5447 0000163C E2EF                    	loop	cfm0
  5448 0000163E C3                      	retn
  5449                                  
  5450                                  %include 'diskio.s'  ; 07/03/2015
  5451                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  5452                              <1> ; (re-write kernel for test by using previous version without a major defect)
  5453                              <1> ; ****************************************************************************
  5454                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
  5455                              <1> 
  5456                              <1> ; Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  5457                              <1> ; Last Modification: 18/07/2022
  5458                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
  5459                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
  5460                              <1> ;
  5461                              <1> ; ****************************************************************************
  5462                              <1> ; Ref: Retro UNIX 386 v1.1 Kernel (v0.2.1.5) - DISKIO.INC
  5463                              <1> 
  5464                              <1> ; ///////// DISK I/O SYSTEM ///////////////
  5465                              <1> 
  5466                              <1> ; 11/07/2022
  5467                              <1> ;; 06/02/2015
  5468                              <1> ;diskette_io:
  5469                              <1> ;	pushfd
  5470                              <1> ;	push 	cs
  5471                              <1> ;	call 	DISKETTE_IO_1
  5472                              <1> ;	retn
  5473                              <1> 	
  5474                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
  5475                              <1> ;//////////////////////////////////////////////////////
  5476                              <1> 
  5477                              <1> ; 11/07/2022 - (direct call instead of int 13h simulation)
  5478                              <1> ;		Function in AL
  5479                              <1> ;			0 = reset
  5480                              <1> ;			1 = read
  5481                              <1> ;			2 = write
  5482                              <1> ;		Disk drive number in DL
  5483                              <1> ;			0 & 1 = floppy disks	
  5484                              <1> ;			80h .. 83h = hard disks
  5485                              <1> ;		Sector address (LBA) in ECX
  5486                              <1> ;		Buffer address in EBX
  5487                              <1> ;		R/W sector count is (always) 1
  5488                              <1> ;
  5489                              <1> ;		Return:
  5490                              <1> ;			Status in AH (>0 = error code)
  5491                              <1> ;			if CF = 1 -> error code in AH
  5492                              <1> ;			if CF = 0 -> successful
  5493                              <1> ;			AL = undefined
  5494                              <1> ;
  5495                              <1> ;		Modified registers: (only) EAX
  5496                              <1> 
  5497                              <1> ; 10/07/2022
  5498                              <1> ; 08/07/2022 - (diskio code has been simplified/shortened 
  5499                              <1> ;		by removing unused IBM PC-AT disk functions)
  5500                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  5501                              <1> ; 20/02/2015
  5502                              <1> ; 06/02/2015 (unix386.s)
  5503                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
  5504                              <1> ;
  5505                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
  5506                              <1> ;
  5507                              <1> ; ADISK.EQU
  5508                              <1> 
  5509                              <1> ;----- Wait control constants 
  5510                              <1> 
  5511                              <1> ;amount of time to wait while RESET is active.
  5512                              <1> 
  5513                              <1> WAITCPU_RESET_ON   EQU	21		;Reset on must last at least 14us
  5514                              <1> 					;at 250 KBS xfer rate.
  5515                              <1> 					;see INTEL MCS, 1985, pg. 5-456
  5516                              <1> 
  5517                              <1> WAITCPU_FOR_STATUS EQU	100		;allow 30 microseconds for
  5518                              <1> 					;status register to become valid
  5519                              <1> 					;before re-reading.
  5520                              <1> 
  5521                              <1> ;After sending a byte to NEC, status register may remain
  5522                              <1> ;incorrectly set for 24 us.
  5523                              <1> 
  5524                              <1> WAITCPU_RQM_LOW	   EQU	24		;number of loops to check for
  5525                              <1> 					;RQM low.
  5526                              <1> 
  5527                              <1> ; COMMON.MAC
  5528                              <1> ;
  5529                              <1> ;	Timing macros
  5530                              <1> ;
  5531                              <1> 
  5532                              <1> %macro 		SIODELAY 0 		; SHORT IODELAY
  5533                              <1> 		jmp short $+2
  5534                              <1> %endmacro		
  5535                              <1> 
  5536                              <1> %macro		IODELAY  0		; NORMAL IODELAY
  5537                              <1> 		jmp short $+2
  5538                              <1> 		jmp short $+2
  5539                              <1> %endmacro
  5540                              <1> 
  5541                              <1> %macro		NEWIODELAY 0
  5542                              <1> 		out 0EBh,al
  5543                              <1> %endmacro 
  5544                              <1> 
  5545                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  5546                              <1> ;;; WAIT_FOR_MEM
  5547                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
  5548                              <1> ;WAIT_FDU_INT_HI	equ	1
  5549                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
  5550                              <1> ;;; WAIT_FOR_PORT
  5551                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
  5552                              <1> ;WAIT_FDU_SEND_HI	equ	0
  5553                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
  5554                              <1> ;Time to wait while waiting for each byte of NEC results = .5
  5555                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  5556                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
  5557                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
  5558                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
  5559                              <1> ;;; WAIT_REFRESH
  5560                              <1> ;amount of time to wait for head settle, per unit in parameter
  5561                              <1> ;table = 1 ms.
  5562                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
  5563                              <1> 
  5564                              <1> 
  5565                              <1> ; //////////////// DISKETTE I/O ////////////////
  5566                              <1> 
  5567                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
  5568                              <1> 
  5569                              <1> ;----------------------------------------
  5570                              <1> ;	EQUATES USED BY POST AND BIOS	:
  5571                              <1> ;----------------------------------------
  5572                              <1> 
  5573                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  5574                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  5575                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  5576                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
  5577                              <1> 
  5578                              <1> ;----------------------------------------
  5579                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
  5580                              <1> ;-------------------------------------------------------------------------------
  5581                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
  5582                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
  5583                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
  5584                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
  5585                              <1> 
  5586                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
  5587                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
  5588                              <1> ;		EQU	011H		; - RESERVED			      ;C
  5589                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
  5590                              <1> ;		EQU	013H		; - RESERVED			      ;E
  5591                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
  5592                              <1> 
  5593                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
  5594                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
  5595                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
  5596                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
  5597                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
  5598                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
  5599                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
  5600                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
  5601                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
  5602                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
  5603                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
  5604                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
  5605                              <1> 
  5606                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
  5607                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
  5608                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
  5609                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
  5610                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
  5611                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
  5612                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
  5613                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
  5614                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
  5615                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
  5616                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
  5617                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
  5618                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
  5619                              <1> 
  5620                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
  5621                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
  5622                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
  5623                              <1> 
  5624                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
  5625                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
  5626                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
  5627                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
  5628                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
  5629                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
  5630                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
  5631                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
  5632                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
  5633                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
  5634                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
  5635                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
  5636                              <1> 
  5637                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
  5638                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
  5639                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
  5640                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
  5641                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
  5642                              <1> 
  5643                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
  5644                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
  5645                              <1> ;INTA00		EQU	020H		; 8259 PORT
  5646                              <1> INTA01		EQU	021H		; 8259 PORT
  5647                              <1> INTB00		EQU	0A0H		; 2ND 8259
  5648                              <1> INTB01		EQU	0A1H		;
  5649                              <1> 
  5650                              <1> ;-------------------------------------------------------------------------------
  5651                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
  5652                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
  5653                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
  5654                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
  5655                              <1> ;-------------------------------------------------------------------------------
  5656                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
  5657                              <1> 
  5658                              <1> ;-------------------------------------------------------------------------------
  5659                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
  5660                              <1> 
  5661                              <1> ; 10/07/2022
  5662                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5663                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
  5664                              <1> ; (unix386.s <-- dsectrm2.s)
  5665                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
  5666                              <1> 
  5667                              <1> ; 10/12/2014
  5668                              <1> ;
  5669                              <1> ;int40h:
  5670                              <1> ;	pushf
  5671                              <1> ;	push 	cs
  5672                              <1> ;	;cli
  5673                              <1> ;	call 	DISKETTE_IO_1
  5674                              <1> ;	retn
  5675                              <1> 
  5676                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
  5677                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  5678                              <1> ;
  5679                              <1> 
  5680                              <1> ;-- Retro UNIX 386 v1.1 (Kernel v0.2.1.5) ---08/07/2022-------------------------
  5681                              <1> ; DISKETTE I/O
  5682                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
  5683                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
  5684                              <1> ; INPUT
  5685                              <1> ;	(AH)= 00H RESET DISKETTE SYSTEM
  5686                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
  5687                              <1> ;		ON ALL DRIVES
  5688                              <1> ;------------------------------------------------------------------------------- 
  5689                              <1> ;	(AH)= 01H  READ THE DESIRED SECTORS INTO MEMORY
  5690                              <1> ;-------------------------------------------------------------------------------
  5691                              <1> ;	(AH)= 02H  WRITE THE DESIRED SECTORS FROM MEMORY
  5692                              <1> ;-------------------------------------------------------------------------------
  5693                              <1> ;
  5694                              <1> ;	REGISTERS FOR READ/WRITE
  5695                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5696                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
  5697                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
  5698                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
  5699                              <1> ;		320/360	320/360	    0-39
  5700                              <1> ;		320/360	1.2M	    0-39
  5701                              <1> ;		1.2M	1.2M	    0-79
  5702                              <1> ;		720K	720K	    0-79
  5703                              <1> ;		1.44M	1.44M	    0-79	
  5704                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED)
  5705                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
  5706                              <1> ;		320/360	320/360	     1-8/9
  5707                              <1> ;		320/360	1.2M	     1-8/9
  5708                              <1> ;		1.2M	1.2M	     1-15
  5709                              <1> ;		720K	720K	     1-9
  5710                              <1> ;		1.44M	1.44M	     1-18		
  5711                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
  5712                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
  5713                              <1> ;		320/360	320/360	        8/9
  5714                              <1> ;		320/360	1.2M	        8/9
  5715                              <1> ;		1.2M	1.2M		15
  5716                              <1> ;		720K	720K		9
  5717                              <1> ;		1.44M	1.44M		18
  5718                              <1> ;
  5719                              <1> ;	(EBX) - ADDRESS OF BUFFER
  5720                              <1> ;
  5721                              <1> ;-------------------------------------------------------------------------------
  5722                              <1> ; OUTPUT FOR ALL FUNCTIONS
  5723                              <1> ;	AH = STATUS OF OPERATION
  5724                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
  5725                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
  5726                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)
  5727                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
  5728                              <1> ;	FOR READ/WRITE/VERIFY
  5729                              <1> ;		DS,BX,DX,CX PRESERVED
  5730                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
  5731                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
  5732                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
  5733                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
  5734                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
  5735                              <1> ;-------------------------------------------------------------------------------
  5736                              <1> ;
  5737                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
  5738                              <1> ;
  5739                              <1> ;   -----------------------------------------------------------------
  5740                              <1> ;   |       |       |       |       |       |       |       |       |
  5741                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
  5742                              <1> ;   |       |       |       |       |       |       |       |       |
  5743                              <1> ;   -----------------------------------------------------------------
  5744                              <1> ;	|	|	|	|	|	|	|	|
  5745                              <1> ;	|	|	|	|	|	-----------------
  5746                              <1> ;	|	|	|	|	|		|
  5747                              <1> ;	|	|	|	|    RESERVED		|
  5748                              <1> ;	|	|	|	|		  PRESENT STATE
  5749                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
  5750                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
  5751                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
  5752                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
  5753                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
  5754                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
  5755                              <1> ;	|	|	|	|	110: RESERVED
  5756                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
  5757                              <1> ;	|	|	|	|
  5758                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
  5759                              <1> ;	|	|	|
  5760                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED
  5761                              <1> ;	|	|					 (360K IN 1.2M DRIVE)
  5762                              <1> ;	|	|
  5763                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
  5764                              <1> ;
  5765                              <1> ;						00: 500 KBS
  5766                              <1> ;						01: 300 KBS
  5767                              <1> ;						10: 250 KBS
  5768                              <1> ;						11: RESERVED
  5769                              <1> ;
  5770                              <1> ;
  5771                              <1> 
  5772                              <1> struc MD
  5773 00000000 <res 00000001>      <1> 	.SPEC1:	  resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  5774 00000001 <res 00000001>      <1> 	.SPEC2:	  resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  5775 00000002 <res 00000001>      <1> 	.OFF_TIM: resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  5776 00000003 <res 00000001>      <1> 	.BYT_SEC: resb	1	; 512 BYTES/SECTOR
  5777 00000004 <res 00000001>      <1> 	.SEC_TRK: resb	1	; EOT (LAST SECTOR ON TRACK)
  5778 00000005 <res 00000001>      <1> 	.GAP:	  resb	1	; GAP LENGTH
  5779 00000006 <res 00000001>      <1> 	.DTL:	  resb	1	; DTL
  5780 00000007 <res 00000001>      <1> 	.GAP3:	  resb	1	; GAP LENGTH FOR FORMAT
  5781 00000008 <res 00000001>      <1> 	.FIL_BYT: resb	1	; FILL BYTE FOR FORMAT
  5782 00000009 <res 00000001>      <1> 	.HD_TIM:  resb	1	; HEAD SETTLE TIME (MILLISECONDS)
  5783 0000000A <res 00000001>      <1> 	.STR_TIM: resb	1	; MOTOR START TIME (1/8 SECONDS)
  5784 0000000B <res 00000001>      <1> 	.MAX_TRK: resb	1	; MAX. TRACK NUMBER
  5785 0000000C <res 00000001>      <1> 	.RATE:	  resb	1	; DATA TRANSFER RATE
  5786                              <1> endstruc
  5787                              <1> 
  5788                              <1> BIT7OFF	EQU	7FH
  5789                              <1> BIT7ON	EQU	80H
  5790                              <1> 
  5791                              <1> ; 11/07/2022 - (direct call instead of int 13h simulation)
  5792                              <1> ;		Function in AL
  5793                              <1> ;			0 = reset
  5794                              <1> ;			1 = read
  5795                              <1> ;			2 = write
  5796                              <1> ;		Disk drive number in DL
  5797                              <1> ;			0 & 1 = floppy disks	
  5798                              <1> ;			80h .. 83h = hard disks
  5799                              <1> ;		Sector address (LBA) in ECX
  5800                              <1> ;		Buffer address in EBX
  5801                              <1> ;		R/W sector count is (always) 1
  5802                              <1> ;
  5803                              <1> ;		Return:
  5804                              <1> ;			Status in AH (>0 = error code)
  5805                              <1> ;			if CF = 1 -> error code in AH
  5806                              <1> ;			if CF = 0 -> successful
  5807                              <1> ;			AL = undefined
  5808                              <1> ;
  5809                              <1> ;		Modified registers: (only) EAX
  5810                              <1> 
  5811                              <1> ; 11/07/2022
  5812                              <1> ;;int13h: ; 16/02/2015
  5813                              <1> ;; 16/02/2015 - 21/02/2015
  5814                              <1> ;int40h:
  5815                              <1> ;	pushfd
  5816                              <1> ;	push 	cs
  5817                              <1> ;	call 	DISKETTE_IO_1
  5818                              <1> ;	retn	
  5819                              <1> 
  5820                              <1> DISKETTE_IO_1:
  5821                              <1> 
  5822                              <1> 	;sti				; INTERRUPTS BACK ON
  5823                              <1> 	; 11/07/2022
  5824                              <1> 	; save registers
  5825 0000163F 55                  <1> 	push	ebp			; ANY
  5826                              <1> 
  5827                              <1> 	; 11/07/2022
  5828                              <1> 	;push	edi			; ANY
  5829                              <1> 	;push	edx			; DRIVE NUMBER (DL)
  5830                              <1> 	;push	ebx			; BUFFER ADDRESS
  5831                              <1> 	;push	ecx			; SECTOR ADDRESS (LBA)
  5832                              <1> 	;push	esi			; ANY
  5833                              <1> 
  5834                              <1> 	; 11/07/2022
  5835 00001640 89DD                <1> 	mov	ebp, ebx ; buffer address
  5836 00001642 C605[EC670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; RESET DISKETTE STATUS
  5837 00001649 0FB6FA              <1> 	movzx	edi, dl ; drive number (0 or 1)
  5838                              <1> 	
  5839 0000164C 08C0                <1> 	or	al, al			; RESET ?
  5840 0000164E 7507                <1> 	jnz	short DISKETTE_RW_1	; NO
  5841                              <1> 
  5842 00001650 E84D010000          <1> 	call	DSK_RESET
  5843                              <1> 
  5844 00001655 EB37                <1> 	jmp	short DISKETTE_RW_2	
  5845                              <1> 
  5846                              <1> DISKETTE_RW_1:
  5847                              <1> 	; 12/07/2022
  5848                              <1> 	; 11/07/2022
  5849                              <1> 	; ecx = sector address (LBA, < 2880)
  5850                              <1> 	; ebp = buffer address
  5851                              <1> 	; edi = drive number (0 or 1)
  5852                              <1> 	;  al = function (read = 1 or write = 2)
  5853                              <1> 
  5854 00001657 88C2                <1> 	mov	dl, al ; *
  5855                              <1> convert_to_chs:
  5856                              <1> 	;;;
  5857 00001659 B004                <1> 	mov	al, 4 ; MD.SEC_TRK ; sector per track (drv.spt)
  5858 0000165B E8D9050000          <1> 	call	GET_PARM
  5859                              <1> 	; 12/07/2022
  5860 00001660 88E6                <1> 	mov	dh, ah ; spt
  5861 00001662 89C8                <1> 	mov	eax, ecx ; sector address (LBA) 
  5862 00001664 F6F6                <1> 	div	dh  ; AX/DH
  5863 00001666 88E1                <1> 	mov	cl, ah ; sector number - 1
  5864 00001668 FEC1                <1> 	inc	cl  ; sector number (1 based)
  5865 0000166A 28ED                <1> 	sub	ch, ch ; head = 0 
  5866                              <1> 	; heads = 2
  5867 0000166C D0E8                <1> 	shr	al, 1 ; al = al/2
  5868 0000166E 80D500              <1> 	adc	ch, 0 ; head = 1 or head = 0
  5869 00001671 C1E110              <1> 	shl	ecx, 16
  5870 00001674 88C1                <1> 	mov	cl, al ; track (cylinder)
  5871 00001676 88D5                <1> 	mov	ch, dl ; function number 
  5872 00001678 89CE                <1> 	mov	esi, ecx ; byte 0 = track, byte 1 = function
  5873                              <1> 			 ; byte 2 = sector, byte 3 = head
  5874 0000167A C1C610              <1> 	rol	esi, 16
  5875                              <1> 			 ; byte 0 = sector, byte 1 = head
  5876                              <1> 			 ; byte 2 = track, byte 3 = function		
  5877                              <1> 	;;; 
  5878 0000167D 80FA02              <1> 	cmp	dl, 2 ; *
  5879 00001680 7407                <1> 	je	short DISKETTE_W
  5880                              <1> DISKETTE_R:	
  5881                              <1> 	; dl = 1 ; *
  5882 00001682 E809000000          <1> 	call	DSK_READ
  5883 00001687 EB05                <1> 	jmp	short DISKETTE_RW_2
  5884                              <1> DISKETTE_W:
  5885 00001689 E80F000000          <1> 	call	DSK_WRITE
  5886                              <1> DISKETTE_RW_2:
  5887                              <1> 	; 11/07/2022
  5888                              <1> 	; Restore registers
  5889                              <1> 	;pop	esi
  5890                              <1> 	;pop	ecx
  5891                              <1> 	;pop	ebx
  5892                              <1> 	;pop	edx
  5893                              <1> 	;pop	edi
  5894                              <1> 
  5895                              <1> 	; 11/07/2022
  5896 0000168E 5D                  <1> 	pop	ebp
  5897 0000168F C3                  <1> 	retn
  5898                              <1> 
  5899                              <1> ;-------------------------------------------------------------------------------
  5900                              <1> ; DISK_READ	(AH = 01H)  ; Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5901                              <1> ;	DISKETTE READ.
  5902                              <1> ;
  5903                              <1> ; ON ENTRY:	EDI	: DRIVE #
  5904                              <1> ;		SI-HI	: HEAD #
  5905                              <1> ;		SI-LOW	: # OF SECTORS
  5906                              <1> ;		ES	: BUFFER SEGMENT
  5907                              <1> ;		[BP]	: SECTOR #
  5908                              <1> ;		[BP+1]	: TRACK #
  5909                              <1> ;		[BP+2]	: BUFFER OFFSET
  5910                              <1> ;
  5911                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5912                              <1> ;-------------------------------------------------------------------------------
  5913                              <1> 
  5914                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5915                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5916                              <1> 
  5917                              <1> DSK_READ:
  5918 00001690 8025[EA670000]7F    <1> 	and	byte [MOTOR_STATUS], 01111111b ; INDICATE A READ OPERATION
  5919 00001697 66B846E6            <1> 	mov	ax, 0E646h		; AX = NEC COMMAND, DMA COMMAND
  5920                              <1> 	;call	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5921                              <1> 	;retn
  5922 0000169B EB0B                <1> 	jmp	short RD_WR_VF
  5923                              <1> 
  5924                              <1> ;-------------------------------------------------------------------------------
  5925                              <1> ; DISK_WRITE	(AH = 02H)
  5926                              <1> ;	DISKETTE WRITE.
  5927                              <1> ;
  5928                              <1> ; ON ENTRY:	EDI	: DRIVE #
  5929                              <1> ;		SI-HI	: HEAD #
  5930                              <1> ;		SI-LOW	: # OF SECTORS
  5931                              <1> ;		ES	: BUFFER SEGMENT
  5932                              <1> ;		[BP]	: SECTOR #
  5933                              <1> ;		[BP+1]	: TRACK #
  5934                              <1> ;		[BP+2]	: BUFFER OFFSET
  5935                              <1> ;
  5936                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5937                              <1> ;-------------------------------------------------------------------------------
  5938                              <1> 
  5939                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5940                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5941                              <1> 
  5942                              <1> DSK_WRITE:
  5943 0000169D 66B84AC5            <1> 	mov	ax, 0C54Ah		; AX = NEC COMMAND, DMA COMMAND
  5944 000016A1 800D[EA670000]80    <1>         or	byte [MOTOR_STATUS], 10000000b ; INDICATE WRITE OPERATION
  5945                              <1> 	;;call	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5946                              <1> 	;;retn
  5947                              <1> 	;jmp	short RD_WR_VF
  5948                              <1> 
  5949                              <1> ;-------------------------------------------------------------------------------
  5950                              <1> ; RD_WR_VF
  5951                              <1> ;	COMMON READ, WRITE
  5952                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  5953                              <1> ;
  5954                              <1> ; ON ENTRY:	AH = READ/WRITE NEC PARAMETER
  5955                              <1> ;		AL = READ/WRITE DMA PARAMETER
  5956                              <1> ;
  5957                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5958                              <1> ;-------------------------------------------------------------------------------
  5959                              <1> 
  5960                              <1> RD_WR_VF:
  5961                              <1> 	; 18/07/2022
  5962                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  5963 000016A8 50                  <1> 	push	eax ; 24/12/2021	; SAVE DMA, NEC PARAMETERS
  5964 000016A9 E8C9010000          <1> 	call	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5965 000016AE E82B020000          <1> 	call	SETUP_STATE		; INITIALIZE START AND END RATE
  5966 000016B3 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE READ/WRITE PARAMETER
  5967                              <1> DO_AGAIN:
  5968 000016B4 50                  <1> 	push	eax ; 24/12/2021	; SAVE READ/WRITE PARAMETER
  5969 000016B5 E865020000          <1> 	call	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  5970 000016BA 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE READ/WRITE PARAMETER
  5971                              <1> 	; 24/12/2021
  5972 000016BB 7305                <1> 	jnc	short RWV
  5973 000016BD E9B6000000          <1> 	jmp	RWV_END			; MEDIA CHANGE ERROR OR TIME-OUT
  5974                              <1> RWV:
  5975 000016C2 50                  <1> 	push	eax ; 24/12/2021	; SAVE READ/WRITE/VERIFY PARAMETER
  5976 000016C3 8AB7[F7670000]      <1> 	mov	dh, [DSK_STATE+edi]	; GET RATE STATE OF THIS DRIVE
  5977 000016C9 80E6C0              <1> 	and	dh, RATE_MSK		; KEEP ONLY RATE
  5978 000016CC E85F050000          <1> 	call	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  5979                              <1> 	; 20/02/2015
  5980 000016D1 7445                <1> 	jz	short RWV_ASSUME	; ERROR IN CMOS
  5981 000016D3 3C01                <1> 	cmp	al, 1			; 40 TRACK DRIVE?
  5982 000016D5 750D                <1> 	jne	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  5983 000016D7 F687[F7670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  5984 000016DE 740F                <1> 	jz	short RWV_2		; YES, CMOS IS CORRECT
  5985                              <1> 	;mov	al, 2			; CHANGE TO 1.2M
  5986                              <1> 	; 12/07/2022
  5987 000016E0 FEC0                <1> 	inc	al  ; al = 2
  5988 000016E2 EB0B                <1> 	jmp	short RWV_2
  5989                              <1> RWV_1:
  5990                              <1> 	; 12/07/2022
  5991                              <1> 	;jb	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  5992 000016E4 F687[F7670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; IS IT REALLY 40 TRACK?
  5993 000016EB 7502                <1> 	jnz	short RWV_2		; NO, 80 TRACK
  5994 000016ED B001                <1> 	mov	al, 1			; IT IS 40 TRACK, FIX CMOS VALUE
  5995                              <1> 	; 12/07/2022
  5996                              <1> 	;jmp	short RWV_3
  5997                              <1> RWV_2:
  5998                              <1> 	; 12/07/2022
  5999                              <1> 	;or	al, al			; TEST FOR NO DRIVE
  6000                              <1> 	;jz	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  6001                              <1> RWV_3:
  6002                              <1> 	; 12/07/2022
  6003                              <1> 	;mov	dl, al	; 11/07/2022
  6004 000016EF E81F010000          <1> 	call	DR_TYPE_CHECK		; RTN EBX = MEDIA/DRIVE PARAM TBL.
  6005 000016F4 7222                <1> 	jc	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  6006                              <1> 
  6007                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  6008                              <1> 
  6009 000016F6 57                  <1> 	push	edi			; SAVE DRIVE #
  6010                              <1> 	;xor	ebx, ebx		; EBX = INDEX TO DR_TYPE TABLE
  6011 000016F7 BB[0C620000]        <1> 	mov	ebx, DR_TYPE
  6012                              <1> 	;mov	ecx, DR_CNT		; ECX = LOOP COUNT
  6013 000016FC B106                <1> 	mov	cl, DR_CNT
  6014                              <1> RWV_DR_SEARCH:
  6015                              <1> 	;mov	ah, [DR_TYPE+ebx]	; GET DRIVE TYPE
  6016 000016FE 8A23                <1> 	mov	ah, [ebx]
  6017 00001700 80E47F              <1> 	and	ah, BIT7OFF		; MASK OUT MSB
  6018 00001703 38E0                <1> 	cmp	al, ah			; DRIVE TYPE MATCH?
  6019                              <1> 	; 12/07/2022
  6020                              <1> 	;cmp	dl, ah ; 11/07/2022
  6021 00001705 7509                <1> 	jne	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  6022                              <1> RWV_DR_FND:
  6023                              <1> 	;mov	edi, [DR_TYPE+ebx+1] 	; EDI = MEDIA/DRIVE PARAMETER TABLE
  6024 00001707 43                  <1> 	inc	ebx
  6025 00001708 8B3B                <1> 	mov	edi, [ebx]
  6026 0000170A 4B                  <1> 	dec	ebx
  6027                              <1> RWV_MD_SEARH:
  6028 0000170B 3A770C              <1>         cmp	dh, [edi+MD.RATE]       ; MATCH?
  6029 0000170E 741D                <1> 	je	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  6030                              <1> RWV_NXT_MD:
  6031 00001710 83C305              <1> 	add	ebx, 5			; CHECK NEXT DRIVE TYPE
  6032                              <1> 	;loop	RWV_DR_SEARCH
  6033 00001713 FEC9                <1> 	dec	cl
  6034 00001715 75E7                <1> 	jnz	short RWV_DR_SEARCH 
  6035 00001717 5F                  <1> 	pop	edi			; RESTORE DRIVE #
  6036                              <1> 
  6037                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  6038                              <1> 
  6039                              <1> RWV_ASSUME:
  6040 00001718 BB[2A620000]        <1> 	mov	ebx, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  6041 0000171D F687[F7670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; TEST FOR 80 TRACK
  6042 00001724 740A                <1> 	jz	short RWV_MD_FND1	; MUST BE 40 TRACK
  6043 00001726 BB[44620000]        <1> 	mov	ebx, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  6044 0000172B EB03                <1> 	jmp	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  6045                              <1> 
  6046                              <1> ;-----	EBX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  6047                              <1> 	 			
  6048                              <1> RWV_MD_FND:
  6049 0000172D 89FB                <1> 	mov	ebx, edi		; EBX = MEDIA/DRIVE PARAMETER TABLE
  6050 0000172F 5F                  <1> 	pop	edi			; RESTORE DRIVE #
  6051                              <1> 	
  6052                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  6053                              <1> 
  6054                              <1> RWV_MD_FND1:
  6055 00001730 E824010000          <1> 	call	SEND_SPEC_MD
  6056 00001735 E851020000          <1> 	call	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  6057 0000173A 7405                <1> 	jz	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  6058 0000173C E82C020000          <1> 	call	SEND_RATE		; SEND DATA RATE TO NEC
  6059                              <1> RWV_DBL:
  6060 00001741 53                  <1> 	push	ebx			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6061 00001742 E847040000          <1> 	call	SETUP_DBL		; CHECK FOR DOUBLE STEP
  6062 00001747 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  6063 00001748 7221                <1> 	jc	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  6064                              <1> 	;pop	eax ; 24/12/2021	; RESTORE NEC COMMAND
  6065                              <1> 	;push	eax ; 24/12/2021	; SAVE NEC COMMAND
  6066                              <1> 	; 08/07/2022
  6067 0000174A 8B0424              <1> 	mov	eax, [esp]
  6068                              <1> 	; 18/07/2022
  6069                              <1> 	;push	ebx			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6070 0000174D E84C020000          <1> 	call	DMA_SETUP		; SET UP THE DMA
  6071                              <1> 	;pop	ebx
  6072 00001752 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE NEC COMMAND
  6073 00001753 722D                <1> 	jc	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  6074 00001755 50                  <1> 	push	eax ; 24/12/2021	; SAVE NEC COMMAND
  6075 00001756 53                  <1> 	push	ebx			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6076 00001757 E88C020000          <1> 	call	NEC_INIT		; INITIALIZE NEC
  6077 0000175C 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  6078 0000175D 720C                <1> 	jc	short CHK_RET		; ERROR - EXIT
  6079 0000175F E8B5020000          <1> 	call	RWV_COM			; OP CODE COMMON TO READ/WRITE
  6080 00001764 7205                <1> 	jc	short CHK_RET		; ERROR - EXIT
  6081 00001766 E8FC020000          <1> 	call	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  6082                              <1> CHK_RET:
  6083 0000176B E89B030000          <1> 	call	RETRY			; CHECK FOR, SETUP RETRY
  6084 00001770 58                  <1> 	pop	eax ; 24/12/2021	; RESTORE READ/WRITE PARAMETER
  6085 00001771 7305                <1> 	jnc	short RWV_END		; CY = 0 NO RETRY
  6086 00001773 E93CFFFFFF          <1>         jmp	DO_AGAIN                ; CY = 1 MEANS RETRY
  6087                              <1> RWV_END:
  6088 00001778 E846030000          <1> 	call	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  6089 0000177D E8D7030000          <1> 	call	NUM_TRANS		; AL = NUMBER TRANSFERRED
  6090                              <1> RWV_BAC:
  6091                              <1> 	; 08/07/2022			; BAD DMA ERROR ENTRY
  6092                              <1> 	;push	eax ; 24/12/2021	; SAVE NUMBER TRANSFERRED
  6093                              <1> 	;CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6094                              <1> 	;pop	eax ; 24/12/2021	; RESTORE NUMBER TRANSFERRED
  6095                              <1> 	;;call	SETUP_END		; VARIOUS CLEANUPS
  6096                              <1> 	;;retn
  6097                              <1> 	;jmp	SETUP_END
  6098                              <1> 
  6099                              <1> ;-------------------------------------------------------------------------------
  6100                              <1> ; SETUP_END
  6101                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  6102                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  6103                              <1> ;
  6104                              <1> ; ON EXIT:
  6105                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6106                              <1> ;-------------------------------------------------------------------------------
  6107                              <1> SETUP_END:
  6108                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5) 
  6109                              <1> 	;mov	dl, 2			; GET THE MOTOR WAIT PARAMETER
  6110                              <1> 	;push	ax			; SAVE NUMBER TRANSFERRED
  6111 00001782 50                  <1> 	push	eax ; 24/12/2021
  6112 00001783 B002                <1> 	mov	al, 2 ; 08/07/2022
  6113 00001785 E8AF040000          <1> 	call	GET_PARM
  6114 0000178A 8825[EB670000]      <1> 	mov	[MOTOR_COUNT], ah	; STORE UPON RETURN
  6115                              <1> 	;pop	ax			; RESTORE NUMBER TRANSFERRED
  6116 00001790 58                  <1> 	pop	eax ; 24/12/2021
  6117 00001791 8A25[EC670000]      <1> 	mov	ah, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  6118 00001797 08E4                <1> 	or	ah, ah			; CHECK FOR ERROR
  6119 00001799 7406                <1> 	jz	short NUN_ERR		; NO ERROR
  6120 0000179B 30C0                <1> 	xor 	al, al			; CLEAR NUMBER RETURNED
  6121                              <1> ;NUN_ERR: 
  6122 0000179D 80FC01              <1> 	cmp	ah, 1			; SET THE CARRY FLAG TO INDICATE
  6123 000017A0 F5                  <1> 	cmc				; SUCCESS OR FAILURE
  6124                              <1> NUN_ERR:
  6125 000017A1 C3                  <1> 	retn
  6126                              <1> 
  6127                              <1> ; 17/07/2022
  6128                              <1> ;-------------------------------------------------------------------------------
  6129                              <1> ; DISK_RESET	(AH = 00H)	
  6130                              <1> ;		RESET THE DISKETTE SYSTEM.
  6131                              <1> ;
  6132                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6133                              <1> ;-------------------------------------------------------------------------------
  6134                              <1> DSK_RESET:
  6135                              <1> 	; 17/07/2022
  6136                              <1> 	; 12/07/2022
  6137                              <1> 	; 11/07/2022
  6138                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6139 000017A2 66BAF203            <1> 	mov	dx, 03F2h		; ADAPTER CONTROL PORT
  6140 000017A6 FA                  <1> 	cli				; NO INTERRUPTS
  6141 000017A7 A0[EA670000]        <1> 	mov	al, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  6142 000017AC 243F                <1> 	and	al, 00111111b		; KEEP SELECTED AND MOTOR ON BITS
  6143 000017AE C0C004              <1> 	rol	al, 4			; MOTOR VALUE TO HIGH NIBBLE
  6144                              <1> 					; DRIVE SELECT TO LOW NIBBLE
  6145 000017B1 0C08                <1> 	or	al, 00001000b		; TURN ON INTERRUPT ENABLE
  6146 000017B3 EE                  <1> 	out	dx, al			; RESET THE ADAPTER
  6147 000017B4 C605[E9670000]00    <1> 	mov	byte [SEEK_STATUS], 0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  6148                              <1> 	;JMP	$+2			; WAIT FOR I/O
  6149                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
  6150                              <1> 					;      PULSE WIDTH)
  6151                              <1> 	; 19/12/2014
  6152                              <1> 	NEWIODELAY
  6153 000017BB E6EB                <2>  out 0EBh,al
  6154                              <1> 
  6155                              <1> 	; 17/12/2014 
  6156                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
  6157 000017BD B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
  6158                              <1> wdw1:
  6159                              <1> 	NEWIODELAY   ; 27/02/2015
  6160 000017C2 E6EB                <2>  out 0EBh,al
  6161 000017C4 E2FC                <1> 	loop	wdw1
  6162                              <1> 	;
  6163 000017C6 0C04                <1> 	or	al, 00000100b		; TURN OFF RESET BIT
  6164 000017C8 EE                  <1> 	out	dx, al			; RESET THE ADAPTER
  6165                              <1> 	; 16/12/2014
  6166                              <1> 	IODELAY
  6167 000017C9 EB00                <2>  jmp short $+2
  6168 000017CB EB00                <2>  jmp short $+2
  6169                              <1> 	;
  6170                              <1> 	;sti				; ENABLE THE INTERRUPTS
  6171 000017CD E862060000          <1> 	call	WAIT_INT		; WAIT FOR THE INTERRUPT
  6172 000017D2 7236                <1> 	jc	short DR_ERR		; IF ERROR, RETURN IT
  6173                              <1> 	;mov	cx, 11000000b		; CL = EXPECTED @NEC_STATUS
  6174                              <1> 	; 12/07/2022
  6175                              <1> 	;xor	ecx, ecx
  6176                              <1> 	; 17/07/2022
  6177                              <1> 	;xor	ch, ch
  6178 000017D4 B1C0                <1> 	mov	cl, 11000000b
  6179                              <1> NXT_DRV:
  6180                              <1> 	; 24/12/2021
  6181 000017D6 51                  <1> 	push	ecx			; SAVE FOR CALL
  6182 000017D7 B8[09180000]        <1> 	mov	eax, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
  6183 000017DC 50                  <1> 	push	eax			;
  6184 000017DD B408                <1> 	mov	ah, 08h			; SENSE INTERRUPT STATUS COMMAND
  6185 000017DF E846050000          <1> 	call	NEC_OUTPUT
  6186 000017E4 58                  <1> 	pop	eax			; THROW AWAY ERROR RETURN
  6187 000017E5 E879060000          <1> 	call	RESULTS			; READ IN THE RESULTS
  6188                              <1> 	; 24/12/2021
  6189 000017EA 59                  <1> 	pop	ecx			; RESTORE AFTER CALL
  6190 000017EB 721D                <1> 	jc	short DR_ERR		; ERROR RETURN
  6191 000017ED 3A0D[ED670000]      <1> 	cmp	cl, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
  6192 000017F3 7515                <1> 	jnz	short DR_ERR		; EVERYTHING OK
  6193 000017F5 FEC1                <1> 	inc	cl			; NEXT EXPECTED @NEC_STATUS
  6194 000017F7 80F9C3              <1> 	cmp	cl, 11000011b		; ALL POSSIBLE DRIVES CLEARED
  6195 000017FA 76DA                <1> 	jbe	short NXT_DRV		; FALL THRU IF 11000100B OR >
  6196                              <1> 	;
  6197 000017FC E82F000000          <1> 	call	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  6198                              <1> RESBAC:
  6199 00001801 E87CFFFFFF          <1> 	call	SETUP_END		; VARIOUS CLEANUPS
  6200                              <1> 	
  6201                              <1> 	; 11/07/2022
  6202                              <1> 	; CF = 1 -> error (error code in AH)
  6203                              <1> 	; CF = 0 -> OK
  6204                              <1> 	
  6205                              <1> 	;; 24/12/2021
  6206                              <1> 	;mov	ebx, esi		; GET SAVED AL TO BL
  6207                              <1> 	;; 11/07/2022
  6208                              <1> 	;; byte 0 = sector, byte 1 = head, byte 2 = track, byte 3 = function 
  6209                              <1> 	;rol	ebx, 8
  6210                              <1> 	; bl = function (reset = 0)
  6211                              <1> 	;
  6212                              <1> 	;mov	al, bl			; PUT BACK FOR RETURN
  6213                              <1> 	
  6214                              <1> 	; 11/07/2022  
  6215 00001806 B000                <1> 	mov	al, 0	; (reset function = 0)
  6216                              <1> 
  6217 00001808 C3                  <1> 	retn
  6218                              <1> 
  6219                              <1> DR_POP_ERR:
  6220                              <1> 	; 24/12/2021
  6221 00001809 59                  <1> 	pop	ecx			; CLEAR STACK
  6222                              <1> DR_ERR:
  6223 0000180A 800D[EC670000]20    <1> 	or	byte [DSKETTE_STATUS], BAD_NEC ; SET ERROR CODE
  6224 00001811 EBEE                <1> 	jmp	short RESBAC		; RETURN FROM RESET
  6225                              <1> 
  6226                              <1> ;-------------------------------------------------------------------------------
  6227                              <1> ; FNC_ERR
  6228                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
  6229                              <1> ;	SET BAD COMMAND IN STATUS.
  6230                              <1> ;
  6231                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6232                              <1> ;-------------------------------------------------------------------------------
  6233                              <1> 
  6234                              <1> 	; 11/07/2022 - not needed (because diskio is used by kernel only)
  6235                              <1> 	
  6236                              <1> ;FNC_ERR:				; INVALID FUNCTION REQUEST
  6237                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6238                              <1> ;	; 24/12/2021
  6239                              <1> ;	mov	eax, esi		; RESTORE AL
  6240                              <1> ;	mov	ah, BAD_CMD		; SET BAD COMMAND ERROR
  6241                              <1> ;	mov	[DSKETTE_STATUS], ah	; STORE IN DATA AREA
  6242                              <1> ;	stc				; SET CARRY INDICATING ERROR
  6243                              <1> ;	retn
  6244                              <1> 
  6245                              <1> ;----------------------------------------------------------------
  6246                              <1> ; DR_TYPE_CHECK							:
  6247                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  6248                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  6249                              <1> ; ON ENTRY:							:
  6250                              <1> ;	AL = DRIVE TYPE						:
  6251                              <1> ; ON EXIT:							:
  6252                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  6253                              <1> ;	     EBX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE	:
  6254                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  6255                              <1> ; REGISTERS ALTERED: EBX, AH ; 11/07/2022 			:
  6256                              <1> ;----------------------------------------------------------------
  6257                              <1> DR_TYPE_CHECK:
  6258                              <1> 	; 12/07/2022
  6259                              <1> 	; 11/07/2022
  6260                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6261                              <1> 	; 24/12/2021
  6262                              <1> 	;push	eax ; 11/07/2022
  6263                              <1> 	;push	ecx ; 08/07/2022
  6264                              <1> 	;xor	ebx,ebx			; EBX = INDEX TO DR_TYPE TABLE
  6265 00001813 BB[0C620000]        <1> 	mov	ebx, DR_TYPE
  6266                              <1> 	;;mov	ecx, DR_CNT		; ECX = LOOP COUNT
  6267                              <1> 	;mov	cl, DR_CNT
  6268 00001818 B406                <1> 	mov	ah, DR_CNT ; 11/07/2022
  6269                              <1> TYPE_CHK:	
  6270                              <1> 	;;mov	ah, [DR_TYPE+ebx]	; GET DRIVE TYPE
  6271                              <1> 	;mov	ah, [ebx]
  6272                              <1> 	;cmp	al, ah			; DRIVE TYPE MATCH?
  6273 0000181A 3A03                <1> 	cmp	al, [ebx] ; 11/07/2022
  6274 0000181C 740E                <1> 	je	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  6275                              <1> 	; 16/02/2015 (32 bit address modification)
  6276 0000181E 83C305              <1> 	add	ebx, 5			; CHECK NEXT DRIVE TYPE
  6277                              <1> 	;loop	TYPE_CHK
  6278                              <1> 	;dec	cl
  6279 00001821 FECC                <1> 	dec	ah ; 11/07/2022
  6280 00001823 75F5                <1> 	jnz	short TYPE_CHK
  6281                              <1> 	;
  6282 00001825 BB[6B620000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  6283                              <1> 					; Default for GET_PARM (11/12/2014)
  6284                              <1> 	;
  6285 0000182A F9                  <1> 	stc				; DRIVE TYPE NOT FOUND IN TABLE
  6286                              <1> 	;jmp	short TYPE_RTN
  6287                              <1> 	; 12/07/2022
  6288 0000182B C3                  <1> 	retn
  6289                              <1> DR_TYPE_VALID:
  6290                              <1> 	;mov	ebx, [DR_TYPE+ebx+1] 	; EBX = MEDIA TABLE
  6291 0000182C 43                  <1> 	inc	ebx
  6292 0000182D 8B1B                <1> 	mov	ebx, [ebx]
  6293                              <1> TYPE_RTN:
  6294                              <1> 	;pop	ecx ; 08/07/2022
  6295                              <1> 	; 24/12/2021
  6296                              <1> 	;pop	eax ; 11/07/2022
  6297 0000182F C3                  <1> 	retn
  6298                              <1> 		
  6299                              <1> ;----------------------------------------------------------------
  6300                              <1> ; SEND_SPEC							:
  6301                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6302                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  6303                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  6304                              <1> ; ON EXIT:	NONE						:
  6305                              <1> ; REGISTERS ALTERED: ECX, EDX					:
  6306                              <1> ;----------------------------------------------------------------
  6307                              <1> SEND_SPEC:
  6308                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6309 00001830 50                  <1> 	push	eax			; SAVE EAX
  6310 00001831 B8[57180000]        <1> 	mov	eax, SPECBAC		; LOAD ERROR ADDRESS
  6311 00001836 50                  <1> 	push	eax			; PUSH NEC_OUT ERROR RETURN
  6312 00001837 B403                <1> 	mov	ah, 03h			; SPECIFY COMMAND
  6313 00001839 E8EC040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  6314                              <1> 	;sub	dl, dl			; FIRST SPECIFY BYTE
  6315 0000183E 28C0                <1> 	sub	al, al ; 08/07/2022
  6316 00001840 E8F4030000          <1> 	call	GET_PARM		; GET PARAMETER TO AH
  6317 00001845 E8E0040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  6318                              <1> 	;mov	dl, 1			; SECOND SPECIFY BYTE
  6319 0000184A B001                <1> 	mov	al, 1 ; 08/07/2022
  6320 0000184C E8E8030000          <1> 	call	GET_PARM		; GET PARAMETER TO AH
  6321 00001851 E8D4040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  6322 00001856 58                  <1> 	pop	eax			; POP ERROR RETURN
  6323                              <1> SPECBAC:
  6324 00001857 58                  <1> 	pop	eax			; RESTORE ORIGINAL EAX VALUE
  6325 00001858 C3                  <1> 	retn
  6326                              <1> 
  6327                              <1> ;----------------------------------------------------------------
  6328                              <1> ; SEND_SPEC_MD							:
  6329                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6330                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (EBX)	:
  6331                              <1> ; ON ENTRY:	EBX = MEDIA/DRIVE PARAMETER TABLE		:
  6332                              <1> ; ON EXIT:	NONE						:
  6333                              <1> ; REGISTERS ALTERED: EAX ; 11/07/2022				:
  6334                              <1> ;----------------------------------------------------------------
  6335                              <1> SEND_SPEC_MD:
  6336                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6337                              <1> 	;push	eax ; 11/07/2022	; SAVE RATE DATA
  6338 00001859 B8[76180000]        <1> 	mov	eax, SPEC_ESBAC		; LOAD ERROR ADDRESS
  6339 0000185E 50                  <1> 	push	eax			; PUSH NEC_OUT ERROR RETURN
  6340 0000185F B403                <1> 	mov	ah, 03h			; SPECIFY COMMAND
  6341 00001861 E8C4040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  6342 00001866 8A23                <1>         mov	ah, [ebx+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  6343 00001868 E8BD040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  6344 0000186D 8A6301              <1>         mov	ah, [ebx+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  6345 00001870 E8B5040000          <1> 	call	NEC_OUTPUT		; OUTPUT THE COMMAND
  6346 00001875 58                  <1> 	pop	eax			; POP ERROR RETURN
  6347                              <1> SPEC_ESBAC:
  6348                              <1> 	;pop	eax ; 11/07/2022	; RESTORE ORIGINAL EAX VALUE
  6349 00001876 C3                  <1> 	retn
  6350                              <1> 
  6351                              <1> ;-------------------------------------------------------------------------------
  6352                              <1> ; XLAT_NEW  
  6353                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  6354                              <1> ;	MODE TO NEW ARCHITECTURE.
  6355                              <1> ;
  6356                              <1> ; ON ENTRY:	EDI = DRIVE #
  6357                              <1> ;-------------------------------------------------------------------------------
  6358                              <1> XLAT_NEW:
  6359                              <1> 	; 11/07/2022
  6360                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6361                              <1> 	;cmp	edi, 1				; VALID DRIVE
  6362                              <1> 	;ja	short XN_OUT			; IF INVALID BACK
  6363                              <1> 	;
  6364 00001877 80BF[F7670000]00    <1> 	cmp	byte [DSK_STATE+edi], 0		; NO DRIVE ?
  6365 0000187E 7401                <1> 	jz	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  6366                              <1> 	;
  6367                              <1> 	;mov	al, [HF_CNTRL]			; DRIVE INFORMATION
  6368                              <1> 	;mov	ecx, edi			; ECX = DRIVE NUMBER
  6369                              <1> 	;or	cl, cl
  6370                              <1> 	;jz	short XN_0  ; 08/07/2022
  6371                              <1> 	;shl	cl, 2				; CL = SHIFT COUNT, A=0, B=4
  6372                              <1> 	;;mov	al, [HF_CNTRL]			; DRIVE INFORMATION
  6373                              <1> 	;ror	al, cl				; TO LOW NIBBLE
  6374                              <1> ;XN_0:	
  6375                              <1> 	;and	al, DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  6376                              <1>         ;and	byte [DSK_STATE+edi], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  6377                              <1> 	;or	[DSK_STATE+edi], al		; UPDATE DRIVE STATE
  6378                              <1> XN_OUT:
  6379 00001880 C3                  <1> 	retn
  6380                              <1> DO_DET:
  6381                              <1> 	;;call	DRIVE_DET			; TRY TO DETERMINE
  6382                              <1> 	;;retn
  6383                              <1> 	;jmp	DRIVE_DET
  6384                              <1> 
  6385                              <1> ;-------------------------------------------------------------------------------
  6386                              <1> ; DRIVE_DET
  6387                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  6388                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  6389                              <1> ; ON ENTRY:	EDI = DRIVE #
  6390                              <1> ;-------------------------------------------------------------------------------
  6391                              <1> DRIVE_DET:
  6392                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6393 00001881 E8EE030000          <1> 	call	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  6394 00001886 E857050000          <1> 	call	RECAL			; RECALIBRATE DRIVE
  6395 0000188B 724E                <1> 	jc	short DD_BAC		; ASSUME NO DRIVE PRESENT
  6396 0000188D B530                <1> 	mov	ch, TRK_SLAP		; SEEK TO TRACK 48
  6397 0000188F E8CF040000          <1> 	call	SEEK
  6398 00001894 7245                <1> 	jc	short DD_BAC		; ERROR NO DRIVE
  6399 00001896 B50B                <1> 	mov	ch, QUIET_SEEK+1	; SEEK TO TRACK 10
  6400                              <1> SK_GIN:
  6401 00001898 FECD                <1> 	dec	ch			; DECREMENT TO NEXT TRACK
  6402                              <1> 	;push	cx		
  6403                              <1> 	; 24/12/2021
  6404 0000189A 51                  <1> 	push	ecx			; SAVE TRACK
  6405 0000189B E8C3040000          <1> 	call	SEEK
  6406 000018A0 723A                <1> 	jc	short POP_BAC		; POP AND RETURN
  6407 000018A2 B8[DC180000]        <1> 	mov	eax, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  6408 000018A7 50                  <1> 	push	eax
  6409 000018A8 B404                <1> 	mov	ah, SENSE_DRV_ST	; SENSE DRIVE STATUS COMMAND BYTE
  6410 000018AA E87B040000          <1> 	call	NEC_OUTPUT		; OUTPUT TO NEC
  6411                              <1> 	; 08/07/2022
  6412 000018AF 89F8                <1> 	mov	eax, edi		; AL = DRIVE
  6413 000018B1 88C4                <1> 	mov	ah, al			; AH = DRIVE
  6414 000018B3 E872040000          <1> 	call	NEC_OUTPUT		; OUTPUT TO NEC
  6415 000018B8 E8A6050000          <1> 	call	RESULTS			; GO GET STATUS
  6416 000018BD 58                  <1> 	pop	eax			; THROW AWAY ERROR ADDRESS
  6417                              <1> 	;pop	cx			; RESTORE TRACK
  6418                              <1> 	; 24/12/2021
  6419 000018BE 59                  <1> 	pop	ecx
  6420 000018BF F605[ED670000]10    <1> 	test	byte [NEC_STATUS], HOME	; TRACK 0 ?
  6421 000018C6 74D0                <1> 	jz	short SK_GIN		; GO TILL TRACK 0
  6422 000018C8 08ED                <1> 	or	ch, ch			; IS HOME AT TRACK 0
  6423 000018CA 7408                <1> 	jz	short IS_80		; MUST BE 80 TRACK DRIVE
  6424                              <1> 
  6425                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  6426                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  6427                              <1> 
  6428 000018CC 808F[F7670000]94    <1> 	or	byte [DSK_STATE+edi], DRV_DET+MED_DET+RATE_250
  6429 000018D3 C3                  <1> 	retn				; ALL INFORMATION SET
  6430                              <1> IS_80:
  6431 000018D4 808F[F7670000]01    <1> 	or	byte [DSK_STATE+edi], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  6432                              <1> DD_BAC:
  6433 000018DB C3                  <1> 	retn
  6434                              <1> POP_BAC:
  6435                              <1> 	;pop	cx			; THROW AWAY
  6436                              <1> 	; 24/12/2021
  6437 000018DC 59                  <1> 	pop	ecx
  6438 000018DD C3                  <1> 	retn
  6439                              <1> 
  6440                              <1> ;-------------------------------------------------------------------------------
  6441                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  6442                              <1> ;-------------------------------------------------------------------------------
  6443                              <1> SETUP_STATE:
  6444                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6445 000018DE F687[F7670000]10    <1> 	test	byte [DSK_STATE+edi], MED_DET ; MEDIA DETERMINED ?
  6446 000018E5 7537                <1> 	jnz	short J1C		; NO STATES IF DETERMINED
  6447 000018E7 66B84000            <1>        	mov	ax, (RATE_500*256)+RATE_300 ; AH = START RATE, AL = END RATE
  6448 000018EB F687[F7670000]04    <1> 	test	byte [DSK_STATE+edi], DRV_DET ; DRIVE ?
  6449 000018F2 740D                <1> 	jz	short AX_SET		; DO NOT KNOW DRIVE
  6450 000018F4 F687[F7670000]02    <1> 	test	byte [DSK_STATE+edi], FMT_CAPA ; MULTI-RATE?
  6451 000018FB 7504                <1> 	jnz	short AX_SET		; JUMP IF YES
  6452 000018FD 66B88080            <1>         mov	ax, RATE_250*257	; START A END RATE 250 FOR 360 DRIVE
  6453                              <1> AX_SET:	
  6454 00001901 80A7[F7670000]1F    <1> 	and	byte [DSK_STATE+edi], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  6455 00001908 08A7[F7670000]      <1> 	or	[DSK_STATE+edi], ah	; RATE FIRST TO TRY
  6456 0000190E 8025[F4670000]F3    <1> 	and	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  6457 00001915 C0C804              <1> 	ror	al, 4			; TO OPERATION LAST RATE LOCATION
  6458 00001918 0805[F4670000]      <1> 	or	[LASTRATE], al		; LAST RATE
  6459                              <1> J1C:	
  6460 0000191E C3                  <1> 	retn
  6461                              <1> 
  6462                              <1> ;-------------------------------------------------------------------------------
  6463                              <1> ; MED_CHANGE	
  6464                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  6465                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  6466                              <1> ;
  6467                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  6468                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  6469                              <1> ;-------------------------------------------------------------------------------
  6470                              <1> MED_CHANGE:
  6471                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6472 0000191F E897050000          <1> 	call	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  6473 00001924 7446                <1> 	jz	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  6474 00001926 80A7[F7670000]EF    <1> 	and	byte [DSK_STATE+edi], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  6475                              <1> 
  6476                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  6477                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  6478                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  6479                              <1> 
  6480 0000192D 89F9                <1> 	mov	ecx, edi		; CL = DRIVE #
  6481 0000192F B001                <1> 	mov	al, 1			; MOTOR ON BIT MASK
  6482 00001931 D2E0                <1> 	shl	al, cl			; TO APPROPRIATE POSITION
  6483 00001933 F6D0                <1> 	not	al			; KEEP ALL BUT MOTOR ON
  6484 00001935 FA                  <1> 	cli				; NO INTERRUPTS
  6485 00001936 2005[EA670000]      <1> 	and	[MOTOR_STATUS], al	; TURN MOTOR OFF INDICATOR
  6486 0000193C FB                  <1> 	sti				; INTERRUPTS ENABLED
  6487 0000193D E832030000          <1> 	call	MOTOR_ON		; TURN MOTOR ON
  6488                              <1> 
  6489                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  6490                              <1> 
  6491 00001942 E85BFEFFFF          <1> 	call	DSK_RESET		; RESET NEC
  6492 00001947 B501                <1> 	mov	ch, 1			; MOVE TO CYLINDER 1
  6493 00001949 E815040000          <1> 	call	SEEK			; ISSUE SEEK
  6494 0000194E 30ED                <1> 	xor	ch, ch			; MOVE TO CYLINDER 0
  6495 00001950 E80E040000          <1> 	call	SEEK			; ISSUE SEEK
  6496 00001955 C605[EC670000]06    <1> 	mov	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  6497                              <1> OK1:
  6498 0000195C E85A050000          <1> 	call	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  6499 00001961 7407                <1> 	jz	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  6500                              <1> OK4:
  6501 00001963 C605[EC670000]80    <1> 	mov	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  6502                              <1> OK2:		
  6503 0000196A F9                  <1> 	stc				; MEDIA CHANGED, SET CY
  6504 0000196B C3                  <1> 	retn
  6505                              <1> MC_OUT:
  6506                              <1> 	;clc	; 08/07/2022		; NO MEDIA CHANGED, CLEAR CY
  6507 0000196C C3                  <1> 	retn
  6508                              <1> 
  6509                              <1> ;-------------------------------------------------------------------------------
  6510                              <1> ; SEND_RATE
  6511                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  6512                              <1> ; ON ENTRY:	EDI = DRIVE #
  6513                              <1> ; ON EXIT:	NONE
  6514                              <1> ; REGISTERS ALTERED: EDX, EAX ; 11/07/2022
  6515                              <1> ;-------------------------------------------------------------------------------
  6516                              <1> SEND_RATE:
  6517                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6518                              <1> 	;push	ax			; SAVE REG.
  6519                              <1> 	; 24/12/2021
  6520                              <1> 	;push	eax ; 11/07/2022
  6521 0000196D 8025[F4670000]3F    <1> 	and	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  6522 00001974 8A87[F7670000]      <1> 	mov	al, [DSK_STATE+edi]	; GET RATE STATE OF THIS DRIVE
  6523 0000197A 24C0                <1> 	and	al, SEND_MSK		; KEEP ONLY RATE BITS
  6524 0000197C 0805[F4670000]      <1> 	or	[LASTRATE], al		; SAVE NEW RATE FOR NEXT CHECK
  6525 00001982 C0C002              <1> 	rol	al, 2			; MOVE TO BIT OUTPUT POSITIONS
  6526 00001985 66BAF703            <1> 	mov	dx, 03F7h		; OUTPUT NEW DATA RATE
  6527 00001989 EE                  <1> 	out	dx, al
  6528                              <1> 	;pop	ax			; RESTORE REG.
  6529                              <1> 	; 24/12/2021
  6530                              <1> 	;pop	eax ; 11/07/2022
  6531 0000198A C3                  <1> 	retn
  6532                              <1> 
  6533                              <1> ;-------------------------------------------------------------------------------
  6534                              <1> ; CHK_LASTRATE
  6535                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  6536                              <1> ; ON ENTRY:
  6537                              <1> ;	EDI = DRIVE #
  6538                              <1> ; ON EXIT:
  6539                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  6540                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  6541                              <1> ; REGISTERS ALTERED: EAX ; 11/07/2022
  6542                              <1> ;-------------------------------------------------------------------------------
  6543                              <1> CHK_LASTRATE:
  6544                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6545                              <1> 	;push	ax			; SAVE REG.
  6546                              <1> 	; 24/12/2021
  6547                              <1> 	;push	eax ; 11/07/2022
  6548 0000198B 8A25[F4670000]      <1> 	mov	ah, [LASTRATE] ; 08/07/2022 (BugFix) 
  6549                              <1> 					; GET LAST DATA RATE SELECTED
  6550 00001991 8A87[F7670000]      <1> 	mov	al, [DSK_STATE+edi]	; GET RATE STATE OF THIS DRIVE
  6551 00001997 6625C0C0            <1>        	and	ax, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  6552 0000199B 38E0                <1> 	cmp	al, ah			; COMPARE TO PREVIOUSLY TRIED
  6553                              <1> 					; ZF = 1 RATE IS THE SAME
  6554                              <1> 	;pop	ax			; RESTORE REG.
  6555                              <1> 	; 24/12/2021
  6556                              <1> 	;pop	eax ; 11/07/2022
  6557 0000199D C3                  <1> 	retn
  6558                              <1> 
  6559                              <1> ;-------------------------------------------------------------------------------
  6560                              <1> ; DMA_SETUP
  6561                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  6562                              <1> ;
  6563                              <1> ; ON ENTRY:	AL = DMA COMMAND
  6564                              <1> ;
  6565                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6566                              <1> ;-------------------------------------------------------------------------------
  6567                              <1> 
  6568                              <1> ; SI = Head #, # of Sectors or DASD Type
  6569                              <1> 
  6570                              <1> ; 22/08/2015
  6571                              <1> ; 08/02/2015 - Protected Mode Modification
  6572                              <1> ; 06/02/2015 - 07/02/2015
  6573                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  6574                              <1> ; (DMA Addres = Physical Address)
  6575                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  6576                              <1> ;
  6577                              <1> ; 04/02/2016 (clc)
  6578                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  6579                              <1> ; 16/12/2014 (IODELAY)
  6580                              <1> 
  6581                              <1> DMA_SETUP:
  6582                              <1> 	; 18/07/2022
  6583                              <1> 	; 11/07/2022
  6584                              <1> 	;	ebp = buffer address
  6585                              <1> 	
  6586                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6587                              <1> 	;; 20/02/2015
  6588                              <1> 	;mov	edx, [ebp+4] ; 11/07/2022 ; Buffer address
  6589                              <1> 	; 08/07/2022 - not needed for Retro UNIX 386 v1.1
  6590                              <1> 	;test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  6591                              <1> 	;jnz	short dma_bnd_err_stc
  6592                              <1> 
  6593                              <1> 	; al = dma command
  6594                              <1> 	
  6595                              <1> ;	; 18/07/2022
  6596                              <1> ;	;	(512 bytes/sector only!) 
  6597                              <1> ;	; 24/12/2021
  6598                              <1> ;	push	eax			; DMA command
  6599                              <1> ;	;push	edx ; 11/07/2022	; *
  6600                              <1> ;	;mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  6601                              <1> ;	mov	al, 3 ; 08/07/2022
  6602                              <1> ;	call	GET_PARM		; 
  6603                              <1> ;	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6604                              <1> ;	;mov	ax, si			; Sector count
  6605                              <1> ;	;mov	ah, al			; AH = # OF SECTORS
  6606                              <1> ;	;sub	al, al			; AL = 0, AX = # SECTORS * 256
  6607                              <1> ;	;shr	ax, 1			; AX = # SECTORS * 128
  6608                              <1> ;	;shl	ax, cl			; SHIFT BY PARAMETER VALUE
  6609                              <1> ;	; 08/07/2022
  6610                              <1> ;	; 24/12/2021
  6611                              <1> ;	;mov	edx, esi
  6612                              <1> ;	sub	eax, eax
  6613                              <1> ;	;mov	ah, dl
  6614                              <1> ;	;shr	eax, 1
  6615                              <1> ;	mov	al, 128
  6616                              <1> ;	shl	eax, cl
  6617                              <1> ;	;
  6618                              <1> ;	dec	eax			; -1 FOR DMA VALUE
  6619                              <1> ;	mov	ecx, eax
  6620                              <1> ;	;pop	edx ; 11/07/2022	; *
  6621                              <1> ;	; 24/12/2021
  6622                              <1> ;	pop	eax
  6623                              <1> 
  6624                              <1> 	; 18/07/2022
  6625                              <1> 	;mov	cx, 511
  6626                              <1> 
  6627                              <1> 	; 08/07/2022
  6628                              <1> 	;cmp	al, 42h
  6629                              <1>         ;jne	short NOT_VERF
  6630                              <1> 	;mov	edx, 0FF0000h
  6631                              <1> 	;jmp	short J33
  6632                              <1> ;NOT_VERF:
  6633                              <1> 	; 11/07/2022
  6634 0000199E 89EA                <1> 	mov	edx, ebp
  6635                              <1> 	;
  6636                              <1> 	;add	dx, cx			; check for (64K) overflow
  6637                              <1> 	; 18/07/2022
  6638                              <1> 	; (512 bytes/sector)
  6639 000019A0 6681C2FF01          <1> 	add	dx, 511
  6640 000019A5 7239                <1> 	jc	short dma_bnd_err
  6641                              <1> 	;
  6642                              <1> 	;sub	dx, cx ; 11/07/2022	; Restore start address
  6643                              <1> J33:
  6644                              <1> 	; 08/07/2022
  6645 000019A7 FA                  <1> 	cli				; DISABLE INTERRUPTS DURING DMA SET-UP
  6646 000019A8 E60C                <1> 	out	DMA+12, al		; SET THE FIRST/LAST F/F
  6647                              <1> 	IODELAY				; WAIT FOR I/O
  6648 000019AA EB00                <2>  jmp short $+2
  6649 000019AC EB00                <2>  jmp short $+2
  6650 000019AE E60B                <1> 	out	DMA+11, al		; OUTPUT THE MODE BYTE
  6651                              <1> 	;mov	eax, edx		; Buffer address
  6652                              <1> 	; 11/07/2022
  6653 000019B0 89E8                <1> 	mov	eax, ebp ; buffer address
  6654 000019B2 E604                <1> 	out	DMA+4, al		; OUTPUT LOW ADDRESS
  6655                              <1> 	IODELAY				; WAIT FOR I/O
  6656 000019B4 EB00                <2>  jmp short $+2
  6657 000019B6 EB00                <2>  jmp short $+2
  6658 000019B8 88E0                <1> 	mov	al, ah
  6659 000019BA E604                <1> 	out	DMA+4, al		; OUTPUT HIGH ADDRESS
  6660 000019BC C1E810              <1> 	shr	eax, 16
  6661                              <1> 	IODELAY				; I/O WAIT STATE
  6662 000019BF EB00                <2>  jmp short $+2
  6663 000019C1 EB00                <2>  jmp short $+2
  6664 000019C3 E681                <1> 	out	081h, al		; OUTPUT highest BITS TO PAGE REGISTER
  6665                              <1> 	IODELAY
  6666 000019C5 EB00                <2>  jmp short $+2
  6667 000019C7 EB00                <2>  jmp short $+2
  6668                              <1> 	;;mov	ax, cx			; Byte count - 1
  6669                              <1> 	;mov	al, cl
  6670                              <1> 	; 18/07/2022
  6671                              <1> 	; (Byte count - 1 = 511)
  6672 000019C9 B0FF                <1> 	mov	al, 0FFh ; 511-256
  6673 000019CB E605                <1> 	out	DMA+5, al		; LOW BYTE OF COUNT
  6674                              <1> 	IODELAY				; WAIT FOR I/O
  6675 000019CD EB00                <2>  jmp short $+2
  6676 000019CF EB00                <2>  jmp short $+2
  6677                              <1> 	;;mov	al, ah
  6678                              <1> 	;mov	al, ch
  6679                              <1> 	; 18/07/2022
  6680 000019D1 B001                <1> 	mov	al, 1 ; 256
  6681 000019D3 E605                <1> 	out	DMA+5, al		; HIGH BYTE OF COUNT
  6682                              <1> 	IODELAY
  6683 000019D5 EB00                <2>  jmp short $+2
  6684 000019D7 EB00                <2>  jmp short $+2
  6685 000019D9 FB                  <1> 	sti				; RE-ENABLE INTERRUPTS
  6686 000019DA B002                <1> 	mov	al, 2			; MODE FOR 8237
  6687 000019DC E60A                <1> 	out	DMA+10, al		; INITIALIZE THE DISKETTE CHANNEL
  6688                              <1> 	
  6689 000019DE F8                  <1> 	clc	; 04/02/2016
  6690                              <1> 	
  6691 000019DF C3                  <1> 	retn
  6692                              <1> 
  6693                              <1> 	; 18/07/2022
  6694                              <1> ;dma_bnd_err_stc:
  6695                              <1> ;	stc
  6696                              <1> 
  6697                              <1> dma_bnd_err:
  6698 000019E0 C605[EC670000]09    <1> 	mov	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6699 000019E7 C3                  <1> 	retn				; CY SET BY ABOVE IF ERROR
  6700                              <1> 
  6701                              <1> ;-------------------------------------------------------------------------------
  6702                              <1> ; NEC_INIT	
  6703                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  6704                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  6705                              <1> ;
  6706                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  6707                              <1> ;
  6708                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6709                              <1> ;-------------------------------------------------------------------------------
  6710                              <1> NEC_INIT:
  6711                              <1> 	; 11/07/2022
  6712                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6713                              <1> 	;push	ax			; SAVE NEC COMMAND
  6714                              <1> 	; 24/12/2021
  6715 000019E8 50                  <1> 	push	eax
  6716 000019E9 E886020000          <1> 	call	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  6717                              <1> 
  6718                              <1> ;-----	DO THE SEEK OPERATION
  6719                              <1> 
  6720                              <1> 	;mov	ch, [ebp+1]		; CH = TRACK #
  6721                              <1> 	; 11/07/2022
  6722 000019EE 89F1                <1> 	mov	ecx, esi ; byte 2 = track, byte = 1 head, byte 0 = sector
  6723 000019F0 C1E908              <1> 	shr	ecx, 8
  6724                              <1> 	; ch = track #	
  6725                              <1> 
  6726 000019F3 E86B030000          <1> 	call	SEEK			; MOVE TO CORRECT TRACK
  6727                              <1> 	;pop	ax			; RECOVER COMMAND
  6728                              <1> 	; 24/12/2021
  6729 000019F8 58                  <1> 	pop	eax
  6730 000019F9 721D                <1> 	jc	short ER_1		; ERROR ON SEEK
  6731 000019FB BB[181A0000]        <1> 	mov	ebx, ER_1		; LOAD ERROR ADDRESS
  6732 00001A00 53                  <1> 	push	ebx			; PUSH NEC_OUT ERROR RETURN
  6733                              <1> 
  6734                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  6735                              <1> 
  6736 00001A01 E824030000          <1> 	call	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  6737 00001A06 89F0                <1> 	mov	eax, esi		; AH = HEAD #
  6738 00001A08 89FB                <1> 	mov	ebx, edi		; BL = DRIVE #
  6739 00001A0A C0E402              <1> 	sal	ah, 2			; MOVE IT TO BIT 2
  6740 00001A0D 80E404              <1> 	and	ah, 00000100b		; ISOLATE THAT BIT
  6741 00001A10 08DC                <1> 	or	ah, bl			; OR IN THE DRIVE NUMBER
  6742 00001A12 E813030000          <1> 	call	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  6743 00001A17 5B                  <1> 	pop	ebx			; THROW AWAY ERROR RETURN
  6744                              <1> ER_1:
  6745 00001A18 C3                  <1> 	retn
  6746                              <1> 
  6747                              <1> ;-------------------------------------------------------------------------------
  6748                              <1> ; RWV_COM
  6749                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  6750                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  6751                              <1> ;
  6752                              <1> ; ON ENTRY:	EBX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  6753                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6754                              <1> ;-------------------------------------------------------------------------------
  6755                              <1> RWV_COM:
  6756                              <1> 	; 11/07/2022
  6757                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6758 00001A19 B8[661A0000]        <1> 	mov	eax, ER_2		; LOAD ERROR ADDRESS
  6759 00001A1E 50                  <1> 	push	eax			; PUSH NEC_OUT ERROR RETURN
  6760                              <1> 	;mov	ah, [ebp+1]		; OUTPUT TRACK #
  6761                              <1> 	; 11/07/2022
  6762 00001A1F 89F0                <1> 	mov	eax, esi ; byte 0 = sector, byte 1 = head, byte 2 = track
  6763 00001A21 C1E808              <1> 	shr	eax, 8
  6764                              <1> 	; ah = track # 
  6765 00001A24 E801030000          <1> 	call	NEC_OUTPUT
  6766 00001A29 89F0                <1> 	mov	eax, esi		; OUTPUT HEAD #
  6767                              <1> 	; ah = head #
  6768 00001A2B E8FA020000          <1> 	call	NEC_OUTPUT
  6769                              <1>         ;mov	ah, [ebp]		; OUTPUT SECTOR #
  6770 00001A30 89F0                <1> 	mov	eax, esi
  6771 00001A32 88C4                <1> 	mov	ah, al
  6772                              <1>  	; ah = sector #
  6773 00001A34 E8F1020000          <1> 	CALL	NEC_OUTPUT
  6774                              <1> 	;mov	dl, 3			; BYTES/SECTOR PARAMETER FROM BLOCK
  6775 00001A39 B003                <1> 	mov	al, 3 ; 08/07/2022
  6776 00001A3B E8F9010000          <1> 	call	GET_PARM 		; .. TO THE NEC
  6777 00001A40 E8E5020000          <1> 	call	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6778                              <1> 	;mov	dl, 4			; EOT PARAMETER FROM BLOCK
  6779 00001A45 B004                <1> 	mov	al, 4 ; 08/07/2022
  6780 00001A47 E8ED010000          <1> 	call	GET_PARM 		; .. TO THE NEC
  6781 00001A4C E8D9020000          <1> 	call	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6782 00001A51 8A6305              <1>         mov	ah, [ebx+MD.GAP]	; GET GAP LENGTH
  6783                              <1> _R15:
  6784 00001A54 E8D1020000          <1> 	call	NEC_OUTPUT
  6785                              <1> 	;mov	dl, 6			; DTL PARAMETER PROM BLOCK
  6786 00001A59 B006                <1> 	mov	al, 6 ; 08/07/2022
  6787 00001A5B E8D9010000          <1> 	call	GET_PARM		; .. TO THE NEC
  6788 00001A60 E8C5020000          <1> 	call	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  6789 00001A65 58                  <1> 	pop	eax			; THROW AWAY ERROR EXIT
  6790                              <1> ER_2:
  6791 00001A66 C3                  <1> 	retn
  6792                              <1> 
  6793                              <1> ;-------------------------------------------------------------------------------
  6794                              <1> ; NEC_TERM
  6795                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  6796                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  6797                              <1> ;
  6798                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6799                              <1> ;-------------------------------------------------------------------------------
  6800                              <1> 
  6801                              <1> NEC_TERM:
  6802                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6803                              <1> 
  6804                              <1> ;-----	LET THE OPERATION HAPPEN
  6805                              <1> 
  6806 00001A67 56                  <1> 	push	esi			; SAVE HEAD #, # OF SECTORS
  6807 00001A68 E8C7030000          <1> 	call	WAIT_INT		; WAIT FOR THE INTERRUPT
  6808 00001A6D 9C                  <1> 	pushfd	; 24/12/2021
  6809 00001A6E E8F0030000          <1> 	call	RESULTS			; GET THE NEC STATUS
  6810 00001A73 724B                <1> 	jc	short SET_END_POP
  6811 00001A75 9D                  <1> 	popfd	; 24/12/2021
  6812 00001A76 723E                <1> 	jc	short SET_END		; LOOK FOR ERROR
  6813                              <1> 
  6814                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  6815                              <1> 
  6816 00001A78 FC                  <1> 	cld				; SET THE CORRECT DIRECTION
  6817 00001A79 BE[ED670000]        <1> 	mov	esi, NEC_STATUS		; POINT TO STATUS FIELD
  6818 00001A7E AC                  <1> 	lodsb				; GET ST0
  6819 00001A7F 24C0                <1> 	and	al, 11000000b		; TEST FOR NORMAL TERMINATION
  6820 00001A81 7433                <1> 	jz	short SET_END
  6821 00001A83 3C40                <1> 	cmp	al, 01000000b		; TEST FOR ABNORMAL TERMINATION
  6822 00001A85 7527                <1> 	jnz	short J18		; NOT ABNORMAL, BAD NEC
  6823                              <1> 
  6824                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  6825                              <1> 
  6826 00001A87 AC                  <1> 	lodsb				; GET ST1
  6827 00001A88 D0E0                <1> 	sal	al, 1			; TEST FOR EDT FOUND
  6828 00001A8A B404                <1> 	mov	ah, RECORD_NOT_FND
  6829 00001A8C 7222                <1> 	jc	short J19
  6830 00001A8E C0E002              <1> 	sal	al, 2
  6831 00001A91 B410                <1> 	mov	ah, BAD_CRC
  6832 00001A93 721B                <1> 	jc	short J19
  6833 00001A95 D0E0                <1> 	sal	al, 1			; TEST FOR DMA OVERRUN
  6834 00001A97 B408                <1> 	mov	ah, BAD_DMA
  6835 00001A99 7215                <1> 	jc	short J19
  6836 00001A9B C0E002              <1> 	sal	al, 2			; TEST FOR RECORD NOT FOUND
  6837 00001A9E B404                <1> 	mov	ah, RECORD_NOT_FND
  6838 00001AA0 720E                <1> 	jc	short J19
  6839 00001AA2 D0E0                <1> 	sal	al, 1
  6840 00001AA4 B403                <1> 	mov	ah, WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  6841 00001AA6 7208                <1> 	jc	short J19
  6842 00001AA8 D0E0                <1> 	sal	al, 1			; TEST MISSING ADDRESS MARK
  6843 00001AAA B402                <1> 	mov	ah, BAD_ADDR_MARK
  6844 00001AAC 7202                <1> 	jc	short J19
  6845                              <1> 
  6846                              <1> ;----- 	NEC MUST HAVE FAILED
  6847                              <1> J18:
  6848 00001AAE B420                <1> 	mov	ah, BAD_NEC
  6849                              <1> J19:
  6850 00001AB0 0825[EC670000]      <1> 	or	[DSKETTE_STATUS], ah
  6851                              <1> SET_END:
  6852 00001AB6 803D[EC670000]01    <1> 	cmp	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  6853 00001ABD F5                  <1> 	cmc
  6854 00001ABE 5E                  <1> 	pop	esi
  6855 00001ABF C3                  <1> 	retn				; RESTORE HEAD #, # OF SECTORS
  6856                              <1> 
  6857                              <1> SET_END_POP:
  6858 00001AC0 9D                  <1> 	popfd	; 24/12/2021
  6859 00001AC1 EBF3                <1> 	jmp	short SET_END
  6860                              <1> 
  6861                              <1> ;-------------------------------------------------------------------------------
  6862                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  6863                              <1> ;-------------------------------------------------------------------------------
  6864                              <1> DSTATE:
  6865                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6866 00001AC3 803D[EC670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; CHECK FOR ERROR
  6867 00001ACA 753E                <1> 	jne	short SETBAC		; IF ERROR JUMP
  6868 00001ACC 808F[F7670000]10    <1> 	or	byte [DSK_STATE+edi], MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  6869 00001AD3 F687[F7670000]04    <1> 	test	byte [DSK_STATE+edi], DRV_DET ; DRIVE DETERMINED ?
  6870 00001ADA 752E                <1> 	jnz	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  6871 00001ADC 8A87[F7670000]      <1> 	mov	al, [DSK_STATE+edi]	; LOAD STATE
  6872 00001AE2 24C0                <1> 	and	al, RATE_MSK		; KEEP ONLY RATE
  6873 00001AE4 3C80                <1> 	cmp	al, RATE_250		; RATE 250 ?
  6874 00001AE6 751B                <1> 	jne	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  6875                              <1> 
  6876                              <1> ;----- 	CHECK IF IT IS 1.44M
  6877                              <1> 
  6878 00001AE8 E843010000          <1> 	call	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6879                              <1> 	;;20/02/2015
  6880                              <1> 	;;jc	short M_12		; CMOS BAD
  6881 00001AED 7414                <1> 	jz	short M_12 ;; 20/02/2015
  6882 00001AEF 3C04                <1> 	cmp	al, 4			; 1.44MB DRIVE ?
  6883 00001AF1 7410                <1> 	je	short M_12		; YES
  6884                              <1> M_720:
  6885 00001AF3 80A7[F7670000]FD    <1> 	and	byte [DSK_STATE+edi], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  6886 00001AFA 808F[F7670000]04    <1> 	or	byte [DSK_STATE+edi], DRV_DET  ; MARK DRIVE DETERMINED
  6887 00001B01 EB07                <1> 	jmp	short SETBAC		; BACK
  6888                              <1> M_12:	
  6889 00001B03 808F[F7670000]06    <1> 	or	byte [DSK_STATE+edi], DRV_DET+FMT_CAPA 
  6890                              <1> 					; TURN ON DETERMINED & FMT CAPA
  6891                              <1> SETBAC:
  6892 00001B0A C3                  <1> 	retn
  6893                              <1> 
  6894                              <1> ;-------------------------------------------------------------------------------
  6895                              <1> ; RETRY	
  6896                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  6897                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  6898                              <1> ;
  6899                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  6900                              <1> ;-------------------------------------------------------------------------------
  6901                              <1> RETRY:
  6902                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6903 00001B0B 803D[EC670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; GET STATUS OF OPERATION
  6904 00001B12 7444                <1> 	je	short NO_RETRY		; SUCCESSFUL OPERATION
  6905 00001B14 803D[EC670000]80    <1> 	cmp	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT NO RETRY
  6906 00001B1B 743B                <1> 	je	short NO_RETRY
  6907 00001B1D 8AA7[F7670000]      <1> 	mov	ah, [DSK_STATE+edi]	; GET MEDIA STATE OF DRIVE
  6908 00001B23 F6C410              <1> 	test	ah, MED_DET		; ESTABLISHED/DETERMINED ?
  6909 00001B26 7530                <1> 	jnz	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  6910 00001B28 80E4C0              <1> 	and	ah, RATE_MSK		; ISOLATE RATE
  6911 00001B2B 8A2D[F4670000]      <1> 	mov	ch, [LASTRATE]		; GET START OPERATION STATE
  6912 00001B31 C0C504              <1> 	rol	ch, 4			; TO CORRESPONDING BITS
  6913 00001B34 80E5C0              <1> 	and	ch, RATE_MSK		; ISOLATE RATE BITS
  6914 00001B37 38E5                <1> 	cmp	ch, ah			; ALL RATES TRIED
  6915 00001B39 741D                <1> 	je	short NO_RETRY		; IF YES, THEN TRUE ERROR
  6916                              <1> 
  6917                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  6918                              <1> ;	 00000000B (500) -> 10000000B	(250)
  6919                              <1> ;	 10000000B (250) -> 01000000B	(300)
  6920                              <1> ;	 01000000B (300) -> 00000000B	(500)
  6921                              <1> 
  6922 00001B3B 80FC01              <1> 	cmp	ah, RATE_500+1		; SET CY FOR RATE 500
  6923 00001B3E D0DC                <1> 	rcr	ah, 1			; TO NEXT STATE
  6924 00001B40 80E4C0              <1> 	and	ah, RATE_MSK		; KEEP ONLY RATE BITS
  6925 00001B43 80A7[F7670000]1F    <1> 	and	byte [DSK_STATE+edi], ~(RATE_MSK+DBL_STEP)
  6926                              <1> 					; RATE, DBL STEP OFF
  6927 00001B4A 08A7[F7670000]      <1> 	or	[DSK_STATE+edi], ah	; TURN ON NEW RATE
  6928 00001B50 C605[EC670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; RESET STATUS FOR RETRY
  6929 00001B57 F9                  <1> 	stc				; SET CARRY FOR RETRY
  6930                              <1> NO_RETRY:	; 08/07/2022
  6931 00001B58 C3                  <1> 	retn				; RETRY RETURN
  6932                              <1> 
  6933                              <1> ;NO_RETRY:
  6934                              <1> 	;clc				; CLEAR CARRY NO RETRY
  6935                              <1> 	;RETn				; NO RETRY RETURN
  6936                              <1> 
  6937                              <1> ;-------------------------------------------------------------------------------
  6938                              <1> ; NUM_TRANS
  6939                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  6940                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  6941                              <1> ;
  6942                              <1> ; ON ENTRY:	[BP+1] = TRACK
  6943                              <1> ;		SI-HI  = HEAD
  6944                              <1> ;		[BP]   = START SECTOR
  6945                              <1> ;
  6946                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  6947                              <1> ;-------------------------------------------------------------------------------
  6948                              <1> NUM_TRANS:
  6949                              <1> 	; 11/07/2022
  6950                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6951 00001B59 30C0                <1> 	xor	al, al			; CLEAR FOR ERROR
  6952 00001B5B 803D[EC670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; CHECK FOR ERROR
  6953                              <1> 	; 24/12/2021
  6954 00001B62 7529                <1> 	jne	short NT_OUT		; IF ERROR 0 TRANSFERRED
  6955                              <1> 	;mov	dl, 4			; SECTORS/TRACK OFFSET TO DL
  6956 00001B64 B004                <1> 	mov	al, 4 ; 08/07/2022
  6957 00001B66 E8CE000000          <1> 	call	GET_PARM		; AH = SECTORS/TRACK
  6958                              <1> 	;mov	bl, [NEC_STATUS+5]	; GET ENDING SECTOR
  6959 00001B6B A0[F2670000]        <1> 	mov	al, [NEC_STATUS+5]
  6960 00001B70 89F1                <1> 	mov	ecx, esi		; CH = HEAD # STARTED
  6961 00001B72 88CB                <1> 	mov	bl, cl ; 11/07/2022 ; sector #
  6962 00001B74 3A2D[F1670000]      <1> 	cmp	ch, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  6963 00001B7A 750D                <1> 	jne	short DIF_HD		; IF ON SAME HEAD, THEN NO ADJUST
  6964                              <1> 	; 11/07/2022
  6965                              <1> 	;mov	ch, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  6966                              <1> 	;cmp	ch, [ebp+1]		; IS IT ASKED FOR TRACK
  6967                              <1> 	;jz	short SAME_TR		; IF SAME TRACK NO INCREASE
  6968 00001B7C C1E908              <1> 	shr	ecx, 8 ; byte 3 = track # --> byte 2
  6969 00001B7F 3A2D[F0670000]      <1> 	cmp	ch, [NEC_STATUS+3]
  6970 00001B85 7404                <1> 	je	short SAME_TRK		
  6971                              <1> 	; 11/07/2022
  6972                              <1> 	;add	bl, ah			; ADD SECTORS/TRACK
  6973 00001B87 00E0                <1> 	add	al, ah
  6974                              <1> DIF_HD:
  6975                              <1> 	;add	bl, ah			; ADD SECTORS/TRACK
  6976 00001B89 00E0                <1> 	add	al, ah
  6977                              <1> SAME_TRK:
  6978                              <1> 	;sub	bl, [ebp]		; SUBTRACT START FROM END
  6979                              <1> 	;mov	al, bl			; TO AL
  6980 00001B8B 28D8                <1> 	sub	al, bl
  6981                              <1> NT_OUT:
  6982 00001B8D C3                  <1> 	retn
  6983                              <1> 
  6984                              <1> ;-------------------------------------------------------------------------------
  6985                              <1> ; SETUP_DBL
  6986                              <1> ;	CHECK DOUBLE STEP.
  6987                              <1> ;
  6988                              <1> ; ON ENTRY :	EDI = DRIVE #
  6989                              <1> ;
  6990                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  6991                              <1> ;-------------------------------------------------------------------------------
  6992                              <1> SETUP_DBL:
  6993                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  6994 00001B8E 8AA7[F7670000]      <1> 	mov	ah, [DSK_STATE+edi]	; ACCESS STATE
  6995 00001B94 F6C410              <1> 	test	ah, MED_DET		; ESTABLISHED STATE ?
  6996 00001B97 7578                <1> 	jnz	short NO_DBL		; IF ESTABLISHED THEN DOUBLE DONE
  6997                              <1> 
  6998                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  6999                              <1> 
  7000 00001B99 C605[E9670000]00    <1> 	mov	byte [SEEK_STATUS], 0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  7001 00001BA0 E8CF000000          <1> 	call	MOTOR_ON		; ENSURE MOTOR STAY ON
  7002 00001BA5 B500                <1> 	mov	ch, 0			; LOAD TRACK 0
  7003 00001BA7 E8B7010000          <1> 	call	SEEK			; SEEK TO TRACK 0
  7004 00001BAC E862000000          <1> 	call	READ_ID			; READ ID FUNCTION
  7005 00001BB1 7243                <1> 	jc	short SD_ERR		; IF ERROR NO TRACK 0
  7006                              <1> 
  7007                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  7008                              <1> 
  7009 00001BB3 66B95004            <1> 	mov	cx, 0450h 		; START, MAX TRACKS
  7010 00001BB7 F687[F7670000]01    <1> 	test	byte [DSK_STATE+edi], TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  7011 00001BBE 7402                <1> 	jz	short CNT_OK		; IF NOT COUNT IS SETUP
  7012 00001BC0 B1A0                <1> 	mov	cl, 0A0h		; MAXIMUM TRACK 1.2 MB
  7013                              <1> 
  7014                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  7015                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  7016                              <1> ;	THEN SET DOUBLE STEP ON.
  7017                              <1> 
  7018                              <1> CNT_OK:
  7019 00001BC2 C605[EB670000]FF    <1>        	mov	byte [MOTOR_COUNT], 0FFh ; ENSURE MOTOR STAYS ON FOR OPERATION 
  7020                              <1> 	; 24/12/2021
  7021 00001BC9 51                  <1> 	push	ecx			; SAVE TRACK, COUNT
  7022 00001BCA C605[EC670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS, EXPECT ERRORS
  7023 00001BD1 31C0                <1> 	xor	eax, eax		; CLEAR EAX
  7024 00001BD3 D0ED                <1> 	shr	ch, 1			; HALVE TRACK, CY = HEAD
  7025 00001BD5 C0D003              <1> 	rcl	al, 3			; AX = HEAD IN CORRECT BIT
  7026                              <1> 	; 24/12/2021
  7027 00001BD8 50                  <1> 	push	eax			; SAVE HEAD
  7028 00001BD9 E885010000          <1> 	call	SEEK			; SEEK TO TRACK
  7029                              <1> 	; 24/12/2021
  7030 00001BDE 58                  <1> 	pop	eax			; RESTORE HEAD
  7031 00001BDF 09C7                <1> 	or	edi, eax		; DI = HEAD OR'ED DRIVE
  7032 00001BE1 E82D000000          <1> 	call	READ_ID			; READ ID HEAD 0
  7033 00001BE6 9C                  <1> 	pushf				; SAVE RETURN FROM READ_ID
  7034 00001BE7 6681E7FB00          <1> 	and	di, 11111011b		; TURN OFF HEAD 1 BIT
  7035 00001BEC 9D                  <1> 	popf				; RESTORE ERROR RETURN
  7036                              <1> 	; 24/12/2021
  7037 00001BED 59                  <1> 	pop	ecx			; RESTORE COUNT
  7038 00001BEE 7308                <1> 	jnc	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  7039 00001BF0 FEC5                <1> 	inc	ch			; INC FOR NEXT TRACK
  7040 00001BF2 38CD                <1> 	cmp	ch, cl			; REACHED MAXIMUM YET
  7041 00001BF4 75CC                <1> 	jnz	short CNT_OK		; CONTINUE TILL ALL TRIED
  7042                              <1> 
  7043                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  7044                              <1> 
  7045                              <1> SD_ERR:	
  7046 00001BF6 F9                  <1> 	stc				; SET CARRY FOR ERROR
  7047 00001BF7 C3                  <1> 	retn				; SETUP_DBL ERROR EXIT
  7048                              <1> 
  7049                              <1> DO_CHK:
  7050 00001BF8 8A0D[F0670000]      <1> 	mov	cl, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  7051 00001BFE 888F[F9670000]      <1> 	mov	[DSK_TRK+edi], cl	; STORE TRACK NUMBER
  7052 00001C04 D0ED                <1> 	shr	ch, 1			; HALVE TRACK
  7053 00001C06 38CD                <1> 	cmp	ch, cl			; IS IT THE SAME AS ASKED FOR TRACK
  7054 00001C08 7407                <1> 	jz	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  7055 00001C0A 808F[F7670000]20    <1> 	or	byte [DSK_STATE+edi], DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  7056                              <1> NO_DBL:
  7057 00001C11 F8                  <1> 	clc				; CLEAR ERROR FLAG
  7058 00001C12 C3                  <1> 	retn
  7059                              <1> 
  7060                              <1> ;-------------------------------------------------------------------------------
  7061                              <1> ; READ_ID
  7062                              <1> ;	READ ID FUNCTION.
  7063                              <1> ;
  7064                              <1> ; ON ENTRY:	EDI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  7065                              <1> ;
  7066                              <1> ; ON EXIT: 	EDI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  7067                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7068                              <1> ;-------------------------------------------------------------------------------
  7069                              <1> READ_ID:
  7070                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7071 00001C13 B8[2F1C0000]        <1> 	mov	eax, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  7072 00001C18 50                  <1> 	push	eax
  7073 00001C19 B44A                <1> 	mov	ah, 4Ah			; READ ID COMMAND
  7074 00001C1B E80A010000          <1> 	call	NEC_OUTPUT		; TO CONTROLLER
  7075 00001C20 89F8                <1> 	mov	eax, edi		; DRIVE # TO AH, HEAD 0
  7076 00001C22 88C4                <1> 	mov	ah, al
  7077 00001C24 E801010000          <1> 	call	NEC_OUTPUT		; TO CONTROLLER
  7078 00001C29 E839FEFFFF          <1> 	call	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  7079 00001C2E 58                  <1> 	pop	eax			; THROW AWAY ERROR ADDRESS
  7080                              <1> ER_3:
  7081 00001C2F C3                  <1> 	retn
  7082                              <1> 
  7083                              <1> ;-------------------------------------------------------------------------------
  7084                              <1> ; CMOS_TYPE
  7085                              <1> ;	RETURNS CMOS DISKETTE TYPE
  7086                              <1> ;
  7087                              <1> ; ON ENTRY:	EDI = DRIVE #
  7088                              <1> ;
  7089                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  7090                              <1> ;-------------------------------------------------------------------------------
  7091                              <1> 
  7092                              <1> CMOS_TYPE: ; 11/12/2014
  7093                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7094 00001C30 8A87[8C620000]      <1> 	mov	al, [edi+fd0_type] ; diskette type
  7095 00001C36 20C0                <1> 	and 	al, al ; 18/12/2014
  7096 00001C38 C3                  <1> 	retn
  7097                              <1> 
  7098                              <1> ;-------------------------------------------------------------------------------
  7099                              <1> ; GET_PARM
  7100                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  7101                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  7102                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  7103                              <1> ;	THE PARAMETER IN DL.
  7104                              <1> ;
  7105                              <1> ; ON ENTRY:	AL = INDEX OF BYTE TO BE FETCHED ; 08/07/2022
  7106                              <1> ;
  7107                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  7108                              <1> ;		AL DESTROYED
  7109                              <1> ;-------------------------------------------------------------------------------
  7110                              <1> GET_PARM:
  7111                              <1> 	; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7112                              <1> 	;	 ENTRY:
  7113                              <1> 	;	     AL = INDEX
  7114                              <1> 	;	    EDI = DRIVE #
  7115                              <1> 	; 	 RETURN:
  7116                              <1> 	;	     AH = REQUESTED PARAMETER
  7117                              <1> 	;	     AL DESTROYED
  7118                              <1> 	
  7119                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7120                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  7121                              <1> 	;push	esi ; 11/07/2022
  7122 00001C39 53                  <1> 	push	ebx			; SAVE EBX	
  7123 00001C3A 0FB6D8              <1> 	movzx	ebx, al			; EBX = INDEX
  7124                              <1>    	; 17/12/2014
  7125                              <1> 	;mov	ax, [cfd] ; current (AL) and previous fd (AH)
  7126                              <1> 	; 11/07/2022
  7127                              <1> 	;cmp	al, ah
  7128                              <1> 	;je	short gpndc
  7129                              <1> 
  7130                              <1> 	; 11/07/2022
  7131 00001C3D 89F8                <1> 	mov	eax, edi
  7132 00001C3F 3A05[81620000]      <1> 	cmp	al, [pfd] ; is same with previous drive # ?
  7133 00001C45 7423                <1> 	je	short gpndc	
  7134                              <1> 
  7135 00001C47 A2[81620000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  7136                              <1> 
  7137 00001C4C 53                  <1> 	push	ebx ; 08/02/2015
  7138                              <1> 	
  7139                              <1> 	;mov	bl, al 
  7140                              <1> 	; 11/12/2014
  7141                              <1> 	;mov	al, [ebx+fd0_type]	; Drive type (0,1,2,3,4)
  7142                              <1> 	; 11/07/2022
  7143 00001C4D 8A87[8C620000]      <1> 	mov	al, [edi+fd0_type]	; Drive type (0,1,2,3,4)	
  7144                              <1> 	; 18/12/2014
  7145 00001C53 20C0                <1> 	and	al, al
  7146 00001C55 7507                <1> 	jnz	short gpdtc
  7147 00001C57 BB[6B620000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  7148 00001C5C EB05                <1>         jmp     short gpdpu
  7149                              <1> gpdtc:	
  7150 00001C5E E8B0FBFFFF          <1> 	call	DR_TYPE_CHECK
  7151                              <1> 	; cf = 1 -> EBX points to 1.44MB fd parameter table (default)
  7152                              <1> gpdpu:
  7153 00001C63 891D[08620000]      <1> 	mov	[DISK_POINTER], ebx
  7154 00001C69 5B                  <1> 	pop	ebx
  7155                              <1> gpndc:
  7156                              <1> 	;mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  7157                              <1> 	;mov	ah, [esi+ebx]		; GET THE WORD
  7158                              <1> 	; 11/07/2022
  7159 00001C6A 031D[08620000]      <1> 	add	ebx, [DISK_POINTER]
  7160 00001C70 8A23                <1> 	mov	ah, [ebx] 
  7161 00001C72 5B                  <1> 	pop	ebx			; RESTORE EBX
  7162                              <1> 	;pop	esi ; 11/07/2022
  7163 00001C73 C3                  <1> 	retn
  7164                              <1> 
  7165                              <1> ;-------------------------------------------------------------------------------
  7166                              <1> ; MOTOR_ON
  7167                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  7168                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  7169                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  7170                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  7171                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  7172                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  7173                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  7174                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  7175                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  7176                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  7177                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  7178                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  7179                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  7180                              <1> ;
  7181                              <1> ; ON ENTRY:	EDI = DRIVE #
  7182                              <1> ; ON EXIT:	EAX, ECX, EDX DESTROYED
  7183                              <1> ;-------------------------------------------------------------------------------
  7184                              <1> MOTOR_ON:
  7185                              <1> 	; 12/07/2022
  7186                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7187 00001C74 53                  <1> 	push	ebx			; SAVE REG.
  7188 00001C75 E820000000          <1> 	call	TURN_ON			; TURN ON MOTOR
  7189 00001C7A 721C                <1> 	jc	short MOT_IS_ON		; IF CY=1 NO WAIT
  7190                              <1> 	;call	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7191                              <1> 	; 08/07/2022
  7192                              <1> 	;call	XLAT_NEW ; 12/07/2022	; TRANSLATE STATE TO PRESENT ARCH,
  7193                              <1> 	;call	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  7194                              <1> 	;jc	short MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  7195                              <1> M_WAIT:
  7196                              <1> 	;mov	dl,10			; GET THE MOTOR WAIT PARAMETER
  7197 00001C7C B00A                <1> 	mov	al, 10 ; 08/07/2022
  7198 00001C7E E8B6FFFFFF          <1> 	call	GET_PARM
  7199                              <1> 	; 08/07/2022			; AH = MOTOR WAIT PARAMETER
  7200 00001C83 80FC08              <1> 	cmp	ah, 8			; SEE IF AT LEAST A SECOND IS SPECIFIED			
  7201                              <1> 	;jae	short GP2		; IF YES, CONTINUE
  7202 00001C86 7302                <1> 	jae	short J13
  7203 00001C88 B408                <1> 	mov	ah, 8			; ONE SECOND WAIT FOR MOTOR START UP
  7204                              <1> 
  7205                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  7206                              <1> GP2:	
  7207                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  7208                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  7209 00001C8A B95E200000          <1> 	mov	ecx, 8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  7210 00001C8F E817F7FFFF          <1> 	call	WAITF			; GO TO FIXED WAIT ROUTINE
  7211                              <1> 	;dec	al			; DECREMENT TIME VALUE
  7212 00001C94 FECC                <1> 	dec	ah
  7213 00001C96 75F2                <1> 	jnz	short J13		; ARE WE DONE YET
  7214                              <1> MOT_IS_ON:
  7215 00001C98 5B                  <1> 	pop	ebx			; RESTORE REG.
  7216 00001C99 C3                  <1> 	retn
  7217                              <1> 
  7218                              <1> ;-------------------------------------------------------------------------------
  7219                              <1> ; TURN_ON
  7220                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  7221                              <1> ;
  7222                              <1> ; ON ENTRY:	EDI = DRIVE #
  7223                              <1> ;
  7224                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  7225                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  7226                              <1> ;		EAX, EBX, ECX, EDX DESTROYED
  7227                              <1> ;-------------------------------------------------------------------------------
  7228                              <1> TURN_ON:
  7229                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7230 00001C9A 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  7231 00001C9C 88D9                <1> 	mov	cl, bl			; CL = DRIVE #
  7232 00001C9E C0C304              <1> 	rol	bl, 4			; BL = DRIVE SELECT
  7233 00001CA1 FA                  <1> 	cli				; NO INTERRUPTS WHILE DETERMINING STATUS
  7234 00001CA2 C605[EB670000]FF    <1> 	mov	byte [MOTOR_COUNT], 0FFh ; ENSURE MOTOR STAYS ON FOR OPERATION
  7235 00001CA9 A0[EA670000]        <1> 	mov	al, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7236 00001CAE 2430                <1> 	and	al, 00110000b		; KEEP ONLY DRIVE SELECT BITS
  7237 00001CB0 B401                <1> 	mov	ah, 1			; MASK FOR DETERMINING MOTOR BIT
  7238 00001CB2 D2E4                <1> 	shl	ah, cl			; AH = MOTOR ON, A=00000001, B=00000010
  7239                              <1> 
  7240                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  7241                              <1> ;  BL = DRIVE SELECT DESIRED
  7242                              <1> ;  AH = MOTOR ON MASK DESIRED
  7243                              <1> 
  7244 00001CB4 38D8                <1> 	cmp	al, bl			; REQUESTED DRIVE ALREADY SELECTED ?
  7245 00001CB6 7508                <1> 	jne	short TURN_IT_ON	; IF NOT SELECTED JUMP
  7246 00001CB8 8425[EA670000]      <1> 	test	ah, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  7247 00001CBE 7535                <1> 	jnz	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  7248                              <1> 
  7249                              <1> TURN_IT_ON:
  7250 00001CC0 08DC                <1> 	or	ah, bl			; AH = DRIVE SELECT AND MOTOR ON
  7251 00001CC2 8A3D[EA670000]      <1> 	mov	bh, [MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  7252 00001CC8 80E70F              <1> 	and	bh, 00001111b		; KEEP ONLY MOTOR BITS
  7253 00001CCB 8025[EA670000]CF    <1> 	and	byte [MOTOR_STATUS], 11001111b ; CLEAR OUT DRIVE SELECT
  7254 00001CD2 0825[EA670000]      <1> 	or	[MOTOR_STATUS], ah	; OR IN DRIVE SELECTED AND MOTOR ON
  7255 00001CD8 A0[EA670000]        <1> 	mov	al, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7256 00001CDD 88C3                <1> 	mov	bl, al			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  7257 00001CDF 80E30F              <1> 	and	bl, 00001111b		; KEEP ONLY MOTOR BITS
  7258 00001CE2 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  7259 00001CE3 243F                <1> 	and	al, 00111111b		; STRIP AWAY UNWANTED BITS
  7260 00001CE5 C0C004              <1> 	rol	al, 4			; PUT BITS IN DESIRED POSITIONS
  7261 00001CE8 0C0C                <1> 	or	al, 00001100b		; NO RESET, ENABLE DMA/INTERRUPT
  7262 00001CEA 66BAF203            <1> 	mov	dx, 03F2h		; SELECT DRIVE AND TURN ON MOTOR
  7263 00001CEE EE                  <1> 	out	dx, al
  7264 00001CEF 38FB                <1> 	cmp	bl, bh			; NEW MOTOR TURNED ON ?
  7265                              <1> 	;je	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  7266 00001CF1 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  7267 00001CF3 F8                  <1> 	clc				; RESET CARRY MEANING WAIT
  7268 00001CF4 C3                  <1> 	retn
  7269                              <1> 
  7270                              <1> NO_MOT_WAIT:
  7271 00001CF5 FB                  <1> 	sti
  7272                              <1> no_mot_w1: ; 27/02/2015
  7273 00001CF6 F9                  <1> 	stc				; SET NO WAIT REQUIRED
  7274                              <1> 	;sti				; INTERRUPTS BACK ON
  7275 00001CF7 C3                  <1> 	retn
  7276                              <1> 
  7277                              <1> ;-------------------------------------------------------------------------------
  7278                              <1> ; HD_WAIT
  7279                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  7280                              <1> ;
  7281                              <1> ; ON ENTRY:	DI = DRIVE #
  7282                              <1> ;
  7283                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  7284                              <1> ;-------------------------------------------------------------------------------
  7285                              <1> HD_WAIT:
  7286                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7287                              <1> 	;mov	dl, 9			; GET HEAD SETTLE PARAMETER
  7288 00001CF8 B009                <1> 	mov	al, 9	; 08/07/2022
  7289 00001CFA E83AFFFFFF          <1> 	CALL	GET_PARM
  7290 00001CFF 08E4                <1> 	or	ah, ah	; 17/12/2014	; CHECK FOR ANY WAIT?
  7291 00001D01 7519                <1> 	jnz	short DO_WAT		; IF THERE DO NOT ENFORCE
  7292 00001D03 F605[EA670000]80    <1>         test	byte [MOTOR_STATUS], 10000000b ; SEE IF A WRITE OPERATION
  7293                              <1> 	;jz	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  7294                              <1> 	;or	ah, ah			; CHECK FOR ANY WAIT?
  7295                              <1> 	;jnz	short DO_WAT		; IF THERE DO NOT ENFORCE
  7296 00001D0A 741D                <1> 	jz	short HW_DONE
  7297 00001D0C B40F                <1> 	mov	ah, HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  7298 00001D0E 8A87[F7670000]      <1> 	mov	al, [DSK_STATE+edi]	; LOAD STATE
  7299 00001D14 24C0                <1> 	and	al, RATE_MSK		; KEEP ONLY RATE
  7300 00001D16 3C80                <1> 	cmp	al, RATE_250		; 1.2 M DRIVE ?
  7301 00001D18 7502                <1> 	jnz	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  7302                              <1> ;GP3:
  7303 00001D1A B414                <1> 	mov	ah, HD320_SETTLE		; USE 320/360 HEAD SETTLE
  7304                              <1> ;	jmp	short DO_WAT
  7305                              <1> 
  7306                              <1> ;ISNT_WRITE:
  7307                              <1> ;	or	ah, ah			; CHECK FOR NO WAIT
  7308                              <1> ;	jz	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  7309                              <1> 
  7310                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  7311                              <1> DO_WAT:
  7312                              <1> ;	mov	al, ah			; AL = # MILLISECONDS
  7313                              <1> ;	;xor	ah, ah			; AX = # MILLISECONDS
  7314                              <1> J29:					; 	1 MILLISECOND LOOP
  7315                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  7316                              <1> 	;mov	ecx, 66			; COUNT AT 15.085737 US PER COUNT
  7317                              <1> 	; 08/07/2022
  7318 00001D1C 29C9                <1> 	sub	ecx, ecx
  7319 00001D1E B142                <1> 	mov	cl, 66
  7320 00001D20 E886F6FFFF          <1> 	call	WAITF			; DELAY FOR 1 MILLISECOND
  7321                              <1> 	;dec	al			; DECREMENT THE COUNT
  7322 00001D25 FECC                <1> 	dec	ah
  7323 00001D27 75F3                <1> 	jnz	short J29		; DO AL MILLISECOND # OF TIMES
  7324                              <1> HW_DONE:
  7325 00001D29 C3                  <1> 	retn
  7326                              <1> 
  7327                              <1> ;-------------------------------------------------------------------------------
  7328                              <1> ; NEC_OUTPUT
  7329                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  7330                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  7331                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  7332                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  7333                              <1> ; 
  7334                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  7335                              <1> ;
  7336                              <1> ; ON EXIT:	CY = 0  SUCCESS
  7337                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  7338                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  7339                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  7340                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  7341                              <1> ;
  7342                              <1> ;		EAX, ECX, EDX DESTROYED
  7343                              <1> ;-------------------------------------------------------------------------------
  7344                              <1> 
  7345                              <1> ; 09/12/2014 [Erdogan Tan] 
  7346                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  7347                              <1> ; Diskette Drive Controller Status Register (3F4h)
  7348                              <1> ;	This read only register facilitates the transfer of data between
  7349                              <1> ;	the system microprocessor and the controller.
  7350                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  7351                              <1> ;	  with the system micrprocessor.
  7352                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  7353                              <1> ;	  the transfer is to the controller.
  7354                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  7355                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  7356                              <1> ; Bit 3 - Reserved.
  7357                              <1> ; Bit 2 - Reserved.
  7358                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7359                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 0 is in the seek mode.
  7360                              <1> 
  7361                              <1> ; Data Register (3F5h)
  7362                              <1> ; This read/write register passes data, commands and parameters, and provides
  7363                              <1> ; diskette status information.
  7364                              <1>   		
  7365                              <1> NEC_OUTPUT:
  7366                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7367                              <1> 	;push	ebx			; SAVE REG.
  7368 00001D2A BAF4030000          <1> 	mov	edx, 03F4h		; STATUS PORT
  7369                              <1> 	;xor	ecx, ecx		; COUNT FOR TIME OUT
  7370                              <1> 	; 16/12/2014
  7371                              <1> 	; waiting for (max.) 0.5 seconds
  7372                              <1>         ;;mov	byte [wait_count], 0 ;; 27/02/2015
  7373                              <1> 	;
  7374                              <1> 	; 17/12/2014
  7375                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  7376                              <1> 	;
  7377                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  7378                              <1> 	;		go on.
  7379                              <1> 	;INPUT:
  7380                              <1> 	;	AH=Mask for isolation bits.
  7381                              <1> 	;	AL=pattern to look for.
  7382                              <1> 	;	DX=Port to test for
  7383                              <1> 	;	ECX=Number of memory refresh periods to delay.
  7384                              <1> 	;	     (normally 30 microseconds per period.)
  7385                              <1> 	;
  7386                              <1> 	;WFP_SHORT:  
  7387                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  7388                              <1> 	;
  7389                              <1> 
  7390 00001D2F B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  7391                              <1> ;
  7392                              <1> ;WFPS_OUTER_LP:
  7393                              <1> ;	;
  7394                              <1> ;WFPS_CHECK_PORT:
  7395                              <1> J23:
  7396 00001D34 EC                  <1> 	in	al, dx			; GET STATUS
  7397 00001D35 24C0                <1> 	and	al, 11000000b		; KEEP STATUS AND DIRECTION
  7398 00001D37 3C80                <1> 	cmp	al, 10000000b		; STATUS 1 AND DIRECTION 0 ?
  7399 00001D39 7418                <1> 	jz	short J27		; STATUS AND DIRECTION OK
  7400                              <1> WFPS_HI:
  7401 00001D3B E461                <1> 	in	al, PORT_B	; 061h	; SYS1	; wait for hi to lo
  7402 00001D3D A810                <1> 	test	al, 010h		; transition on memory
  7403 00001D3F 75FA                <1> 	jnz	short WFPS_HI		; refresh.
  7404                              <1> WFPS_LO:
  7405 00001D41 E461                <1> 	in	al, PORT_B		; SYS1
  7406 00001D43 A810                <1> 	test	al, 010h
  7407 00001D45 74FA                <1> 	jz	short WFPS_LO
  7408                              <1> 	;loop	short WFPS_CHECK_PORT
  7409 00001D47 E2EB                <1> 	loop	J23	; 27/02/2015	; REPEAT TILL DELAY FINISHED
  7410                              <1> 
  7411                              <1> 	; fail
  7412                              <1> 
  7413                              <1> ;WFPS_TIMEOUT:
  7414                              <1> 
  7415                              <1> ;-----	FALL THRU TO ERROR RETURN
  7416                              <1> 
  7417 00001D49 800D[EC670000]80    <1> 	or	byte [DSKETTE_STATUS], TIME_OUT
  7418                              <1> 	;pop	ebx			; RESTORE REG.
  7419 00001D50 58                  <1> 	pop	eax ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  7420 00001D51 F9                  <1> 	stc				; INDICATE ERROR TO CALLER
  7421 00001D52 C3                  <1> 	retn
  7422                              <1> 
  7423                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  7424                              <1> 
  7425                              <1> J27:	
  7426 00001D53 88E0                <1> 	mov	al, ah			; GET BYTE TO OUTPUT
  7427 00001D55 42                  <1> 	inc	edx			; DATA PORT = STATUS PORT + 1
  7428 00001D56 EE                  <1> 	out	dx, al			; OUTPUT THE BYTE
  7429                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  7430                              <1> 	; 27/02/2015
  7431 00001D57 9C                  <1> 	pushfd	; 24/12/2021		; SAVE FLAGS
  7432                              <1> 	;mov	ecx, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  7433 00001D58 29C9                <1> 	sub	ecx, ecx
  7434 00001D5A B103                <1> 	mov	cl, 3 ; 24/12/2021
  7435 00001D5C E84AF6FFFF          <1> 	call 	WAITF			; NEC FLAGS UPDATE CYCLE
  7436 00001D61 9D                  <1> 	popfd	; 24/12/2021		; RESTORE FLAGS FOR EXIT
  7437                              <1> 	;pop	ebx			; RESTORE REG
  7438 00001D62 C3                  <1> 	retn				; CY = 0 FROM TEST INSTRUCTION
  7439                              <1> 
  7440                              <1> ;-------------------------------------------------------------------------------
  7441                              <1> ; SEEK
  7442                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  7443                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  7444                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  7445                              <1> ;
  7446                              <1> ; ON ENTRY:	EDI = DRIVE #
  7447                              <1> ;		CH = TRACK #
  7448                              <1> ;
  7449                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7450                              <1> ;		EAX, EBX, ECX, EDX DESTROYED
  7451                              <1> ;-------------------------------------------------------------------------------
  7452                              <1> SEEK:
  7453                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7454 00001D63 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  7455 00001D65 B001                <1> 	mov	al, 1			; ESTABLISH MASK FOR RECALIBRATE TEST
  7456 00001D67 86CB                <1> 	xchg	cl, bl			; SET DRIVE VALUE INTO CL
  7457 00001D69 D2C0                <1> 	rol	al, cl			; SHIFT MASK BY THE DRIVE VALUE
  7458 00001D6B 86CB                <1> 	xchg	cl, bl			; RECOVER DRIVE VALUE
  7459 00001D6D 8405[E9670000]      <1> 	test	al, [SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  7460 00001D73 7526                <1> 	jnz	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  7461                              <1> 
  7462 00001D75 0805[E9670000]      <1> 	or	[SEEK_STATUS], al	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  7463 00001D7B E862000000          <1> 	call	RECAL			; RECALIBRATE DRIVE
  7464 00001D80 730E                <1> 	jnc	short AFT_RECAL		; RECALIBRATE DONE
  7465                              <1> 
  7466                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  7467                              <1> 
  7468 00001D82 C605[EC670000]00    <1> 	mov	byte [DSKETTE_STATUS], 0 ; CLEAR OUT INVALID STATUS
  7469 00001D89 E854000000          <1> 	call	RECAL			; RECALIBRATE DRIVE
  7470 00001D8E 7251                <1> 	jc	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  7471                              <1> 
  7472                              <1> AFT_RECAL:
  7473 00001D90 C687[F9670000]00    <1> 	mov	byte [DSK_TRK+edi], 0	; SAVE NEW CYLINDER AS PRESENT POSITION
  7474 00001D97 08ED                <1> 	or	ch, ch			; CHECK FOR SEEK TO TRACK 0
  7475 00001D99 743F                <1> 	jz	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  7476                              <1> 
  7477                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  7478                              <1> 
  7479 00001D9B F687[F7670000]20    <1> J28A:	test	byte [DSK_STATE+edi], DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  7480 00001DA2 7402                <1> 	jz	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  7481 00001DA4 D0E5                <1> 	shl	ch, 1			; DOUBLE NUMBER OF STEP TO TAKE
  7482                              <1> 
  7483 00001DA6 3AAF[F9670000]      <1> _R7:	cmp	ch, [DSK_TRK+edi]	; SEE IF ALREADY AT THE DESIRED TRACK
  7484 00001DAC 7433                <1> 	je	short RB		; IF YES, DO NOT NEED TO SEEK
  7485                              <1> 
  7486 00001DAE BA[E11D0000]        <1> 	mov	edx, NEC_ERR		; LOAD RETURN ADDRESS
  7487 00001DB3 52                  <1> 	push	edx ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  7488 00001DB4 88AF[F9670000]      <1> 	mov	[DSK_TRK+edi], ch	; SAVE NEW CYLINDER AS PRESENT POSITION
  7489 00001DBA B40F                <1> 	mov	ah, 0Fh			; SEEK COMMAND TO NEC
  7490 00001DBC E869FFFFFF          <1> 	call	NEC_OUTPUT
  7491 00001DC1 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  7492 00001DC3 88DC                <1> 	mov	ah, bl			; OUTPUT DRIVE NUMBER
  7493 00001DC5 E860FFFFFF          <1> 	call	NEC_OUTPUT
  7494 00001DCA 8AA7[F9670000]      <1> 	mov	ah, [DSK_TRK+edi]	; GET CYLINDER NUMBER
  7495 00001DD0 E855FFFFFF          <1> 	call	NEC_OUTPUT
  7496 00001DD5 E827000000          <1> 	call	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  7497                              <1> 
  7498                              <1> ;-----	WAIT FOR HEAD SETTLE
  7499                              <1> 
  7500                              <1> DO_WAIT:
  7501 00001DDA 9C                  <1> 	pushfd	; 24/12/2021		; SAVE STATUS
  7502 00001DDB E818FFFFFF          <1> 	call	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  7503 00001DE0 9D                  <1> 	popfd	; 24/12/2021		; RESTORE STATUS
  7504                              <1> RB:
  7505                              <1> NEC_ERR:
  7506                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  7507                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  7508 00001DE1 C3                  <1> 	retn				; RETURN TO CALLER
  7509                              <1> 
  7510                              <1> ;-------------------------------------------------------------------------------
  7511                              <1> ; RECAL
  7512                              <1> ;	RECALIBRATE DRIVE
  7513                              <1> ;
  7514                              <1> ; ON ENTRY:	EDI = DRIVE #
  7515                              <1> ;
  7516                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  7517                              <1> ;-------------------------------------------------------------------------------
  7518                              <1> RECAL:
  7519                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7520                              <1> 	;push	cx
  7521                              <1> 	; 24/12/2021
  7522 00001DE2 51                  <1> 	push	ecx
  7523 00001DE3 B8[FF1D0000]        <1> 	mov	eax, RC_BACK		; LOAD NEC_OUTPUT ERROR
  7524 00001DE8 50                  <1> 	push	eax
  7525 00001DE9 B407                <1> 	mov	ah, 07h			; RECALIBRATE COMMAND
  7526 00001DEB E83AFFFFFF          <1> 	call	NEC_OUTPUT
  7527 00001DF0 89FB                <1> 	mov	ebx, edi		; EBX = DRIVE #
  7528 00001DF2 88DC                <1> 	mov	ah, bl
  7529 00001DF4 E831FFFFFF          <1> 	call	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  7530 00001DF9 E803000000          <1> 	call	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  7531 00001DFE 58                  <1> 	pop	eax			; THROW AWAY ERROR
  7532                              <1> RC_BACK:
  7533                              <1> 	;pop	cx
  7534                              <1> 	; 24/12/2021
  7535 00001DFF 59                  <1> 	pop	ecx
  7536 00001E00 C3                  <1> 	RETn
  7537                              <1> 
  7538                              <1> ;-------------------------------------------------------------------------------
  7539                              <1> ; CHK_STAT_2
  7540                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  7541                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  7542                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  7543                              <1> ;
  7544                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7545                              <1> ;-------------------------------------------------------------------------------
  7546                              <1> CHK_STAT_2:
  7547                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7548 00001E01 B8[291E0000]        <1>         mov	eax, CS_BACK		; LOAD NEC_OUTPUT ERROR ADDRESS
  7549 00001E06 50                  <1> 	push	eax
  7550 00001E07 E828000000          <1> 	call	WAIT_INT		; WAIT FOR THE INTERRUPT
  7551 00001E0C 721A                <1> 	jc	short J34		; IF ERROR, RETURN IT
  7552 00001E0E B408                <1> 	mov	ah, 08h			; SENSE INTERRUPT STATUS COMMAND
  7553 00001E10 E815FFFFFF          <1> 	call	NEC_OUTPUT
  7554 00001E15 E849000000          <1> 	call	RESULTS			; READ IN THE RESULTS
  7555 00001E1A 720C                <1> 	jc	short J34
  7556 00001E1C A0[ED670000]        <1> 	mov	al, [NEC_STATUS]	; GET THE FIRST STATUS BYTE
  7557 00001E21 2460                <1> 	and	al, 01100000b		; ISOLATE THE BITS
  7558 00001E23 3C60                <1> 	cmp	al, 01100000b		; TEST FOR CORRECT VALUE
  7559 00001E25 7403                <1> 	jz	short J35		; IF ERROR, GO MARK IT
  7560 00001E27 F8                  <1> 	clc				; GOOD RETURN
  7561                              <1> J34:
  7562 00001E28 58                  <1> 	pop	eax			; THROW AWAY ERROR RETURN
  7563                              <1> CS_BACK:
  7564 00001E29 C3                  <1> 	retn
  7565                              <1> J35:
  7566 00001E2A 800D[EC670000]40    <1> 	or	byte [DSKETTE_STATUS], BAD_SEEK
  7567 00001E31 F9                  <1> 	stc				; ERROR RETURN CODE
  7568 00001E32 EBF4                <1> 	jmp	short J34
  7569                              <1> 
  7570                              <1> ;-------------------------------------------------------------------------------
  7571                              <1> ; WAIT_INT
  7572                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  7573                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  7574                              <1> ;	IF THE DRIVE IS NOT READY.
  7575                              <1> ;
  7576                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7577                              <1> ;-------------------------------------------------------------------------------
  7578                              <1> 
  7579                              <1> ; 17/12/2014
  7580                              <1> ; 2.5 seconds waiting !
  7581                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  7582                              <1> ; amount of time to wait for completion interrupt from NEC.
  7583                              <1> 
  7584                              <1> WAIT_INT:
  7585                              <1> 	; 12/07/2022
  7586                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7587 00001E34 FB                  <1> 	sti				; TURN ON INTERRUPTS, JUST IN CASE
  7588                              <1> 	; 12/07/2022
  7589                              <1> 	;clc				; CLEAR TIMEOUT INDICATOR
  7590                              <1>        ;mov	bl, 10			; CLEAR THE COUNTERS
  7591                              <1>        ;xor	cx, cx			; FOR 2 SECOND WAIT
  7592                              <1> 
  7593                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  7594                              <1> 	;
  7595                              <1> 	;WAIT_FOR_MEM:	
  7596                              <1> 	;	Waits for a bit at a specified memory location pointed
  7597                              <1> 	;	to by ES:[DI] to become set.
  7598                              <1> 	;INPUT:
  7599                              <1> 	;	AH=Mask to test with.
  7600                              <1> 	;	ES:[DI] = memory location to watch.
  7601                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7602                              <1> 	;	     (normally 30 microseconds per period.)
  7603                              <1> 
  7604                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  7605                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  7606                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  7607                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  7608                              <1> 	; 27/02/2015
  7609 00001E35 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  7610                              <1> WFMS_CHECK_MEM:
  7611 00001E3A F605[E9670000]80    <1> 	test	byte [SEEK_STATUS], INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7612 00001E41 7516                <1>         jnz     short J37
  7613                              <1> WFMS_HI:
  7614 00001E43 E461                <1> 	in	al, PORT_B  ; 061h	; SYS1, wait for lo to hi
  7615 00001E45 A810                <1> 	test	al, 010h		; transition on memory
  7616 00001E47 75FA                <1> 	jnz	short WFMS_HI		; refresh.
  7617                              <1> WFMS_LO:
  7618 00001E49 E461                <1> 	in	al, PORT_B		; SYS1
  7619 00001E4B A810                <1> 	test	al, 010h
  7620 00001E4D 74FA                <1> 	jz	short WFMS_LO
  7621 00001E4F E2E9                <1>         loop	WFMS_CHECK_MEM
  7622                              <1> ;WFMS_OUTER_LP:
  7623                              <1> ;;	or	bl, bl			; check outer counter
  7624                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  7625                              <1> ;	dec	bl
  7626                              <1> ;	jz	short J36A	
  7627                              <1> ;	jmp	short WFMS_CHECK_MEM
  7628                              <1> 
  7629                              <1> 	;17/12/2014
  7630                              <1> 	;16/12/2014
  7631                              <1> ;	mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  7632                              <1> ;J36:
  7633                              <1> ;	test	byte [SEEK_STATUS], INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7634                              <1> ;	jnz	short J37
  7635                              <1> 	;16/12/2014
  7636                              <1> 	;loop	J36			; COUNT DOWN WHILE WAITING
  7637                              <1> 	;dec	bl			; SECOND LEVEL COUNTER
  7638                              <1> 	;jnz	short J36
  7639                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  7640                              <1> ;	jb	short J36
  7641                              <1> 
  7642                              <1> ;WFMS_TIMEOUT:
  7643                              <1> ;J36A:
  7644 00001E51 800D[EC670000]80    <1> 	or	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  7645 00001E58 F9                  <1> 	stc				; ERROR RETURN
  7646                              <1> J37:
  7647 00001E59 9C                  <1> 	pushf				; SAVE CURRENT CARRY
  7648 00001E5A 8025[E9670000]7F    <1> 	and	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  7649 00001E61 9D                  <1> 	popf				; RECOVER CARRY
  7650 00001E62 C3                  <1> 	retn				; GOOD RETURN CODE
  7651                              <1> 
  7652                              <1> ;-------------------------------------------------------------------------------
  7653                              <1> ; RESULTS
  7654                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  7655                              <1> ;	FOLLOWING AN INTERRUPT.
  7656                              <1> ;
  7657                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7658                              <1> ;		EAX, EBX, ECX, EDX DESTROYED
  7659                              <1> ;-------------------------------------------------------------------------------
  7660                              <1> RESULTS:
  7661                              <1> 	; 12/07/2022
  7662                              <1> 	; 11/07/2022
  7663                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7664 00001E63 57                  <1> 	push	edi
  7665 00001E64 BF[ED670000]        <1> 	mov	edi, NEC_STATUS		; POINTER TO DATA AREA
  7666 00001E69 B307                <1> 	mov	bl, 7			; MAX STATUS BYTES
  7667 00001E6B 66BAF403            <1> 	mov	dx, 03F4h		; STATUS PORT
  7668                              <1> 
  7669                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  7670                              <1> 
  7671                              <1> _R10: 
  7672                              <1> 	; 16/12/2014
  7673                              <1> 	; wait for (max) 0.5 seconds
  7674                              <1> 	;mov	bh, 2			; HIGH ORDER COUNTER
  7675                              <1> 	;xor	cx, cx			; COUNTER
  7676                              <1> 
  7677                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  7678                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  7679                              <1> 	; 27/02/2015
  7680                              <1> 
  7681 00001E6F B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  7682                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  7683                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  7684                              <1> 
  7685                              <1> WFPSR_OUTER_LP:
  7686                              <1> 	;
  7687                              <1> WFPSR_CHECK_PORT:
  7688                              <1> J39:					; WAIT FOR MASTER
  7689 00001E74 EC                  <1> 	in	al, dx			; GET STATUS
  7690 00001E75 24C0                <1> 	and	al, 11000000b		; KEEP ONLY STATUS AND DIRECTION
  7691 00001E77 3CC0                <1> 	cmp	al, 11000000b		; STATUS 1 AND DIRECTION 1 ?
  7692 00001E79 7418                <1> 	jz	short J42		; STATUS AND DIRECTION OK
  7693                              <1> WFPSR_HI:
  7694 00001E7B E461                <1> 	in	al, PORT_B	;061h	; SYS1	; wait for hi to lo
  7695 00001E7D A810                <1> 	test	al, 010h		; transition on memory
  7696 00001E7F 75FA                <1> 	jnz	short WFPSR_HI		; refresh.
  7697                              <1> WFPSR_LO:
  7698 00001E81 E461                <1> 	in	al, PORT_B		; SYS1
  7699 00001E83 A810                <1> 	test	al, 010h
  7700 00001E85 74FA                <1> 	jz	short WFPSR_LO
  7701 00001E87 E2EB                <1>         loop	WFPSR_CHECK_PORT
  7702                              <1> 	
  7703                              <1> 	;; 27/02/2015
  7704                              <1> 	;;dec	bh
  7705                              <1> 	;;jnz	short WFPSR_OUTER_LP
  7706                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  7707                              <1> 
  7708                              <1> 	;;mov	byte [wait_count], 0
  7709                              <1> ;J39:					; WAIT FOR MASTER
  7710                              <1> ;	in	al, dx			; GET STATUS
  7711                              <1> ;	and	al, 11000000b		; KEEP ONLY STATUS AND DIRECTION
  7712                              <1> ;	cmp	al, 11000000b		; STATUS 1 AND DIRECTION 1 ?
  7713                              <1> ;	jz	short J42		; STATUS AND DIRECTION OK
  7714                              <1> 	;loop	J39			; LOOP TILL TIMEOUT
  7715                              <1> 	;dec	bh			; DECREMENT HIGH ORDER COUNTER
  7716                              <1> 	;jnz	short J39		; REPEAT TILL DELAY DONE
  7717                              <1> 	;
  7718                              <1> 	;;cmp	byte [wait_count], 10	; (10/18.2 seconds)
  7719                              <1> 	;;jb	short J39	
  7720                              <1> 
  7721                              <1> ;WFPSR_TIMEOUT:
  7722 00001E89 800D[EC670000]80    <1> 	or	byte [DSKETTE_STATUS], TIME_OUT
  7723 00001E90 F9                  <1> 	stc				; SET ERROR RETURN
  7724 00001E91 EB26                <1> 	jmp	short POPRES		; POP REGISTERS AND RETURN
  7725                              <1> 
  7726                              <1> ;-----	READ IN THE STATUS
  7727                              <1> 
  7728                              <1> J42:
  7729 00001E93 EB00                <1> 	JMP	$+2			; I/O DELAY
  7730                              <1> 	;inc	dx			; POINT AT DATA PORT
  7731 00001E95 FEC2                <1> 	inc	dl
  7732 00001E97 EC                  <1> 	in	al, dx			; GET THE DATA
  7733                              <1> 	; 16/12/2014
  7734                              <1> 	NEWIODELAY
  7735 00001E98 E6EB                <2>  out 0EBh,al
  7736                              <1> 	
  7737                              <1> 	;mov	[edi], al		; STORE THE BYTE
  7738                              <1> 	;inc	edi			; INCREMENT THE POINTER
  7739                              <1> 	; 11/07/2022
  7740 00001E9A AA                  <1> 	stosb
  7741                              <1> 
  7742                              <1> 	; 16/12/2014
  7743                              <1> ;	push	cx
  7744                              <1> ;	mov	cx, 30
  7745                              <1> ;wdw2:
  7746                              <1> ;	NEWIODELAY
  7747                              <1> ;	loop	wdw2
  7748                              <1> ;	pop	cx
  7749                              <1> 
  7750                              <1> 	;mov	ecx,3			; MINIMUM 24 MICROSECONDS FOR NEC
  7751                              <1> 	; 12/07/2022
  7752 00001E9B 29C9                <1> 	sub	ecx, ecx
  7753 00001E9D B103                <1> 	mov	cl, 3
  7754 00001E9F E807F5FFFF          <1> 	call	WAITF			; WAIT 30 TO 45 MICROSECONDS
  7755                              <1> 	;dec	dx			; POINT AT STATUS PORT
  7756 00001EA4 FECA                <1> 	dec	dl
  7757 00001EA6 EC                  <1> 	in	al, dx			; GET STATUS
  7758                              <1> 	; 16/12/2014
  7759                              <1> 	NEWIODELAY
  7760 00001EA7 E6EB                <2>  out 0EBh,al
  7761                              <1> 	;
  7762 00001EA9 A810                <1> 	test	al, 00010000b		; TEST FOR NEC STILL BUSY
  7763 00001EAB 740C                <1> 	jz	short POPRES		; RESULTS DONE ?
  7764                              <1> 
  7765 00001EAD FECB                <1> 	dec	bl			; DECREMENT THE STATUS COUNTER
  7766 00001EAF 75BE                <1>         jnz	short _R10              ; GO BACK FOR MORE
  7767 00001EB1 800D[EC670000]20    <1> 	or	byte [DSKETTE_STATUS], BAD_NEC ; TOO MANY STATUS BYTES
  7768 00001EB8 F9                  <1> 	stc				; SET ERROR FLAG
  7769                              <1> 
  7770                              <1> ;-----	RESULT OPERATION IS DONE
  7771                              <1> POPRES:
  7772 00001EB9 5F                  <1> 	pop	edi
  7773 00001EBA C3                  <1> 	retn				; RETURN WITH CARRY SET
  7774                              <1> 
  7775                              <1> ;-------------------------------------------------------------------------------
  7776                              <1> ; READ_DSKCHNG
  7777                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  7778                              <1> ;
  7779                              <1> ; ON ENTRY:	EDI = DRIVE #
  7780                              <1> ;
  7781                              <1> ; ON EXIT:	EDI = DRIVE #
  7782                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  7783                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  7784                              <1> ;		EAX, ECX, EDX DESTROYED
  7785                              <1> ;-------------------------------------------------------------------------------
  7786                              <1> READ_DSKCHNG:
  7787                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7788 00001EBB E8B4FDFFFF          <1> 	call	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  7789 00001EC0 66BAF703            <1> 	mov	dx, 03F7h		; ADDRESS DIGITAL INPUT REGISTER
  7790 00001EC4 EC                  <1> 	in	al, dx			; INPUT DIGITAL INPUT REGISTER
  7791 00001EC5 A880                <1> 	test	al, DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  7792 00001EC7 C3                  <1> 	retn				; RETURN TO CALLER WITH ZERO FLAG SET
  7793                              <1> 
  7794                              <1> fdc_int:  
  7795                              <1> 	  ; 30/07/2015	
  7796                              <1> 	  ; 16/02/2015
  7797                              <1> ;int_0Eh: ; 11/12/2014
  7798                              <1> 
  7799                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL 6 ) ---------------------------------------
  7800                              <1> ; DISK_INT
  7801                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  7802                              <1> ;
  7803                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  7804                              <1> ;-------------------------------------------------------------------------------
  7805                              <1> DISK_INT_1:
  7806                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7807                              <1> 	;push	eax			; SAVE WORK REGISTER
  7808                              <1> 	; 24/12/2021
  7809 00001EC8 50                  <1> 	push	eax
  7810 00001EC9 1E                  <1> 	push	ds
  7811 00001ECA 66B81000            <1> 	mov	ax, KDATA
  7812 00001ECE 8ED8                <1> 	mov 	ds, ax
  7813 00001ED0 800D[E9670000]80    <1>         or	byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  7814 00001ED7 B020                <1> 	mov	al, EOI			; END OF INTERRUPT MARKER
  7815 00001ED9 E620                <1> 	out	INTA00, al		; INTERRUPT CONTROL PORT
  7816 00001EDB 1F                  <1> 	pop	ds
  7817                              <1> 	;pop	ax			; RECOVER REGISTER
  7818                              <1> 	; 24/12/2021
  7819 00001EDC 58                  <1> 	pop	eax
  7820 00001EDD CF                  <1> 	iretd				; RETURN FROM INTERRUPT
  7821                              <1> 
  7822                              <1> ;-------------------------------------------------------------------------------
  7823                              <1> ; DSKETTE_SETUP
  7824                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  7825                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  7826                              <1> ;-------------------------------------------------------------------------------
  7827                              <1> DSKETTE_SETUP:
  7828                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7829                              <1> 	;push	eax			; SAVE REGISTERS
  7830                              <1> 	;push	ebx
  7831                              <1> 	;push	ecx
  7832 00001EDE 52                  <1> 	push	edx
  7833                              <1> 	;push	edi
  7834                              <1> 	; 14/12/2014
  7835                              <1> 	;mov	dword [DISK_POINTER], MD_TBL6
  7836                              <1> 	;
  7837                              <1> 	;or	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  7838                              <1> 
  7839 00001EDF 31FF                <1> 	xor	edi, edi 		; INITIALIZE DRIVE POINTER
  7840 00001EE1 29C9                <1> 	sub	ecx, ecx
  7841 00001EE3 66890D[F7670000]    <1> 	mov	[DSK_STATE], cx ; 0	; INITIALIZE STATES
  7842                              <1> 	; 08/07/2022
  7843                              <1> 	;and	byte [LASTRATE], ~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  7844 00001EEA 800D[F4670000]C0    <1> 	or	byte [LASTRATE], SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  7845 00001EF1 880D[E9670000]      <1> 	mov	[SEEK_STATUS], cl ; 0	; INDICATE RECALIBRATE NEEDED
  7846 00001EF7 880D[EB670000]      <1> 	mov	[MOTOR_COUNT], cl ; 0	; INITIALIZE MOTOR COUNT
  7847 00001EFD 880D[EA670000]      <1> 	mov	[MOTOR_STATUS], cl ; 0	; INITIALIZE DRIVES TO OFF STATE
  7848 00001F03 880D[EC670000]      <1> 	mov	[DSKETTE_STATUS], cl ; 0 ; NO ERRORS
  7849                              <1> 	;
  7850                              <1> 	; 28/02/2015
  7851                              <1> 	;mov	word [cfd], 100h 
  7852 00001F09 E894F8FFFF          <1> 	call	DSK_RESET
  7853 00001F0E 5A                  <1> 	pop	edx
  7854 00001F0F C3                  <1> 	retn
  7855                              <1> 
  7856                              <1> ;//////////////////////////////////////////////////////
  7857                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7858                              <1> ;
  7859                              <1> 
  7860                              <1> ; 12/07/2022
  7861                              <1> ;int13h: ; 21/02/2015
  7862                              <1> ;	pushfd
  7863                              <1> ;	push 	cs
  7864                              <1> ;	call 	DISK_IO
  7865                              <1> ;	retn
  7866                              <1> 
  7867                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  7868                              <1> ;/////////////////////////////////////////////////////////////////////
  7869                              <1> 
  7870                              <1> ; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7871                              <1> ; ((Direct call instead of int 13h simulation))
  7872                              <1> ;
  7873                              <1> ;		Function in AL
  7874                              <1> ;			0 = reset
  7875                              <1> ;			1 = read
  7876                              <1> ;			2 = write
  7877                              <1> ;		Disk drive number in DL
  7878                              <1> ;			0 & 1 = floppy disks	
  7879                              <1> ;			80h .. 83h = hard disks
  7880                              <1> ;		Sector address (LBA) in ECX
  7881                              <1> ;		Buffer address in EBX
  7882                              <1> ;		R/W sector count is (always) 1
  7883                              <1> ;
  7884                              <1> ;		Return:
  7885                              <1> ;			Status in AH (>0 = error code)
  7886                              <1> ;			if CF = 1 -> error code in AH
  7887                              <1> ;			if CF = 0 -> successful
  7888                              <1> ;			AL = undefined
  7889                              <1> ;
  7890                              <1> ;		Modified registers: (only) EAX
  7891                              <1> 
  7892                              <1> ; 10/07/2022
  7893                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7894                              <1> 
  7895                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  7896                              <1> ; 23/02/2015
  7897                              <1> ; 21/02/2015 (unix386.s)
  7898                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  7899                              <1> ;
  7900                              <1> ; Original Source Code:
  7901                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  7902                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  7903                              <1> ;
  7904                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  7905                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  7906                              <1> ;
  7907                              <1> 
  7908                              <1> ;The wait for controller to be not busy is 10 seconds.
  7909                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  7910                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  7911                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  7912                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  7913                              <1> 
  7914                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  7915                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  7916                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  7917                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  7918                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  7919                              <1> 
  7920                              <1> ;The wait for Data request on read and write longs is
  7921                              <1> ;2000 us. (?)
  7922                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  7923                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  7924                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  7925                              <1> 
  7926                              <1> ; Port 61h (PORT_B)
  7927                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  7928                              <1> 
  7929                              <1> ; 23/12/2014
  7930                              <1> %define CMD_BLOCK       ebp-8  ; 21/02/2015
  7931                              <1> 
  7932                              <1> 	; 11/07/2022
  7933                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  7934                              <1> 
  7935                              <1> ;--- INT 13H -------------------------------------------------------------------
  7936                              <1> ;									       :
  7937                              <1> ; FIXED DISK I/O INTERFACE						       :
  7938                              <1> ;									       :
  7939                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  7940                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  7941                              <1> ;									       :
  7942                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  7943                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  7944                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  7945                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  7946                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  7947                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  7948                              <1> ;									       :
  7949                              <1> ;------------------------------------------------------------------------------:
  7950                              <1> ;									       :
  7951                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  7952                              <1> ;									       :
  7953                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  7954                              <1> ;	(AH)= 01H  READ THE DESIRED SECTORS INTO MEMORY                        :
  7955                              <1> ;	(AH)= 02H  WRITE THE DESIRED SECTORS FROM MEMORY                       :
  7956                              <1> ;									       :
  7957                              <1> ;------------------------------------------------------------------------------:
  7958                              <1> ;									       :
  7959                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  7960                              <1> ;									       :
  7961                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  7962                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  7963                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  7964                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  7965                              <1> ;									       :
  7966                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  7967                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  7968                              <1> ;				 (10 BITS TOTAL)			       :
  7969                              <1> ;									       :
  7970                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  7971                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  7972                              <1> ;									       :
  7973                              <1> ;		(EBX)   -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  7974                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  7975                              <1> ;									       :
  7976                              <1> ;------------------------------------------------------------------------------:
  7977                              <1> ; OUTPUT								       :
  7978                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  7979                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  7980                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  7981                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  7982                              <1> ;									       :
  7983                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  7984                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  7985                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  7986                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  7987                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  7988                              <1> ;		REWRITTEN.						       :
  7989                              <1> ;									       :
  7990                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  7991                              <1> ;	   INPUT:							       :
  7992                              <1> ;	     (DL) = DRIVE NUMBER					       :
  7993                              <1> ;	   OUTPUT:							       :
  7994                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  7995                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  7996                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  7997                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  7998                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  7999                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  8000                              <1> ;									       :
  8001                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  8002                              <1> ;	INFORMATION.							       :
  8003                              <1> ;									       :
  8004                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  8005                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  8006                              <1> ;									       :
  8007                              <1> ;-------------------------------------------------------------------------------
  8008                              <1> 
  8009                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  8010                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  8011                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  8012                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  8013                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  8014                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  8015                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  8016                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  8017                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  8018                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  8019                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  8020                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  8021                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  8022                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  8023                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  8024                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  8025                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  8026                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  8027                              <1> 
  8028                              <1> ;--------------------------------------------------------
  8029                              <1> ;							:
  8030                              <1> ; FIXED DISK PARAMETER TABLE				:
  8031                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  8032                              <1> ;							:
  8033                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  8034                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  8035                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  8036                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  8037                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  8038                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  8039                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  8040                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  8041                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  8042                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  8043                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  8044                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  8045                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  8046                              <1> ;							:
  8047                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  8048                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  8049                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  8050                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  8051                              <1> ;							:
  8052                              <1> ;--------------------------------------------------------
  8053                              <1> 
  8054                              <1> ;--------------------------------------------------------
  8055                              <1> ;							:
  8056                              <1> ; HARDWARE SPECIFIC VALUES				:
  8057                              <1> ;							:
  8058                              <1> ;  -  CONTROLLER I/O PORT				:
  8059                              <1> ;							:
  8060                              <1> ;     > WHEN READ FROM: 				:
  8061                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  8062                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  8063                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  8064                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  8065                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  8066                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  8067                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  8068                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  8069                              <1> ;							:
  8070                              <1> ;     > WHEN WRITTEN TO:				:
  8071                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  8072                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  8073                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  8074                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  8075                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  8076                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  8077                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  8078                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  8079                              <1> ;							:
  8080                              <1> ;--------------------------------------------------------
  8081                              <1> 
  8082                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  8083                              <1> ;HF1_PORT	equ	0170h	
  8084                              <1> ;HF_REG_PORT	EQU	03F6H
  8085                              <1> ;HF1_REG_PORT	equ	0376h
  8086                              <1> 
  8087                              <1> HDC1_BASEPORT	equ	1F0h
  8088                              <1> HDC2_BASEPORT	equ	170h		
  8089                              <1> 
  8090                              <1> align 2
  8091                              <1> 
  8092                              <1> ;-----		STATUS REGISTER
  8093                              <1> 
  8094                              <1> ST_ERROR	EQU	00000001B	;
  8095                              <1> ST_INDEX	EQU	00000010B	;
  8096                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  8097                              <1> ST_DRQ		EQU	00001000B	;
  8098                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  8099                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  8100                              <1> ST_READY	EQU	01000000B	;
  8101                              <1> ST_BUSY 	EQU	10000000B	;
  8102                              <1> 
  8103                              <1> ;-----		ERROR REGISTER
  8104                              <1> 
  8105                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  8106                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  8107                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  8108                              <1> ;		EQU	00001000B	; NOT USED
  8109                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  8110                              <1> ;		EQU	00100000B	; NOT USED
  8111                              <1> ERR_DATA_ECC	EQU	01000000B
  8112                              <1> ERR_BAD_BLOCK	EQU	10000000B
  8113                              <1> 
  8114                              <1> 
  8115                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  8116                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  8117                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  8118                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  8119                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  8120                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  8121                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  8122                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  8123                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  8124                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  8125                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  8126                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  8127                              <1> 
  8128                              <1> ;MAX_FILE	EQU	2
  8129                              <1> ;S_MAX_FILE	EQU	2
  8130                              <1> MAX_FILE	equ	4		; 22/12/2014
  8131                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  8132                              <1> 
  8133                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  8134                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  8135                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  8136                              <1> 
  8137                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  8138                              <1> 
  8139                              <1> ;-----		COMMAND BLOCK REFERENCE
  8140                              <1> 
  8141                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  8142                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  8143                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  8144                              <1> ; 19/12/2014
  8145                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  8146                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  8147                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8148                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8149                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  8150                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  8151                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  8152                              <1> 
  8153                              <1> align 2
  8154                              <1> 
  8155                              <1> ;----------------------------------------------------------------
  8156                              <1> ; FIXED DISK I/O SETUP						:
  8157                              <1> ;								:
  8158                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  8159                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  8160                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  8161                              <1> ;								:
  8162                              <1> ;----------------------------------------------------------------
  8163                              <1> 
  8164                              <1> 	; 12/07/2022
  8165                              <1> 	; 11/07/2022
  8166                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8167                              <1> 
  8168                              <1> DISK_SETUP:
  8169                              <1> 	;cli
  8170                              <1> 	;;mov	ax, ABS0 			; GET ABSOLUTE SEGMENT
  8171                              <1> 	;xor	ax, ax
  8172                              <1> 	;mov	ds, ax				; SET SEGMENT REGISTER
  8173                              <1> 	;mov	ax, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  8174                              <1> 	;mov	[DISK_VECTOR], ax		; INTO INT 40H
  8175                              <1> 	;mov	ax, [ORG_VECTOR+2]
  8176                              <1> 	;mov	[DISK_VECTOR+2], ax
  8177                              <1> 	;mov	word [ORG_VECTOR], DISK_IO	; FIXED DISK HANDLER
  8178                              <1> 	;mov	[ORG_VECTOR+2], cs
  8179                              <1> 	; 1st controller (primary master, slave) - IRQ 14
  8180                              <1> 	;;mov	word [HDISK_INT], HD_INT	; FIXED DISK INTERRUPT
  8181                              <1> 	;mov	word [HDISK_INT1], HD_INT	;
  8182                              <1> 	;;mov	[HDISK_INT+2], cs
  8183                              <1> 	;mov	[HDISK_INT1+2], cs
  8184                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  8185                              <1> 	;mov	word [HDISK_INT2], HD1_INT	;
  8186                              <1> 	;mov	[HDISK_INT2+2], cs
  8187                              <1> 	;
  8188                              <1> 	;;mov	word [HF_TBL_VEC], HD0_DPT	; PARM TABLE DRIVE 80
  8189                              <1> 	;;mov	word [HF_TBL_VEC+2], DPT_SEGM
  8190                              <1> 	;;mov	word [HF1_TBL_VEC], HD1_DPT	; PARM TABLE DRIVE 81
  8191                              <1> 	;;mov	word [HF1_TBL_VEC+2], DPT_SEGM
  8192                              <1> 	;push	cs
  8193                              <1> 	;pop	ds
  8194                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  8195                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  8196 00001F10 C705[00680000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  8197 00001F18 0900                <1>
  8198                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  8199                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  8200 00001F1A C705[04680000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  8201 00001F22 0900                <1>
  8202                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  8203                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  8204 00001F24 C705[08680000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  8205 00001F2C 0900                <1>
  8206                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  8207                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  8208 00001F2E C705[0C680000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  8209 00001F36 0900                <1>
  8210                              <1> 	;
  8211                              <1> 	;;in	al, INTB01		; TURN ON SECOND INTERRUPT CHIP
  8212                              <1> 	;;;and	al, 0BFh
  8213                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  8214                              <1> 	;;;JMP	$+2
  8215                              <1> 	;;IODELAY
  8216                              <1> 	;;out	INTB01, al
  8217                              <1> 	;;IODELAY
  8218                              <1> 	;;in	al, INTA01		; LET INTERRUPTS PASS THRU TO
  8219                              <1> 	;;and	al, 0FBh 		; SECOND CHIP
  8220                              <1> 	;;;JMP	$+2
  8221                              <1> 	;;IODELAY
  8222                              <1> 	;;out	INTA01, al
  8223                              <1> 	;
  8224                              <1> 	;sti
  8225                              <1> 	;;push	ds			; MOVE ABS0 POINTER TO
  8226                              <1> 	;;pop	es			; EXTRA SEGMENT POINTER
  8227                              <1> 	;;;call	DDS			; ESTABLISH DATA SEGMENT
  8228                              <1> 	;;mov	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8229                              <1> 	;;mov	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  8230                              <1> 	;;mov	byte [CONTROL_BYTE],0
  8231                              <1> 	;;mov	byte [PORT_OFF],0	; ZERO CARD OFFSET
  8232                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  8233                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  8234                              <1> 	;mov	si, hd0_type
  8235 00001F38 BE[8E620000]        <1> 	mov	esi, hd0_type
  8236                              <1> 	;;mov	cx, 4
  8237                              <1> 	;mov	ecx, 4
  8238                              <1> 	; 11/07/2022
  8239 00001F3D 29C9                <1> 	sub	ecx, ecx
  8240 00001F3F B104                <1> 	mov	cl, 4
  8241                              <1> hde_l:
  8242 00001F41 AC                  <1> 	lodsb
  8243 00001F42 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  8244 00001F44 7206                <1> 	jb	short _L4
  8245 00001F46 FE05[FC670000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  8246                              <1> _L4: ; 26/02/2015
  8247 00001F4C E2F3                <1> 	loop	hde_l	
  8248                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  8249                              <1> ;L4:
  8250                              <1> 	; 
  8251                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  8252                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  8253                              <1> 	;;mov 	cl, 3
  8254                              <1> 	;;
  8255                              <1> 	;;mov	dl, 80h			; CHECK THE CONTROLLER
  8256                              <1> ;;hdc_dl:
  8257                              <1> 	;;mov	ah, 14h			; USE CONTROLLER DIAGNOSTIC COMMAND
  8258                              <1> 	;;int	13h			; CALL BIOS WITH DIAGNOSTIC COMMAND
  8259                              <1> 	;;;jc	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  8260                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  8261                              <1> 	;;jnc	short hdc_reset0
  8262                              <1> 	;;loop	hdc_dl
  8263                              <1> 	;;; 27/12/2014
  8264                              <1> 	;;stc
  8265                              <1> 	;;retn
  8266                              <1> 	;
  8267                              <1> ;;hdc_reset0:
  8268                              <1> 	; 18/01/2015
  8269 00001F4E 8A0D[FC670000]      <1> 	mov	cl, [HF_NUM]
  8270 00001F54 20C9                <1> 	and	cl, cl
  8271 00001F56 740D                <1> 	jz	short POD_DONE
  8272                              <1> 	;
  8273 00001F58 B27F                <1> 	mov	dl, 7Fh
  8274                              <1> hdc_reset1:
  8275 00001F5A FEC2                <1> 	inc	dl
  8276                              <1> 	;; 31/12/2015
  8277                              <1> 	;;push	dx
  8278                              <1> 	;;push	cx
  8279                              <1> 	;;push	ds
  8280                              <1> 	;;sub	ax, ax
  8281                              <1> 	;;mov	ds, ax
  8282                              <1> 	;;mov	ax, [TIMER_LOW]		; GET START TIMER COUNTS
  8283                              <1> 	;;pop	ds
  8284                              <1> 	;;mov	bx, ax
  8285                              <1> 	;;add	ax, 6*182		; 60 SECONDS* 18.2
  8286                              <1> 	;;mov	cx, ax
  8287                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  8288                              <1> 	;;
  8289                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  8290                              <1> 	;;call	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  8291                              <1> 	;;pop	cx
  8292                              <1> 	;;pop	dx
  8293                              <1> 	;;
  8294                              <1> 	; 18/01/2015
  8295                              <1> 	;mov	ah, 0Dh ; ALTERNATE RESET
  8296                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8297                              <1> 	;mov	ah, 5 ; ALTERNATE RESET
  8298                              <1> 	;;int	13h
  8299                              <1> 	;call	int13h
  8300                              <1> 	; 12/07/2022
  8301 00001F5C 30C0                <1> 	xor	al, al  ; reset
  8302 00001F5E E803000000          <1> 	call	DISK_IO	
  8303                              <1> 	;
  8304 00001F63 E2F5                <1> 	loop	hdc_reset1
  8305                              <1> POD_DONE:
  8306 00001F65 C3                  <1> 	RETn
  8307                              <1> 
  8308                              <1> ;----------------------------------------
  8309                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  8310                              <1> ;----------------------------------------
  8311                              <1> 
  8312                              <1> ; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8313                              <1> ; ((Direct call instead of int 13h simulation))
  8314                              <1> ;
  8315                              <1> ;		Function in AL
  8316                              <1> ;			0 = reset
  8317                              <1> ;			1 = read
  8318                              <1> ;			2 = write
  8319                              <1> ;		Disk drive number in DL
  8320                              <1> ;			0 & 1 = floppy disks	
  8321                              <1> ;			80h .. 83h = hard disks
  8322                              <1> ;		Sector address (LBA) in ECX
  8323                              <1> ;		Buffer address in EBX
  8324                              <1> ;		R/W sector count is (always) 1
  8325                              <1> ;
  8326                              <1> ;		Return:
  8327                              <1> ;			Status in AH (>0 = error code)
  8328                              <1> ;			if CF = 1 -> error code in AH
  8329                              <1> ;			if CF = 0 -> successful
  8330                              <1> ;			AL = undefined
  8331                              <1> ;
  8332                              <1> ;		Modified registers: (only) EAX
  8333                              <1> 	
  8334                              <1> 
  8335                              <1> ; 11/07/2022
  8336                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8337                              <1> 
  8338                              <1> DISK_IO:
  8339                              <1> 	; 11/07/2022
  8340                              <1> 	; save registers
  8341 00001F66 57                  <1> 	push	edi			; ANY
  8342 00001F67 56                  <1> 	push	esi			; ANY
  8343 00001F68 53                  <1> 	push	ebx			; BUFFER ADDRESS
  8344 00001F69 51                  <1> 	push	ecx			; SECTOR ADDRESS (LBA)
  8345 00001F6A 52                  <1> 	push	edx			; DRIVE NUMBER (DL)
  8346                              <1> 
  8347                              <1> 	;cmp	dl, 80h			; TEST FOR FIXED DISK DRIVE
  8348                              <1> 	;;jae	short A1		; YES, HANDLE HERE
  8349                              <1> 	;;;;int	40H			; DISKETTE HANDLER
  8350                              <1> 	;;;call	int40h
  8351                              <1> 	;;jb	DISKETTE_IO_1
  8352                              <1> 	;; 24/12/2021
  8353                              <1> 	;jnb	short A1
  8354                              <1> 	;jmp	DISKETTE_IO_1
  8355                              <1> 
  8356                              <1> 	; 11/07/2022
  8357 00001F6B 80FA80              <1> 	cmp	dl, 80h
  8358 00001F6E 730B                <1> 	jae	short A1
  8359                              <1> 
  8360 00001F70 E8CAF6FFFF          <1> 	call	DISKETTE_IO_1
  8361                              <1> 
  8362                              <1> DISK_IO_RTN:
  8363                              <1> 	; restore registers
  8364 00001F75 5A                  <1> 	pop	edx
  8365 00001F76 59                  <1> 	pop	ecx
  8366 00001F77 5B                  <1> 	pop	ebx
  8367 00001F78 5E                  <1> 	pop	esi
  8368 00001F79 5F                  <1> 	pop	edi
  8369 00001F7A C3                  <1> 	retn	
  8370                              <1> 
  8371                              <1> ;RET_2:
  8372                              <1> ;	retf	4			; BACK TO CALLER
  8373                              <1> 
  8374                              <1> A1:
  8375                              <1> 	; 11/07/2022
  8376                              <1> 	;sti				; ENABLE INTERRUPTS
  8377                              <1> 	;cmp	dl, (80h + S_MAX_FILE - 1)
  8378                              <1> 	;ja	short RET_2
  8379                              <1> 	
  8380                              <1> 	; 18/01/2015
  8381                              <1> 	;;or	ah, ah
  8382                              <1> 	;or	al, al ; 11/07/2022 (reset function)
  8383                              <1> 	;jz	short A3 ; 08/07/2022
  8384                              <1> 	
  8385                              <1> 	;;cmp	ah, 5  ; Alternate reset
  8386                              <1> 	;cmp	al, 5  ; 11/07/2022
  8387                              <1> 	;je	short A2
  8388                              <1> 	
  8389                              <1> 	; 11/07/2022 - no need to check
  8390                              <1> 	;		 (only kernel calls diskio functions)
  8391                              <1> 	;;cmp	ah, M1L/4 ; cmp ah, 6
  8392                              <1> 	;jb	short A3
  8393                              <1> 	;; BAD COMMAND
  8394                              <1>         ;mov     byte [DISK_STATUS1], BAD_CMD
  8395                              <1> ;RET_2:
  8396                              <1> 	;retf	4
  8397                              <1> 
  8398                              <1> 	; 11/07/2022
  8399                              <1> 	;stc
  8400                              <1> 	;retn
  8401                              <1> A2:
  8402                              <1> 	;sub	ah, ah	; Reset
  8403                              <1> 	; 11/07/2022
  8404                              <1> 	;sub	al, al
  8405                              <1> A3:
  8406                              <1> 					; SAVE REGISTERS DURING OPERATION
  8407 00001F7B C8080000            <1> 	enter	8,0			; SAVE (EBP) AND MAKE ROOM FOR @CMD_BLOCK
  8408                              <1> 	
  8409                              <1> 	; 11/07/2022
  8410                              <1> 	; 08/07/2022
  8411                              <1> 	;push	ebx			;  IN THE STACK, THE COMMAND BLOCK IS:
  8412                              <1> 	;push	ecx			;   @CMD_BLOCK == BYTE PTR [EBP]-8
  8413                              <1> 	;push	edx
  8414                              <1> 	;push	esi
  8415                              <1> 	;push	edi
  8416                              <1> 	
  8417 00001F7F E80D000000          <1> 	call	DISK_IO_CONT		; PERFORM THE OPERATION
  8418                              <1> 
  8419 00001F84 C9                  <1> 	leave	; 11/07/2022
  8420                              <1> 	
  8421 00001F85 8A25[FB670000]      <1> 	mov	ah, [DISK_STATUS1]	; GET STATUS FROM OPERATION
  8422 00001F8B 80FC01              <1> 	cmp	ah, 1			; SET THE CARRY FLAG TO INDICATE
  8423 00001F8E F5                  <1> 	cmc				; SUCCESS OR FAILURE
  8424                              <1> 	
  8425                              <1> 	;pop	edi			; RESTORE REGISTERS
  8426                              <1> 	;pop	esi
  8427                              <1>       	;pop	edx
  8428                              <1> 	;pop	ecx
  8429                              <1> 	;pop	ebx
  8430                              <1> 	
  8431                              <1> 	;leave				; ADJUST (ESP) AND RESTORE (EBP)
  8432                              <1> 	
  8433                              <1> 	; 11/07/2022
  8434                              <1> 	;retf	4			; THROW AWAY SAVED FLAGS
  8435                              <1> 
  8436 00001F8F EBE4                <1> 	jmp	short DISK_IO_RTN
  8437                              <1> 
  8438                              <1> DISK_IO_CONT:
  8439                              <1> 	; 17/07/2022
  8440                              <1> 	; 11/07/2022
  8441                              <1> 	;	INPUT:
  8442                              <1> 	;	    AL = 0 : reset
  8443                              <1> 	;	    AL = 1 : read
  8444                              <1> 	;	    Al = 2 : write
  8445                              <1> 	; 	
  8446                              <1> 	; 10/07/2022
  8447                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8448                              <1> SU0:
  8449 00001F91 C605[FB670000]00    <1> 	mov	byte [DISK_STATUS1], 0 	; RESET THE STATUS INDICATOR
  8450                              <1> 	; 10/07/2022
  8451 00001F98 89DE                <1> 	mov	esi, ebx ; 21/02/2015	; DATA (BUFFER) ADDRESS
  8452                              <1> 
  8453 00001F9A 8A1D[FC670000]      <1> 	mov	bl, [HF_NUM]		; GET NUMBER OF DRIVES
  8454 00001FA0 80E27F              <1> 	and	dl, 7Fh			; GET DRIVE AS 0 OR 1
  8455                              <1> 					; (get drive number as 0 to 3)
  8456 00001FA3 38D3                <1> 	cmp	bl, dl
  8457                              <1>         ;;jbe	BAD_COMMAND_POP         ; INVALID DRIVE
  8458                              <1>         ;jbe    BAD_COMMAND ;; 14/02/2015
  8459                              <1> 	; 24/12/2021
  8460 00001FA5 7705                <1> 	ja	short su0_su1
  8461 00001FA7 E98D000000          <1> 	jmp	BAD_COMMAND
  8462                              <1> su0_su1:
  8463                              <1>         ;;03/01/2015
  8464 00001FAC 29DB                <1> 	sub	ebx, ebx
  8465 00001FAE 88D3                <1> 	mov	bl, dl
  8466 00001FB0 883D[10680000]      <1> 	mov	[LBAMode], bh  ; 0
  8467                              <1> 	;test	byte [ebx+hd0_type], 1	; LBA ready ?
  8468                              <1> 	;jz	short su1		; no
  8469                              <1> 	;inc	byte [LBAMode]
  8470                              <1> ;su1:
  8471                              <1> 	; 21/02/2015 (32 bit modification)
  8472                              <1> 	; 04/01/2015
  8473                              <1> 	;push	ax ; ***
  8474                              <1> 	; 24/12/2021
  8475 00001FB6 50                  <1> 	push	eax ; *** ; function (in AL) ; 11/07/2022
  8476                              <1> 	; 24/12/2021
  8477 00001FB7 52                  <1> 	push	edx ; *
  8478 00001FB8 50                  <1> 	push	eax ; function (in AL)	; 11/07/2022
  8479 00001FB9 E8CA030000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  8480                              <1> 	; 02/02/2015
  8481 00001FBE 668B4310            <1> 	mov	ax, [ebx+16]   ; I/O port base address (1F0h, 170h)
  8482 00001FC2 66A3[82620000]      <1> 	mov	[HF_PORT], ax
  8483 00001FC8 668B5312            <1> 	mov	dx, [ebx+18]   ; control port address (3F6h, 376h)
  8484 00001FCC 668915[84620000]    <1> 	mov	[HF_REG_PORT], dx
  8485 00001FD3 8A4314              <1> 	mov	al, [ebx+20]   ; head register upper nibble (A0h,B0h,E0h,F0h)
  8486                              <1> 	; 23/02/2015
  8487 00001FD6 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  8488 00001FD8 7406                <1> 	jz 	short su1
  8489 00001FDA FE05[10680000]      <1> 	inc	byte [LBAMode] ; 1 
  8490                              <1> su1: 	 
  8491 00001FE0 C0E804              <1> 	shr 	al, 4
  8492 00001FE3 2401                <1> 	and	al, 1			
  8493 00001FE5 A2[86620000]        <1> 	mov	[hf_m_s], al 
  8494                              <1> 	;
  8495                              <1> 	; 03/01/2015
  8496 00001FEA 8A4308              <1> 	mov	al, [ebx+8]		; GET CONTROL BYTE MODIFIER
  8497                              <1> 	;mov	dx, [HF_REG_PORT]	; Device Control register	
  8498 00001FED EE                  <1> 	out	dx, al			; SET EXTRA HEAD OPTION
  8499                              <1> 					; Control Byte: (= 08h, here)
  8500                              <1> 					; bit 0 - 0
  8501                              <1> 					; bit 1 - nIEN (1 = disable irq)
  8502                              <1> 					; bit 2 - SRST (software RESET)
  8503                              <1> 					; bit 3 - use extra heads (8 to 15)
  8504                              <1> 					;         -always set to 1-	
  8505                              <1> 					; (bits 3 to 7 are reserved
  8506                              <1> 					;          for ATA devices)
  8507 00001FEE 8A25[FD670000]      <1> 	mov	ah, [CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8508 00001FF4 80E4C0              <1> 	and	ah, 0C0h 		; CONTROL BYTE
  8509 00001FF7 08C4                <1> 	or	ah, al
  8510 00001FF9 8825[FD670000]      <1> 	mov	[CONTROL_BYTE], ah	
  8511                              <1> 	; 04/01/2015
  8512                              <1> 	;pop	ax
  8513                              <1> 	; 24/12/2021
  8514 00001FFF 58                  <1> 	pop	eax ; function (in AL) ; 11/07/2022
  8515                              <1> 	;pop	dx ; * ;; 14/02/2015
  8516                              <1> 	; 24/12/2021
  8517 00002000 5A                  <1> 	pop	edx ; *
  8518                              <1> 	;and	ah, ah	; Reset function ?
  8519 00002001 20C0                <1> 	and	al, al	; 11/07/2022
  8520 00002003 7506                <1> 	jnz	short su2
  8521                              <1> 	;pop	ax ; ***
  8522                              <1> 	; 24/12/2021
  8523 00002005 58                  <1> 	pop	eax ; *** 	
  8524                              <1> 	;;pop	bx
  8525 00002006 E9EA000000          <1>         jmp     DISK_RESET
  8526                              <1> su2:
  8527                              <1> 	; 11/07/2022
  8528                              <1> 	; ecx = sector address (lba)
  8529                              <1> 	;  dl = hard disk drive number (80h, 81h .. 83h)	 
  8530                              <1> 	;  al = function (0 = read, 1 = write)	
  8531                              <1> 
  8532 0000200B 803D[10680000]00    <1> 	cmp	byte [LBAMode], 0
  8533 00002012 7620                <1> 	jna	short su3 ; convert LBA address to CHS parameters
  8534                              <1> 	
  8535                              <1> ;	; 02/02/2015 (LBA read/write function calls)
  8536                              <1> ;	;cmp	ah, 1Bh
  8537                              <1> ;	cmp	ah, 3 ; 08/07/2022
  8538                              <1> ;	jb	short lbarw1
  8539                              <1> ;	;;cmp	ah, 1Ch
  8540                              <1> ;	;cmp	ah, 4 ; 08/07/2022 
  8541                              <1> ;	;ja 	short invldfnc
  8542                              <1> ;	;;pop	dx ; * ; 14/02/2015
  8543                              <1> ;	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  8544                              <1> 
  8545 00002014 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  8546                              <1> 
  8547                              <1> 	; 11/07/2022
  8548                              <1> 	;; 14/02/2015
  8549                              <1> 	;mov	cl, dl ; 14/02/2015
  8550                              <1> 
  8551                              <1> 	;;mov	dx, bx
  8552                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  8553                              <1> 	;;mov	bx, di
  8554                              <1> 	;mov	si, di ; Buffer offset
  8555                              <1> 
  8556                              <1> 	; 11/07/2022
  8557                              <1> 	;jmp	short lbarw2
  8558                              <1> 
  8559                              <1> ;lbarw1:
  8560                              <1> ;	; convert CHS to LBA
  8561                              <1> ;	;
  8562                              <1> ;	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  8563                              <1> ;	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  8564                              <1> ;	;	+ Sector - 1
  8565                              <1> ;	;push	dx ; * ;; 14/02/2015
  8566                              <1> ;	; 24/12/2021
  8567                              <1> ;	push	edx ; *
  8568                              <1> ;	;xor	dh, dh
  8569                              <1> ;	xor	edx, edx
  8570                              <1> ;	mov	dl, [ebx+14]	; sectors per track (logical)
  8571                              <1> ;	;xor	ah, ah
  8572                              <1> ;	xor	eax, eax
  8573                              <1> ;	mov	al, [ebx+2]	; heads (logical) 
  8574                              <1> ;	dec	al
  8575                              <1> ;	;inc	ax		; 0 =  256
  8576                              <1> ;	inc	eax ; 24/12/2021
  8577                              <1> ;	mul 	dx
  8578                              <1> ;		; AX = # of Heads * Sectors/Track
  8579                              <1> ;	mov	dx, cx
  8580                              <1> ;	;and	cx, 3Fh	 ; sector (1 to 63)
  8581                              <1> ;	and	ecx, 3fh
  8582                              <1> ;	xchg	dl, dh
  8583                              <1> ;	shr	dh, 6
  8584                              <1> ;		; DX = cylinder (0 to 1023)
  8585                              <1> ;	;mul 	dx
  8586                              <1> ;		; DX:AX = # of Heads * Sectors/Track * Cylinder
  8587                              <1> ;	mul	edx
  8588                              <1> ;	dec	cl  ; sector - 1
  8589                              <1> ;	;add	ax, cx
  8590                              <1> ;	;adc	dx, 0
  8591                              <1> ;		; DX:AX = # of Heads * Sectors/Track * Cylinder + Sector -1
  8592                              <1> ;	add	eax, ecx
  8593                              <1> ;	;pop	cx ; * ; ch = head, cl = drive number (zero based)
  8594                              <1> ;	; 24/12/2021
  8595                              <1> ;	pop	ecx ; * ; ch = head, cl = drive number (zero based)
  8596                              <1> ;	;push	dx
  8597                              <1> ;	;push	ax
  8598                              <1> ;	push	eax
  8599                              <1> ;	mov	al, [ebx+14]  ; sectors per track (logical)	
  8600                              <1> ;	mul	ch
  8601                              <1> ;		; AX = Head * Sectors/Track
  8602                              <1> ;	cwd
  8603                              <1> ;	;pop	dx
  8604                              <1> ;	pop	edx
  8605                              <1> ;	;add	ax, dx
  8606                              <1> ;	;pop	dx
  8607                              <1> ;	;adc	dx, 0 ; add carry bit
  8608                              <1> ;	add	eax, edx
  8609                              <1> ;
  8610                              <1> ;lbarw2:
  8611                              <1> 	; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8612                              <1> 	
  8613 00002016 29D2                <1> 	sub	edx, edx ; 21/02/2015
  8614                              <1> 	
  8615                              <1> 	; 11/07/2022
  8616                              <1> 	;mov	dl, cl ; 21/02/2015
  8617                              <1>         
  8618 00002018 C645F800            <1> 	mov     byte [CMD_BLOCK], 0 ; Features Register
  8619                              <1> 				; NOTE: Features register (1F1h, 171h)
  8620                              <1> 				; is not used for ATA device R/W functions. 
  8621                              <1> 				; It is old/obsolete 'write precompensation'
  8622                              <1> 				; register and error register
  8623                              <1> 				; for old ATA/IDE devices.
  8624                              <1> 	; 18/01/2014
  8625                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  8626 0000201C 8A0D[86620000]      <1> 	mov	cl, [hf_m_s]
  8627                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  8628                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  8629                              <1> 				; bit 6 = 1 = LBA mode
  8630                              <1> 				; bit 7 = 1
  8631 00002022 80C90E              <1> 	or	cl, 0Eh ; 1110b
  8632                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  8633 00002025 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  8634 0000202A C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  8635                              <1> 	;or	dh, ch
  8636 0000202D 09C8                <1> 	or	eax, ecx	
  8637                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  8638                              <1> 				  ; (Sector Number Register)
  8639                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  8640                              <1> 				  ; (Cylinder Low Register)
  8641                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  8642                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  8643                              <1> 				  ; (Cylinder High Register)
  8644                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  8645                              <1> 				  ; (Drive/Head Register)
  8646                              <1> 	
  8647                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  8648 0000202F 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  8649                              <1> 	;14/02/2015
  8650                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  8651 00002032 EB3D                <1> 	jmp	short su4
  8652                              <1> su3:
  8653                              <1> 	; 02/02/2015 
  8654                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  8655                              <1> 	;cmp 	ah, 14h
  8656                              <1> 	;jna 	short chsfnc
  8657                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8658                              <1> 	;cmp	ah, 2
  8659                              <1> 	;jna	short chsfnc
  8660                              <1> 	; 11/07/2022 
  8661                              <1> 	; (al = function, read = 1 or write = 2)
  8662 00002034 3C02                <1> 	cmp	al, 2 
  8663 00002036 760B                <1> 	jna	short chsfnc
  8664                              <1> invldfnc:
  8665                              <1>         ; 14/02/2015  
  8666                              <1> 	;pop	es ; **
  8667                              <1>         ;pop	ax ; ***
  8668                              <1>         ; 24/12/2021
  8669 00002038 58                  <1> 	pop	eax ; ***
  8670                              <1> 	;;jmp	short BAD_COMMAND_POP
  8671                              <1> 	; 11/07/2022
  8672                              <1>         ;jmp     short BAD_COMMAND
  8673                              <1> 
  8674                              <1> 	; 11/07/2022
  8675                              <1> BAD_COMMAND:
  8676 00002039 C605[FB670000]01    <1> 	mov	byte [DISK_STATUS1], BAD_CMD  ; COMMAND ERROR
  8677                              <1> 	;mov	al, 0
  8678 00002040 28C0                <1> 	sub	al, al ; 0
  8679 00002042 C3                  <1> 	retn
  8680                              <1> 
  8681                              <1> chsfnc:	
  8682 00002043 668B4305            <1> 	mov	ax, [ebx+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  8683                              <1> 	;shr	ax, 2
  8684                              <1> 	; 17/07/2022
  8685 00002047 C1E802              <1> 	shr	eax, 2
  8686 0000204A 8845F8              <1> 	mov	[CMD_BLOCK], al
  8687                              <1> 	;
  8688                              <1> 	;;mov	al, [ebx+8]		; GET CONTROL BYTE MODIFIER
  8689                              <1> 	;;push	edx ; *
  8690                              <1> 	;;mov	dx, [HF_REG_PORT]
  8691                              <1> 	;;out	dx, al			; SET EXTRA HEAD OPTION
  8692                              <1> 	;;pop	edx ; * 
  8693                              <1> 	;;mov	ah, [CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  8694                              <1> 	;;and	ah, 0C0h 		; CONTROL BYTE	
  8695                              <1> 	;;or	ah, al
  8696                              <1> 	;;mov	[CONTROL_BYTE], ah
  8697                              <1> 	;
  8698 0000204D 88C8                <1> 	mov	al, cl			; GET SECTOR NUMBER
  8699 0000204F 243F                <1> 	and	al, 3Fh
  8700 00002051 8845FA              <1> 	mov	[CMD_BLOCK+2], al
  8701 00002054 886DFB              <1> 	mov	[CMD_BLOCK+3], ch 	; GET CYLINDER NUMBER
  8702 00002057 88C8                <1> 	mov	al, cl
  8703 00002059 C0E806              <1> 	shr	al, 6
  8704 0000205C 8845FC              <1> 	mov	[CMD_BLOCK+4], al	; CYLINDER HIGH ORDER 2 BITS
  8705                              <1> 	;;05/01/2015
  8706                              <1> 	;;mov	al, dl			; DRIVE NUMBER
  8707 0000205F A0[86620000]        <1> 	mov	al, [hf_m_s]
  8708 00002064 C0E004              <1> 	shl	al, 4
  8709 00002067 80E60F              <1> 	and	dh, 0Fh			; HEAD NUMBER
  8710 0000206A 08F0                <1> 	or	al, dh
  8711 0000206C 0CA0                <1> 	or	al, 80h+20h		; ECC AND 512 BYTE SECTORS
  8712 0000206E 8845FD              <1> 	mov	[CMD_BLOCK+5], al	; ECC/SIZE/DRIVE/HEAD
  8713                              <1> su4:
  8714                              <1> 	;; 14/02/2015
  8715                              <1>         ;;pop	ax
  8716                              <1>         ;;mov	[CMD_BLOCK+1], AL	; SECTOR COUNT
  8717                              <1>         ;;push	ax
  8718                              <1>         ;;mov	al, ah			; GET INTO LOW BYTE
  8719                              <1>         ;;xor	ah, ah			; ZERO HIGH BYTE
  8720                              <1>         ;;sal	ax, 1			; *2 FOR TABLE LOOKUP
  8721                              <1> 	;pop	ax ; ***
  8722                              <1> 	; 24/12/2021
  8723 00002071 58                  <1> 	pop	eax ; *** ; function (in AL) ; 11/07/2022
  8724                              <1> 	
  8725                              <1> 	;mov	[CMD_BLOCK+1], al
  8726 00002072 C645F901            <1>         mov	byte [CMD_BLOCK+1], 1 ; (always 1 sector r/w)
  8727                              <1> 
  8728                              <1> 	; 11/07/2022
  8729                              <1> 	;mov	ebx, esi
  8730                              <1> 	; (esi = buffer address)	
  8731                              <1> 
  8732 00002076 3C02                <1> 	cmp	al, 2
  8733 00002078 7433                <1> 	je	short DISK_WRITE
  8734                              <1> 
  8735                              <1> 	;jmp	short DISK_READ
  8736                              <1> 
  8737                              <1> ;	;xor	ebx, ebx
  8738                              <1> ;	;mov	bl, ah
  8739                              <1> ;
  8740                              <1> ;       ;xor	bh, bh
  8741                              <1> ;       ;sal	bx, 1
  8742                              <1> ;       sal	ebx, 2	; 32 bit offset (21/02/2015)
  8743                              <1> ;	;;mov	si, ax			; PUT INTO SI FOR BRANCH
  8744                              <1> ;       ;;cmp	ax, M1L			; TEST WITHIN RANGE
  8745                              <1> ;       ;;jnb	short BAD_COMMAND_POP
  8746                              <1> ;   	; 08/07/2022
  8747                              <1> ;	;cmp	ebx, M1L
  8748                              <1> ;	;jnb	short BAD_COMMAND
  8749                              <1> ;
  8750                              <1> ;	xchg	ebx, esi
  8751                              <1> ;
  8752                              <1> ;	;;;pop	ax			; RESTORE AX
  8753                              <1> ;	;;;pop	bx			; AND DATA ADDRESS
  8754                              <1> ;	
  8755                              <1> ;	;;push	cx
  8756                              <1> ;	;;push	ax			; ADJUST ES:BX
  8757                              <1> ;	;mov	cx, bx			; GET 3 HIGH ORDER NIBBLES OF BX
  8758                              <1> ;	;shr	cx, 4
  8759                              <1> ;	;mov	ax, es
  8760                              <1> ;	;add	ax, cx
  8761                              <1> ;	;mov	es, ax
  8762                              <1> ;	;and	bx, 000Fh		; ES:BX CHANGED TO ES:000X
  8763                              <1> ;	;;pop	ax
  8764                              <1> ;	;;pop	cx
  8765                              <1> ;
  8766                              <1> ;	jmp	dword [esi+M1]
  8767                              <1> 
  8768                              <1> ;;BAD_COMMAND_POP:
  8769                              <1> ;;	pop	ax
  8770                              <1> ;;	pop	bx
  8771                              <1> ;
  8772                              <1> ;	; 11/07/2022
  8773                              <1> ;BAD_COMMAND:
  8774                              <1> ;	mov	byte [DISK_STATUS1], BAD_CMD  ; COMMAND ERROR
  8775                              <1> ;	;mov	al, 0
  8776                              <1> ;	sub	al, al ; 0
  8777                              <1> ;	retn
  8778                              <1> 
  8779                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8780                              <1> 
  8781                              <1> ;----------------------------------------
  8782                              <1> ;	DISK READ ROUTINE    (AH = 01H) :
  8783                              <1> ;----------------------------------------
  8784                              <1> ; 
  8785                              <1> DISK_READ:
  8786 0000207A C645FE20            <1> 	mov	byte [CMD_BLOCK+6], READ_CMD
  8787                              <1>         ;jmp	COMMANDI
  8788                              <1> 
  8789                              <1> ; 16/07/2022
  8790                              <1> ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8791                              <1> 
  8792                              <1> ;----------------------------------------
  8793                              <1> ; COMMANDI				:
  8794                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  8795                              <1> ;	NSECTOR RETURNS ZERO		:
  8796                              <1> ;----------------------------------------
  8797                              <1> COMMANDI:
  8798                              <1> 	; 11/07/2022 
  8799                              <1> 	;	(check 64K boundary is not needed)
  8800                              <1> 	;call	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  8801                              <1> 	;jc	short CMD_ABORT
  8802                              <1> 	
  8803                              <1> 	;mov	di, bx
  8804                              <1> 	; 11/07/2022
  8805                              <1> 	; (esi = buffer address)
  8806                              <1> 	;mov	edi, ebx ; 21/02/2015
  8807 0000207E 89F7                <1> 	mov	edi, esi ; 11/07/2022	
  8808                              <1> 
  8809 00002080 E8AE010000          <1> 	call	COMMAND 		; OUTPUT COMMAND
  8810 00002085 7525                <1> 	jnz	short CMD_ABORT
  8811                              <1> CMD_I1:
  8812 00002087 E819020000          <1> 	call	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  8813 0000208C 751E                <1> 	jnz	short TM_OUT		; TIME OUT
  8814                              <1> 	;;mov	cx,256			; SECTOR SIZE IN WORDS
  8815                              <1> 	;mov	ecx, 256 ; 21/02/2015	
  8816 0000208E 29C9                <1> 	sub	ecx, ecx
  8817 00002090 FEC5                <1> 	inc	ch
  8818                              <1> 	; ecx = 256
  8819                              <1> 	;mov	dx, HF_PORT
  8820 00002092 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  8821 00002099 FA                  <1> 	cli
  8822 0000209A FC                  <1> 	cld
  8823 0000209B F3666D              <1> 	rep	insw			; GET THE SECTOR
  8824 0000209E FB                  <1> 	sti
  8825                              <1> 	
  8826                              <1> 	;test	byte [CMD_BLOCK+6], ECC_MODE ; CHECK FOR NORMAL INPUT
  8827                              <1> 	;jz	short CMD_I3
  8828                              <1> 	;call	WAIT_DRQ		; WAIT FOR DATA REQUEST
  8829                              <1> 	;jc	short TM_OUT
  8830                              <1> 	;;mov	dx, HF_PORT
  8831                              <1> 	;mov	dx,[HF_PORT]
  8832                              <1> 	;xor	ecx, ecx	
  8833                              <1> 	;;mov	ecx, 4  ; mov cx, 4	; OUTPUT THE ECC BYTES
  8834                              <1> 	;mov	cl, 4
  8835                              <1> ;CMD_I2: 
  8836                              <1> 	;inc	al, dx
  8837                              <1> 	;mov 	[edi], al ; 21/02/2015
  8838                              <1> 	;inc	edi
  8839                              <1> 	;loop	CMD_I2
  8840                              <1> CMD_I3:
  8841                              <1> 	; 16/07/2022
  8842                              <1> 	; wait for 400 ns
  8843 0000209F 80C207              <1> 	add 	dl, 7
  8844 000020A2 EC                  <1> 	in	al, dx
  8845 000020A3 EC                  <1> 	in	al, dx
  8846 000020A4 EC                  <1> 	in	al, dx
  8847                              <1> 	;
  8848 000020A5 E817010000          <1> 	call	CHECK_STATUS
  8849 000020AA 7500                <1> 	jnz	short CMD_ABORT		; ERROR RETURNED
  8850                              <1> 	; 11/07/2022
  8851                              <1> 	; (sector count = 1)
  8852                              <1> 	;dec	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  8853                              <1> 	;jnz	SHORT CMD_I1
  8854                              <1> CMD_ABORT:
  8855                              <1> TM_OUT: 
  8856 000020AC C3                  <1> 	retn
  8857                              <1> 
  8858                              <1> ;---------------------------------------------------
  8859                              <1> 
  8860                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8861                              <1> 
  8862                              <1> ;----------------------------------------
  8863                              <1> ;	DISK WRITE ROUTINE   (AH = 02H) :
  8864                              <1> ;----------------------------------------
  8865                              <1> 
  8866                              <1> DISK_WRITE:
  8867 000020AD C645FE30            <1> 	mov	byte [CMD_BLOCK+6], WRITE_CMD
  8868                              <1>         ;JMP	COMMANDO
  8869                              <1> 
  8870                              <1> ; 16/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
  8871                              <1> ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8872                              <1> 
  8873                              <1> ;----------------------------------------
  8874                              <1> ; COMMANDO				:
  8875                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  8876                              <1> ;	NSECTOR RETURNS ZERO		:
  8877                              <1> ;----------------------------------------
  8878                              <1> COMMANDO:
  8879                              <1> 	; 11/07/2022 
  8880                              <1> 	;	(check 64K boundary is not needed)
  8881                              <1> 	;call	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  8882                              <1> 	;jc	short CMD_ABORT
  8883                              <1> CMD_OF:
  8884                              <1> 	; 11/07/2022
  8885                              <1> 	; (esi = ebx = buffer address)
  8886                              <1> 	;mov	esi, ebx ; 21/02/2015
  8887 000020B1 E87D010000          <1> 	call	COMMAND 		; OUTPUT COMMAND
  8888 000020B6 75F4                <1> 	jnz	short CMD_ABORT
  8889 000020B8 E83F020000          <1> 	call	WAIT_DRQ		; WAIT FOR DATA REQUEST
  8890 000020BD 72ED                <1> 	jc	short TM_OUT		; TOO LONG
  8891                              <1> CMD_O1:
  8892                              <1> 	; 16/07/2022
  8893 000020BF 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  8894                              <1> 
  8895                              <1> 	; 10/07/2022
  8896                              <1> 	;mov	ecx, 256 ; 21/02/2015
  8897 000020C6 31C9                <1> 	xor	ecx, ecx
  8898 000020C8 FEC5                <1> 	inc	ch
  8899                              <1> 	; ecx = 256
  8900 000020CA FA                  <1> 	cli
  8901 000020CB FC                  <1> 	cld
  8902 000020CC F3666F              <1> 	rep	outsw
  8903 000020CF FB                  <1> 	sti
  8904                              <1> 
  8905                              <1> 	; 10/07/2022
  8906                              <1> 	;test	byte [CMD_BLOCK+6], ECC_MODE ; CHECK FOR NORMAL OUTPUT
  8907                              <1> 	;jz	short CMD_O3
  8908                              <1> 	;
  8909                              <1> 	;call	WAIT_DRQ		; WAIT FOR DATA REQUEST
  8910                              <1> 	;jc	short TM_OUT
  8911                              <1> 	;;mov	dx, HF_PORT
  8912                              <1> 	;mov	dx, [HF_PORT]
  8913                              <1> 	;sub	ecx, ecx	
  8914                              <1> 	;;mov	ecx, 4  ; mov cx, 4	; OUTPUT THE ECC BYTES
  8915                              <1> 	;mov	cl, 4
  8916                              <1> ;CMD_O2:
  8917                              <1> 	;;lodsb
  8918                              <1> 	;mov	al, [esi]
  8919                              <1> 	;out	dx, al
  8920                              <1> 	;inc	esi
  8921                              <1> 	;loop	CMD_O2
  8922                              <1> 
  8923                              <1> CMD_O3:
  8924 000020D0 E8D0010000          <1> 	call	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  8925 000020D5 75D5                <1> 	jnz	short TM_OUT		; ERROR RETURNED
  8926 000020D7 E8E5000000          <1> 	call	CHECK_STATUS
  8927 000020DC 75CE                <1> 	jnz	short CMD_ABORT
  8928                              <1> 
  8929                              <1> 	; 11/07/2022
  8930                              <1> 	; (sector count = 1)
  8931                              <1> 	;test	byte [HF_STATUS], ST_DRQ ; CHECK FOR MORE
  8932                              <1> 	;jnz	short CMD_O1
  8933                              <1> 	
  8934                              <1> 	;mov	dx, HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  8935 000020DE 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  8936 000020E5 80C202              <1> 	add	dl, 2
  8937                              <1> 	;inc	dl
  8938                              <1> 	;inc	dl
  8939 000020E8 EC                  <1> 	in	al, dx			;
  8940 000020E9 A8FF                <1> 	test	al, 0FFh 		;
  8941 000020EB 7407                <1> 	jz	short CMD_O4		; COUNT = 0  OK
  8942 000020ED C605[FB670000]BB    <1> 	mov	byte [DISK_STATUS1], UNDEF_ERR 
  8943                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  8944                              <1> CMD_O4:
  8945 000020F4 C3                  <1> 	retn
  8946                              <1> 
  8947                              <1> ; 10/07/2022
  8948                              <1> ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  8949                              <1> 
  8950                              <1> ;----------------------------------------
  8951                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  8952                              <1> ;----------------------------------------
  8953                              <1> 
  8954                              <1> ; 18-1-2015 : one controller reset (not other one)
  8955                              <1> 
  8956                              <1> DISK_RESET:
  8957 000020F5 FA                  <1> 	cli
  8958 000020F6 E4A1                <1> 	in	al, INTB01		; GET THE MASK REGISTER
  8959                              <1> 	;JMP	$+2
  8960                              <1> 	IODELAY
  8961 000020F8 EB00                <2>  jmp short $+2
  8962 000020FA EB00                <2>  jmp short $+2
  8963                              <1> 	;and	al, 0BFh 		; ENABLE FIXED DISK INTERRUPT
  8964 000020FC 243F                <1> 	and	al, 3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  8965 000020FE E6A1                <1> 	out	INTB01, al
  8966 00002100 FB                  <1> 	sti				; START INTERRUPTS
  8967                              <1> 	; 14/02/2015
  8968                              <1> 	;mov	di, dx
  8969                              <1> 	; 24/12/2021
  8970 00002101 89D7                <1> 	mov	edi, edx	
  8971                              <1> 	; 04/01/2015
  8972                              <1> 	;xor	di,di
  8973                              <1> drst0:
  8974 00002103 B004                <1> 	mov	al, 04h  ; bit 2 - SRST 
  8975                              <1> 	;mov	dx, HF_REG_PORT
  8976 00002105 668B15[84620000]    <1> 	mov	dx, [HF_REG_PORT]
  8977 0000210C EE                  <1> 	out	dx, al			; RESET
  8978                              <1> ;	mov	cx, 10			; DELAY COUNT
  8979                              <1> ;DRD:	dec	cx
  8980                              <1> ;	jnz	short DRD		; WAIT 4.8 MICRO-SEC
  8981                              <1> 	;mov	cx, 2			; wait for 30 micro seconds	
  8982                              <1>         ;mov	ecx, 2 ; 21/02/2015
  8983                              <1> 	; 10/07/2022
  8984 0000210D 29C9                <1> 	sub	ecx, ecx
  8985 0000210F B102                <1> 	mov	cl, 2
  8986 00002111 E895F2FFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  8987                              <1>                                         ; 40 micro seconds)
  8988 00002116 A0[FD670000]        <1> 	mov	al, [CONTROL_BYTE]
  8989 0000211B 240F                <1> 	and	al, 0Fh			; SET HEAD OPTION
  8990 0000211D EE                  <1> 	out	dx, al			; TURN RESET OFF
  8991 0000211E E8B2010000          <1> 	call	NOT_BUSY
  8992 00002123 7514                <1> 	jnz	short DRERR		; TIME OUT ON RESET
  8993 00002125 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  8994 0000212C FEC2                <1> 	inc	dl  ; HF_PORT+1
  8995                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  8996                              <1>         ;mov	cl, 10
  8997                              <1>         ;mov     ecx, 10 ; 21/02/2015
  8998                              <1> 	; 10/07/2022
  8999                              <1> 	;xor	ecx, ecx
  9000 0000212E B10A                <1> 	mov	cl, 10 
  9001                              <1> drst1:
  9002 00002130 EC                  <1> 	in	al, dx			; GET RESET STATUS
  9003 00002131 3C01                <1> 	cmp	al, 1
  9004                              <1> 	; 04/01/2015
  9005 00002133 740C                <1> 	jz	short drst2
  9006                              <1> 	;jnz	short DRERR		; BAD RESET STATUS
  9007                              <1>         	; Drive/Head Register - bit 4
  9008                              <1> 	;loop	drst1
  9009                              <1> 	; 10/07/2022
  9010 00002135 FEC9                <1> 	dec	cl
  9011 00002137 75F7                <1> 	jnz	short drst1
  9012                              <1> DRERR:	
  9013 00002139 C605[FB670000]05    <1> 	mov	byte [DISK_STATUS1], BAD_RESET ; CARD FAILED
  9014 00002140 C3                  <1> 	retn
  9015                              <1> drst2:
  9016                              <1> 	; 14/02/2015
  9017                              <1> 	;mov	dx, di
  9018                              <1> 	; 24/12/2021
  9019 00002141 89FA                <1> 	mov	edx, edi
  9020                              <1> ;drst3:
  9021                              <1> ;	; 05/01/2015
  9022                              <1> ;	shl 	di, 1
  9023                              <1> ;	; 04/01/2015
  9024                              <1> ;	mov	ax, [di+hd_cports]
  9025                              <1> ;	cmp	ax, [HF_REG_PORT]
  9026                              <1> ;	je	short drst4
  9027                              <1> ;	mov	[HF_REG_PORT], ax
  9028                              <1> ;	; 03/01/2015
  9029                              <1> ;	mov	ax, [di+hd_ports]
  9030                              <1> ;       mov     [HF_PORT], ax
  9031                              <1> ;	; 05/01/2014
  9032                              <1> ;	shr	di, 1
  9033                              <1> ;	; 04/01/2015
  9034                              <1> ;	jmp	short drst0	; reset other controller
  9035                              <1> ;drst4:
  9036                              <1> ;	; 05/01/2015
  9037                              <1> ;	shr	di, 1
  9038                              <1> ;	mov	al, [di+hd_dregs]
  9039                              <1> ;	and	al, 10h ; bit 4 only
  9040                              <1> ;	shr	al, 4 ; bit 4 -> bit 0
  9041                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  9042                              <1> 	;
  9043 00002143 A0[86620000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  9044 00002148 A801                <1> 	test	al, 1
  9045                              <1> 	;jnz	short drst6
  9046 0000214A 7516                <1>         jnz     short drst4
  9047 0000214C 8065FDEF            <1> 	and	byte [CMD_BLOCK+5], 0EFh ; SET TO DRIVE 0
  9048                              <1> ;drst5:
  9049                              <1> drst3:
  9050 00002150 E813000000          <1> 	call	INIT_DRV		; SET MAX HEADS
  9051                              <1> 	;mov	dx, di
  9052 00002155 E8A3000000          <1> 	call	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  9053                              <1> 	; 04/01/2014
  9054                              <1> ;	inc	di
  9055                              <1> ;	mov	dx, di
  9056                              <1> ;	cmp	dl, [HF_NUM]
  9057                              <1> ;	jb	short drst3
  9058                              <1> ;DRE:
  9059 0000215A C605[FB670000]00    <1> 	mov	byte [DISK_STATUS1], 0 	; IGNORE ANY SET UP ERRORS
  9060 00002161 C3                  <1> 	retn
  9061                              <1> ;drst6:
  9062                              <1> drst4:		; Drive/Head Register - bit 4
  9063 00002162 804DFD10            <1> 	or	byte [CMD_BLOCK+5], 010h ; SET TO DRIVE 1     
  9064                              <1>         ;jmp    short drst5
  9065 00002166 EBE8                <1>         jmp     short drst3
  9066                              <1> 
  9067                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9068                              <1> 
  9069                              <1> ;----------------------------------------
  9070                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  9071                              <1> ;----------------------------------------
  9072                              <1> 	; 03/01/2015
  9073                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  9074                              <1> 	; logical sector per logical track
  9075                              <1> 	; and logical heads - 1 would be set but
  9076                              <1> 	; it is seen as it will be good
  9077                              <1> 	; if physical parameters will be set here
  9078                              <1> 	; because, number of heads <= 16.
  9079                              <1> 	; (logical heads usually more than 16)
  9080                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  9081                              <1> 	;	== INT 13h physical parameters
  9082                              <1> 
  9083                              <1> ;INIT_DRV:
  9084                              <1> ;	mov	byte [CMD_BLOCK+6], SET_PARM_CMD
  9085                              <1> ;	call	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  9086                              <1> ;	mov	al, [es:bx+2]		; GET NUMBER OF HEADS
  9087                              <1> ;	dec	al			; CONVERT TO 0-INDEX
  9088                              <1> ;	mov	ah, [CMD_BLOCK+5] 	; GET SDH REGISTER
  9089                              <1> ;	and	ah, 0F0h 		; CHANGE HEAD NUMBER
  9090                              <1> ;	or	ah, al			; TO MAX HEAD
  9091                              <1> ;	mov	[CMD_BLOCK+5], ah
  9092                              <1> ;	mov	al, [es:bx+14]		; MAX SECTOR NUMBER
  9093                              <1> ;	mov	[CMD_BLOCK+1], al
  9094                              <1> ;	sub	ax, ax
  9095                              <1> ;	mov	[CMD_BLOCK+3], al 	; ZERO FLAGS
  9096                              <1> ;	call	COMMAND 		; TELL CONTROLLER
  9097                              <1> ;	jnz	short INIT_EXIT		; CONTROLLER BUSY ERROR
  9098                              <1> ;	call	NOT_BUSY		; WAIT FOR IT TO BE DONE
  9099                              <1> ;	jnz	short INIT_EXIT		; TIME OUT
  9100                              <1> ;	call	CHECK_STATUS
  9101                              <1> ;INIT_EXIT:
  9102                              <1> ;	retn
  9103                              <1> 
  9104                              <1> ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9105                              <1> 
  9106                              <1> ; 04/01/2015
  9107                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  9108                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  9109                              <1> INIT_DRV:
  9110                              <1> 	;xor	ah, ah
  9111 00002168 31C0                <1> 	xor	eax, eax ; 21/02/2015
  9112 0000216A B00B                <1> 	mov	al, 11 ; Physical heads from translated HDPT
  9113 0000216C 3825[10680000]      <1>         cmp     [LBAMode], ah   ; 0
  9114 00002172 7702                <1> 	ja	short idrv0
  9115 00002174 B002                <1> 	mov	al, 2  ; Physical heads from standard HDPT
  9116                              <1> idrv0:
  9117                              <1> 	; DL = drive number (0 based)
  9118 00002176 E80D020000          <1> 	call	GET_VEC
  9119                              <1> 	;push	bx
  9120 0000217B 53                  <1> 	push	ebx ; 21/02/2015
  9121                              <1> 	;add	bx, ax
  9122 0000217C 01C3                <1> 	add	ebx, eax
  9123                              <1> 	;; 05/01/2015
  9124 0000217E 8A25[86620000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  9125                              <1> 	;;and 	ah, 1 
  9126 00002184 C0E404              <1> 	shl	ah, 4
  9127 00002187 80CCA0              <1> 	or	ah, 0A0h  ; Drive/Head register - 10100000b (A0h)	
  9128                              <1> 	;mov	al, [es:bx]
  9129 0000218A 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  9130 0000218C FEC8                <1> 	dec	al	 ; last head number 
  9131                              <1> 	;and	al, 0Fh
  9132 0000218E 08E0                <1> 	or	al, ah	 ; lower 4 bits for head number
  9133                              <1> 	;
  9134 00002190 C645FE91            <1> 	mov	byte [CMD_BLOCK+6], SET_PARM_CMD
  9135 00002194 8845FD              <1> 	mov	[CMD_BLOCK+5], al
  9136                              <1> 	;pop	bx
  9137 00002197 5B                  <1> 	pop	ebx
  9138 00002198 29C0                <1> 	sub	eax, eax ; 21/02/2015
  9139 0000219A B004                <1> 	mov	al, 4 ; Physical sec per track from translated HDPT
  9140 0000219C 803D[10680000]00    <1> 	cmp	byte [LBAMode], 0
  9141 000021A3 7702                <1> 	ja	short idrv1
  9142 000021A5 B00E                <1> 	mov	al, 14 ; Physical sec per track from standard HDPT
  9143                              <1> idrv1:
  9144                              <1> 	;xor	ah, ah
  9145                              <1> 	;add	bx, ax
  9146 000021A7 01C3                <1> 	add	ebx, eax ; 21/02/2015
  9147                              <1> 	;mov	al, [es:bx]
  9148                              <1> 			; sector number
  9149 000021A9 8A03                <1> 	mov	al, [ebx]
  9150 000021AB 8845F9              <1> 	mov	[CMD_BLOCK+1], al
  9151 000021AE 28C0                <1> 	sub	al, al
  9152 000021B0 8845FB              <1> 	mov	[CMD_BLOCK+3], al ; ZERO FLAGS
  9153 000021B3 E87B000000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  9154 000021B8 751E                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  9155 000021BA E816010000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  9156 000021BF 7517                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  9157                              <1> 	;call	CHECK_STATUS
  9158                              <1> 	;jmp	short CHECK_STATUS
  9159                              <1> ;INIT_EXIT:
  9160                              <1> 	;retn
  9161                              <1> 
  9162                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9163                              <1> 
  9164                              <1> ;----------------------------------------
  9165                              <1> ;	CHECK FIXED DISK STATUS 	:
  9166                              <1> ;----------------------------------------
  9167                              <1> CHECK_STATUS:
  9168 000021C1 E861010000          <1> 	call	CHECK_ST		; CHECK THE STATUS BYTE
  9169                              <1> 	;jnz	short CHECK_S1		; AN ERROR WAS FOUND
  9170                              <1> 	; 10/07/2022
  9171 000021C6 7510                <1> 	jnz	short CHECK_S2
  9172 000021C8 A801                <1> 	test	al, ST_ERROR		; WERE THERE ANY OTHER ERRORS
  9173 000021CA 7405                <1> 	jz	short CHECK_S1		; NO ERROR REPORTED
  9174 000021CC E894010000          <1> 	call	CHECK_ER		; ERROR REPORTED
  9175                              <1> CHECK_S1:
  9176 000021D1 803D[FB670000]00    <1> 	cmp	byte [DISK_STATUS1], 0 	; SET STATUS FOR CALLER
  9177                              <1> CHECK_S2:
  9178                              <1> INIT_EXIT:	; 10/07/2022
  9179 000021D8 C3                  <1> 	retn
  9180                              <1> 
  9181                              <1> ;----------------------------------------
  9182                              <1> ;	TEST DISK READY      (AH = 10H) :
  9183                              <1> ;----------------------------------------
  9184                              <1> 
  9185                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  9186 000021D9 E8F7000000          <1> 	call	NOT_BUSY
  9187 000021DE 751C                <1> 	jnz	short TR_EX
  9188 000021E0 8A45FD              <1> 	mov	al, [CMD_BLOCK+5] 	; SELECT DRIVE
  9189 000021E3 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  9190 000021EA 80C206              <1> 	add	dl, 6
  9191 000021ED EE                  <1> 	out	dx, al
  9192 000021EE E834010000          <1> 	call	CHECK_ST		; CHECK STATUS ONLY
  9193 000021F3 7507                <1> 	jnz	short TR_EX
  9194 000021F5 C605[FB670000]00    <1> 	mov	byte [DISK_STATUS1], 0 	; WIPE OUT DATA CORRECTED ERROR
  9195                              <1> TR_EX:	
  9196 000021FC C3                  <1> 	retn
  9197                              <1> 
  9198                              <1> ;----------------------------------------
  9199                              <1> ;	RECALIBRATE	     (AH = 11H) :
  9200                              <1> ;----------------------------------------
  9201                              <1> 
  9202                              <1> HDISK_RECAL:
  9203 000021FD C645FE10            <1>         mov	byte [CMD_BLOCK+6], RECAL_CMD ; 10h, 16
  9204 00002201 E82D000000          <1> 	call	COMMAND 		; START THE OPERATION
  9205 00002206 7523                <1> 	jnz	short RECAL_EXIT	; ERROR
  9206 00002208 E898000000          <1> 	call	_WAIT			; WAIT FOR COMPLETION
  9207 0000220D 7407                <1> 	jz	short RECAL_X 		; TIME OUT ONE OK ?
  9208 0000220F E891000000          <1> 	call	_WAIT			; WAIT FOR COMPLETION LONGER
  9209 00002214 7515                <1> 	jnz	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  9210                              <1> RECAL_X:
  9211 00002216 E8A6FFFFFF          <1> 	call	CHECK_STATUS
  9212 0000221B 803D[FB670000]40    <1> 	cmp	byte [DISK_STATUS1], BAD_SEEK ; SEEK NOT COMPLETE
  9213 00002222 7507                <1> 	jne	short RECAL_EXIT	; IS OK
  9214 00002224 C605[FB670000]00    <1> 	mov	byte [DISK_STATUS1], 0
  9215                              <1> RECAL_EXIT:
  9216 0000222B 803D[FB670000]00    <1>         cmp	byte [DISK_STATUS1], 0
  9217 00002232 C3                  <1> 	retn
  9218                              <1> 
  9219                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9220                              <1> 
  9221                              <1> ;--------------------------------------------------------
  9222                              <1> ; COMMAND						:
  9223                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  9224                              <1> ; OUTPUT						:
  9225                              <1> ;	BL = STATUS					:
  9226                              <1> ;	BH = ERROR REGISTER				:
  9227                              <1> ;--------------------------------------------------------
  9228                              <1> 
  9229                              <1> COMMAND:
  9230                              <1> 	;push	ebx ; 10/07/2022	; WAIT FOR SEEK COMPLETE AND READY
  9231                              <1> 	;;mov	ecx, DELAY_2		; SET INITIAL DELAY BEFORE TEST
  9232                              <1> COMMAND1:
  9233                              <1> 	;;push	ecx			; SAVE LOOP COUNT
  9234 00002233 E8A1FFFFFF          <1> 	call	TST_RDY 		; CHECK DRIVE READY
  9235                              <1> 	;;pop	ecx
  9236                              <1> 	;pop	ebx ; 10/07/2022
  9237 00002238 7418                <1> 	jz	short COMMAND2		; DRIVE IS READY
  9238 0000223A 803D[FB670000]80    <1>         cmp	byte [DISK_STATUS1], TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  9239                              <1> 	;jz	short CMD_TIMEOUT
  9240                              <1> 	;;loop	COMMAND1		; KEEP TRYING FOR A WHILE
  9241                              <1> 	;jmp	short COMMAND4		; ITS NOT GOING TO GET READY
  9242 00002241 7507                <1> 	jne	short COMMAND4
  9243                              <1> CMD_TIMEOUT:
  9244 00002243 C605[FB670000]20    <1> 	mov	byte [DISK_STATUS1], BAD_CNTLR
  9245                              <1> COMMAND4:
  9246                              <1> 	;;pop	ebx ; 10/07/2022
  9247 0000224A 803D[FB670000]00    <1>         cmp	byte [DISK_STATUS1], 0	; SET CONDITION CODE FOR CALLER
  9248 00002251 C3                  <1> 	retn
  9249                              <1> COMMAND2:
  9250                              <1> 	;;pop	ebx ; 10/07/2022
  9251                              <1> 	;push	edi ; 10/07/2022
  9252 00002252 C605[F6670000]00    <1> 	mov	byte [HF_INT_FLAG], 0	; RESET INTERRUPT FLAG
  9253 00002259 FA                  <1> 	cli				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  9254 0000225A E4A1                <1> 	in	al, INTB01		; TURN ON SECOND INTERRUPT CHIP
  9255                              <1> 	;and	al, 0BFh
  9256 0000225C 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  9257                              <1> 	;JMP	$+2
  9258                              <1> 	IODELAY
  9259 0000225E EB00                <2>  jmp short $+2
  9260 00002260 EB00                <2>  jmp short $+2
  9261 00002262 E6A1                <1> 	out	INTB01, al
  9262 00002264 E421                <1> 	in	al, INTA01		; LET INTERRUPTS PASS THRU TO
  9263 00002266 24FB                <1> 	and	al, 0FBh 		; SECOND CHIP
  9264                              <1> 	;JMP	$+2
  9265                              <1> 	IODELAY
  9266 00002268 EB00                <2>  jmp short $+2
  9267 0000226A EB00                <2>  jmp short $+2
  9268 0000226C E621                <1> 	out	INTA01, al
  9269 0000226E FB                  <1> 	sti
  9270                              <1> 	;xor	edi, edi		; INDEX THE COMMAND TABLE
  9271                              <1> 	; 10/07/2022
  9272 0000226F 31C9                <1> 	xor	ecx, ecx
  9273                              <1> 	;mov	dx, HF_PORT+1		; DISK ADDRESS
  9274 00002271 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  9275 00002278 FEC2                <1> 	inc	dl
  9276 0000227A F605[FD670000]C0    <1> 	test	byte [CONTROL_BYTE], 0C0h ; CHECK FOR RETRY SUPPRESSION
  9277 00002281 7411                <1> 	jz	short COMMAND3
  9278 00002283 8A45FE              <1> 	mov	al, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  9279 00002286 24F0                <1> 	and	al, 0F0h 		; GET RID OF MODIFIERS
  9280 00002288 3C20                <1> 	cmp	al, 20h			; 20H-40H IS READ, WRITE, VERIFY
  9281 0000228A 7208                <1> 	jb	short COMMAND3
  9282 0000228C 3C40                <1> 	cmp	al, 40h
  9283 0000228E 7704                <1> 	ja	short COMMAND3
  9284 00002290 804DFE01            <1> 	or	byte [CMD_BLOCK+6], NO_RETRIES 
  9285                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  9286                              <1> COMMAND3:
  9287                              <1> 	;mov	al, [CMD_BLOCK+edi]	; GET THE COMMAND STRING BYTE
  9288                              <1> 	; 10/07/2022
  9289 00002294 8A440DF8            <1> 	mov	al, [CMD_BLOCK+ecx]
  9290 00002298 EE                  <1> 	out	dx, al			; GIVE IT TO CONTROLLER
  9291                              <1> 	IODELAY
  9292 00002299 EB00                <2>  jmp short $+2
  9293 0000229B EB00                <2>  jmp short $+2
  9294                              <1> 	;inc	edi			; NEXT BYTE IN COMMAND BLOCK
  9295                              <1> 	; 10/07/2022
  9296 0000229D 41                  <1> 	inc	ecx
  9297                              <1> 	;inc	dx			; NEXT DISK ADAPTER REGISTER
  9298 0000229E 42                  <1> 	inc	edx   ; 10/07/2022	
  9299                              <1> 	;cmp	di, 7 ; 01/01/2015	; ALL DONE?
  9300                              <1> 	;jne	short COMMAND3		; NO--GO DO NEXT ONE
  9301 0000229F 80F907              <1> 	cmp	cl, 7 ; 10/07/2022
  9302 000022A2 72F0                <1> 	jb	short COMMAND3
  9303                              <1> 	;pop	edi ; 10/07/2022
  9304 000022A4 C3                  <1> 	retn				; ZERO FLAG IS SET
  9305                              <1> 
  9306                              <1> ;CMD_TIMEOUT:
  9307                              <1> ;	mov	byte [DISK_STATUS1], BAD_CNTLR
  9308                              <1> ;COMMAND4:
  9309                              <1> ;	pop	ebx
  9310                              <1> ;	cmp	byte [DISK_STATUS1], 0 	; SET CONDITION CODE FOR CALLER
  9311                              <1> ;	retn
  9312                              <1> 
  9313                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9314                              <1> 
  9315                              <1> ;----------------------------------------
  9316                              <1> ;	WAIT FOR INTERRUPT		:
  9317                              <1> ;----------------------------------------
  9318                              <1> ;WAIT:
  9319                              <1> _WAIT:
  9320 000022A5 FB                  <1> 	sti				; MAKE SURE INTERRUPTS ARE ON
  9321                              <1> 	;sub	cx, cx			; SET INITIAL DELAY BEFORE TEST
  9322                              <1> 	;clc
  9323                              <1> 	;mov	ax, 9000h		; DEVICE WAIT INTERRUPT
  9324                              <1> 	;int	15h
  9325                              <1> 	;jc	short WT2		; DEVICE TIMED OUT
  9326                              <1> 	;mov	bl, DELAY_1		; SET DELAY COUNT
  9327                              <1> 
  9328                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  9329                              <1> 	;; 21/02/2015
  9330                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  9331                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  9332 000022A6 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  9333                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  9334                              <1> ;-----	WAIT LOOP
  9335                              <1> 
  9336                              <1> WT1:	
  9337                              <1> 	;test	byte [HF_INT_FLAG], 80h	; TEST FOR INTERRUPT
  9338 000022AB F605[F6670000]C0    <1> 	test 	byte [HF_INT_FLAG], 0C0h
  9339                              <1> 	;loopz	WT1
  9340 000022B2 7512                <1> 	jnz	short WT3		; INTERRUPT--LETS GO
  9341                              <1> 	;dec	bl
  9342                              <1> 	;jnz	short WT1		; KEEP TRYING FOR A WHILE
  9343                              <1> 
  9344                              <1> WT1_hi:
  9345 000022B4 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  9346 000022B6 A810                <1> 	test	al, 10h			; transition on memory
  9347 000022B8 75FA                <1> 	jnz	short WT1_hi		; refresh.
  9348                              <1> WT1_lo:
  9349 000022BA E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  9350 000022BC A810                <1> 	test	al, 10h			
  9351 000022BE 74FA                <1> 	jz	short WT1_lo
  9352 000022C0 E2E9                <1> 	loop	WT1
  9353                              <1> 	;;or	bl, bl
  9354                              <1> 	;;jz	short WT2	
  9355                              <1> 	;;dec	bl
  9356                              <1> 	;;jmp	short WT1
  9357                              <1> 	;dec	bl
  9358                              <1> 	;jnz	short WT1	
  9359                              <1> WT2:	
  9360                              <1> 	; 10/07/2022
  9361                              <1> 	;mov	byte [DISK_STATUS1], TIME_OUT ; REPORT TIME OUT ERROR
  9362 000022C2 B080                <1> 	mov	al, TIME_OUT
  9363 000022C4 EB07                <1> 	jmp	short WT4
  9364                              <1> WT3:
  9365                              <1> 	;mov	byte [DISK_STATUS1], 0
  9366                              <1> 	;mov	byte [HF_INT_FLAG], 0
  9367 000022C6 28C0                <1> 	sub	al, al ; 0
  9368 000022C8 A2[F6670000]        <1> 	mov	byte [HF_INT_FLAG], al
  9369                              <1> WT4:
  9370                              <1> NB2:	
  9371 000022CD A2[FB670000]        <1> 	mov	byte [DISK_STATUS1], al
  9372                              <1> 
  9373                              <1> 	;cmp	byte [DISK_STATUS1], 0 	; SET CONDITION CODE FOR CALLER
  9374 000022D2 20C0                <1> 	and	al, al
  9375                              <1> 	; zf = 0 -> time out, zf = 1 -> ok
  9376 000022D4 C3                  <1> 	retn
  9377                              <1> 
  9378                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9379                              <1> 
  9380                              <1> ;----------------------------------------
  9381                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  9382                              <1> ;----------------------------------------
  9383                              <1> NOT_BUSY:
  9384 000022D5 FB                  <1> 	sti				; MAKE SURE INTERRUPTS ARE ON
  9385                              <1> 	;push	ebx
  9386                              <1> 	;sub	cx, cx			; SET INITIAL DELAY BEFORE TEST
  9387 000022D6 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  9388 000022DD 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  9389                              <1> 	;mov	bl, DELAY_1
  9390                              <1> 					; wait for 10 seconds
  9391                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  9392                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  9393                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  9394 000022E0 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  9395                              <1> 	;
  9396                              <1> 	;;mov	byte [wait_count], 0    ; Reset wait counter
  9397                              <1> NB1:	
  9398 000022E5 EC                  <1> 	in	al, dx			; CHECK STATUS
  9399                              <1> 	;test	al, ST_BUSY
  9400 000022E6 2480                <1> 	and	al, ST_BUSY
  9401                              <1> 	;loopnz NB1
  9402 000022E8 74E3                <1> 	jz	short NB2 ; al = 0	; NOT BUSY--LETS GO
  9403                              <1> 	;dec	bl			
  9404                              <1> 	;jnz	short NB1		; KEEP TRYING FOR A WHILE
  9405                              <1> 
  9406                              <1> NB1_hi: 
  9407 000022EA E461                <1> 	in	al, SYS1		; wait for hi to lo
  9408 000022EC A810                <1> 	test	al, 010h		; transition on memory
  9409 000022EE 75FA                <1> 	jnz	short NB1_hi		; refresh.
  9410                              <1> NB1_lo: 
  9411 000022F0 E461                <1> 	in	al, SYS1
  9412 000022F2 A810                <1> 	test	al, 010h
  9413 000022F4 74FA                <1> 	jz	short NB1_lo
  9414 000022F6 E2ED                <1> 	loop	NB1
  9415                              <1> 	;dec	bl
  9416                              <1> 	;jnz	short NB1
  9417                              <1> 	;
  9418                              <1> 	;;cmp	byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  9419                              <1> 	;;jb	short NB1
  9420                              <1> 	;
  9421                              <1> 	;mov	byte [DISK_STATUS1], TIME_OUT ; REPORT TIME OUT ERROR
  9422                              <1> 	;jmp	short NB3
  9423 000022F8 B080                <1> 	mov	al, TIME_OUT
  9424                              <1> ;NB2:	
  9425 000022FA EBD1                <1> 	jmp	short NB2 ; 10/07/2022
  9426                              <1> 
  9427                              <1> ;	;mov	byte [DISK_STATUS1], 0
  9428                              <1> ;;NB3:	
  9429                              <1> ;	;pop	ebx
  9430                              <1> ;	mov	[DISK_STATUS1], al	;;; will be set after return
  9431                              <1> ;	;cmp	byte [DISK_STATUS1], 0 	; SET CONDITION CODE FOR CALLER
  9432                              <1> ;	or	al, al			; (zf = 0 --> timeout)
  9433                              <1> ;	retn
  9434                              <1> 
  9435                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9436                              <1> 
  9437                              <1> ;----------------------------------------
  9438                              <1> ;	WAIT FOR DATA REQUEST		:
  9439                              <1> ;----------------------------------------
  9440                              <1> WAIT_DRQ:
  9441                              <1> 	;mov	cx, DELAY_3
  9442                              <1> 	;mov	dx, HF_PORT+7
  9443 000022FC 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  9444 00002303 80C207              <1> 	add	dl, 7
  9445                              <1> 	;;mov	bl, WAIT_HDU_DRQ_HI	; 0
  9446                              <1> 	;mov	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  9447                              <1> 					; (but it is written as 2000
  9448                              <1> 					; micro seconds in ATORGS.ASM file
  9449                              <1> 					; of Award Bios - 1999, D1A0622)
  9450 00002306 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  9451                              <1> WQ_1:
  9452 0000230B EC                  <1> 	in	al, dx			; GET STATUS
  9453 0000230C A808                <1> 	test	al, ST_DRQ		; WAIT FOR DRQ
  9454 0000230E 7516                <1> 	jnz	short WQ_OK
  9455                              <1> 	;loop	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  9456                              <1> WQ_hi:	
  9457 00002310 E461                <1> 	in	al, SYS1		; wait for hi to lo
  9458 00002312 A810                <1> 	test	al, 010h		; transition on memory
  9459 00002314 75FA                <1> 	jnz	short WQ_hi		; refresh.
  9460                              <1> WQ_lo:  
  9461 00002316 E461                <1> 	in	al, SYS1
  9462 00002318 A810                <1> 	test	al, 010h
  9463 0000231A 74FA                <1> 	jz	short WQ_lo
  9464 0000231C E2ED                <1> 	loop	WQ_1
  9465                              <1> 
  9466 0000231E C605[FB670000]80    <1> 	mov	byte [DISK_STATUS1], TIME_OUT ; ERROR
  9467 00002325 F9                  <1> 	stc
  9468                              <1> WQ_OK:
  9469 00002326 C3                  <1> 	retn
  9470                              <1> ;WQ_OK:
  9471                              <1> 	;clc
  9472                              <1> 	;retn
  9473                              <1> 
  9474                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9475                              <1> 
  9476                              <1> ;----------------------------------------
  9477                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  9478                              <1> ;----------------------------------------
  9479                              <1> CHECK_ST:
  9480                              <1> 	;mov	dx, HF_PORT+7		; GET THE STATUS
  9481 00002327 668B15[82620000]    <1> 	mov	dx, [HF_PORT]
  9482 0000232E 80C207              <1> 	add	dl, 7
  9483 00002331 EC                  <1> 	in	al, dx
  9484 00002332 A2[F5670000]        <1> 	mov	[HF_STATUS], al
  9485                              <1> 	;mov	ah, 0
  9486 00002337 28E4                <1> 	sub	ah, ah ; 0
  9487 00002339 A880                <1> 	test	al, ST_BUSY		; IF STILL BUSY
  9488 0000233B 751A                <1> 	jnz	short CKST_EXIT		; REPORT OK
  9489 0000233D B4CC                <1> 	mov	ah, WRITE_FAULT
  9490 0000233F A820                <1> 	test 	al, ST_WRT_FLT		; CHECK FOR WRITE FAULT
  9491 00002341 7514                <1> 	jnz	short CKST_EXIT
  9492 00002343 B4AA                <1> 	mov	ah, NOT_RDY
  9493 00002345 A840                <1> 	test	al, ST_READY		; CHECK FOR NOT READY
  9494 00002347 740E                <1> 	jz	short CKST_EXIT
  9495 00002349 B440                <1> 	mov	ah, BAD_SEEK
  9496 0000234B A810                <1> 	test	al, ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  9497 0000234D 7408                <1> 	jz	short CKST_EXIT
  9498 0000234F B411                <1> 	mov	ah, DATA_CORRECTED
  9499 00002351 A804                <1> 	test	al, ST_CORRCTD		; CHECK FOR CORRECTED ECC
  9500 00002353 7502                <1> 	jnz	short CKST_EXIT
  9501                              <1> 	;mov	ah, 0
  9502 00002355 30E4                <1> 	xor	ah, ah ; 0
  9503                              <1> CKST_EXIT:
  9504 00002357 8825[FB670000]      <1> 	mov	[DISK_STATUS1], ah	; SET ERROR FLAG
  9505 0000235D 80FC11              <1> 	cmp	ah, DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  9506 00002360 7402                <1> 	je	short CKST_EX1
  9507                              <1> 	;cmp	ah, 0
  9508 00002362 20E4                <1> 	and	ah, ah
  9509                              <1> CKST_EX1:
  9510 00002364 C3                  <1> 	retn
  9511                              <1> 
  9512                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9513                              <1> 
  9514                              <1> ;----------------------------------------
  9515                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  9516                              <1> ;----------------------------------------
  9517                              <1> CHECK_ER:
  9518                              <1> 	;mov	dx, HF_PORT+1		; GET THE ERROR REGISTER
  9519 00002365 668B15[82620000]    <1> 	mov	dx, [HF_PORT]		;
  9520 0000236C FEC2                <1> 	inc	dl
  9521 0000236E EC                  <1> 	in	al, dx
  9522                              <1> 	; 10/07/2022
  9523                              <1> 	;mov	[HF_ERROR], al
  9524                              <1> 	;push	ebx	; 21/02/2015
  9525 0000236F 29C9                <1> 	sub	ecx, ecx
  9526                              <1> 	;mov	ecx, 8			; TEST ALL 8 BITS
  9527 00002371 B108                <1> 	mov	cl, 8
  9528                              <1> CK1:	
  9529 00002373 D0E0                <1> 	shl	al, 1			; MOVE NEXT ERROR BIT TO CARRY
  9530 00002375 7202                <1> 	jc	short CK2		; FOUND THE ERROR
  9531 00002377 E2FA                <1> 	loop	CK1			; KEEP TRYING
  9532                              <1> CK2:
  9533                              <1> 	;mov	ebx, ERR_TBL		; COMPUTE ADDRESS OF
  9534                              <1> 	;add	ebx, ecx		; ERROR CODE
  9535 00002379 81C1[78620000]      <1> 	add	ecx, ERR_TBL ; 10/07/2022	
  9536                              <1> 
  9537                              <1> 	;;;mov	ah, byte [cs:bx]	; GET ERROR CODE
  9538                              <1> 	;;mov	ah, [bx]
  9539                              <1> 	;mov	ah, [ebx] ; 21/02/2015
  9540 0000237F 8A21                <1> 	mov	ah, [ecx]	
  9541                              <1> CKEX:
  9542 00002381 8825[FB670000]      <1> 	mov	[DISK_STATUS1], ah	; SAVE ERROR CODE
  9543                              <1> 	; 10/07/2022
  9544                              <1> 	;pop	ebx
  9545                              <1> 	;;cmp	ah, 0
  9546                              <1> 	;and	ah, ah
  9547 00002387 C3                  <1> 	retn
  9548                              <1> 
  9549                              <1> ;--------------------------------------------------------
  9550                              <1> ; CHECK_DMA						:
  9551                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  9552                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  9553                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  9554                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  9555                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  9556                              <1> ;  -ERROR OTHERWISE					:
  9557                              <1> ;--------------------------------------------------------
  9558                              <1> 
  9559                              <1> 	; 11/07/2022
  9560                              <1> 	; (not needed for hard disks and 32 bit OS)
  9561                              <1> 	;
  9562                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9563                              <1> ;CHECK_DMA:
  9564                              <1> ;	;;push	ax			; SAVE REGISTERS
  9565                              <1> ;	;; 24/12/2021
  9566                              <1> ;	;;push	eax
  9567                              <1> ;	;mov	ax, 8000h		; AH = MAX # SECTORS
  9568                              <1> ;					; AL = MAX OFFSET
  9569                              <1> ;	; 10/07/2022
  9570                              <1> ;	;test	byte [CMD_BLOCK+6], ECC_MODE
  9571                              <1> ;	;jz	short CKD1
  9572                              <1> ;	;mov	ax, 7F04h		; ECC IS 4 MORE BYTES
  9573                              <1> ;CKD1:	
  9574                              <1> ;	;cmp	ah, [CMD_BLOCK+1]	; NUMBER OF SECTORS
  9575                              <1> ;	;ja	short CKDOK		; IT WILL FIT
  9576                              <1> ;	;jb	short CKDERR		; TOO MANY
  9577                              <1> ;	
  9578                              <1> ;	cmp	byte [CMD_BLOCK+1], 80h
  9579                              <1> ;	jb	short CKDOK
  9580                              <1> ;	ja	short CKDERR
  9581                              <1> ;	;cmp	al, bl			; CHECK OFFSET ON MAX SECTORS
  9582                              <1> ;	;jb	short CKDERR		; ERROR
  9583                              <1> ;CKD2:
  9584                              <1> ;	or	bl, bl
  9585                              <1> ;	jz	short CKDR
  9586                              <1> ;	
  9587                              <1> ;;CKDOK:	
  9588                              <1> ;	;clc				; CLEAR CARRY
  9589                              <1> ;	;;pop	ax
  9590                              <1> ;	;; 24/12/2021
  9591                              <1> ;	;pop	eax
  9592                              <1> ;	;retn				; NORMAL RETURN
  9593                              <1> ;CKDERR: 
  9594                              <1> ;	stc				; INDICATE ERROR
  9595                              <1> ;	mov	byte [DISK_STATUS1], DMA_BOUNDARY
  9596                              <1> ;	;;pop	ax
  9597                              <1> ;	;; 24/12/2021
  9598                              <1> ;	;pop	eax	
  9599                              <1> ;	retn
  9600                              <1> ;
  9601                              <1> ;	; 10/07/2022
  9602                              <1> ;CKDOK:
  9603                              <1> ;	clc
  9604                              <1> ;CKDR:
  9605                              <1> ;	retn
  9606                              <1> 
  9607                              <1> ;----------------------------------------
  9608                              <1> ;	SET UP EBX-> DISK PARMS	        :
  9609                              <1> ;----------------------------------------
  9610                              <1> 					
  9611                              <1> ; INPUT -> DL = 0 based drive number
  9612                              <1> ; OUTPUT -> EBX = disk parameter table address
  9613                              <1> 
  9614                              <1> 	; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
  9615                              <1> 
  9616                              <1> GET_VEC:
  9617                              <1> 	;sub	ax, ax			; GET DISK PARAMETER ADDRESS
  9618                              <1> 	;mov	es, ax
  9619                              <1> 	;test	dl, 1
  9620                              <1> 	;jz	short GV_0
  9621                              <1> ;	les	bx, [HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  9622                              <1> ;	jmp	short GV_EXIT
  9623                              <1> ;GV_0:
  9624                              <1> ;	les 	bx,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  9625                              <1> ;
  9626 00002388 31DB                <1> 	xor	ebx, ebx
  9627 0000238A 88D3                <1> 	mov	bl, dl
  9628                              <1> 	;02/01/2015
  9629                              <1> 	;xor	bh, bh
  9630                              <1> 	;shl	bl, 1			; port address offset
  9631                              <1> 	;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  9632                              <1> 	;shl	bl, 1			; dpt pointer offset
  9633 0000238C C0E302              <1> 	shl	bl, 2
  9634                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  9635 0000238F 81C3[00680000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  9636                              <1> 	;push	word [bx+2]		; dpt segment
  9637                              <1> 	;pop	es
  9638                              <1> 	;mov	bx, [bx]		; dpt offset
  9639 00002395 8B1B                <1> 	mov	ebx, [ebx]		
  9640                              <1> ;GV_EXIT:
  9641 00002397 C3                  <1> 	retn
  9642                              <1> 
  9643                              <1> 	; 24/12/2021 - Retro UNIX 386 v1.1
  9644                              <1> hdc1_int: ; 21/02/2015
  9645                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  9646                              <1> ;								:
  9647                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9648                              <1> ;								:
  9649                              <1> ;----------------------------------------------------------------
  9650                              <1> 
  9651                              <1> ; 22/12/2014
  9652                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  9653                              <1> ;	 '11/15/85'
  9654                              <1> ; AWARD BIOS 1999 (D1A0622) 
  9655                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  9656                              <1> 
  9657                              <1> ;int_76h:
  9658                              <1> HD_INT:
  9659                              <1> 	;push	ax
  9660                              <1> 	; 24/12/2021
  9661 00002398 50                  <1> 	push	eax
  9662 00002399 1E                  <1> 	push	ds
  9663                              <1> 	;CALL	DDS
  9664                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  9665 0000239A 66B81000            <1> 	mov	ax, KDATA
  9666 0000239E 8ED8                <1> 	mov 	ds, ax
  9667                              <1> 	;
  9668                              <1> 	;;MOV	@HF_INT_FLAG, 0FFH	; ALL DONE
  9669                              <1>         ;mov	byte [CS:HF_INT_FLAG], 0FFh
  9670 000023A0 C605[F6670000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  9671                              <1> 	;
  9672                              <1> 	;push	dx
  9673                              <1> 	; 24/12/2021
  9674 000023A7 52                  <1> 	push	edx
  9675 000023A8 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  9676                              <1> 					; Clear Controller
  9677                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  9678 000023AC EC                  <1> 	in	al, dx			;
  9679                              <1> 	;pop	dx
  9680                              <1> 	; 24/12/2021
  9681 000023AD 5A                  <1> 	pop	edx
  9682                              <1> 	NEWIODELAY
  9683 000023AE E6EB                <2>  out 0EBh,al
  9684                              <1> 	;
  9685 000023B0 B020                <1> 	mov	al, EOI			; NON-SPECIFIC END OF INTERRUPT
  9686 000023B2 E6A0                <1> 	out	INTB00, al		; FOR CONTROLLER #2
  9687                              <1> 	;JMP	$+2			; WAIT
  9688                              <1> 	NEWIODELAY
  9689 000023B4 E6EB                <2>  out 0EBh,al
  9690 000023B6 E620                <1> 	out	INTA00, al		; FOR CONTROLLER #1
  9691 000023B8 1F                  <1> 	pop	ds
  9692                              <1> 	;sti				; RE-ENABLE INTERRUPTS
  9693                              <1> 	;mov	ax, 9100h		; DEVICE POST
  9694                              <1> 	;int	15h			; INTERRUPT
  9695                              <1> irq15_iret: ; 25/02/2015
  9696                              <1> 	;pop	ax
  9697                              <1> 	; 24/12/2021
  9698 000023B9 58                  <1> 	pop	eax
  9699 000023BA CF                  <1> 	iretd				; RETURN FROM INTERRUPT
  9700                              <1> 
  9701                              <1> 	; 24/12/2021 - Retro UNIX 386 v1.1
  9702                              <1> hdc2_int: ; 21/02/2015
  9703                              <1> ;--- HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) ----------------------
  9704                              <1> ;								:
  9705                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  9706                              <1> ;								:
  9707                              <1> ;----------------------------------------------------------------
  9708                              <1> 
  9709                              <1> ;int_77h:
  9710                              <1> HD1_INT:
  9711                              <1> 	;push	ax
  9712                              <1> 	; 24/12/2021
  9713 000023BB 50                  <1> 	push	eax
  9714                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  9715                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  9716 000023BC B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  9717 000023BE E6A0                <1> 	out	0A0h, al
  9718 000023C0 EB00                <1>         jmp short $+2
  9719 000023C2 EB00                <1> 	jmp short $+2
  9720 000023C4 E4A0                <1> 	in	al, 0A0h
  9721 000023C6 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  9722 000023C8 74EF                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  9723                              <1> 	;
  9724 000023CA 1E                  <1> 	push	ds
  9725                              <1> 	;CALL	DDS
  9726                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  9727 000023CB 66B81000            <1> 	mov	ax, KDATA
  9728 000023CF 8ED8                <1> 	mov 	ds, ax
  9729                              <1> 	;
  9730                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  9731                              <1>         ;or	byte [CS:HF_INT_FLAG], 0C0h 
  9732 000023D1 800D[F6670000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  9733                              <1> 	;
  9734                              <1> 	;push	dx
  9735                              <1> 	; 24/12/2021
  9736 000023D8 52                  <1> 	push	edx
  9737 000023D9 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  9738                              <1> 					; Clear Controller (Award BIOS 1999)
  9739 000023DD EBCD                <1> 	jmp	short Clear_IRQ1415
  9740                              <1> 
  9741                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  9742                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  9743                              <1> 
  9744                              <1> ;////////////////////////////////////////////////////////////////////
  9745                              <1> ;; END OF DISK I/O SYTEM ///
  9746                                  %include 'memory.s'  ; 09/03/2015
  9747                              <1> ; Retro UNIX 386 v2 - memory.s - 26/01/2020
  9748                              <1> ; Last Modification: 17/07/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.3)
  9749                              <1> ; ----------------------------------------------------------------------------
  9750                              <1> ;
  9751                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
  9752                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
  9753                              <1> ; 18/10/2015 (!not completed!)
  9754                              <1> ;
  9755                              <1> ; Source code for NASM - Netwide Assembler (2.11)
  9756                              <1> 
  9757                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
  9758                              <1> 
  9759                              <1> ;;04/11/2014 (unix386.s)	
  9760                              <1> ;PDE_A_PRESENT	equ 1		; Present flag for PDE
  9761                              <1> ;PDE_A_WRITE	equ 2		; Writable (write permission) flag
  9762                              <1> ;PDE_A_USER	equ 4		; User (non-system/kernel) page flag
  9763                              <1> ;;
  9764                              <1> ;PTE_A_PRESENT	equ 1		; Present flag for PTE (bit 0)
  9765                              <1> ;PTE_A_WRITE	equ 2		; Writable (write permission) flag (bit 1)
  9766                              <1> ;PTE_A_USER	equ 4		; User (non-system/kernel) page flag (bit 2)
  9767                              <1> ;PTE_A_ACCESS   equ 32		; Accessed flag (bit 5) ; 09/03/2015
  9768                              <1> 
  9769                              <1> ; 27/04/2015
  9770                              <1> ; 09/03/2015
  9771                              <1> PAGE_SIZE 	equ 4096	; page size in bytes
  9772                              <1> PAGE_SHIFT 	equ 12		; page table shift count
  9773                              <1> PAGE_D_SHIFT 	equ 22 ; 12+10	; page directory shift count
  9774                              <1> PAGE_OFF	equ 0FFFh	; 12 bit byte offset in page frame
  9775                              <1> PTE_MASK 	equ 03FFh	; page table entry mask
  9776                              <1> PTE_DUPLICATED  equ 200h	; duplicated page sign (AVL bit 0)
  9777                              <1> PDE_A_CLEAR	equ 0F000h	; to clear PDE attribute bits
  9778                              <1> PTE_A_CLEAR	equ 0F000h	; to clear PTE attribute bits
  9779                              <1> LOGIC_SECT_SIZE equ 512		; logical sector size
  9780                              <1> ERR_MAJOR_PF	equ 0E0h	; major error: page fault
  9781                              <1> ; 15/10/2016 (TRDOS 386 v2)
  9782                              <1> ERR_MINOR_IM	equ 4 ;15/10/2016 (1->4); insufficient (out of) memory
  9783                              <1> ERR_MINOR_PV	equ 6 ;15/10/2016 (3->6); protection violation
  9784                              <1> SWP_DISK_READ_ERR 	   equ 40
  9785                              <1> SWP_DISK_NOT_PRESENT_ERR   equ 41
  9786                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 42
  9787                              <1> SWP_NO_FREE_SPACE_ERR      equ 43
  9788                              <1> SWP_DISK_WRITE_ERR         equ 44
  9789                              <1> SWP_NO_PAGE_TO_SWAP_ERR    equ 45
  9790                              <1> PTE_A_ACCESS_BIT equ 5	; Bit 5 (accessed flag)        
  9791                              <1> SECTOR_SHIFT     equ 3	; sector shift (to convert page block number)
  9792                              <1> ; 10/06/2021 (Retro UNIX 386 v2)
  9793                              <1> ; 12/07/2016 (TRDOS 386 v2) 
  9794                              <1> PTE_SHARED	 equ 400h		; AVL bit 1, direct memory access bit	
  9795                              <1> 					; (Indicates that the page is not allocated
  9796                              <1> 					; for the process, it is a shared or system
  9797                              <1>                                         ; page, it must not be deallocated!)
  9798                              <1> ; 14/12/2020
  9799                              <1> ; (Linear Frame Buffer - video memory mark : AVL bit 1, outside M.A.T.)
  9800                              <1> PDE_EXTERNAL	equ 400h	; Page directory entry for external memory blocks
  9801                              <1> PTE_EXTERNAL	equ 400h	; Allocated kernel pages for Linear Frame Buffer
  9802                              <1> 				; (Out of memory allocation table)	
  9803                              <1> ;
  9804                              <1> ;; Retro Unix 386 v1 - paging method/principles
  9805                              <1> ;;
  9806                              <1> ;; 10/10/2014
  9807                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
  9808                              <1> ;;
  9809                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
  9810                              <1> ;;	(virtual address = physical address)
  9811                              <1> ;; KERNEL PAGE TABLES:
  9812                              <1> ;;	Kernel page directory and all page tables are
  9813                              <1> ;;	on memory as initialized, as equal to physical memory
  9814                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
  9815                              <1> ;;
  9816                              <1> ;;	what for: User pages may be swapped out, when accessing
  9817                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
  9818                              <1> ;;	kernel would have to swap it in! But it is also may be
  9819                              <1> ;;	in use by a user process. (In system/kernel mode
  9820                              <1> ;;	kernel can access all memory pages even if they are
  9821                              <1> ;;	reserved/allocated for user processes. Swap out/in would
  9822                              <1> ;;	cause conflicts.) 
  9823                              <1> ;;	
  9824                              <1> ;;	As result of these conditions,
  9825                              <1> ;;	all kernel pages must be initialized as equal to 
  9826                              <1> ;;	physical layout for preventing page faults. 
  9827                              <1> ;;	Also, calling "allocate page" procedure after
  9828                              <1> ;;	a page fault can cause another page fault (double fault)
  9829                              <1> ;;	if all kernel page tables would not be initialized.
  9830                              <1> ;;
  9831                              <1> ;;	[first_page] = Beginning of users space, as offset to 
  9832                              <1> ;;	memory allocation table. (double word aligned)
  9833                              <1> ;;
  9834                              <1> ;;	[next_page] = first/next free space to be searched
  9835                              <1> ;;	as offset to memory allocation table. (dw aligned)
  9836                              <1> ;;
  9837                              <1> ;;	[last_page] = End of memory (users space), as offset
  9838                              <1> ;;	to memory allocation table. (double word aligned)
  9839                              <1> ;;
  9840                              <1> ;; USER PAGE TABLES:
  9841                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
  9842                              <1> ;;		'ready only' marked copies of the 
  9843                              <1> ;;		parent process's page table entries (for
  9844                              <1> ;;		same physical memory).
  9845                              <1> ;;		(A page will be copied to a new page after
  9846                              <1> ;;		 if it causes R/W page fault.)
  9847                              <1> ;;
  9848                              <1> ;;	Every user process has own (different)
  9849                              <1> ;;	page directory and page tables.	
  9850                              <1> ;;
  9851                              <1> ;;	Code starts at virtual address 0, always.
  9852                              <1> ;;	(Initial value of EIP is 0 in user mode.)
  9853                              <1> ;;	(Programs can be written/developed as simple
  9854                              <1> ;;	 flat memory programs.)
  9855                              <1> ;;
  9856                              <1> ;; MEMORY ALLOCATION STRATEGY:
  9857                              <1> ;;	Memory page will be allocated by kernel only 
  9858                              <1> ;;		(in kernel/system mode only).
  9859                              <1> ;;	* After a
  9860                              <1> ;;	  - 'not present' page fault
  9861                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
  9862                              <1> ;;	* For loading (opening, reading) a file or disk/drive
  9863                              <1> ;;	* As responce to 'allocate additional memory blocks' 
  9864                              <1> ;;	  request by running process.
  9865                              <1> ;;	* While creating a process, allocating a new buffer,
  9866                              <1> ;;	  new page tables etc.
  9867                              <1> ;;
  9868                              <1> ;;	At first,
  9869                              <1> ;;	- 'allocate page' procedure will be called;
  9870                              <1> ;,	   if it will return with a valid (>0) physical address
  9871                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
  9872                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
  9873                              <1> ;;	- 'allocate page' will be called for allocating page
  9874                              <1> ;;	   directory, page table and running space (data/code).
  9875                              <1> ;;	- every successful 'allocate page' call will decrease
  9876                              <1> ;;	  'free_pages' count (pointer).
  9877                              <1> ;;	- 'out of (insufficient) memory error' will be returned
  9878                              <1> ;;	  if 'free_pages' points to a ZERO.
  9879                              <1> ;;	- swapping out and swapping in (if it is not a new page)
  9880                              <1> ;;	  procedures will be called as responce to 'out of memory'
  9881                              <1> ;;	  error except errors caused by attribute conflicts.
  9882                              <1> ;;	 (swapper functions)	 
  9883                              <1> ;;					
  9884                              <1> ;;	At second,
  9885                              <1> ;;	- page directory entry will be updated then page table
  9886                              <1> ;;	  entry will be updated.		
  9887                              <1> ;;
  9888                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
  9889                              <1> ;;	- M.A.T. has a size according to available memory as
  9890                              <1> ;;	  follows:
  9891                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
  9892                              <1> ;;		  - a bit with value of 0 means allocated page
  9893                              <1> ;;		  - a bit with value of 1 means a free page
  9894                              <1> ;,	- 'free_pages' pointer holds count of free pages
  9895                              <1> ;;	  depending on M.A.T.
  9896                              <1> ;;		(NOTE: Free page count will not be checked
  9897                              <1> ;;		again -on M.A.T.- after initialization. 
  9898                              <1> ;;		Kernel will trust on initial count.)
  9899                              <1> ;,	- 'free_pages' count will be decreased by allocation
  9900                              <1> ;;	  and it will be increased by deallocation procedures.
  9901                              <1> ;;	
  9902                              <1> ;;	- Available memory will be calculated during
  9903                              <1> ;;	  the kernel's initialization stage (in real mode).
  9904                              <1> ;;	  Memory allocation table and kernel page tables 
  9905                              <1> ;;	  will be formatted/sized as result of available
  9906                              <1> ;;	  memory calculation before paging is enabled.
  9907                              <1> ;;
  9908                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
  9909                              <1> ;;	- Memory Allocation Table size will be 128 KB.
  9910                              <1> ;;	- Memory allocation for kernel page directory size 
  9911                              <1> ;;	  is always 4 KB. (in addition to total allocation size
  9912                              <1> ;;	  for page tables)
  9913                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
  9914                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
  9915                              <1> ;;	- User (available) space will be started 
  9916                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
  9917                              <1> ;;	- The first 640 KB is for kernel's itself plus
  9918                              <1> ;;	  memory allocation table and kernel's page directory
  9919                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
  9920                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
  9921                              <1> ;; 	  for buffers.
  9922                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
  9923                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
  9924                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
  9925                              <1> ;;
  9926                              <1> ;; For 1GB Available Memory:
  9927                              <1> ;;	- Memory Allocation Table size will be 32 KB.
  9928                              <1> ;;	- Memory allocation for kernel page directory size 
  9929                              <1> ;;	  is always 4 KB. (in addition to total allocation size
  9930                              <1> ;;	  for page tables)
  9931                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
  9932                              <1> ;;	  is 1 MB (256*4*1024 bytes).
  9933                              <1> ;;	- User (available) space will be started 
  9934                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
  9935                              <1> ;;	- The first 640 KB is for kernel's itself plus
  9936                              <1> ;;	  memory allocation table and kernel's page directory
  9937                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
  9938                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
  9939                              <1> ;; 	  for buffers.
  9940                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
  9941                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
  9942                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
  9943                              <1> ;;
  9944                              <1> ;;
  9945                              <1> 
  9946                              <1> ;;************************************************************************************
  9947                              <1> ;; 
  9948                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
  9949                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
  9950                              <1> 
  9951                              <1> ;; Main factor: "sys fork" system call 
  9952                              <1> ;;	
  9953                              <1> ;; 		FORK
  9954                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
  9955                              <1> ;;  writable pages ---->|
  9956                              <1> ;;                      |----> child - duplicated PTEs, read only pages
  9957                              <1> ;; 
  9958                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
  9959                              <1> ;; 
  9960                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
  9961                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
  9962                              <1> ;;       -while R/W bit is 0-. 
  9963                              <1> ;; 
  9964                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
  9965                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
  9966                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
  9967                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
  9968                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
  9969                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
  9970                              <1> ;; 
  9971                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
  9972                              <1> ;; # Parent's read only pages are copied to new child pages. 
  9973                              <1> ;;   Parent's PTE attributes are not changed.
  9974                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
  9975                              <1> ;;    destroy/mix previous fork result).
  9976                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
  9977                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
  9978                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
  9979                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
  9980                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
  9981                              <1> ;;   as Child's Page Table Entries without copying actual page.
  9982                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
  9983                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
  9984                              <1> ;; 
  9985                              <1> ;; !? WHAT FOR (duplication after duplication):
  9986                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
  9987                              <1> ;; program/executable code continues from specified location as child process, 
  9988                              <1> ;; returns back previous code location as parent process, every child after 
  9989                              <1> ;; every sys fork uses last image of code and data just prior the fork.
  9990                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
  9991                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
  9992                              <1> ;; was copied to child's process segment (all of code and data) according to
  9993                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
  9994                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
  9995                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
  9996                              <1> ;; (complete running image of parent process) to the child process; 
  9997                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
  9998                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
  9999                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
 10000                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
 10001                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
 10002                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
 10003                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
 10004                              <1> ;; new/fresh pages will be used to load and run new executable/program.
 10005                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
 10006                              <1> ;; for sharing same read only pages between parent and child processes.
 10007                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
 10008                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
 10009                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
 10010                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
 10011                              <1> ;; -deallocation problem-.
 10012                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
 10013                              <1> ;; 
 10014                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10015                              <1> ;; # Page fault handler will do those:
 10016                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10017                              <1> ;;   - If it is reset/clear, there is a child uses same page.
 10018                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
 10019                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
 10020                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
 10021                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
 10022                              <1> ;;     read only page will be converted to writable and unique page which belongs
 10023                              <1> ;;     to child process.)	
 10024                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10025                              <1> ;; # Page fault handler will do those:
 10026                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10027                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
 10028                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
 10029                              <1> ;;     address or not. 
 10030                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
 10031                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
 10032                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
 10033                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
 10034                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
 10035                              <1> ;; 
 10036                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
 10037                              <1> ;;       will be set as writable (and unique) in case of child process was using 
 10038                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
 10039                              <1> ;;       duplication method details, it is not possible multiple child processes
 10040                              <1> ;;       were using same page with duplicated PTEs.
 10041                              <1> ;; 
 10042                              <1> ;;************************************************************************************   
 10043                              <1> 
 10044                              <1> ;; 08/10/2014
 10045                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
 10046                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
 10047                              <1> 
 10048                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
 10049                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
 10050                              <1> ;; (25/08/2014, Revision: 5057) file 
 10051                              <1> ;; by KolibriOS Team (2004-2012)
 10052                              <1> 
 10053                              <1> allocate_page:
 10054                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 10055                              <1> 	;	 (temporary modifications)
 10056                              <1> 	; 01/07/2015
 10057                              <1> 	; 05/05/2015
 10058                              <1> 	; 30/04/2015
 10059                              <1> 	; 16/10/2014
 10060                              <1> 	; 08/10/2014
 10061                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
 10062                              <1> 	;
 10063                              <1> 	; INPUT -> none
 10064                              <1> 	;
 10065                              <1> 	; OUTPUT ->
 10066                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10067                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
 10068                              <1> 	;
 10069                              <1> 	;	CF = 1 and EAX = 0 
 10070                              <1> 	; 		   if there is not a free page to be allocated	
 10071                              <1> 	;
 10072                              <1> 	; Modified Registers -> none (except EAX)
 10073                              <1> 	;
 10074 000023DF A1[70670000]        <1> 	mov	eax, [free_pages]
 10075 000023E4 21C0                <1> 	and	eax, eax
 10076 000023E6 7438                <1> 	jz	short out_of_memory
 10077                              <1> 	;
 10078 000023E8 53                  <1> 	push	ebx
 10079 000023E9 51                  <1> 	push	ecx
 10080                              <1> 	;
 10081 000023EA BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
 10082 000023EF 89D9                <1> 	mov	ecx, ebx
 10083                              <1>  				     ; NOTE: 32 (first_page) is initial
 10084                              <1> 				     ; value of [next_page].
 10085                              <1> 				     ; It points to the first available
 10086                              <1> 				     ; page block for users (ring 3) ...	
 10087                              <1> 				     ; (MAT offset 32 = 1024/32)	
 10088                              <1> 				     ; (at the of the first 4 MB)		
 10089 000023F1 031D[74670000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
 10090                              <1> 				 ; next_free_page >> 5
 10091 000023F7 030D[78670000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
 10092                              <1> 				 ; (total_pages - 1) >> 5
 10093                              <1> al_p_scan:
 10094 000023FD 39CB                <1> 	cmp	ebx, ecx
 10095 000023FF 770A                <1> 	ja	short al_p_notfound
 10096                              <1> 	;
 10097                              <1> 	; 01/07/2015
 10098                              <1> 	; AMD64 Architecture Programmers Manual
 10099                              <1> 	; Volume 3:
 10100                              <1> 	; General-Purpose and System Instructions
 10101                              <1> 	;
 10102                              <1> 	; BSF - Bit Scan Forward
 10103                              <1> 	;
 10104                              <1> 	;   Searches the value in a register or a memory location
 10105                              <1> 	;   (second operand) for the least-significant set bit. 
 10106                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
 10107                              <1> 	;   and stores the index of the least-significant set bit in a destination
 10108                              <1> 	;   register (first operand). If the second operand contains 0, 
 10109                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
 10110                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
 10111                              <1> 	;   of the searched value
 10112                              <1> 	;
 10113 00002401 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 10114                              <1> 			   ; Clear ZF if a bit is found set (1) and 
 10115                              <1> 			   ; loads the destination with an index to
 10116                              <1> 			   ; first set bit. (0 -> 31) 
 10117                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 10118 00002404 751C                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
 10119                              <1> 			 ;
 10120                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
 10121                              <1> 			 ;	  with value of 1 means 
 10122                              <1> 			 ;	  the corresponding page is free 
 10123                              <1> 			 ;	  (Retro UNIX 386 v1 feature only!)
 10124 00002406 83C304              <1> 	add	ebx, 4
 10125                              <1> 			 ; We return back for searching next page block
 10126                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
 10127                              <1> 			 ;	 we always will find at least 1 free page here.
 10128 00002409 EBF2                <1>         jmp     short al_p_scan
 10129                              <1> 	;
 10130                              <1> al_p_notfound:
 10131 0000240B 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10132 00002411 890D[74670000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
 10133                              <1> 				 ; (deallocate_page procedure will change it)
 10134 00002417 31C0                <1> 	xor	eax, eax
 10135 00002419 A3[70670000]        <1> 	mov	[free_pages], eax ; 0
 10136 0000241E 59                  <1> 	pop	ecx
 10137 0000241F 5B                  <1> 	pop	ebx
 10138                              <1> 	;
 10139                              <1> ; 17/04/2021
 10140                              <1> ; ('swap_out' procedure call is disabled as temporary)
 10141                              <1> 
 10142                              <1> out_of_memory:
 10143                              <1> ;	call	swap_out
 10144                              <1> ;	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
 10145                              <1> ;	;
 10146                              <1> ;	sub 	eax, eax ; 0
 10147 00002420 F9                  <1> 	stc
 10148 00002421 C3                  <1> 	retn
 10149                              <1> 
 10150                              <1> al_p_found:
 10151 00002422 89D9                <1> 	mov	ecx, ebx
 10152 00002424 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10153 0000242A 890D[74670000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
 10154                              <1> 				 ; address/offset (to the next)
 10155 00002430 FF0D[70670000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
 10156                              <1> 	;
 10157 00002436 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 10158                              <1> 				 ; is copied into the Carry Flag and then cleared
 10159                              <1> 				 ; in the destination.
 10160                              <1> 				 ;
 10161                              <1> 				 ; Reset the bit which is corresponding to the 
 10162                              <1> 				 ; (just) allocated page.
 10163                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
 10164 00002439 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
 10165 0000243C 01C8                <1> 	add	eax, ecx	 ; = page number
 10166 0000243E C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
 10167                              <1> 	; EAX = physical address of memory page
 10168                              <1> 	;
 10169                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
 10170                              <1> 	;       according to this EAX value...
 10171 00002441 59                  <1> 	pop	ecx
 10172 00002442 5B                  <1> 	pop	ebx
 10173                              <1> al_p_ok:
 10174 00002443 C3                  <1> 	retn
 10175                              <1> 
 10176                              <1> make_page_dir:
 10177                              <1> 	; 18/04/2015
 10178                              <1> 	; 12/04/2015
 10179                              <1> 	; 23/10/2014
 10180                              <1> 	; 16/10/2014
 10181                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10182                              <1> 	;
 10183                              <1> 	; INPUT ->
 10184                              <1> 	;	none
 10185                              <1> 	; OUTPUT ->
 10186                              <1> 	;	(EAX = 0)
 10187                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10188                              <1> 	;	cf = 0 ->
 10189                              <1> 	;	u.pgdir = page directory (physical) address of the current
 10190                              <1> 	;		  process/user.
 10191                              <1> 	;
 10192                              <1> 	; Modified Registers -> EAX
 10193                              <1> 	;
 10194 00002444 E896FFFFFF          <1> 	call	allocate_page
 10195 00002449 7216                <1> 	jc	short mkpd_error
 10196                              <1> 	;
 10197 0000244B A3[046D0000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
 10198                              <1> 				  ; (Physical address)
 10199                              <1> clear_page:
 10200                              <1> 	; 18/04/2015
 10201                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10202                              <1> 	;
 10203                              <1> 	; INPUT ->
 10204                              <1> 	;	EAX = physical address of the page
 10205                              <1> 	; OUTPUT ->
 10206                              <1> 	;	all bytes of the page will be cleared
 10207                              <1> 	;
 10208                              <1> 	; Modified Registers -> none
 10209                              <1> 	;
 10210 00002450 57                  <1> 	push	edi
 10211 00002451 51                  <1> 	push	ecx
 10212 00002452 50                  <1> 	push	eax
 10213 00002453 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 10214 00002458 89C7                <1> 	mov	edi, eax
 10215 0000245A 31C0                <1> 	xor	eax, eax
 10216 0000245C F3AB                <1> 	rep	stosd
 10217 0000245E 58                  <1> 	pop	eax
 10218 0000245F 59                  <1> 	pop	ecx
 10219 00002460 5F                  <1> 	pop	edi
 10220                              <1> mkpd_error:
 10221                              <1> mkpt_error:
 10222 00002461 C3                  <1> 	retn
 10223                              <1> 
 10224                              <1> make_page_table:
 10225                              <1> 	; 23/06/2015
 10226                              <1> 	; 18/04/2015
 10227                              <1> 	; 12/04/2015
 10228                              <1> 	; 16/10/2014
 10229                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10230                              <1> 	;
 10231                              <1> 	; INPUT ->
 10232                              <1> 	;	EBX = virtual (linear) address
 10233                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10234                              <1> 	;	      (higher 20 bits must be ZERO)
 10235                              <1> 	;	      (bit 0 must be 1)	 
 10236                              <1> 	;	u.pgdir = page directory (physical) address
 10237                              <1> 	; OUTPUT ->
 10238                              <1> 	;	EDX = Page directory entry address
 10239                              <1> 	;	EAX = Page table address
 10240                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10241                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
 10242                              <1> 	;
 10243                              <1> 	; Modified Registers -> EAX, EDX
 10244                              <1> 	;
 10245 00002462 E878FFFFFF          <1> 	call	allocate_page
 10246 00002467 72F8                <1> 	jc	short mkpt_error
 10247 00002469 E811000000          <1> 	call	set_pde	
 10248 0000246E EBE0                <1> 	jmp	short clear_page
 10249                              <1> 
 10250                              <1> make_page:
 10251                              <1> 	; 24/07/2015
 10252                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
 10253                              <1> 	;
 10254                              <1> 	; INPUT ->
 10255                              <1> 	;	EBX = virtual (linear) address
 10256                              <1> 	;	ECX = page attributes (lower 12 bits)
 10257                              <1> 	;	      (higher 20 bits must be ZERO)
 10258                              <1> 	;	      (bit 0 must be 1)	 
 10259                              <1> 	;	u.pgdir = page directory (physical) address
 10260                              <1> 	; OUTPUT ->
 10261                              <1> 	;	EBX = Virtual address
 10262                              <1> 	;	(EDX = PTE value)
 10263                              <1> 	;	EAX = Physical address
 10264                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10265                              <1> 	;
 10266                              <1> 	; Modified Registers -> EAX, EDX
 10267                              <1> 	;
 10268 00002470 E86AFFFFFF          <1> 	call	allocate_page
 10269 00002475 7207                <1> 	jc	short mkp_err
 10270 00002477 E821000000          <1> 	call	set_pte	
 10271 0000247C 73D2                <1> 	jnc	short clear_page ; 18/04/2015
 10272                              <1> mkp_err:
 10273 0000247E C3                  <1> 	retn
 10274                              <1> 
 10275                              <1> set_pde:	; Set page directory entry (PDE)
 10276                              <1> 	; 20/07/2015
 10277                              <1> 	; 18/04/2015
 10278                              <1> 	; 12/04/2015
 10279                              <1> 	; 23/10/2014
 10280                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10281                              <1> 	;
 10282                              <1> 	; INPUT ->
 10283                              <1> 	;	EAX = physical address
 10284                              <1> 	;	      (use present value if EAX = 0)
 10285                              <1> 	;	EBX = virtual (linear) address
 10286                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10287                              <1> 	;	      (higher 20 bits must be ZERO)
 10288                              <1> 	;	      (bit 0 must be 1)	 
 10289                              <1> 	;	u.pgdir = page directory (physical) address
 10290                              <1> 	; OUTPUT ->
 10291                              <1> 	;	EDX = PDE address
 10292                              <1> 	;	EAX = page table address (physical)
 10293                              <1> 	;	;(CF=1 -> Invalid page address)
 10294                              <1> 	;
 10295                              <1> 	; Modified Registers -> EDX
 10296                              <1> 	;
 10297 0000247F 89DA                <1> 	mov	edx, ebx
 10298 00002481 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
 10299 00002484 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
 10300 00002487 0315[046D0000]      <1> 	add	edx, [u.pgdir]
 10301                              <1> 	;
 10302 0000248D 21C0                <1> 	and	eax, eax
 10303 0000248F 7506                <1> 	jnz	short spde_1
 10304                              <1> 	;
 10305 00002491 8B02                <1> 	mov	eax, [edx]  ; old PDE value
 10306                              <1> 	;test	al, 1
 10307                              <1> 	;jz	short spde_2
 10308 00002493 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
 10309                              <1> spde_1:
 10310                              <1> 	;and	cx, 0FFFh
 10311 00002497 8902                <1> 	mov	[edx], eax
 10312 00002499 66090A              <1> 	or	[edx], cx
 10313 0000249C C3                  <1> 	retn
 10314                              <1> ;spde_2: ; error
 10315                              <1> ;	stc
 10316                              <1> ;	retn
 10317                              <1> 
 10318                              <1> set_pte:	; Set page table entry (PTE)
 10319                              <1> 	; 24/07/2015
 10320                              <1> 	; 20/07/2015
 10321                              <1> 	; 23/06/2015
 10322                              <1> 	; 18/04/2015
 10323                              <1> 	; 12/04/2015
 10324                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10325                              <1> 	;
 10326                              <1> 	; INPUT ->
 10327                              <1> 	;	EAX = physical page address
 10328                              <1> 	;	      (use present value if EAX = 0)
 10329                              <1> 	;	EBX = virtual (linear) address
 10330                              <1> 	;	ECX = page attributes (lower 12 bits)
 10331                              <1> 	;	      (higher 20 bits must be ZERO)
 10332                              <1> 	;	      (bit 0 must be 1)	 
 10333                              <1> 	;	u.pgdir = page directory (physical) address
 10334                              <1> 	; OUTPUT ->
 10335                              <1> 	;	EAX = physical page address
 10336                              <1> 	;	(EDX = PTE value)
 10337                              <1> 	;	EBX = virtual address
 10338                              <1> 	;
 10339                              <1> 	;	CF = 1 -> error
 10340                              <1> 	;
 10341                              <1> 	; Modified Registers -> EAX, EDX
 10342                              <1> 	;
 10343 0000249D 50                  <1> 	push	eax
 10344 0000249E A1[046D0000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
 10345 000024A3 E837000000          <1> 	call 	get_pde
 10346                              <1> 		; EDX = PDE address
 10347                              <1> 		; EAX = PDE value
 10348 000024A8 5A                  <1> 	pop	edx ; physical page address
 10349 000024A9 722A                <1> 	jc	short spte_err ; PDE not present
 10350                              <1> 	;
 10351 000024AB 53                  <1> 	push	ebx ; 24/07/2015
 10352 000024AC 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10353                              <1> 			    ; EDX = PT address (physical)	
 10354 000024B0 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
 10355 000024B3 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
 10356                              <1> 			 ; clear higher 10 bits (PD bits)
 10357 000024B9 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
 10358 000024BC 01C3                <1> 	add	ebx, eax
 10359                              <1> 	;
 10360 000024BE 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
 10361 000024C0 A801                <1> 	test	al, 1
 10362 000024C2 740C                <1> 	jz	short spte_0
 10363 000024C4 09D2                <1> 	or	edx, edx
 10364 000024C6 750F                <1> 	jnz	short spte_1
 10365 000024C8 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10366 000024CC 89C2                <1> 	mov	edx, eax
 10367 000024CE EB09                <1> 	jmp	short spte_2	
 10368                              <1> spte_0:
 10369                              <1> 	; If this PTE contains a swap (disk) address,
 10370                              <1> 	; it can be updated by using 'swap_in' procedure
 10371                              <1> 	; only!
 10372 000024D0 21C0                <1> 	and	eax, eax
 10373 000024D2 7403                <1> 	jz	short spte_1
 10374                              <1> 	; 24/07/2015
 10375                              <1> 	; swapped page ! (on disk)
 10376 000024D4 5B                  <1> 	pop	ebx
 10377                              <1> spte_err:
 10378 000024D5 F9                  <1> 	stc
 10379 000024D6 C3                  <1> 	retn
 10380                              <1> spte_1: 
 10381 000024D7 89D0                <1> 	mov	eax, edx
 10382                              <1> spte_2:
 10383 000024D9 09CA                <1> 	or	edx, ecx
 10384                              <1> 	; 23/06/2015
 10385 000024DB 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
 10386                              <1> 	; 24/07/2015
 10387 000024DD 5B                  <1> 	pop	ebx
 10388 000024DE C3                  <1> 	retn
 10389                              <1> 
 10390                              <1> get_pde:	; Get present value of the relevant PDE
 10391                              <1> 	; 20/07/2015
 10392                              <1> 	; 18/04/2015
 10393                              <1> 	; 12/04/2015
 10394                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10395                              <1> 	;
 10396                              <1> 	; INPUT ->
 10397                              <1> 	;	EBX = virtual (linear) address
 10398                              <1> 	;	EAX = page directory (physical) address
 10399                              <1> 	; OUTPUT ->
 10400                              <1> 	;	EDX = Page directory entry address
 10401                              <1> 	;	EAX = Page directory entry value
 10402                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10403                              <1> 	; Modified Registers -> EDX, EAX
 10404                              <1> 	;
 10405 000024DF 89DA                <1> 	mov	edx, ebx
 10406 000024E1 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
 10407 000024E4 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
 10408 000024E7 01C2                <1> 	add	edx, eax ; page directory address (physical)
 10409 000024E9 8B02                <1> 	mov	eax, [edx]
 10410 000024EB A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
 10411 000024ED 751F                <1> 	jnz	short gpte_retn
 10412 000024EF F9                  <1> 	stc
 10413                              <1> gpde_retn:	
 10414 000024F0 C3                  <1> 	retn
 10415                              <1> 
 10416                              <1> get_pte:
 10417                              <1> 		; Get present value of the relevant PTE
 10418                              <1> 	; 29/07/2015
 10419                              <1> 	; 20/07/2015
 10420                              <1> 	; 18/04/2015
 10421                              <1> 	; 12/04/2015
 10422                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10423                              <1> 	;
 10424                              <1> 	; INPUT ->
 10425                              <1> 	;	EBX = virtual (linear) address
 10426                              <1> 	;	EAX = page directory (physical) address
 10427                              <1> 	; OUTPUT ->
 10428                              <1> 	;	EDX = Page table entry address (if CF=0)
 10429                              <1> 	;	      Page directory entry address (if CF=1)
 10430                              <1> 	;            (Bit 0 value is 0 if PT is not present)
 10431                              <1> 	;	EAX = Page table entry value (page address)
 10432                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 10433                              <1> 	; Modified Registers -> EAX, EDX
 10434                              <1> 	;
 10435 000024F1 E8E9FFFFFF          <1> 	call 	get_pde
 10436 000024F6 72F8                <1> 	jc	short gpde_retn	; page table is not present
 10437                              <1> 	;jnc	short gpte_1
 10438                              <1> 	;retn
 10439                              <1> ;gpte_1:
 10440 000024F8 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10441 000024FC 89DA                <1> 	mov	edx, ebx
 10442 000024FE C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
 10443 00002501 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
 10444                              <1> 			 ; clear higher 10 bits (PD bits)
 10445 00002507 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
 10446 0000250A 01C2                <1> 	add	edx, eax
 10447 0000250C 8B02                <1> 	mov	eax, [edx]
 10448                              <1> gpte_retn:
 10449 0000250E C3                  <1> 	retn
 10450                              <1> 
 10451                              <1> deallocate_page_dir:
 10452                              <1> 	; 15/09/2015
 10453                              <1> 	; 05/08/2015
 10454                              <1> 	; 30/04/2015
 10455                              <1> 	; 28/04/2015
 10456                              <1> 	; 17/10/2014
 10457                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10458                              <1> 	;
 10459                              <1> 	; INPUT ->
 10460                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
 10461                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10462                              <1> 	; OUTPUT ->
 10463                              <1> 	;	All of page tables in the page directory
 10464                              <1> 	;	and page dir's itself will be deallocated
 10465                              <1> 	;	except 'read only' duplicated pages (will be converted
 10466                              <1> 	;	to writable pages).
 10467                              <1> 	;
 10468                              <1> 	; Modified Registers -> EAX
 10469                              <1> 	;
 10470                              <1> 	;
 10471 0000250F 56                  <1> 	push	esi
 10472 00002510 51                  <1> 	push	ecx
 10473 00002511 50                  <1> 	push	eax
 10474 00002512 89C6                <1> 	mov	esi, eax 
 10475 00002514 31C9                <1> 	xor	ecx, ecx
 10476                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
 10477                              <1> 	; it must not be deallocated
 10478 00002516 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
 10479                              <1> dapd_0:
 10480 00002518 AD                  <1> 	lodsd
 10481 00002519 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
 10482 0000251B 7409                <1> 	jz	short dapd_1	
 10483 0000251D 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10484 00002521 E812000000          <1> 	call	deallocate_page_table			
 10485                              <1> dapd_1:
 10486 00002526 41                  <1> 	inc	ecx ; page directory entry index
 10487 00002527 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
 10488 0000252D 72E9                <1> 	jb	short dapd_0
 10489                              <1> dapd_2:
 10490 0000252F 58                  <1> 	pop	eax
 10491 00002530 E870000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
 10492 00002535 59                  <1> 	pop	ecx
 10493 00002536 5E                  <1> 	pop	esi
 10494 00002537 C3                  <1> 	retn
 10495                              <1> 
 10496                              <1> deallocate_page_table:
 10497                              <1> 	; 17/07/2022
 10498                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 10499                              <1> 	;	 (temporary modifications)
 10500                              <1> 	; 12/07/2016 (TRDOS 386 v2)
 10501                              <1> 	; 19/09/2015
 10502                              <1> 	; 15/09/2015
 10503                              <1> 	; 05/08/2015
 10504                              <1> 	; 30/04/2015
 10505                              <1> 	; 28/04/2015
 10506                              <1> 	; 24/10/2014
 10507                              <1> 	; 23/10/2014
 10508                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10509                              <1> 	;
 10510                              <1> 	; INPUT ->
 10511                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
 10512                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 10513                              <1> 	;	(ECX = page directory entry index)
 10514                              <1> 	; OUTPUT ->
 10515                              <1> 	;	All of pages in the page table and page table's itself
 10516                              <1> 	;	will be deallocated except 'read only' duplicated pages
 10517                              <1> 	;	(will be converted to writable pages).
 10518                              <1> 	;
 10519                              <1> 	; Modified Registers -> EAX
 10520                              <1> 	;
 10521 00002538 56                  <1> 	push	esi
 10522 00002539 57                  <1> 	push	edi
 10523 0000253A 52                  <1> 	push	edx
 10524 0000253B 50                  <1> 	push	eax ; *
 10525 0000253C 89C6                <1> 	mov	esi, eax 
 10526 0000253E 31FF                <1> 	xor	edi, edi ; 0
 10527                              <1> dapt_0:
 10528 00002540 AD                  <1> 	lodsd
 10529 00002541 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
 10530 00002543 7453                <1> 	jz	short dapt_1
 10531                              <1> 	;
 10532 00002545 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
 10533                              <1> 				  ; (must be 1)
 10534 00002547 753D                <1> 	jnz	short dapt_3
 10535                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
 10536 00002549 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
 10537                              <1> 				   ; as child's page ?
 10538 0000254D 7442                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
 10539                              <1> 	; check the parent's PTE value is read only & same page or not.. 
 10540                              <1> 	; ECX = page directory entry index (0-1023)
 10541 0000254F 53                  <1> 	push	ebx
 10542 00002550 51                  <1> 	push	ecx
 10543                              <1> 	;shl	cx, 2 ; *4 
 10544                              <1> 	; 17/07/2022
 10545 00002551 C1E102              <1> 	shl	ecx, 2
 10546 00002554 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
 10547 00002556 8B0B                <1> 	mov	ecx, [ebx]
 10548 00002558 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
 10549 0000255B 7427                <1> 	jz	short dapt_2	; parent process does not use this page
 10550 0000255D 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 10551                              <1> 	; EDI = page table entry index (0-1023)
 10552 00002562 89FA                <1> 	mov	edx, edi 
 10553                              <1> 	;shl	dx, 2 ; *4
 10554                              <1> 	; 17/07/2022
 10555 00002564 C1E202              <1> 	shl	edx, 2 
 10556 00002567 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
 10557 00002569 8B1A                <1> 	mov	ebx, [edx]
 10558 0000256B F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
 10559 0000256E 7414                <1> 	jz	short dapt_2	; parent process does not use this page
 10560 00002570 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
 10561 00002574 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
 10562 00002579 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
 10563 0000257B 7507                <1> 	jne	short dapt_2	; not same page
 10564                              <1> 				; deallocate the child's page
 10565 0000257D 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
 10566 00002580 59                  <1> 	pop	ecx
 10567 00002581 5B                  <1> 	pop	ebx
 10568 00002582 EB0D                <1> 	jmp	short dapt_4
 10569                              <1> 
 10570                              <1> ; 17/04/2021
 10571                              <1> ; ('dapt_1' is disabled as temporary)
 10572                              <1> ;
 10573                              <1> ;dapt_1:
 10574                              <1> ;	or	eax, eax	; swapped page ?
 10575                              <1> ;	jz	short dapt_5	; no
 10576                              <1> ;				; yes
 10577                              <1> ;	shr	eax, 1
 10578                              <1> ;	call	unlink_swap_block ; Deallocate swapped page block
 10579                              <1> ;				  ; on the swap disk (or in file)
 10580                              <1> ;	jmp	short dapt_5
 10581                              <1> dapt_2:
 10582 00002584 59                  <1> 	pop	ecx
 10583 00002585 5B                  <1> 	pop	ebx
 10584                              <1> dapt_3:	
 10585                              <1> 	; 12/07/2016
 10586 00002586 66A90004            <1> 	test	ax, PTE_SHARED ; shared or direct memory access indicator
 10587 0000258A 7505                <1> 	jnz	short dapt_4   ; AVL bit 1 = 1, do not deallocate this page!
 10588                              <1> 	;
 10589                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 10590 0000258C E814000000          <1> 	call	deallocate_page ; set the mem allocation bit of this page
 10591                              <1> dapt_4:
 10592 00002591 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
 10593                              <1> dapt_1:	; 17/04/2021 (temporary)
 10594                              <1> dapt_5:
 10595 00002598 47                  <1> 	inc	edi ; page table entry index
 10596 00002599 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
 10597 0000259F 729F                <1> 	jb	short dapt_0
 10598                              <1> 	;
 10599 000025A1 58                  <1> 	pop	eax ; *
 10600 000025A2 5A                  <1> 	pop	edx
 10601 000025A3 5F                  <1> 	pop	edi	
 10602 000025A4 5E                  <1> 	pop	esi
 10603                              <1> 	;
 10604                              <1> 	;call	deallocate_page	; deallocate the page table's itself
 10605                              <1> 	;retn
 10606                              <1> 
 10607                              <1> deallocate_page:
 10608                              <1> 	; 15/09/2015
 10609                              <1> 	; 28/04/2015
 10610                              <1> 	; 10/03/2015
 10611                              <1> 	; 17/10/2014
 10612                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 10613                              <1> 	;
 10614                              <1> 	; INPUT -> 
 10615                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10616                              <1> 	; OUTPUT ->
 10617                              <1> 	;	[free_pages] is increased
 10618                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
 10619                              <1> 	;	CF = 1 if the page is already deallocated
 10620                              <1> 	; 	       (or not allocated) before.  
 10621                              <1> 	;
 10622                              <1> 	; Modified Registers -> EAX
 10623                              <1> 	;
 10624 000025A5 53                  <1> 	push	ebx
 10625 000025A6 52                  <1> 	push	edx
 10626                              <1> 	;
 10627 000025A7 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
 10628                              <1> 				     ; 12 bits right
 10629                              <1> 				     ; to get page number
 10630 000025AA 89C2                <1> 	mov	edx, eax
 10631                              <1> 	; 15/09/2015
 10632 000025AC C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
 10633                              <1> 				     ; (1 allocation bit = 1 page)
 10634                              <1> 				     ; (1 allocation bytes = 8 pages)
 10635 000025AF 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 10636                              <1> 				     ; (to get 32 bit position)			
 10637                              <1> 	;
 10638 000025B2 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
 10639 000025B7 01D3                <1> 	add	ebx, edx
 10640 000025B9 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 10641                              <1> 				     ; (allocation bit position)	 
 10642 000025BC 3B15[74670000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
 10643                              <1> 				     ; than the address in 'next_page' ?
 10644                              <1> 				     ; (next/first free page value)		
 10645 000025C2 7306                <1> 	jnb	short dap_1	     ; no	
 10646 000025C4 8915[74670000]      <1> 	mov	[next_page], edx     ; yes
 10647                              <1> dap_1:
 10648 000025CA 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
 10649                              <1> 				     ; set relevant bit to 1.
 10650                              <1> 				     ; set CF to the previous bit value	
 10651                              <1> 	;cmc			     ; complement carry flag	
 10652                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
 10653                              <1> 				     ; if the page is already deallocated
 10654                              <1> 				     ; before.	
 10655 000025CD FF05[70670000]      <1>         inc     dword [free_pages]
 10656                              <1> dap_2:
 10657 000025D3 5A                  <1> 	pop	edx
 10658 000025D4 5B                  <1> 	pop	ebx
 10659 000025D5 C3                  <1> 	retn
 10660                              <1> 
 10661                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10662                              <1> ;;                                                              ;;
 10663                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
 10664                              <1> ;; Distributed under terms of the GNU General Public License    ;;
 10665                              <1> ;;                                                              ;;
 10666                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 10667                              <1> 
 10668                              <1> ;;$Revision: 5057 $
 10669                              <1> 
 10670                              <1> 
 10671                              <1> ;;align 4
 10672                              <1> ;;proc alloc_page
 10673                              <1> 
 10674                              <1> ;;        pushfd
 10675                              <1> ;;        cli
 10676                              <1> ;;        push    ebx
 10677                              <1> ;;;//-
 10678                              <1> ;;        cmp     [pg_data.pages_free], 1
 10679                              <1> ;;        jle     .out_of_memory
 10680                              <1> ;;;//-
 10681                              <1> ;;
 10682                              <1> ;;        mov     ebx, [page_start]
 10683                              <1> ;;        mov     ecx, [page_end]
 10684                              <1> ;;.l1:
 10685                              <1> ;;        bsf     eax, [ebx];
 10686                              <1> ;;        jnz     .found
 10687                              <1> ;;        add     ebx, 4
 10688                              <1> ;;        cmp     ebx, ecx
 10689                              <1> ;;        jb      .l1
 10690                              <1> ;;        pop     ebx
 10691                              <1> ;;        popfd
 10692                              <1> ;;        xor     eax, eax
 10693                              <1> ;;        ret
 10694                              <1> ;;.found:
 10695                              <1> ;;;//-
 10696                              <1> ;;        dec     [pg_data.pages_free]
 10697                              <1> ;;        jz      .out_of_memory
 10698                              <1> ;;;//-
 10699                              <1> ;;        btr     [ebx], eax
 10700                              <1> ;;        mov     [page_start], ebx
 10701                              <1> ;;        sub     ebx, sys_pgmap
 10702                              <1> ;;        lea     eax, [eax+ebx*8]
 10703                              <1> ;;        shl     eax, 12
 10704                              <1> ;;;//-       dec [pg_data.pages_free]
 10705                              <1> ;;        pop     ebx
 10706                              <1> ;;        popfd
 10707                              <1> ;;        ret
 10708                              <1> ;;;//-
 10709                              <1> ;;.out_of_memory:
 10710                              <1> ;;        mov     [pg_data.pages_free], 1
 10711                              <1> ;;        xor     eax, eax
 10712                              <1> ;;        pop     ebx
 10713                              <1> ;;        popfd
 10714                              <1> ;;        ret
 10715                              <1> ;;;//-
 10716                              <1> ;;endp
 10717                              <1> 
 10718                              <1> duplicate_page_dir:
 10719                              <1> 	; 21/09/2015
 10720                              <1> 	; 31/08/2015
 10721                              <1> 	; 20/07/2015
 10722                              <1> 	; 28/04/2015
 10723                              <1> 	; 27/04/2015
 10724                              <1> 	; 18/04/2015
 10725                              <1> 	; 12/04/2015
 10726                              <1> 	; 18/10/2014
 10727                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 10728                              <1> 	;
 10729                              <1> 	; INPUT -> 
 10730                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 10731                              <1> 	;		    page directory.
 10732                              <1> 	; OUTPUT ->
 10733                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 10734                              <1> 	;	       page directory.
 10735                              <1> 	;	(New page directory with new page table entries.)
 10736                              <1> 	;	(New page tables with read only copies of the parent's
 10737                              <1> 	;	pages.)
 10738                              <1> 	;	EAX = 0 -> Error (CF = 1)
 10739                              <1> 	;
 10740                              <1> 	; Modified Registers -> none (except EAX)
 10741                              <1> 	;
 10742 000025D6 E804FEFFFF          <1> 	call	allocate_page
 10743 000025DB 723E                <1> 	jc	short dpd_err
 10744                              <1> 	;
 10745 000025DD 55                  <1> 	push	ebp ; 20/07/2015
 10746 000025DE 56                  <1> 	push	esi
 10747 000025DF 57                  <1> 	push	edi
 10748 000025E0 53                  <1> 	push	ebx
 10749 000025E1 51                  <1> 	push	ecx
 10750 000025E2 8B35[046D0000]      <1> 	mov	esi, [u.pgdir]
 10751 000025E8 89C7                <1> 	mov	edi, eax
 10752 000025EA 50                  <1> 	push	eax ; save child's page directory address
 10753                              <1> 	; 31/08/2015
 10754                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 10755                              <1> 	; (use same system space for all user page tables) 
 10756 000025EB A5                  <1> 	movsd
 10757 000025EC BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 10758 000025F1 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 10759                              <1> dpd_0:	
 10760 000025F6 AD                  <1> 	lodsd
 10761                              <1> 	;or	eax, eax
 10762                              <1>         ;jnz     short dpd_1
 10763 000025F7 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 10764 000025F9 7508                <1> 	jnz	short dpd_1
 10765                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
 10766 000025FB 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 10767 00002601 EB0F                <1> 	jmp	short dpd_2
 10768                              <1> dpd_1:	
 10769 00002603 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 10770 00002607 89C3                <1> 	mov	ebx, eax
 10771                              <1> 	; EBX = Parent's page table address
 10772 00002609 E81F000000          <1> 	call	duplicate_page_table
 10773 0000260E 720C                <1> 	jc	short dpd_p_err
 10774                              <1> 	; EAX = Child's page table address
 10775 00002610 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 10776                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 10777                              <1> 			 ; (present, writable, user)
 10778                              <1> dpd_2:
 10779 00002612 AB                  <1> 	stosd
 10780 00002613 E2E1                <1> 	loop	dpd_0
 10781                              <1> 	;
 10782 00002615 58                  <1> 	pop	eax  ; restore child's page directory address
 10783                              <1> dpd_3:
 10784 00002616 59                  <1> 	pop	ecx
 10785 00002617 5B                  <1> 	pop	ebx
 10786 00002618 5F                  <1> 	pop	edi
 10787 00002619 5E                  <1> 	pop	esi
 10788 0000261A 5D                  <1> 	pop	ebp ; 20/07/2015
 10789                              <1> dpd_err:
 10790 0000261B C3                  <1> 	retn
 10791                              <1> dpd_p_err:
 10792                              <1> 	; release the allocated pages missing (recover free space)
 10793 0000261C 58                  <1> 	pop	eax  ; the new page directory address (physical)
 10794 0000261D 8B1D[046D0000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 10795 00002623 E8E7FEFFFF          <1> 	call 	deallocate_page_dir
 10796 00002628 29C0                <1> 	sub	eax, eax ; 0
 10797 0000262A F9                  <1> 	stc
 10798 0000262B EBE9                <1> 	jmp	short dpd_3	
 10799                              <1> 
 10800                              <1> duplicate_page_table:
 10801                              <1> 	; 31/12/2021 - Retro UNIX 386 v1.2
 10802                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 10803                              <1> 	;	 (temporary modifications)
 10804                              <1> 	; 16/04/2021 (Retro UNIX 386 v2)
 10805                              <1> 	; 20/02/2017 (TRDOS 386 v2)
 10806                              <1> 	; 21/09/2015
 10807                              <1> 	; 20/07/2015
 10808                              <1> 	; 05/05/2015
 10809                              <1> 	; 28/04/2015
 10810                              <1> 	; 27/04/2015
 10811                              <1> 	; 18/04/2015
 10812                              <1> 	; 18/10/2014
 10813                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 10814                              <1> 	;
 10815                              <1> 	; INPUT -> 
 10816                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 10817                              <1> 	;       20/02/2017		 
 10818                              <1> 	;	EBP = Linear address of the page (from 'duplicate_page_dir')
 10819                              <1> 	;	      (Linear address = CORE + user's virtual address) 	
 10820                              <1> 	; OUTPUT ->
 10821                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 10822                              <1> 	;	      (with 'read only' attribute of page table entries)
 10823                              <1> 	;	20/02/2017
 10824                              <1> 	;	EBP = Next linear page address (for 'duplicate_page_dir')
 10825                              <1> 	;	
 10826                              <1> 	;	CF = 1 -> error 
 10827                              <1> 	;
 10828                              <1> 	; Modified Registers -> EBP (except EAX)
 10829                              <1> 	;
 10830 0000262D E8ADFDFFFF          <1> 	call	allocate_page
 10831 00002632 725B                <1> 	jc	short dpt_err
 10832                              <1> 	;
 10833 00002634 50                  <1> 	push	eax ; *
 10834 00002635 56                  <1> 	push	esi
 10835 00002636 57                  <1> 	push	edi
 10836 00002637 52                  <1> 	push	edx
 10837 00002638 51                  <1> 	push	ecx
 10838                              <1> 	;
 10839 00002639 89DE                <1> 	mov	esi, ebx
 10840 0000263B 89C7                <1> 	mov	edi, eax
 10841 0000263D 89C2                <1> 	mov	edx, eax
 10842 0000263F 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 10843                              <1> dpt_0:
 10844 00002645 AD                  <1> 	lodsd
 10845 00002646 21C0                <1> 	and	eax, eax
 10846 00002648 7435                <1> 	jz	short dpt_3
 10847 0000264A A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 10848                              <1> 	; 17/04/2021 (temporary)
 10849 0000264C 7503                <1> 	jnz	short dpt_1
 10850                              <1> 	;jz	short dpt_p_err
 10851                              <1> 	; 31/12/2021
 10852 0000264E F9                  <1> 	stc
 10853 0000264F EB39                <1> 	jmp	short dpt_p_err
 10854                              <1> 
 10855                              <1> ; 17/04/2021
 10856                              <1> ; ('reload_page' procedure call is disabled as temporary)
 10857                              <1> ;
 10858                              <1> ;	; 20/07/2015
 10859                              <1> ;	; ebp = virtual (linear) address of the memory page
 10860                              <1> ;	call	reload_page ; 28/04/2015
 10861                              <1> ;	jc	short dpt_p_err
 10862                              <1> dpt_1:
 10863                              <1> 	; 21/09/2015
 10864 00002651 89C1                <1> 	mov	ecx, eax
 10865 00002653 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 10866 00002657 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
 10867 0000265A 751A                <1> 	jnz	short dpt_2
 10868                              <1> 	; Read only (parent) page
 10869                              <1> 	; 	- there is a third process which uses this page -
 10870                              <1> 	; Allocate a new page for the child process
 10871 0000265C E87EFDFFFF          <1> 	call	allocate_page
 10872 00002661 7227                <1> 	jc	short dpt_p_err
 10873 00002663 57                  <1> 	push	edi
 10874 00002664 56                  <1> 	push	esi
 10875 00002665 89CE                <1> 	mov	esi, ecx
 10876 00002667 89C7                <1> 	mov	edi, eax
 10877 00002669 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 10878 0000266E F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 10879 00002670 5E                  <1> 	pop	esi
 10880 00002671 5F                  <1> 	pop	edi
 10881                              <1> 	;
 10882                              <1> 
 10883                              <1> ; 17/04/2021
 10884                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
 10885                              <1> ; 
 10886                              <1> ;	push	ebx
 10887                              <1> ;	push	eax
 10888                              <1> ;	; 20/07/2015
 10889                              <1> ;	mov	ebx, ebp
 10890                              <1> ;	; ebx = virtual (linear) address of the memory page
 10891                              <1> ;	call	add_to_swap_queue
 10892                              <1> ;	pop	eax
 10893                              <1> ;	pop	ebx
 10894                              <1> 
 10895                              <1> 	; 21/09/2015
 10896 00002672 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 10897                              <1> 		; user + writable + present page
 10898 00002674 EB09                <1> 	jmp	short dpt_3
 10899                              <1> dpt_2:
 10900                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 10901 00002676 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
 10902                              <1> 		    ; (read only page!)
 10903 00002678 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
 10904 0000267B 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
 10905                              <1> dpt_3:
 10906 0000267F AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 10907                              <1> 	;
 10908 00002680 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 10909                              <1> 	;
 10910 00002686 39D7                <1> 	cmp	edi, edx
 10911 00002688 72BB                <1> 	jb	short dpt_0
 10912                              <1> dpt_p_err:
 10913 0000268A 59                  <1> 	pop	ecx
 10914 0000268B 5A                  <1> 	pop	edx
 10915 0000268C 5F                  <1> 	pop	edi
 10916 0000268D 5E                  <1> 	pop	esi
 10917 0000268E 58                  <1> 	pop	eax ; *
 10918                              <1> dpt_err:
 10919 0000268F C3                  <1> 	retn
 10920                              <1> 
 10921                              <1> page_fault_handler: ; CPU EXCEPTION 0Eh (14) : Page Fault !
 10922                              <1> 	; 31/12/2021 - Retro UNIX 386 v1.2
 10923                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 10924                              <1> 	;	 (temporary modifications)
 10925                              <1> 	; 21/09/2015
 10926                              <1> 	; 19/09/2015
 10927                              <1> 	; 17/09/2015
 10928                              <1> 	; 28/08/2015
 10929                              <1> 	; 20/07/2015
 10930                              <1> 	; 28/06/2015
 10931                              <1> 	; 03/05/2015
 10932                              <1> 	; 30/04/2015
 10933                              <1> 	; 18/04/2015
 10934                              <1> 	; 12/04/2015
 10935                              <1> 	; 30/10/2014
 10936                              <1> 	; 11/09/2014
 10937                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
 10938                              <1> 	;
 10939                              <1> 	; Note: This is not an interrupt/exception handler.
 10940                              <1> 	;	This is a 'page fault remedy' subroutine 
 10941                              <1> 	;	which will be called by standard/uniform
 10942                              <1> 	;	exception handler.
 10943                              <1> 	;
 10944                              <1> 	; INPUT -> 
 10945                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
 10946                              <1> 	;
 10947                              <1> 	;	cr2 = the virtual (linear) address 
 10948                              <1> 	;	      which has caused to page fault (19/09/2015)
 10949                              <1> 	;
 10950                              <1> 	; OUTPUT ->
 10951                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 10952                              <1> 	;	EAX = 0 -> no error
 10953                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
 10954                              <1> 	;
 10955                              <1> 	; Modified Registers -> none (except EAX)
 10956                              <1> 	;	
 10957                              <1>         ;
 10958                              <1>         ; ERROR CODE:
 10959                              <1> 	;	 31  .....	4   3	2   1	0
 10960                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 10961                              <1> 	;	|   Reserved  | I | R | U | W | P |
 10962                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 10963                              <1> 	;
 10964                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
 10965                              <1>     	;		a page-protection violation. When not set,
 10966                              <1> 	;		it was caused by a non-present page.
 10967                              <1> 	; W : WRITE   -	When set, the page fault was caused by
 10968                              <1> 	;		a page write. When not set, it was caused
 10969                              <1> 	;		by a page read.
 10970                              <1> 	; U : USER    -	When set, the page fault was caused 
 10971                              <1> 	;		while CPL = 3. 
 10972                              <1> 	;		This does not necessarily mean that
 10973                              <1> 	;		the page fault was a privilege violation.
 10974                              <1> 	; R : RESERVD -	When set, the page fault was caused by
 10975                              <1> 	;     WRITE	reading a 1 in a reserved field.
 10976                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
 10977                              <1> 	;     FETCH	an instruction fetch
 10978                              <1> 	;
 10979                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
 10980                              <1> 	;  31               22                  12 11                    0
 10981                              <1> 	; +-------------------+-------------------+-----------------------+
 10982                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
 10983                              <1>        	; +-------------------+-------------------+-----------------------+
 10984                              <1> 	;
 10985                              <1> 
 10986                              <1> 	;; CR3 REGISTER (Control Register 3)
 10987                              <1> 	;  31                                   12             5 4 3 2   0
 10988                              <1> 	; +---------------------------------------+-------------+---+-----+
 10989                              <1>       	; |                                       |  		|P|P|     |
 10990                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
 10991                              <1>       	; |                                       | 		|D|T|     |
 10992                              <1>    	; +---------------------------------------+-------------+---+-----+
 10993                              <1> 	;
 10994                              <1> 	;	PWT    - WRITE THROUGH
 10995                              <1> 	;	PCD    - CACHE DISABLE		
 10996                              <1> 	;
 10997                              <1> 	;
 10998                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
 10999                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11000                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11001                              <1>       	; |                                       |     | | | | |P|P|U|R| |
 11002                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
 11003                              <1>       	; |                                       |     | | | | |D|T|S|W| |
 11004                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11005                              <1> 	;
 11006                              <1>         ;       P      - PRESENT
 11007                              <1>         ;       R/W    - READ/WRITE
 11008                              <1>         ;       U/S    - USER/SUPERVISOR
 11009                              <1> 	;	PWT    - WRITE THROUGH
 11010                              <1> 	;	PCD    - CACHE DISABLE	
 11011                              <1> 	;	A      - ACCESSED	
 11012                              <1>         ;       D      - DIRTY (IGNORED)
 11013                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11014                              <1> 	;	G      - GLOBAL	(IGNORED) 
 11015                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11016                              <1> 	;
 11017                              <1> 	;
 11018                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
 11019                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11020                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11021                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
 11022                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
 11023                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
 11024                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11025                              <1> 	;
 11026                              <1>         ;       P      - PRESENT
 11027                              <1>         ;       R/W    - READ/WRITE
 11028                              <1>         ;       U/S    - USER/SUPERVISOR
 11029                              <1> 	;	PWT    - WRITE THROUGH
 11030                              <1> 	;	PCD    - CACHE DISABLE	
 11031                              <1> 	;	A      - ACCESSED	
 11032                              <1>         ;       D      - DIRTY
 11033                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11034                              <1> 	;	G      - GLOBAL	 
 11035                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11036                              <1> 	;
 11037                              <1> 	;
 11038                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
 11039                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11040                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11041                              <1>       	; |                                       |     | | | | | | |U|R| |
 11042                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
 11043                              <1>       	; |                                       |     | | | | | | |S|W| |
 11044                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11045                              <1> 	;
 11046                              <1>         ;       P      - PRESENT
 11047                              <1>         ;       R/W    - READ/WRITE
 11048                              <1>         ;       U/S    - USER/SUPERVISOR
 11049                              <1>         ;       D      - DIRTY
 11050                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11051                              <1> 	;
 11052                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
 11053                              <1> 	;
 11054                              <1> 	;
 11055                              <1> 	;; Invalid Page Table Entry
 11056                              <1> 	; 31                                                           1 0
 11057                              <1>       	; +-------------------------------------------------------------+-+
 11058                              <1>       	; |                                                             | |
 11059                              <1>       	; |                          AVAILABLE                          |0|
 11060                              <1>       	; |                                                             | |
 11061                              <1>       	; +-------------------------------------------------------------+-+
 11062                              <1> 	;
 11063                              <1> 
 11064 00002690 53                  <1> 	push	ebx
 11065 00002691 52                  <1> 	push	edx
 11066 00002692 51                  <1> 	push	ecx
 11067                              <1> 	;
 11068                              <1> 	; 21/09/2015 (debugging)
 11069 00002693 FF05[1C6D0000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
 11070 00002699 FF05[1C680000]      <1> 	inc	dword [PF_Count]  ; total page fault count	
 11071                              <1> 	; 28/06/2015
 11072                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
 11073 0000269F 8A15[14680000]      <1> 	mov	dl, [error_code]
 11074                              <1> 	;
 11075 000026A5 F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
 11076                              <1> 			; sign
 11077 000026A8 7416                <1> 	jz	short pfh_alloc_np
 11078                              <1> 	; 
 11079                              <1> 	; If it is not a 'write on read only page' type page fault
 11080                              <1> 	; major page fault error with minor reason must be returned without 
 11081                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
 11082                              <1> 	; after return here!
 11083                              <1> 	; Page fault will be remedied, by copying page contents
 11084                              <1> 	; to newly allocated page with write permission;
 11085                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
 11086                              <1> 	; used for working with minimum possible memory usage. 
 11087                              <1> 	; sys_fork will duplicate page directory and tables of parent  
 11088                              <1> 	; process with 'read only' flag. If the child process attempts to
 11089                              <1> 	; write on these read only pages, page fault will be directed here
 11090                              <1> 	; for allocating a new page with same data/content. 
 11091                              <1> 	;
 11092                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
 11093                              <1> 	; will not force to separate CODE and DATA space 
 11094                              <1> 	; in a process/program... 
 11095                              <1> 	; CODE segment/section may contain DATA!
 11096                              <1> 	; It is flat, smoth and simplest programming method already as in 
 11097                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
 11098                              <1> 	;	
 11099 000026AA F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
 11100                              <1> 			; sign
 11101 000026AD 744F                <1>         jz	short pfh_p_err
 11102                              <1> 	; 31/08/2015
 11103 000026AF F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
 11104                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
 11105 000026B2 744A                <1>         jz	short pfh_pv_err
 11106                              <1> 	;
 11107                              <1> 	; make a new page and copy the parent's page content
 11108                              <1> 	; as the child's new page content
 11109                              <1> 	;
 11110 000026B4 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
 11111                              <1> 			 ; which has caused to page fault
 11112 000026B7 E87C000000          <1> 	call 	copy_page
 11113 000026BC 7239                <1>         jc	short pfh_im_err ; insufficient memory
 11114                              <1> 	;
 11115 000026BE EB72                <1>         jmp     pfh_cpp_ok
 11116                              <1> 	;
 11117                              <1> pfh_alloc_np:
 11118 000026C0 E81AFDFFFF          <1> 	call	allocate_page	; (allocate a new page)
 11119 000026C5 7230                <1>         jc	short pfh_im_err ; 'insufficient memory' error
 11120                              <1> pfh_chk_cpl:
 11121                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11122                              <1> 		; (Lower 12 bits are ZERO, because 
 11123                              <1> 		;	the address is on a page boundary)
 11124 000026C7 80E204              <1> 	and	dl, 4	; CPL = 3 ?
 11125 000026CA 7505                <1> 	jnz	short pfh_um
 11126                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
 11127 000026CC 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
 11128                              <1> 			 ; of the current/active page directory
 11129                              <1> 			 ; (Always kernel/system mode page directory, here!)
 11130                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
 11131 000026CF EB06                <1> 	jmp	short pfh_get_pde
 11132                              <1> 	;
 11133                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
 11134 000026D1 8B1D[046D0000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
 11135                              <1> 			; Physical address of the USER's page directory
 11136                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
 11137                              <1> pfh_get_pde:
 11138 000026D7 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
 11139 000026DA 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
 11140                              <1> 			 ; which has been caused to page fault
 11141                              <1> 			 ;
 11142 000026DD C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
 11143 000026E0 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
 11144                              <1> 	;
 11145 000026E3 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
 11146 000026E5 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
 11147 000026E7 F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
 11148 000026EA 741A                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
 11149                              <1> 			  	  ; set/validate page directory entry
 11150 000026EC 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11151 000026F1 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
 11152 000026F3 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
 11153 000026F5 EB25                <1> 	jmp	short pfh_get_pte
 11154                              <1> 
 11155                              <1> 	; 31/12/2021 (short jump)
 11156                              <1> pfh_im_err:
 11157 000026F7 B8E4000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
 11158                              <1> 			; Major (Primary) Error: Page Fault
 11159                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
 11160 000026FC EB36                <1> 	jmp	short pfh_err_retn
 11161                              <1> 
 11162                              <1> 	; 31/12/2021
 11163                              <1> pfh_p_err: ; 09/03/2015
 11164                              <1> pfh_pv_err:
 11165                              <1> 	; Page fault was caused by a protection-violation
 11166 000026FE B8E6000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
 11167                              <1> 			; Major (Primary) Error: Page Fault
 11168                              <1> 			; Minor (Secondary) Error: Protection violation !
 11169 00002703 F9                  <1> 	stc
 11170 00002704 EB2E                <1> 	jmp	short pfh_err_retn
 11171                              <1> 
 11172                              <1> pfh_set_pde:
 11173                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
 11174                              <1> 	;;	 (So, we know this PDE is empty or invalid)
 11175                              <1> 	;
 11176 00002706 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
 11177 00002708 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
 11178 0000270A 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
 11179 0000270C 89C3                <1> 	mov	ebx, eax
 11180 0000270E E8CCFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
 11181 00002713 72E2                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
 11182                              <1> pfh_spde_1:
 11183                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11184 00002715 89C1                <1> 	mov	ecx, eax
 11185 00002717 E834FDFFFF          <1> 	call	clear_page ; Clear page content
 11186                              <1> pfh_get_pte:
 11187 0000271C 0F20D0              <1> 	mov	eax, cr2 ; virtual address
 11188                              <1> 			 ; which has been caused to page fault
 11189 0000271F 89C7                <1> 	mov	edi, eax ; 20/07/2015
 11190 00002721 C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
 11191                              <1> 			 ; higher 20 bits of the page fault address 
 11192 00002724 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
 11193 00002729 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
 11194 0000272C 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
 11195                              <1> ; 17/04/2021 temporary
 11196                              <1> ;	mov	eax, [ebx] ; get previous value of pte
 11197                              <1> ;		; bit 0 of EAX is always 0 (otherwise we would not be here)
 11198                              <1> ; 17/04/2021
 11199                              <1> ; ('swap_in' procedure call has been disabled as temporary)
 11200                              <1> ;
 11201                              <1> ;	and	eax, eax
 11202                              <1> ;	jz	short pfh_gpte_1
 11203                              <1> ;	; 20/07/2015
 11204                              <1> ;	xchg	ebx, ecx ; new page address (physical)
 11205                              <1> ;	push	ebp ; 20/07/2015
 11206                              <1> ;	mov	ebp, cr2
 11207                              <1> ;		; ECX = physical address of the page table entry
 11208                              <1> ;		; EBX = Memory page address (physical!)
 11209                              <1> ;		; EAX = Swap disk (offset) address
 11210                              <1> ;		; EBP = virtual address (page fault address)
 11211                              <1> ;	call	swap_in
 11212                              <1> ;	pop	ebp
 11213                              <1> ;	jc      short pfh_err_retn
 11214                              <1> ;	xchg	ecx, ebx
 11215                              <1> ;		; EBX = physical address of the page table entry
 11216                              <1> ;		; ECX = new page
 11217                              <1> pfh_gpte_1:
 11218 0000272E 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
 11219 00002730 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
 11220                              <1> pfh_cpp_ok:
 11221                              <1> ; 17/04/2021
 11222                              <1> ; ('add_to_swap_queue' procedure call has been disabled as temporary)
 11223                              <1> ;
 11224                              <1> ;	; 20/07/2015
 11225                              <1> ;	mov	ebx, cr2
 11226                              <1> ;	call 	add_to_swap_queue
 11227                              <1> 	;
 11228                              <1> 	; The new PTE (which contains the new page) will be added to 
 11229                              <1> 	; the swap queue, here. 
 11230                              <1> 	; (Later, if memory will become insufficient, 
 11231                              <1> 	; one page will be swapped out which is at the head of 
 11232                              <1> 	; the swap queue by using FIFO and access check methods.)
 11233                              <1> 	;
 11234 00002732 31C0                <1> 	xor	eax, eax  ; 0
 11235                              <1> 	;
 11236                              <1> pfh_err_retn:
 11237 00002734 59                  <1> 	pop	ecx
 11238 00002735 5A                  <1> 	pop	edx
 11239 00002736 5B                  <1> 	pop	ebx
 11240 00002737 C3                  <1> 	retn 
 11241                              <1> 	
 11242                              <1> copy_page:
 11243                              <1> 	; 17/07/2022
 11244                              <1> 	; 16/04/2021
 11245                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11246                              <1> 	; 22/09/2015
 11247                              <1> 	; 21/09/2015
 11248                              <1> 	; 19/09/2015
 11249                              <1> 	; 07/09/2015
 11250                              <1> 	; 31/08/2015
 11251                              <1> 	; 20/07/2015
 11252                              <1> 	; 05/05/2015
 11253                              <1> 	; 03/05/2015
 11254                              <1> 	; 18/04/2015
 11255                              <1> 	; 12/04/2015
 11256                              <1> 	; 30/10/2014
 11257                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
 11258                              <1> 	;
 11259                              <1> 	; INPUT -> 
 11260                              <1> 	;	EBX = Virtual (linear) address of source page
 11261                              <1> 	;	     (Page fault address)
 11262                              <1> 	; OUTPUT ->
 11263                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11264                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11265                              <1> 	;	EAX = 0 (CF = 1) 
 11266                              <1> 	;		if there is not a free page to be allocated
 11267                              <1> 	;	(page content of the source page will be copied
 11268                              <1> 	;	onto the target/new page) 	
 11269                              <1> 	;
 11270                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
 11271                              <1> 	;
 11272                              <1> 
 11273                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11274                              <1> 	; INPUT: 
 11275                              <1> 	;	EBX = Virtual (linear) address of source page
 11276                              <1> 	;	     (Page fault address)
 11277                              <1> 	; OUTPUT:
 11278                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11279                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11280                              <1> 	;	EAX = 0 (CF = 1) 
 11281                              <1> 	;		if there is not a free page to be allocated
 11282                              <1> 	;	(page content of the source page will be copied
 11283                              <1> 	;	onto the target/new page) 	
 11284                              <1> 	;
 11285                              <1> 	; Modified Registers -> ecx, ebx (except EAX) ; 16/04/2021
 11286                              <1> 	
 11287 00002738 56                  <1> 	push	esi ; *
 11288 00002739 57                  <1> 	push	edi ; **
 11289                              <1> 	; 16/04/2021
 11290                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11291                              <1> 	;push	ebx ; ***
 11292                              <1> 	;push	ecx ; ****
 11293 0000273A 31F6                <1> 	xor 	esi, esi
 11294 0000273C C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
 11295 0000273F 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
 11296 00002741 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
 11297 00002744 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
 11298 00002747 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
 11299 00002749 031D[046D0000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
 11300 0000274F 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
 11301 00002751 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
 11302 00002755 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
 11303 00002757 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11304                              <1> 	;shl	bx, 2	   ; shift 2 bits left to get PTE offset
 11305                              <1> 	; 17/07/2022
 11306 0000275D C1E302              <1> 	shl	ebx, 2
 11307 00002760 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
 11308                              <1> 	; 07/09/2015
 11309 00002762 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
 11310                              <1> 				     ; read only page as a child process?)	
 11311 00002767 7509                <1> 	jnz	short cpp_0 ; yes
 11312 00002769 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
 11313 0000276B 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
 11314 00002770 EB31                <1> 	jmp	short cpp_1
 11315                              <1> cpp_0:
 11316 00002772 89FE                <1> 	mov	esi, edi
 11317 00002774 0335[086D0000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
 11318 0000277A 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
 11319 0000277C 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11320 00002780 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
 11321 00002782 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11322                              <1> 	;shl	si, 2	   ; shift 2 bits left to get PTE offset
 11323                              <1> 	; 17/07/2022
 11324 00002788 C1E602              <1> 	shl	esi, 2
 11325 0000278B 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
 11326 0000278D 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
 11327                              <1> 	; 21/09/2015
 11328 0000278F 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
 11329 00002791 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
 11330                              <1> 	;
 11331 00002795 F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
 11332 00002798 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
 11333                              <1> 	;
 11334 0000279A 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
 11335 0000279F 39C8                <1> 	cmp	eax, ecx   ; Same page?	
 11336 000027A1 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
 11337                              <1> 			    ; Convert child's page to writable page
 11338                              <1> cpp_1:
 11339 000027A3 E837FCFFFF          <1> 	call	allocate_page
 11340 000027A8 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
 11341 000027AA 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
 11342 000027AC 7405                <1> 	jz	short cpp_2
 11343                              <1> 		; Convert read only page to writable page 
 11344                              <1> 		;(for the parent of the current process)
 11345                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
 11346                              <1> 	; 22/09/2015
 11347 000027AE 890E                <1> 	mov	[esi], ecx
 11348 000027B0 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
 11349                              <1> 				 ; 1+2+4 = 7
 11350                              <1> cpp_2:
 11351 000027B3 89C7                <1> 	mov	edi, eax ; new page address of the child process
 11352                              <1> 	; 07/09/2015
 11353 000027B5 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
 11354 000027B7 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 11355 000027BC F3A5                <1> 	rep	movsd ; 31/08/2015
 11356                              <1> cpp_3:		
 11357 000027BE 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
 11358 000027C0 8903                <1> 	mov	[ebx], eax ; Update PTE
 11359 000027C2 28C0                <1> 	sub	al, al ; clear attributes
 11360                              <1> cpp_4:
 11361                              <1> 	; 16/04/2021
 11362                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11363                              <1> 	;pop	ecx ; ****
 11364                              <1> 	;pop	ebx ; ***
 11365 000027C4 5F                  <1> 	pop	edi ; **
 11366 000027C5 5E                  <1> 	pop	esi ; *
 11367 000027C6 C3                  <1> 	retn
 11368                              <1> 
 11369                              <1> ;; 28/04/2015
 11370                              <1> ;; 24/10/2014
 11371                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
 11372                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
 11373                              <1> ;;
 11374                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
 11375                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
 11376                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
 11377                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
 11378                              <1> ;;
 11379                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
 11380                              <1> ;;
 11381                              <1> ;; Method:
 11382                              <1> ;;	Swap page queue is a list of allocated pages with physical
 11383                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
 11384                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
 11385                              <1> ;;	When a new page is being allocated, swap queue is updated
 11386                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
 11387                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
 11388                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
 11389                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
 11390                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
 11391                              <1> ;;	offset value becomes it's previous offset value - 4.
 11392                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
 11393                              <1> ;;	the queue/list is not shifted.
 11394                              <1> ;;	After the queue/list shift, newly allocated page is added
 11395                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
 11396                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
 11397                              <1> ;;	will not be added to the tail of swap page queue.  		 
 11398                              <1> ;;	
 11399                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
 11400                              <1> ;;	the first non-accessed, writable page in the list, 
 11401                              <1> ;;	from the head to the tail. The list is shifted to left 
 11402                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
 11403                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
 11404                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
 11405                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
 11406                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
 11407                              <1> ;;	procedure will be failed)...
 11408                              <1> ;;
 11409                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
 11410                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
 11411                              <1> ;;	(PTE) will be added to the tail of the queue after
 11412                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
 11413                              <1> ;;	the queue will be rotated and the PTE in the head will be
 11414                              <1> ;;	added to the tail after resetting 'accessed' bit. 
 11415                              <1> ;;
 11416                              <1> ;;
 11417                              <1> ;;	
 11418                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
 11419                              <1> ;;
 11420                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
 11421                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
 11422                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
 11423                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
 11424                              <1> ;;
 11425                              <1> ;; [swpd_next] = the first free block address in swapped page records
 11426                              <1> ;;    		 for next free block search by 'swap_out' procedure.
 11427                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
 11428                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
 11429                              <1> ;; 		 (entire swap space must be accessed by using
 11430                              <1> ;;		 31 bit offset address) 
 11431                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
 11432                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
 11433                              <1> ;;		  0 for file, or beginning sector of the swap partition
 11434                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
 11435                              <1> ;;
 11436                              <1> ;; 					
 11437                              <1> ;; Method:
 11438                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
 11439                              <1> ;;	procedure swaps out a page from memory to the swap disk 
 11440                              <1> ;;	(partition) or swap file to get a new free page at the memory.
 11441                              <1> ;;	Swapping out is performed by using swap page queue.
 11442                              <1> ;;
 11443                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
 11444                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
 11445                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
 11446                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
 11447                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
 11448                              <1> ;;	Absolute physical (logical) address of the swapped page is 
 11449                              <1> ;;	calculated by adding offset value to the swap partition's 
 11450                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
 11451                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
 11452                              <1> ;;	and offset value is equal to absolute (physical or logical)
 11453                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
 11454                              <1> ;;	is in a partitioned virtual hard disk.) 
 11455                              <1> ;;
 11456                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
 11457                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
 11458                              <1> ;;
 11459                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
 11460                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
 11461                              <1> ;;
 11462                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
 11463                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
 11464                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
 11465                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
 11466                              <1> ;;	it means relevant (respective) block is in use, and, 
 11467                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
 11468                              <1> ;;      swap disk/file block is free.
 11469                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
 11470                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
 11471                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
 11472                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
 11473                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
 11474                              <1> ;;	------------------------------------------------------------
 11475                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
 11476                              <1> ;;	------------------------------------------------------------
 11477                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
 11478                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
 11479                              <1> ;;
 11480                              <1> ;;	..............................................................
 11481                              <1> ;;
 11482                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
 11483                              <1> ;;	then it searches Swap Allocation Table if free count is not
 11484                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
 11485                              <1> ;;	position with value of 1 on the table is converted to swap
 11486                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
 11487                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
 11488                              <1> ;;	number of physical swap disk or virtual swap disk)
 11489                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
 11490                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
 11491                              <1> ;;	(memory page). That will be a direct disk write procedure.
 11492                              <1> ;;	(for preventing late memory allocation, significant waiting). 
 11493                              <1> ;;	If disk write procedure returns with error or free count of 
 11494                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
 11495                              <1> ;;	'insufficient memory error' (cf=1). 
 11496                              <1> ;;
 11497                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
 11498                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
 11499                              <1> ;;	in other words, 'swap_out' will not check the table for other
 11500                              <1> ;;	free blocks after a disk write error. It will return to 
 11501                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
 11502                              <1> ;;
 11503                              <1> ;;	After writing the page on to swap disk/file address/sector,
 11504                              <1> ;;	'swap_out' procedure returns with that swap (offset) sector
 11505                              <1> ;;	address (cf=0). 
 11506                              <1> ;;
 11507                              <1> ;;	..............................................................
 11508                              <1> ;;
 11509                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
 11510                              <1> ;;	file sectors at specified memory page. Then page allocation
 11511                              <1> ;;	procedure updates relevant page table entry with 'present' 
 11512                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
 11513                              <1> ;;	to do, except to terminate the process which is the owner of
 11514                              <1> ;;	the swapped page.
 11515                              <1> ;;
 11516                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
 11517                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
 11518                              <1> ;;	updates [swpd_first] pointer if it is required.
 11519                              <1> ;;
 11520                              <1> ;;	..............................................................	 
 11521                              <1> ;;
 11522                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
 11523                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
 11524                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
 11525                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
 11526                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
 11527                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
 11528                              <1> ;;
 11529                              <1> 
 11530                              <1> ; 17/04/2021
 11531                              <1> ; ('swap_in' procedure call is disabled as temporary)
 11532                              <1> 
 11533                              <1> ; 30/11/2021 - temporary !
 11534                              <1> ;swap_in:
 11535                              <1> 	; 31/08/2015
 11536                              <1> 	; 20/07/2015
 11537                              <1> 	; 28/04/2015
 11538                              <1> 	; 18/04/2015
 11539                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 11540                              <1> 	;
 11541                              <1> 	; INPUT -> 
 11542                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
 11543                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
 11544                              <1> 	;	EAX = Offset Address for the swapped page on the
 11545                              <1> 	;	      swap disk or in the swap file.
 11546                              <1> 	;
 11547                              <1> 	; OUTPUT ->
 11548                              <1> 	;	EAX = 0 if loading at memory has been successful
 11549                              <1> 	;
 11550                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
 11551                              <1> 	;		  or sector not present or drive not ready
 11552                              <1> 	;	     EAX = Error code
 11553                              <1> 	;	     [u.error] = EAX 
 11554                              <1> 	;		       = The last error code for the process
 11555                              <1> 	;		         (will be reset after returning to user)	  
 11556                              <1> 	;
 11557                              <1> 	; Modified Registers -> EAX
 11558                              <1> 	;
 11559                              <1> 
 11560                              <1> ;       cmp     dword [swp_drv], 0
 11561                              <1> ;	jna	short swpin_dnp_err
 11562                              <1> ;
 11563                              <1> ;	cmp	eax, [swpd_size]
 11564                              <1> ;	jnb	short swpin_snp_err
 11565                              <1> ;
 11566                              <1> ;	push	esi
 11567                              <1> ;	push	ebx
 11568                              <1> ;	push	ecx
 11569                              <1> ;	mov	esi, [swp_drv]	
 11570                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 11571                              <1> ;		; Note: Even if corresponding physical disk's sector 
 11572                              <1> ;		; size different than 512 bytes, logical disk sector
 11573                              <1> ;		; size is 512 bytes and disk reading procedure
 11574                              <1> ;		; will be performed for reading 4096 bytes
 11575                              <1> ;		; (2*2048, 8*512). 
 11576                              <1> ;	; ESI = Logical disk description table address
 11577                              <1> ;	; EBX = Memory page (buffer) address (physical!)
 11578                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
 11579                              <1> ;	; ECX = Sector count ; 8 sectors
 11580                              <1> ;	push	eax
 11581                              <1> ;	call	logical_disk_read
 11582                              <1> ;	pop	eax
 11583                              <1> ;	jnc	short swpin_read_ok
 11584                              <1> ;	;
 11585                              <1> ;	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
 11586                              <1> ;	mov	[u.error], eax
 11587                              <1> ;	jmp	short swpin_retn
 11588                              <1> ;	;
 11589                              <1> ;swpin_read_ok:
 11590                              <1> ;	; EAX = Offset address (logical sector number)
 11591                              <1> ;	call	unlink_swap_block  ; Deallocate swap block	
 11592                              <1> ;	;
 11593                              <1> ;	; EBX = Memory page (buffer) address (physical!)
 11594                              <1> ;	; 20/07/2015
 11595                              <1> ;	mov	ebx, ebp ; virtual address (page fault address)
 11596                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 11597                              <1> ;	mov	bl, [u.uno] ; current process number
 11598                              <1> ;	; EBX = Virtual (Linear) address & process number combination
 11599                              <1> ;	call	swap_queue_shift
 11600                              <1> ;	; eax = 0 ; 10/06/2016 (if ebx input > 0, eax output = 0)
 11601                              <1> ;	;sub	eax, eax  ; 0 ; Error Code = 0  (no error)
 11602                              <1> ;	; zf = 1
 11603                              <1> ;swpin_retn:
 11604                              <1> ;	pop	ecx
 11605                              <1> ;	pop	ebx
 11606                              <1> ;	pop	esi
 11607                              <1> ;	retn
 11608                              <1> ;
 11609                              <1> ;swpin_dnp_err:
 11610                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR
 11611                              <1> ;swpin_err_retn:
 11612                              <1> ;	mov	[u.error], eax
 11613                              <1> ;	stc
 11614                              <1> ;	retn
 11615                              <1> ;
 11616                              <1> ;swpin_snp_err:
 11617                              <1> ;	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
 11618                              <1> ;	jmp	short swpin_err_retn
 11619                              <1> 
 11620                              <1> ; 17/04/2021
 11621                              <1> ; ('swap_out' procedure call is disabled as temporary)
 11622                              <1> 
 11623                              <1> ; 30/11/2021 - temporary !
 11624                              <1> ;swap_out:
 11625                              <1> 	; 10/06/2016
 11626                              <1> 	; 07/06/2016
 11627                              <1>         ; 23/05/2016
 11628                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
 11629                              <1> 	; 24/10/2014 - 31/08/2015 (Retro UNIX 386 v1)
 11630                              <1> 	;
 11631                              <1> 	; INPUT -> 
 11632                              <1> 	;	none
 11633                              <1> 	;
 11634                              <1> 	; OUTPUT ->
 11635                              <1> 	;	EAX = Physical page address (which is swapped out
 11636                              <1> 	;	      for allocating a new page)
 11637                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
 11638                              <1> 	;		  or sector not present or drive not ready
 11639                              <1> 	;	     EAX = Error code
 11640                              <1> 	;	     [u.error] = EAX 
 11641                              <1> 	;		       = The last error code for the process
 11642                              <1> 	;		         (will be reset after returning to user)	  
 11643                              <1> 	;
 11644                              <1> 	; Modified Registers -> none (except EAX)
 11645                              <1> 	;
 11646                              <1> 
 11647                              <1> ;	cmp 	word [swpq_count], 1
 11648                              <1> ;       jc      swpout_im_err ; 'insufficient memory'
 11649                              <1> ;
 11650                              <1> ;       ;cmp    dword [swp_drv], 1
 11651                              <1> ;	;jc	short swpout_dnp_err ; 'swap disk/file not present'
 11652                              <1> ;
 11653                              <1> ;       cmp     dword [swpd_free], 1
 11654                              <1> ;       jc      swpout_nfspc_err ; 'no free space on swap disk'
 11655                              <1> ;
 11656                              <1> ;	push	ebx ; *
 11657                              <1> ;swpout_1:
 11658                              <1> ;	; 10/06/2016
 11659                              <1> ;	xor	ebx, ebx ; shift the queue and return a PTE value
 11660                              <1> ;	call	swap_queue_shift
 11661                              <1> ;	and	eax, eax	; 0 = empty queue (improper entries)
 11662                              <1> ;       jz      swpout_npts_err        ; There is not any proper PTE
 11663                              <1> ;				       ; pointer in the swap queue
 11664                              <1> ;	; EAX = PTE value of the page
 11665                              <1> ;	; EBX = PTE address of the page
 11666                              <1> ;	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11667                              <1> ;	;
 11668                              <1> ;	; 07/06/2016
 11669                              <1> ;	; 19/05/2016
 11670                              <1> ;	; check this page is in timer events or not
 11671                              <1> ;	
 11672                              <1> ;swpout_timer_page_0:
 11673                              <1> ;	push	edx ; **
 11674                              <1> ;
 11675                              <1> ;	; 07/06/2016
 11676                              <1> ;	cmp	byte [timer_events], 0 
 11677                              <1> ;	jna	short swpout_2
 11678                              <1> ;	;
 11679                              <1> ;	mov	dl, [timer_events]
 11680                              <1> ;
 11681                              <1> ;	push	ecx ; ***
 11682                              <1> ;	push	ebx ; ****
 11683                              <1> ;	mov	ebx, timer_set ; beginning address of timer event
 11684                              <1> ;			       ; structures 
 11685                              <1> ;swpout_timer_page_1:
 11686                              <1> ;	mov	cl, [ebx]
 11687                              <1> ;	or	cl, cl ; 0 = free, >0 = process number
 11688                              <1> ;	jz	short swpout_timer_page_3
 11689                              <1> ;	mov	ecx, [ebx+12] ; response (signal return) address
 11690                              <1> ;	and	cx, PTE_A_CLEAR ; clear offset part (right 12 bits)
 11691                              <1> ;				; of the response byte address, to
 11692                              <1> ;				; get beginning of the page address)
 11693                              <1> ;	cmp	eax, ecx
 11694                              <1> ;	jne	short swpout_timer_page_2 ; not same page
 11695                              <1> ;	
 11696                              <1> ;	; !same page!
 11697                              <1> ;	;
 11698                              <1> ;	; NOTE: // 19/05/2016 // - TRDOS 386 feature only ! -
 11699                              <1> ;	; This page will be used by the kernel to put timer event
 11700                              <1> ;	; response (signal return) byte at the requested address;
 11701                              <1> ;	; in order to prevent a possible wrong write (while
 11702                              <1> ;	; this page is swapped out) on physical memory,
 11703                              <1> ;	; we must protect this page against to be swapped out!
 11704                              <1> ;	;
 11705                              <1> ;	pop	ebx ; ****
 11706                              <1> ;	pop	ecx ; ***
 11707                              <1> ;	pop	edx ; **
 11708                              <1> ;	jmp	short swpout_1	; do not swap out this page !
 11709                              <1> ; 
 11710                              <1> ;swpout_timer_page_2:
 11711                              <1> ;	; 07/06/2016
 11712                              <1> ;	dec	dl
 11713                              <1> ;	jz	short swpout_timer_page_4
 11714                              <1> ;swpout_timer_page_3:
 11715                              <1> ;	;cmp	ebx, timer_set + 240 ; last timer event (15*16) 
 11716                              <1> ;	;jnb	short swpout_timer_page_4
 11717                              <1> ;	add	ebx, 16
 11718                              <1> ;	jmp	short swpout_timer_page_1	
 11719                              <1> ;
 11720                              <1> ;swpout_timer_page_4:
 11721                              <1> ;	pop	ebx ; ****
 11722                              <1> ;	pop	ecx ; ***
 11723                              <1> ;swpout_2:
 11724                              <1> ;	mov	edx, ebx	       ; Page table entry address	
 11725                              <1> ;	mov	ebx, eax	       ; Buffer (Page) Address				
 11726                              <1> ;	;
 11727                              <1> ;	call	link_swap_block
 11728                              <1> ;	jnc	short swpout_3	       ; It may not be needed here	
 11729                              <1> ;				       ; because [swpd_free] value
 11730                              <1> ;				       ; was checked at the beginging. 	
 11731                              <1> ;	pop	edx ; **
 11732                              <1> ;	pop	ebx ; *
 11733                              <1> ;	jmp	short swpout_nfspc_err 
 11734                              <1> ;swpout_3:
 11735                              <1> ;	test	eax, 80000000h ; test bit 31 (this may not be needed!)
 11736                              <1> ;	jnz	short swpout_nfspc_err  ; 10/06/2016 (bit 31 = 1 !)
 11737                              <1> ;	;	
 11738                              <1> ;	push	esi ; **
 11739                              <1> ;	push	ecx ; ***
 11740                              <1> ;	push	eax ; sector address ; (31 bit !, bit 31 = 0)
 11741                              <1> ;	mov	esi, [swp_drv]	
 11742                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 11743                              <1> ;		; Note: Even if corresponding physical disk's sector 
 11744                              <1> ;		; size different than 512 bytes, logical disk sector
 11745                              <1> ;		; size is 512 bytes and disk writing procedure
 11746                              <1> ;		; will be performed for writing 4096 bytes
 11747                              <1> ;		; (2*2048, 8*512). 
 11748                              <1> ;	; ESI = Logical disk description table address
 11749                              <1> ;	; EBX = Buffer (Page) address
 11750                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
 11751                              <1> ;	; ECX = Sector count ; 8 sectors
 11752                              <1> ;	; edx = PTE address
 11753                              <1> ;	call	logical_disk_write
 11754                              <1> ;	; edx = PTE address
 11755                              <1> ;	pop	ecx ; sector address	
 11756                              <1> ;	jnc	short swpout_write_ok
 11757                              <1> ;	;
 11758                              <1> ;	;; call	unlink_swap_block ; this block must be left as 'in use'
 11759                              <1> ;swpout_dw_err:
 11760                              <1> ;	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
 11761                              <1> ;	mov	[u.error], eax
 11762                              <1> ;	jmp	short swpout_retn
 11763                              <1> ;	;
 11764                              <1> ;swpout_write_ok:
 11765                              <1> ;	; EBX = Buffer (page) address
 11766                              <1> ;	; EDX = Page Table Entry address
 11767                              <1> ;	; ECX = Swap disk sector (file block) address (31 bit)
 11768                              <1> ;	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
 11769                              <1> ;	mov 	[edx], ecx 
 11770                              <1> ;		; bit 0 = 0 (swapped page)
 11771                              <1> ;	mov	eax, ebx
 11772                              <1> ;swpout_retn:
 11773                              <1> ;	pop	ecx ; ***
 11774                              <1> ;	pop	esi ; **
 11775                              <1> ;	pop	ebx ; *
 11776                              <1> ;	retn
 11777                              <1> ;
 11778                              <1> ;;swpout_dnp_err:
 11779                              <1> ;;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
 11780                              <1> ;;	jmp	short swpout_err_retn
 11781                              <1> ;swpout_nfspc_err:
 11782                              <1> ;	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
 11783                              <1> ;swpout_err_retn:
 11784                              <1> ;	mov	[u.error], eax
 11785                              <1> ;	;stc
 11786                              <1> ;	retn
 11787                              <1> ;swpout_npts_err:
 11788                              <1> ;	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
 11789                              <1> ;	pop	ebx
 11790                              <1> ;	jmp	short swpout_err_retn
 11791                              <1> ;swpout_im_err:
 11792                              <1> ;	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
 11793                              <1> ;	jmp	short swpout_err_retn
 11794                              <1> 
 11795                              <1> ; 17/04/2021
 11796                              <1> ; ('swap_queue_shift' procedure call is disabled as temporary)
 11797                              <1> 
 11798                              <1> ; 30/11/2021 - temporary !
 11799                              <1> ;swap_queue_shift:
 11800                              <1> 	; 26/03/2017
 11801                              <1> 	; 10/06/2016
 11802                              <1> 	; 09/06/2016 - TRDOS 386 (TRDOS v2.0)
 11803                              <1> 	; 23/10/2014 - 20/07/2015 (Retro UNIX 386 v1)
 11804                              <1> 	;
 11805                              <1> 	; INPUT ->
 11806                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
 11807                              <1> 	;	      and process number combination (bit 0 to 11)
 11808                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
 11809                              <1> 	;	
 11810                              <1> 	; OUTPUT ->
 11811                              <1> 	;	If EBX input > 0 
 11812                              <1> 	;	   the queue will be shifted 4 bytes (dword),
 11813                              <1> 	; 	   from the tail to the head, up to entry offset
 11814                              <1> 	; 	   which points to EBX input value or nothing
 11815                              <1> 	;	   to do if EBX value is not found on the queue.
 11816                              <1> 	;	   (The entry -with EBX value- will be removed
 11817                              <1> 	;	   from the queue if it is found.)
 11818                              <1> 	;
 11819                              <1> 	;	   EAX = 0		
 11820                              <1> 	;
 11821                              <1> 	;	If EBX input = 0
 11822                              <1> 	;	   the queue will be shifted 4 bytes (dword),
 11823                              <1> 	; 	   from the tail to the head, if the PTE address
 11824                              <1> 	;	   which is pointed in head of the queue is marked
 11825                              <1> 	;	   as "accessed" or it is marked as "non present".
 11826                              <1> 	;	   (If "accessed" flag of the PTE -which is pointed
 11827                              <1> 	;	   in the head- is set -to 1-, it will be reset
 11828                              <1> 	;	   -to 0- and then, the queue will be rotated 
 11829                              <1> 	;	   -without dropping pointer of the PTE from 
 11830                              <1> 	;	   the queue- for 4 bytes on head to tail direction.
 11831                              <1> 	;	   Pointer in the head will be moved into the tail,
 11832                              <1> 	;	   other PTEs will be shifted on head direction.)
 11833                              <1> 	;
 11834                              <1> 	;	   Swap queue will be shifted up to the first
 11835                              <1> 	;	   'present' or 'non accessed' page will be found
 11836                              <1> 	;	   (as pointed) on the queue head (then it will be
 11837                              <1>         ;          removed/dropped from the queue).
 11838                              <1> 	;
 11839                              <1> 	;	   EAX (> 0) = PTE value of the page which is
 11840                              <1> 	;		 (it's pointer -virtual address-) dropped
 11841                              <1> 	;		 (removed) from swap queue.
 11842                              <1> 	;	   EBX = PTE address of the page (if EAX > 0)
 11843                              <1> 	;	         which is (it's pointer -virtual address-)
 11844                              <1> 	;		 dropped (removed) from swap queue.
 11845                              <1> 	;
 11846                              <1> 	;	   EAX = 0 -> empty swap queue ! 
 11847                              <1> 	;
 11848                              <1> 	; Modified Registers -> EAX, EBX
 11849                              <1> 	;
 11850                              <1> ;	movzx   eax, word [swpq_count]  ; Max. 1024
 11851                              <1> ;	and	ax, ax
 11852                              <1> ;	jz	short swpqs_retn
 11853                              <1> ;	push	edi
 11854                              <1> ;	push	esi
 11855                              <1> ;	push	ecx
 11856                              <1> ;	mov	esi, swap_queue
 11857                              <1> ;	mov	ecx, eax
 11858                              <1> ;	or	ebx, ebx
 11859                              <1> ;	jz	short swpqs_7
 11860                              <1> ;swpqs_1:
 11861                              <1> ;	lodsd
 11862                              <1> ;	cmp	eax, ebx
 11863                              <1> ;	je	short swpqs_2
 11864                              <1> ;	loop	swpqs_1
 11865                              <1> ;	; 10/06/2016
 11866                              <1> ;	sub	eax, eax 
 11867                              <1> ;	jmp	short swpqs_6
 11868                              <1> ;swpqs_2:
 11869                              <1> ;	mov	edi, esi
 11870                              <1> ;	sub 	edi, 4
 11871                              <1> ;swpqs_3:
 11872                              <1> ;	dec	word [swpq_count]
 11873                              <1> ;	jz	short swpqs_5
 11874                              <1> ;swpqs_4:
 11875                              <1> ;	dec 	ecx
 11876                              <1> ;	rep	movsd	; shift up (to the head)
 11877                              <1> ;swpqs_5:
 11878                              <1> ;	xor	eax, eax
 11879                              <1> ;	mov	[edi], eax
 11880                              <1> ;swpqs_6:
 11881                              <1> ;	pop	ecx
 11882                              <1> ;	pop	esi
 11883                              <1> ;	pop	edi
 11884                              <1> ;swpqs_retn:
 11885                              <1> ;	retn		
 11886                              <1> ;swpqs_7:
 11887                              <1> ;	mov	edi, esi ; head
 11888                              <1> ;	lodsd
 11889                              <1> ;	; 20/07/2015
 11890                              <1> ;	mov	ebx, eax
 11891                              <1> ;	and	ebx, ~PAGE_OFF ; ~0FFFh 
 11892                              <1> ;		      ; ebx = virtual address (at page boundary)	
 11893                              <1> ;	and	eax, PAGE_OFF ; 0FFFh
 11894                              <1> ;		      ; ax = process number (1 to 4095)
 11895                              <1> ;	cmp	al, [u.uno]
 11896                              <1> ;		; Max. 16 (nproc) processes for Retro UNIX 386 v1
 11897                              <1> ;	jne	short swpqs_8
 11898                              <1> ;	mov	eax, [u.pgdir]
 11899                              <1> ;	jmp	short swpqs_9
 11900                              <1> ;swpqs_8:
 11901                              <1> ;	; 09/06/2016
 11902                              <1> ;	cmp	byte [eax+p.stat-1], 0
 11903                              <1> ;	jna	short swpqs_3     ; free (or terminated) process
 11904                              <1> ;	cmp	byte [eax+p.stat-1], 2 ; waiting
 11905                              <1> ;	ja	short swpqs_3 	  ; zombie (3) or undefined ?	
 11906                              <1> ;
 11907                              <1> ;	;shl	ax, 2
 11908                              <1> ;	shl	al, 2
 11909                              <1> ;	mov 	eax, [eax+p.upage-4]
 11910                              <1> ;	or	eax, eax
 11911                              <1> ;	jz	short swpqs_3 ; invalid upage
 11912                              <1> ;	add	eax, u.pgdir - user
 11913                              <1> ;			 ; u.pgdir value for the process
 11914                              <1> ;			 ; is in [eax]
 11915                              <1> ;	mov	eax, [eax]
 11916                              <1> ;	and	eax, eax
 11917                              <1> ;	jz	short swpqs_3 ; invalid page directory
 11918                              <1> ;swpqs_9:
 11919                              <1> ;	push	edx
 11920                              <1> ;	; eax = page directory
 11921                              <1> ;	; ebx = virtual address
 11922                              <1> ;	call	get_pte
 11923                              <1> ;	mov	ebx, edx	; PTE address
 11924                              <1> ;	pop	edx
 11925                              <1> ;	; 10/06/2016
 11926                              <1> ;	jc	short swpqs_13 ; empty PDE
 11927                              <1> ;	; EAX = PTE value
 11928                              <1> ;	test	al, PTE_A_PRESENT ; bit 0 = 1
 11929                              <1> ;	jz	short swpqs_13  ; Drop non-present page
 11930                              <1> ;			        ; from the queue (head)
 11931                              <1> ;	test	al, PTE_A_WRITE	; bit 1 = 0 (read only)
 11932                              <1> ;	jz	short swpqs_13  ; Drop read only page
 11933                              <1> ;			        ; from the queue (head) 	
 11934                              <1> ;	;test	al, PTE_A_ACCESS ; bit 5 = 1 (Accessed)
 11935                              <1> ;	;jnz	short swpqs_11  ; present
 11936                              <1> ;			        ; accessed page
 11937                              <1> ;       btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
 11938                              <1> ;	jc	short swpqs_11  ; accessed page
 11939                              <1> ;
 11940                              <1> ;	dec	ecx
 11941                              <1> ;	mov	[swpq_count], cx
 11942                              <1> ;       jz      short swpqs_10
 11943                              <1> ;		; esi = head + 4
 11944                              <1> ;		; edi = head
 11945                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 11946                              <1> ;swpqs_10:
 11947                              <1> ;	mov	[edi], ecx ; 0
 11948                              <1> ;	jmp	short swpqs_6 ; 26/03/2017
 11949                              <1> ;
 11950                              <1> ;swpqs_11:
 11951                              <1> ;	mov	[ebx], eax     ; save changed attribute
 11952                              <1> ;	; Rotation (head -> tail)
 11953                              <1> ;	dec	ecx     ; entry count -> last entry number		
 11954                              <1> ;	jz	short swpqs_10
 11955                              <1> ;		; esi = head + 4
 11956                              <1> ;		; edi = head
 11957                              <1> ;	mov	eax, [edi] ; 20/07/2015
 11958                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 11959                              <1> ;	mov	[edi], eax ; head -> tail ; [k] = [1]
 11960                              <1> ;
 11961                              <1> ;	mov	cx, [swpq_count]
 11962                              <1> ;
 11963                              <1> ;swpqs_12:
 11964                              <1> ;	mov	esi, swap_queue ; head
 11965                              <1> ;       jmp     swpqs_7
 11966                              <1> ;
 11967                              <1> ;swpqs_13:
 11968                              <1> ;	dec	ecx
 11969                              <1> ;	mov	[swpq_count], cx
 11970                              <1> ;       jz      swpqs_5
 11971                              <1> ;	jmp	short swpqs_12
 11972                              <1> 
 11973                              <1> ; 17/04/2021
 11974                              <1> ; ('add_to_swp_queue' procedure call is disabled as temporary)
 11975                              <1> 
 11976                              <1> ; 30/11/2021 - temporary !
 11977                              <1> ;add_to_swap_queue:
 11978                              <1> 	; 20/02/2017
 11979                              <1> 	; 20/07/2015
 11980                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 11981                              <1> 	;
 11982                              <1> 	; Adds new page to swap queue
 11983                              <1> 	; (page directories and page tables must not be added
 11984                              <1> 	; to swap queue)	
 11985                              <1> 	;
 11986                              <1> 	; INPUT ->
 11987                              <1> 	;	EBX = Linear (Virtual) addr for current process
 11988                              <1> 	;	[u.uno]
 11989                              <1> 	;	20/02/2017
 11990                              <1> 	;	(Linear address = CORE + user's virtual address)
 11991                              <1> 	;
 11992                              <1> 	; OUTPUT ->
 11993                              <1> 	;	EAX = [swpq_count]
 11994                              <1> 	;	      (after the PTE has been added)
 11995                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
 11996                              <1> 	;	      the PTE could not be added.
 11997                              <1> 	;
 11998                              <1> 	; Modified Registers -> EAX
 11999                              <1> 	;
 12000                              <1> ;	push	ebx
 12001                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12002                              <1> ;	mov	bl, [u.uno] ; current process number
 12003                              <1> ;	call	swap_queue_shift ; drop from the queue if
 12004                              <1> ;				 ; it is already on the queue
 12005                              <1> ;		; then add it to the tail of the queue
 12006                              <1> ;	movzx	eax, word [swpq_count]
 12007                              <1> ;	cmp	ax, 1024
 12008                              <1> ;	jb	short atsq_1
 12009                              <1> ;	sub	ax, ax
 12010                              <1> ;	pop	ebx
 12011                              <1> ;	retn
 12012                              <1> ;atsq_1:
 12013                              <1> ;	push	esi
 12014                              <1> ;	mov	esi, swap_queue
 12015                              <1> ;	and	ax, ax
 12016                              <1> ;	jz	short atsq_2
 12017                              <1> ;	shl	ax, 2	; convert to offset
 12018                              <1> ;	add	esi, eax
 12019                              <1> ;	shr	ax, 2
 12020                              <1> ;atsq_2:
 12021                              <1> ;	inc	ax
 12022                              <1> ;	mov	[esi], ebx ; Virtual address + [u.uno] combination
 12023                              <1> ;	mov	[swpq_count], ax
 12024                              <1> ;	pop	esi
 12025                              <1> ;	pop	ebx
 12026                              <1> ;	retn
 12027                              <1> 
 12028                              <1> ; 17/04/2021
 12029                              <1> ; ('unlink_swap_block' procedure call is disabled as temporary)
 12030                              <1> 
 12031                              <1> ; 30/11/2021 - temporary !
 12032                              <1> ;unlink_swap_block:
 12033                              <1> 	; 15/09/2015
 12034                              <1> 	; 30/04/2015
 12035                              <1> 	; 18/04/2015
 12036                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12037                              <1> 	;
 12038                              <1> 	; INPUT -> 
 12039                              <1> 	;	EAX = swap disk/file offset address
 12040                              <1> 	;	      (bit 1 to bit 31)
 12041                              <1> 	; OUTPUT ->
 12042                              <1> 	;	[swpd_free] is increased
 12043                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
 12044                              <1> 	;
 12045                              <1> 	; Modified Registers -> EAX
 12046                              <1> 	;
 12047                              <1> ;	push	ebx
 12048                              <1> ;	push	edx
 12049                              <1> ;	;
 12050                              <1> ;	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
 12051                              <1> ;				     ; 3 bits right
 12052                              <1> ;				     ; to get swap block/page number
 12053                              <1> ;	mov	edx, eax
 12054                              <1> ;	; 15/09/2015
 12055                              <1> ;	shr	edx, 3		     ; to get offset to S.A.T.
 12056                              <1> ;				     ; (1 allocation bit = 1 page)
 12057                              <1> ;				     ; (1 allocation bytes = 8 pages)
 12058                              <1> ;	and	dl, 0FCh 	     ; clear lower 2 bits
 12059                              <1> ;				     ; (to get 32 bit position)			
 12060                              <1> ;	;
 12061                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table address
 12062                              <1> ;	add	ebx, edx
 12063                              <1> ;	and	eax, 1Fh	     ; lower 5 bits only
 12064                              <1> ;				     ; (allocation bit position)	 
 12065                              <1> ;	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
 12066                              <1> ;				     ; than the address in 'swpd_next' ?
 12067                              <1> ;				     ; (next/first free block value)		
 12068                              <1> ;	jnb	short uswpbl_1	     ; no	
 12069                              <1> ;	mov	[swpd_next], eax     ; yes	
 12070                              <1> ;uswpbl_1:
 12071                              <1> ;	bts	[ebx], eax	     ; unlink/release/deallocate block
 12072                              <1> ;				     ; set relevant bit to 1.
 12073                              <1> ;				     ; set CF to the previous bit value	
 12074                              <1> ;	cmc			     ; complement carry flag	
 12075                              <1> ;	jc	short uswpbl_2	     ; do not increase swfd_free count
 12076                              <1> ;				     ; if the block is already deallocated
 12077                              <1> ;				     ; before.	
 12078                              <1> ;       inc     dword [swpd_free]
 12079                              <1> ;uswpbl_2:
 12080                              <1> ;	pop	edx
 12081                              <1> ;	pop	ebx
 12082                              <1> ;	retn
 12083                              <1> 
 12084                              <1> ; 17/04/2021
 12085                              <1> ; ('link_swap_block' procedure call is disabled as temporary)
 12086                              <1> 
 12087                              <1> ; 30/11/2021 - temporary !
 12088                              <1> ;link_swap_block:
 12089                              <1> 	; 01/07/2015
 12090                              <1> 	; 18/04/2015
 12091                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12092                              <1> 	;
 12093                              <1> 	; INPUT -> none
 12094                              <1> 	;
 12095                              <1> 	; OUTPUT ->
 12096                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
 12097                              <1> 	;	      in sectors (corresponding 
 12098                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
 12099                              <1> 	;
 12100                              <1> 	;	CF = 1 and EAX = 0 
 12101                              <1> 	; 		   if there is not a free block to be allocated	
 12102                              <1> 	;
 12103                              <1> 	; Modified Registers -> none (except EAX)
 12104                              <1> 	;
 12105                              <1> 
 12106                              <1> ;	;mov	eax, [swpd_free]
 12107                              <1> ;	;and	eax, eax
 12108                              <1> ;	;jz	short out_of_swpspc
 12109                              <1> ;	;
 12110                              <1> ;	push	ebx
 12111                              <1> ;	push	ecx
 12112                              <1> ;	;
 12113                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
 12114                              <1> ;	mov	ecx, ebx
 12115                              <1> ;	add	ebx, [swpd_next] ; Free block searching starts from here
 12116                              <1> ;				 ; next_free_swap_block >> 5
 12117                              <1> ;	add	ecx, [swpd_last] ; Free block searching ends here
 12118                              <1> ;				 ; (total_swap_blocks - 1) >> 5
 12119                              <1> ;lswbl_scan:
 12120                              <1> ;	cmp	ebx, ecx
 12121                              <1> ;	ja	short lswbl_notfound
 12122                              <1> ;	;
 12123                              <1> ;	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 12124                              <1> ;			   ; Clears ZF if a bit is found set (1) and 
 12125                              <1> ;			   ; loads the destination with an index to
 12126                              <1> ;			   ; first set bit. (0 -> 31) 
 12127                              <1> ;			   ; Sets ZF to 1 if no bits are found set.
 12128                              <1> ;	; 01/07/2015
 12129                              <1> ;	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
 12130                              <1> ;			 ;
 12131                              <1> ;			 ; NOTE:  a Swap Disk Allocation Table bit 
 12132                              <1> ;			 ;	  with value of 1 means 
 12133                              <1> ;			 ;	  the corresponding page is free 
 12134                              <1> ;			 ;	  (Retro UNIX 386 v1 feaure only!)
 12135                              <1> ;	add	ebx, 4
 12136                              <1> ;			 ; We return back for searching next page block
 12137                              <1> ;			 ; NOTE: [swpd_free] is not ZERO; so, 
 12138                              <1> ;			 ;	 we always will find at least 1 free block here.
 12139                              <1> ;	jmp    	short lswbl_scan
 12140                              <1> ;	;
 12141                              <1> ;lswbl_notfound:	
 12142                              <1> ;	sub	ecx, swap_alloc_table
 12143                              <1> ;	mov	[swpd_next], ecx ; next/first free page = last page 
 12144                              <1> ;				 ; (unlink_swap_block procedure will change it)
 12145                              <1> ;	xor	eax, eax
 12146                              <1> ;	mov	[swpd_free], eax
 12147                              <1> ;	stc
 12148                              <1> ;lswbl_ok:
 12149                              <1> ;	pop	ecx
 12150                              <1> ;	pop	ebx
 12151                              <1> ;	retn
 12152                              <1> ;	;
 12153                              <1> ;;out_of_swpspc:
 12154                              <1> ;;	stc
 12155                              <1> ;;	retn
 12156                              <1> ;
 12157                              <1> ;lswbl_found:
 12158                              <1> ;	mov	ecx, ebx
 12159                              <1> ;	sub	ecx, swap_alloc_table
 12160                              <1> ;	mov	[swpd_next], ecx ; Set first free block searching start
 12161                              <1> ;				 ; address/offset (to the next)
 12162                              <1> ;       dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
 12163                              <1> ;	;
 12164                              <1> ;	btr	[ebx], eax	 ; The destination bit indexed by the source value
 12165                              <1> ;				 ; is copied into the Carry Flag and then cleared
 12166                              <1> ;				 ; in the destination.
 12167                              <1> ;				 ;
 12168                              <1> ;				 ; Reset the bit which is corresponding to the 
 12169                              <1> ;				 ; (just) allocated block.
 12170                              <1> ;	shl	ecx, 5		 ; (block offset * 32) + block index
 12171                              <1> ;	add	eax, ecx	 ; = block number
 12172                              <1> ;	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
 12173                              <1> ;				 ; 1 block =  8 sectors
 12174                              <1> ;	;
 12175                              <1> ;	; EAX = offset address of swap disk/file sector (beginning of the block)
 12176                              <1> ;	;
 12177                              <1> ;	; NOTE: The relevant page table entry will be updated
 12178                              <1> ;	;       according to this EAX value...
 12179                              <1> ;	;
 12180                              <1> ;	jmp	short lswbl_ok
 12181                              <1> 
 12182                              <1> ; 17/04/2021
 12183                              <1> ; ('logical_disk_read' procedure call is disabled as temporary)
 12184                              <1> 
 12185                              <1> ; 30/11/2021 - temporary !
 12186                              <1> ;logical_disk_read:
 12187                              <1> 	; 20/07/2015
 12188                              <1> 	; 09/03/2015 (temporary code here)
 12189                              <1> 	;
 12190                              <1> 	; INPUT ->
 12191                              <1> 	; 	ESI = Logical disk description table address
 12192                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12193                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12194                              <1> 	; 	ECX = Sector count
 12195                              <1> 	;
 12196                              <1> 	;
 12197                              <1> ;	retn
 12198                              <1> 
 12199                              <1> ; 17/04/2021
 12200                              <1> ; ('logical_disk_write' procedure call is disabled as temporary)
 12201                              <1> 
 12202                              <1> ; 30/11/2021 - temporary !
 12203                              <1> ;logical_disk_write:
 12204                              <1> 	; 20/07/2015
 12205                              <1> 	; 09/03/2015 (temporary code here)
 12206                              <1> 	;
 12207                              <1> 	; INPUT ->
 12208                              <1> 	; 	ESI = Logical disk description table address
 12209                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12210                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12211                              <1> 	; 	ECX = Sector count
 12212                              <1> 	;
 12213                              <1> ;	retn
 12214                              <1> 
 12215                              <1> get_physical_addr:
 12216                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 12217                              <1> 	;	(temporary modifications)
 12218                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 12219                              <1> 	; 18/10/2015
 12220                              <1> 	; 29/07/2015
 12221                              <1> 	; 20/07/2015
 12222                              <1> 	; 04/06/2015
 12223                              <1> 	; 20/05/2015
 12224                              <1> 	; 28/04/2015
 12225                              <1> 	; 18/04/2015
 12226                              <1> 	; Get physical address
 12227                              <1> 	;     (allocates a new page for user if it is not present)
 12228                              <1> 	;	
 12229                              <1> 	; (This subroutine is needed for mapping user's virtual 
 12230                              <1> 	; (buffer) address to physical address (of the buffer).)
 12231                              <1> 	; ('sys write', 'sys read' system calls...)
 12232                              <1> 	;
 12233                              <1> 	; INPUT ->
 12234                              <1> 	;	EBX = virtual address
 12235                              <1> 	;	u.pgdir = page directory (physical) address
 12236                              <1> 	;
 12237                              <1> 	; OUTPUT ->
 12238                              <1> 	;	EAX = physical address 
 12239                              <1> 	;	EBX = linear address	
 12240                              <1> 	;	EDX = physical address of the page frame
 12241                              <1> 	;	      (with attribute bits)
 12242                              <1> 	;	ECX = byte count within the page frame
 12243                              <1> 	;
 12244                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
 12245                              <1> 	;
 12246                              <1> 
 12247                              <1> 	; 19/04/2020 - Retro UNIX386 v2
 12248 000027C7 A1[046D0000]        <1> 	mov	eax, [u.pgdir]
 12249                              <1> 
 12250                              <1> ifs_get_physical_addr: ; 19/04/2020 - Retro UNIX 386 v2
 12251                              <1> 	
 12252 000027CC 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
 12253                              <1> 	;
 12254                              <1> 	;mov	eax, [u.pgdir]
 12255 000027D2 E81AFDFFFF          <1> 	call	get_pte
 12256                              <1> 		; EDX = Page table entry address (if CF=0)
 12257                              <1> 	        ;       Page directory entry address (if CF=1)
 12258                              <1> 		;       (Bit 0 value is 0 if PT is not present)
 12259                              <1> 		; EAX = Page table entry value (page address)
 12260                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
 12261 000027D7 731C                <1> 	jnc	short gpa_1
 12262                              <1> 	;
 12263 000027D9 E801FCFFFF          <1> 	call	allocate_page
 12264 000027DE 724B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
 12265                              <1> gpa_0:
 12266 000027E0 E86BFCFFFF          <1> 	call 	clear_page
 12267                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 12268 000027E5 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
 12269                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
 12270                              <1> 			   ; (user, writable, present page)	
 12271 000027E7 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
 12272 000027E9 A1[046D0000]        <1> 	mov	eax, [u.pgdir]	
 12273 000027EE E8FEFCFFFF          <1> 	call	get_pte
 12274 000027F3 7236                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12275                              <1> gpa_1:
 12276                              <1> 	; EAX = PTE value, EDX = PTE address
 12277 000027F5 A801                <1> 	test 	al, PTE_A_PRESENT
 12278 000027F7 750A                <1> 	jnz	short gpa_3
 12279 000027F9 09C0                <1> 	or	eax, eax
 12280 000027FB 7420                <1> 	jz	short gpa_4  ; Allocate a new page
 12281                              <1> 
 12282                              <1> ; 17/04/2021
 12283                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12284 000027FD EB2C                <1> 	jmp	short gpa_im_err  ; temporary !
 12285                              <1> 
 12286                              <1> 	; 20/07/2015
 12287                              <1> ;	push	ebp
 12288                              <1> ;	mov	ebp, ebx ; virtual (linear) address
 12289                              <1> ;	; reload swapped page
 12290                              <1> ;	call	reload_page ; 28/04/2015
 12291                              <1> ;	pop	ebp
 12292                              <1> ;	jc	short gpa_retn
 12293                              <1> gpa_2:
 12294                              <1> ; 17/04/2021
 12295                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
 12296                              <1> 
 12297                              <1> 	; 20/07/2015
 12298                              <1> 	; 20/05/2015
 12299                              <1> 	; add this page to swap queue
 12300                              <1> ;	push	eax 
 12301                              <1> ;	; EBX = Linear (CORE+virtual) address ; 20/02/2017 
 12302                              <1> ;	call 	add_to_swap_queue
 12303                              <1> ;	pop	eax
 12304                              <1> 		; PTE address in EDX
 12305                              <1> 		; virtual address in EBX
 12306                              <1> 
 12307                              <1> 	; EAX = memory page address
 12308 000027FF 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
 12309                              <1> 				  ; present flag, bit 0 = 1
 12310                              <1> 				  ; user flag, bit 2 = 1	
 12311                              <1> 				  ; writable flag, bit 1 = 1
 12312 00002801 8902                <1> 	mov	[edx], eax  ; Update PTE value
 12313                              <1> gpa_3:
 12314                              <1> 	; 18/10/2015
 12315 00002803 89D9                <1> 	mov	ecx, ebx
 12316 00002805 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
 12317 0000280B 89C2                <1> 	mov 	edx, eax
 12318 0000280D 662500F0            <1> 	and	ax, PTE_A_CLEAR
 12319 00002811 01C8                <1> 	add	eax, ecx
 12320 00002813 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
 12321 00002815 81C100100000        <1> 	add	ecx, PAGE_SIZE
 12322 0000281B F8                  <1> 	clc
 12323                              <1> gpa_retn:
 12324 0000281C C3                  <1> 	retn	
 12325                              <1> gpa_4:	
 12326 0000281D E8BDFBFFFF          <1> 	call	allocate_page
 12327 00002822 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12328 00002824 E827FCFFFF          <1> 	call	clear_page
 12329 00002829 EBD4                <1> 	jmp	short gpa_2
 12330                              <1> 
 12331                              <1> gpa_im_err:	
 12332 0000282B B804000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12333                              <1> 				  ; Major error = 0 (No protection fault)	
 12334 00002830 C3                  <1> 	retn
 12335                              <1> 
 12336                              <1> ; 17/04/2021
 12337                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12338                              <1> 
 12339                              <1> ; 30/11/2021 - temporary !
 12340                              <1> ;reload_page:
 12341                              <1> 	; 20/07/2015
 12342                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
 12343                              <1> 	;
 12344                              <1> 	; Reload (Restore) swapped page at memory
 12345                              <1> 	;
 12346                              <1> 	; INPUT -> 
 12347                              <1> 	;	EBP = Virtual (linear) memory address
 12348                              <1> 	;	EAX = PTE value (swap disk sector address)
 12349                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
 12350                              <1> 	; OUTPUT ->
 12351                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
 12352                              <1> 	;
 12353                              <1> 	;	CF = 1 and EAX = error code
 12354                              <1> 	;
 12355                              <1> 	; Modified Registers -> none (except EAX)
 12356                              <1> 	;
 12357                              <1> ;	shr	eax, 1   ; Convert PTE value to swap disk address 
 12358                              <1> ;	push	ebx      ;
 12359                              <1> ;	mov	ebx, eax ; Swap disk (offset) address	
 12360                              <1> ;	call	allocate_page
 12361                              <1> ;	jc	short rlp_im_err
 12362                              <1> ;	xchg 	eax, ebx	
 12363                              <1> ;	; EBX = Physical memory (page) address
 12364                              <1> ;	; EAX = Swap disk (offset) address
 12365                              <1> ;	; EBP = Virtual (linear) memory address
 12366                              <1> ;	call	swap_in
 12367                              <1> ;	jc	short rlp_swp_err  ; (swap disk/file read error)
 12368                              <1> ;	mov	eax, ebx	
 12369                              <1> ;rlp_retn:
 12370                              <1> ;	pop	ebx
 12371                              <1> ;	retn
 12372                              <1> ;	
 12373                              <1> ;rlp_im_err:	
 12374                              <1> ;	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12375                              <1> ;				  ; Major error = 0 (No protection fault)	
 12376                              <1> ;	jmp	short rlp_retn
 12377                              <1> ;
 12378                              <1> ;rlp_swp_err:
 12379                              <1> ;	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
 12380                              <1> ;	jmp	short rlp_retn
 12381                              <1> 
 12382                              <1> copy_page_dir:
 12383                              <1> 	; 17/04/2021 (temporary modifications)
 12384                              <1> 	; 19/09/2015
 12385                              <1> 	; temporary - 07/09/2015
 12386                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12387                              <1> 	;
 12388                              <1> 	; INPUT -> 
 12389                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 12390                              <1> 	;		    page directory.
 12391                              <1> 	; OUTPUT ->
 12392                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 12393                              <1> 	;	       page directory.
 12394                              <1> 	;	(New page directory with new page table entries.)
 12395                              <1> 	;	(New page tables with read only copies of the parent's
 12396                              <1> 	;	pages.)
 12397                              <1> 	;	EAX = 0 -> Error (CF = 1)
 12398                              <1> 	;
 12399                              <1> 	; Modified Registers -> none (except EAX)
 12400                              <1> 	;
 12401 00002831 E8A9FBFFFF          <1> 	call	allocate_page
 12402 00002836 723E                <1> 	jc	short cpd_err
 12403                              <1> 	;
 12404 00002838 55                  <1> 	push	ebp ; 20/07/2015
 12405 00002839 56                  <1> 	push	esi
 12406 0000283A 57                  <1> 	push	edi
 12407 0000283B 53                  <1> 	push	ebx
 12408 0000283C 51                  <1> 	push	ecx
 12409 0000283D 8B35[046D0000]      <1> 	mov	esi, [u.pgdir]
 12410 00002843 89C7                <1> 	mov	edi, eax
 12411 00002845 50                  <1> 	push	eax ; save child's page directory address
 12412                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 12413                              <1> 	; (use same system space for all user page tables) 
 12414 00002846 A5                  <1> 	movsd
 12415 00002847 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 12416 0000284C B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 12417                              <1> cpd_0:	
 12418 00002851 AD                  <1> 	lodsd
 12419                              <1> 	;or	eax, eax
 12420                              <1>         ;jnz	short cpd_1
 12421 00002852 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 12422 00002854 7508                <1> 	jnz	short cpd_1
 12423                              <1>  	; (virtual address at the end of the page table)	
 12424 00002856 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 12425 0000285C EB0F                <1> 	jmp	short cpd_2
 12426                              <1> cpd_1:	
 12427 0000285E 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 12428 00002862 89C3                <1> 	mov	ebx, eax
 12429                              <1> 	; EBX = Parent's page table address
 12430 00002864 E81F000000          <1> 	call	copy_page_table
 12431 00002869 720C                <1> 	jc	short cpd_p_err
 12432                              <1> 	; EAX = Child's page table address
 12433 0000286B 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 12434                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 12435                              <1> 			 ; (present, writable, user)
 12436                              <1> cpd_2:
 12437 0000286D AB                  <1> 	stosd
 12438 0000286E E2E1                <1> 	loop	cpd_0
 12439                              <1> 	;
 12440 00002870 58                  <1> 	pop	eax  ; restore child's page directory address
 12441                              <1> cpd_3:
 12442 00002871 59                  <1> 	pop	ecx
 12443 00002872 5B                  <1> 	pop	ebx
 12444 00002873 5F                  <1> 	pop	edi
 12445 00002874 5E                  <1> 	pop	esi
 12446 00002875 5D                  <1> 	pop	ebp
 12447                              <1> cpd_err:
 12448 00002876 C3                  <1> 	retn
 12449                              <1> cpd_p_err:
 12450                              <1> 	; release the allocated pages missing (recover free space)
 12451 00002877 58                  <1> 	pop	eax  ; the new page directory address (physical)
 12452 00002878 8B1D[046D0000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 12453 0000287E E88CFCFFFF          <1> 	call 	deallocate_page_dir
 12454 00002883 29C0                <1> 	sub	eax, eax ; 0
 12455 00002885 F9                  <1> 	stc
 12456 00002886 EBE9                <1> 	jmp	short cpd_3	
 12457                              <1> 
 12458                              <1> copy_page_table:
 12459                              <1> 	; 17/04/2021 (temporary modifications)
 12460                              <1> 	; 19/09/2015
 12461                              <1> 	; temporary - 07/09/2015
 12462                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12463                              <1> 	;
 12464                              <1> 	; INPUT -> 
 12465                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 12466                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
 12467                              <1> 	; OUTPUT ->
 12468                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 12469                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 12470                              <1> 	;	CF = 1 -> error 
 12471                              <1> 	;
 12472                              <1> 	; Modified Registers -> EBP (except EAX)
 12473                              <1> 	;
 12474 00002888 E852FBFFFF          <1> 	call	allocate_page
 12475 0000288D 7244                <1> 	jc	short cpt_err
 12476                              <1> 	;
 12477 0000288F 50                  <1> 	push	eax ; *
 12478                              <1> 	;push 	ebx
 12479 00002890 56                  <1> 	push	esi
 12480 00002891 57                  <1> 	push	edi
 12481 00002892 52                  <1> 	push	edx
 12482 00002893 51                  <1> 	push	ecx
 12483                              <1> 	;
 12484 00002894 89DE                <1> 	mov	esi, ebx
 12485 00002896 89C7                <1> 	mov	edi, eax
 12486 00002898 89C2                <1> 	mov	edx, eax
 12487 0000289A 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 12488                              <1> cpt_0:
 12489 000028A0 AD                  <1> 	lodsd
 12490 000028A1 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 = 1
 12491                              <1> 	;jnz	short cpt_1 (*)
 12492                              <1> 	; 17/04/2021 (temporary (*)
 12493                              <1> 	;and	eax, eax (*)
 12494 000028A3 741E                <1> 	jz	short cpt_2  ; 17/04/2021
 12495                              <1> 	
 12496                              <1> ; 17/04/2021
 12497                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12498                              <1> ;
 12499                              <1> ;	; ebp = virtual (linear) address of the memory page
 12500                              <1> ;	call	reload_page ; 28/04/2015
 12501                              <1> ;	jc	short cpt_p_err
 12502                              <1> cpt_1:
 12503 000028A5 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 12504 000028A9 89C1                <1> 	mov	ecx, eax
 12505                              <1> 	; Allocate a new page for the child process
 12506 000028AB E82FFBFFFF          <1> 	call	allocate_page
 12507 000028B0 721C                <1> 	jc	short cpt_p_err
 12508 000028B2 57                  <1> 	push	edi
 12509 000028B3 56                  <1> 	push	esi
 12510 000028B4 89CE                <1> 	mov	esi, ecx
 12511 000028B6 89C7                <1> 	mov	edi, eax
 12512 000028B8 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 12513 000028BD F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 12514 000028BF 5E                  <1> 	pop	esi
 12515 000028C0 5F                  <1> 	pop	edi
 12516                              <1> 	; 
 12517                              <1> ; 17/04/2021
 12518                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)	
 12519                              <1> ;
 12520                              <1> ;	push	ebx
 12521                              <1> ;	push	eax
 12522                              <1> ;	mov	ebx, ebp
 12523                              <1> ;	; ebx = virtual address of the memory page
 12524                              <1> ;	call	add_to_swap_queue
 12525                              <1> ;	pop	eax
 12526                              <1> ;	pop	ebx
 12527                              <1> 	;
 12528                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 12529 000028C1 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 12530                              <1> cpt_2:
 12531 000028C3 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 12532                              <1> 	;
 12533 000028C4 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 12534                              <1> 	;
 12535 000028CA 39D7                <1> 	cmp	edi, edx
 12536 000028CC 72D2                <1> 	jb	short cpt_0
 12537                              <1> cpt_p_err:
 12538 000028CE 59                  <1> 	pop	ecx
 12539 000028CF 5A                  <1> 	pop	edx
 12540 000028D0 5F                  <1> 	pop	edi
 12541 000028D1 5E                  <1> 	pop	esi
 12542                              <1> 	;pop	ebx
 12543 000028D2 58                  <1> 	pop	eax ; *
 12544                              <1> cpt_err:
 12545 000028D3 C3                  <1> 	retn
 12546                              <1> 
 12547                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
 12548                              <1> 
 12549                              <1> ;; Data:
 12550                              <1> 
 12551                              <1> ; 09/03/2015
 12552                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
 12553                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
 12554                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 12555                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 12556                              <1> ;swpd_next:  dd 0 ; next free page block
 12557                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
 12558                                  %include 'sysdefs.s' ; 09/03/2015
 12559                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 12560                              <1> ; (re-write kernel for test by using previous version without a major defect)
 12561                              <1> ; ****************************************************************************
 12562                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.4) - SYSDEFS.INC
 12563                              <1> ; Last Modification: 27/12/2022
 12564                              <1> ;
 12565                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 12566                              <1> ; (Modified from 
 12567                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 12568                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 12569                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
 12570                              <1> ; ----------------------------------------------------------------------------
 12571                              <1> ;
 12572                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12573                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12574                              <1> ; <Bell Laboratories (17/3/1972)>
 12575                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12576                              <1> ;
 12577                              <1> ; ****************************************************************************
 12578                              <1> 
 12579                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 12580                              <1> ; (SB structure has been moved here from 'ux.s' 
 12581                              <1> ;	to overcome NASM's bss addressing bug !!!)
 12582                              <1> ; (('ux.s' bss section addresses are being overlapped
 12583                              <1> ;    when SB structure is defined in 'ux.s'))
 12584                              <1> 
 12585                              <1> struc SB ; SuperBlock
 12586                              <1> 
 12587 00000000 <res 00000004>      <1> .Header:	resd 1
 12588                              <1> ;.HiddenSects:
 12589 00000004 <res 00000004>      <1> .BootSectAddr:	resd 1	; Hidden Sectors
 12590                              <1> ;.TotalSects:
 12591 00000008 <res 00000004>      <1> .VolumeSize:	resd 1	; Entire Volume/Partition Size (includes ext. volume)
 12592 0000000C <res 00000004>      <1> .Version:	resd 1	
 12593 00000010 <res 00000004>      <1> .BlockSize:	resd 1	
 12594 00000014 <res 00000004>      <1> .InodeCount:	resd 1	
 12595 00000018 <res 00000004>      <1> .FreeMapAddr:	resd 1	
 12596 0000001C <res 00000004>      <1> .FreeMapSize:	resd 1	
 12597 00000020 <res 00000004>      <1> .InodeMapAddr:	resd 1	
 12598 00000024 <res 00000004>      <1> .InodeMapSize:	resd 1	
 12599 00000028 <res 00000004>      <1> .InodeTblAddr:	resd 1	
 12600 0000002C <res 00000004>      <1> .InodeTblSize:	resd 1	
 12601 00000030 <res 00000004>      <1> .FreeInodes:	resd 1	
 12602 00000034 <res 00000004>      <1> .FirstFreeIno:	resd 1	
 12603 00000038 <res 00000004>      <1> .FreeBlocks:	resd 1	
 12604 0000003C <res 00000004>      <1> .FirstFreeBlk:	resd 1	
 12605 00000040 <res 00000013>      <1> .BootSecParms:	resb 19	; v1
 12606 00000053 <res 00000005>      <1> .BSExtension:	resb 5	; v2 HDFS
 12607 00000058 <res 00000001>      <1> .Status:	resb 1	; 12/05/2021 (system modification status) (*)
 12608 00000059 <res 00000001>      <1> .Pdrv:		resb 1  ; Physical disk number (index) ; 12/05/2021 (*) 
 12609 0000005A <res 00000002>      <1> .Uno:		resw 1	; user/process number ; 12/05/2021 (*)
 12610 0000005C <res 00000004>      <1> .ModifTime:	resd 1	; (last) modification time (*)
 12611 00000060 <res 00000004>      <1> .ExtdVolTbl:	resd 1	; Extended Volume Start/Table Address
 12612 00000064 <res 00000004>      <1> .ExtdVolSize:	resd 1	; Extended Volume (swap section etc.) Size	
 12613 00000068 <res 00000001>      <1> .LBA_rw:	resb 1
 12614 00000069 <res 00000001>      <1> .ClusterSize:	resb 1
 12615 0000006A <res 00000001>      <1> .ReadOnly:	resb 1	; (SB will not be written to disk if bit 0 is 1)
 12616 0000006B <res 00000001>      <1> .Mounted:	resb 1
 12617 0000006C <res 00000004>      <1> .MountInode:	resd 1  ; double word
 12618 00000070 <res 00000001>      <1> .DevMajor:	resb 1
 12619 00000071 <res 00000001>      <1> .DevMinor:	resb 1
 12620 00000072 <res 00000001>      <1> .LongName:	resb 1
 12621 00000073 <res 00000001>      <1> .Direntry32:	resb 1
 12622                              <1> ; 18/07/2021
 12623 00000074 <res 00000004>      <1> .FileBuffer:	resd 1
 12624 00000078 <res 00000004>      <1> .ItabBuffer:	resd 1
 12625 0000007C <res 00000004>      <1> .ImapBuffer:	resd 1
 12626 00000080 <res 00000004>      <1> .FmapBuffer:	resd 1
 12627                              <1>  ; 15/07/2021
 12628 00000084 <res 00000004>      <1> .LastInode:	resd 1
 12629                              <1> ; 02/05/2021
 12630 00000088 <res 00000004>      <1> .FmapIndex:	resd 1
 12631 0000008C <res 00000004>      <1> .ImapIndex:	resd 1
 12632 00000090 <res 00000004>      <1> .ItableIndex:	resd 1
 12633 00000094 <res 00000168>      <1> .Reserved:	resb 508-148 ; 18/07/2021
 12634 000001FC <res 00000004>      <1> .Footer:	resd 1
 12635                              <1> 
 12636                              <1> endstruc
 12637                              <1> 
 12638                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 12639                              <1> ; (file structure has been moved here from 'ux.s' 
 12640                              <1> ;	to overcome NASM's bss addressing bug !!!)
 12641                              <1> ; (('ux.s' bss section addresses are being overlapped
 12642                              <1> ;    when file structure is defined in 'ux.s'))
 12643                              <1> 
 12644                              <1> ; 22/11/2021
 12645                              <1> ; 21/07/2021 - Retro UNIX 386 v2 open file structure revision
 12646                              <1> 
 12647                              <1> struc file	; open files (fsp) structure
 12648 00000000 <res 00000002>      <1>   .inode:  resw 1  ; inode number of open file (32 bit)
 12649 00000002 <res 00000002>      <1>   .i32:	   resw 1  ; higher word of inode number (reserved)
 12650 00000004 <res 00000001>      <1>   .drive:  resb 1  ; logical drive (disk) number
 12651 00000005 <res 00000001>      <1>   .flags:  resb 1  ; open mode and status
 12652 00000006 <res 00000001>      <1>   .count:  resb 1  ; number of processes that have file open
 12653                              <1>   ;.rsvd:  resb 1  ; reserved byte (for next versions)
 12654 00000007 <res 00000001>      <1>   .mnt:    resb 1  ; mnttab index+1 (0 = not mounted)
 12655 00000008 <res 00000004>      <1>   .offset: resd 1  ; file offset/pointer (64 bit) 
 12656 0000000C <res 00000004>      <1>   .o64:	   resd 1  ; higher 32 bit of file offset
 12657                              <1>  .size:  ; = 16		
 12658                              <1> endstruc 
 12659                              <1> 
 12660                              <1> nproc 	equ	16  ; number of processes
 12661                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
 12662                              <1> ;nbuf	equ	6   ; number of buffers (04/02/2016)
 12663                              <1> nbuf	equ	16  ; number of buffers ; 11/06/2022		
 12664                              <1> nfiles  equ	50  ; NFILES equ 50 ; 02/01/2022
 12665                              <1> 
 12666                              <1> ; 27/12/2021
 12667                              <1> ;NFILES	  equ   32  ; temporary ! ( 27/12/2021)
 12668                              <1> ; 02/01/2022
 12669                              <1> ;OPENFILES equ	10  ; open files (for user) ; 28/03/2020
 12670                              <1> 
 12671                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
 12672                              <1> ;core	equ 	0  	    ; 19/04/2013	
 12673                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
 12674                              <1> 	; (if total size of argument list and arguments is 128 bytes)
 12675                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
 12676                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
 12677                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
 12678                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
 12679                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
 12680                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
 12681                              <1> 	; '/core' dump file size = 32768 bytes
 12682                              <1>  
 12683                              <1> ; 08/03/2014 
 12684                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)
 12685                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
 12686                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
 12687                              <1> 
 12688                              <1> ; 30/08/2013
 12689                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
 12690                              <1> 
 12691                              <1> ; 05/02/2014
 12692                              <1> ; process status
 12693                              <1> ;SFREE 	equ 0
 12694                              <1> ;SRUN	equ 1
 12695                              <1> ;SWAIT	equ 2
 12696                              <1> ;SZOMB	equ 3
 12697                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
 12698                              <1> 
 12699                              <1> ; 09/03/2015
 12700                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
 12701                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
 12702                              <1> swap_alloc_table equ 0D0000h  ; swap allocation table address ; temporary
 12703                              <1> 
 12704                              <1> ; 17/09/2015
 12705                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
 12706                              <1> 
 12707                              <1> ; 27/12/2022 (40)
 12708                              <1> ; 12/01/2022 (37,38,39)
 12709                              <1> ; 21/09/2015 (36) 
 12710                              <1> ; 01/07/2015 (35)
 12711                              <1> ; 14/07/2013 (0-34)
 12712                              <1> ; UNIX v1 system calls
 12713                              <1> _rele 	equ 0
 12714                              <1> _exit 	equ 1
 12715                              <1> _fork 	equ 2
 12716                              <1> _read 	equ 3
 12717                              <1> _write	equ 4
 12718                              <1> _open	equ 5
 12719                              <1> _close 	equ 6
 12720                              <1> _wait 	equ 7
 12721                              <1> _creat 	equ 8
 12722                              <1> _link 	equ 9
 12723                              <1> _unlink	equ 10
 12724                              <1> _exec	equ 11
 12725                              <1> _chdir	equ 12
 12726                              <1> _time 	equ 13
 12727                              <1> _mkdir 	equ 14
 12728                              <1> _chmod	equ 15
 12729                              <1> _chown	equ 16
 12730                              <1> _break	equ 17
 12731                              <1> _stat	equ 18
 12732                              <1> _seek	equ 19
 12733                              <1> _tell 	equ 20
 12734                              <1> _mount	equ 21
 12735                              <1> _umount	equ 22
 12736                              <1> _setuid	equ 23
 12737                              <1> _getuid	equ 24
 12738                              <1> _stime	equ 25
 12739                              <1> _quit	equ 26	
 12740                              <1> _intr	equ 27
 12741                              <1> _fstat	equ 28
 12742                              <1> _emt 	equ 29
 12743                              <1> _mdate 	equ 30
 12744                              <1> _stty 	equ 31
 12745                              <1> _gtty	equ 32
 12746                              <1> _ilgins	equ 33
 12747                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
 12748                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
 12749                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
 12750                              <1> ; 12/01/2022 - Retro UNIX 386 v1.2
 12751                              <1> ; Retro UNIX 386 v2 system calls
 12752                              <1> _setgid	equ 37
 12753                              <1> _getgid	equ 38
 12754                              <1> _ver	equ 39 ; (get) Retro Unix 386 version
 12755                              <1> ; 27/12/2022 - Retro UNIX 386 v1.2
 12756                              <1> _mem	equ 40 ; get available memory
 12757                              <1> 
 12758                              <1> %macro sys 1-4
 12759                              <1>     ; 03/09/2015
 12760                              <1>     ; 13/04/2015
 12761                              <1>     ; Retro UNIX 386 v1 system call.
 12762                              <1>     %if %0 >= 2   
 12763                              <1>         mov ebx, %2
 12764                              <1>         %if %0 >= 3
 12765                              <1>             mov ecx, %3
 12766                              <1>             %if %0 = 4
 12767                              <1>                mov edx, %4
 12768                              <1>             %endif
 12769                              <1>         %endif
 12770                              <1>     %endif
 12771                              <1>     mov eax, %1
 12772                              <1>     int 30h
 12773                              <1> %endmacro
 12774                              <1> 
 12775                              <1> ; 13/05/2015 - ERROR CODES
 12776                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
 12777                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
 12778                              <1> ; 14/05/2015
 12779                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
 12780                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
 12781                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
 12782                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error
 12783                              <1> ; 16/05/2015		
 12784                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
 12785                              <1> ; 18/05/2015
 12786                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
 12787                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
 12788                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
 12789                              <1> ; 07/06/2015
 12790                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
 12791                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
 12792                              <1> ; 09/06/2015
 12793                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
 12794                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
 12795                              <1> ; 16/06/2015
 12796                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
 12797                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
 12798                              <1> ; 22/06/2015
 12799                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
 12800                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
 12801                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
 12802                              <1> ; 23/06/2015
 12803                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
 12804                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
 12805                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
 12806                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
 12807                              <1> ; 27/06/2015
 12808                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
 12809                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
 12810                              <1> ; 29/06/2015
 12811                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error
 12812                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error
 12813                              <1> ; 08/02/2022 
 12814                              <1> ; (error numbers from TRDOS 386 v2.0 'sysdefs.s')
 12815                              <1> ; 10/10/2016
 12816                              <1> ERR_INV_FILE_NAME  equ 26 ; 'invalid file name !' error
 12817                              <1> ; 18/05/2016
 12818                              <1> ERR_MISC	   equ 27 ; miscellaneous/other errors
 12819                              <1> ; 15/10/2016
 12820                              <1> ERR_INV_FORMAT	   equ 28 ; 'invalid format !' error
 12821                              <1> ERR_INV_DATA	   equ 29 ; 'invalid data !' error
 12822                              <1> ; 16/10/2016
 12823                              <1> ERR_DISK_WRITE	   equ 30 ; 'disk write protected !'
 12824                              <1> ; 08/02/2022
 12825                              <1> ERR_INV_FS	   equ 28 ;'invalid fs/superblock !' error
 12826                              <1> 
 12827                              <1> ; 12/06/2022
 12828                              <1> ; printer errors
 12829                              <1> ERR_PRN_NOT_RDY	   equ 15 ; 'device not ready !' error
 12830                              <1> ERR_PRN_TIMEOUT	   equ 25 ; 'time out !' error
 12831                              <1> ERR_PRN_PAPER	   equ 31 ; 'out of paper !' error
 12832                              <1> ERR_PRN_IO	   equ 32 ; 'io error !' error
 12833                              <1> ERR_PRN_BUSY	   equ 34 ; 'busy !' error
 12834                              <1> 
 12835                              <1> ; 26/08/2015
 12836                              <1> ; 24/07/2015
 12837                              <1> ; 24/06/2015
 12838                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
 12839                              <1> ; 01/07/2015
 12840                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
 12841                              <1> ;
 12842                              <1> ; 26/11/2021 ('no free blocks on disk !' error)
 12843                              <1> ERR_ALLOC	   equ 33  ; 'disk allocation error !'	
 12844                              <1> ; 22/11/2021
 12845                              <1> ERR_READ_ONLY_FS   equ 30  ; 'read only file system !' error
 12846                              <1> ; 28/11/2021
 12847                              <1> ERR_INV_FILE	   equ 255 ; 'invalid file (inode) !' error
 12848                              <1> ; 04/12/2021
 12849                              <1> ERR_PERM_DENIED	   equ 11  ; 'permission denied !' error
 12850                              <1> ; 11/12/2021
 12851                              <1> ERR_INV_FUNC	   equ 1   ; 'invalid system call !' error
 12852                              <1> ; 10/01/2022
 12853                              <1> ERR_INO_ALLOC	   equ 33  ; 'inode allocation error !'
 12854                              <1> ERR_NOT_REGULAR    equ 255 ; 'not regular file directory !' error
 12855                              <1> 
 12856                              <1> ; 12/01/2022 - Retro UNIX 386 v1.2
 12857                              <1> %define s.time systm+504 ; boot/sysinit time (or current time)
 12858                              <1> 		
 12859                                  %include 'u0.s'      ; 15/03/2015
 12860                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 12861                              <1> ; (re-write kernel for test by using previous version without a major defect)
 12862                              <1> ; ****************************************************************************
 12863                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS0.INC
 12864                              <1> ; Last Modification: 17/07/2022
 12865                              <1> ; ----------------------------------------------------------------------------
 12866                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 12867                              <1> ; (v0.1 - Beginning: 11/07/2012)
 12868                              <1> ;
 12869                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12870                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12871                              <1> ; <Bell Laboratories (17/3/1972)>
 12872                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12873                              <1> ;
 12874                              <1> ; Retro UNIX 8086 v1 - U0.ASM (28/07/2014) //// UNIX v1 -> u0.s
 12875                              <1> ;
 12876                              <1> ; ****************************************************************************
 12877                              <1> 
 12878                              <1> sys_init:
 12879                              <1> 	; 23/02/2022
 12880                              <1> 	; 08/01/2022
 12881                              <1> 	; 01/01/2022
 12882                              <1> 	; 26/12/2021
 12883                              <1> 	; 27/11/2021
 12884                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 (test) compatibility modification
 12885                              <1> 	; 18/10/2015
 12886                              <1> 	; 28/08/2015
 12887                              <1> 	; 24/08/2015
 12888                              <1> 	; 14/08/2015
 12889                              <1> 	; 24/07/2015 
 12890                              <1> 	; 02/07/2015
 12891                              <1> 	; 01/07/2015
 12892                              <1> 	; 23/06/2015
 12893                              <1> 	; 15/04/2015
 12894                              <1> 	; 13/04/2015
 12895                              <1> 	; 11/03/2015 (Retro UNIX 386 v1 - Beginning)
 12896                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 12897                              <1> 	;
 12898                              <1> 	;call	ldrv_init ; Logical drive description tables initialization
 12899                              <1> 	;
 12900                              <1> 	;; 14/02/2014
 12901                              <1> 	;; 14/07/2013
 12902                              <1> 	;mov	ax, 41
 12903                              <1> 	;mov	[rootdir], ax
 12904                              <1> 	;mov	[u.cdir], ax
 12905                              <1> 	;and	al, 1 ; 15/04/2015
 12906                              <1> 	
 12907                              <1> 	; 27/11/2021
 12908                              <1> 	; 18/04/2021 - Retro UNIX 386 v2
 12909 000028D4 31C0                <1> 	xor	eax, eax
 12910 000028D6 FEC0                <1> 	inc	al	; eax = 1 (root directory inode) ; runix v2 fs
 12911 000028D8 A3[866C0000]        <1> 	mov	[rootdir], eax ; = 1 ; 28/10/2021 (32 bit)
 12912 000028DD A3[A86C0000]        <1> 	mov	[u.cdir], eax ; 28/10/2021 (32 bit)
 12913                              <1> 
 12914 000028E2 A2[F56C0000]        <1> 	mov	[u.uno], al ; = 1
 12915                              <1> 	;mov	[mpid], ax ; 1 
 12916                              <1> 	;mov	[p.pid], ax ; 1
 12917                              <1> 	; 01/01/2022
 12918 000028E7 A2[846C0000]        <1> 	mov	[mpid], al
 12919 000028EC A2[64680000]        <1> 	mov	[p.pid], al
 12920 000028F1 A2[C4680000]        <1> 	mov	[p.stat], al ; SRUN, 05/02/2014
 12921                              <1> 	;
 12922 000028F6 B004                <1> 	mov	al, time_count ; 30/08/2013
 12923 000028F8 A2[EC6C0000]        <1> 	mov	[u.quant], al ; 14/07/2013
 12924                              <1> 	; 02/07/2015
 12925 000028FD A1[68670000]        <1> 	mov	eax, [k_page_dir]
 12926 00002902 A3[046D0000]        <1> 	mov	[u.pgdir], eax ; reset
 12927                              <1> 	; 18/10/2015
 12928                              <1> 	;sub	eax, eax
 12929                              <1> 	;mov	[u.ppgdir], eax ; 0
 12930                              <1>         ;
 12931                              <1>  	; 23/02/2022
 12932                              <1>  	;call	epoch
 12933                              <1> 	;mov	[s.time], eax ; 13/03/2015
 12934                              <1> 	; 17/07/2013
 12935 00002907 E881060000          <1> 	call 	bf_init ; buffer initialization
 12936                              <1> 	; 23/02/2022
 12937                              <1> 	; (save sysinit time on sb0)
 12938 0000290C E829030000          <1> 	call	epoch
 12939 00002911 A3[4C6F0000]        <1> 	mov	[s.time], eax ; 13/03/2015
 12940                              <1> 	; 23/06/2015
 12941 00002916 E8C4FAFFFF          <1> 	call	allocate_page
 12942                              <1> 	;;jc	error
 12943                              <1> 	;jc	panic   ; jc short panic (01/07/2015)
 12944                              <1> 	; 05/12/2021
 12945 0000291B 7305                <1> 	jnc	short sysinit_1
 12946 0000291D E989000000          <1> 	jmp	panic
 12947                              <1> sysinit_1:
 12948 00002922 A3[006D0000]        <1> 	mov	[u.upage], eax ; user structure page	
 12949 00002927 A3[D4680000]        <1> 	mov	[p.upage], eax
 12950                              <1> 	;
 12951 0000292C E81FFBFFFF          <1> 	call	clear_page
 12952                              <1> 	;
 12953                              <1> 	; 14/08/2015
 12954 00002931 FA                  <1> 	cli
 12955                              <1> 	; 14/03/2015
 12956                              <1> 	; 17/01/2014
 12957 00002932 E8D0010000          <1> 	call	sp_init ; serial port initialization
 12958                              <1> 	; 14/08/2015
 12959 00002937 FB                  <1> 	sti
 12960                              <1> 	;
 12961                              <1> 	; 30/06/2015
 12962                              <1> 	;mov	esi, kernel_init_ok_msg
 12963                              <1> 	;call 	print_msg
 12964                              <1> 	;
 12965 00002938 30DB                <1> 	xor	bl, bl ; video page 0
 12966                              <1> vp_clr_nxt:  ; clear video pages (reset cursor positions)
 12967 0000293A E8D2330000          <1> 	call 	vp_clr  ; 17/07/2013
 12968 0000293F FEC3                <1> 	inc	bl
 12969 00002941 80FB08              <1> 	cmp	bl, 8
 12970 00002944 72F4                <1> 	jb	short vp_clr_nxt
 12971                              <1> 	;
 12972                              <1> 	; 24/07/2015
 12973                              <1> 	;push	KDATA
 12974                              <1>         ;push	esp
 12975                              <1> 	;mov	[tss.esp0], esp
 12976                              <1>         ;mov	word [tss.ss0], KDATA
 12977                              <1> 	;
 12978                              <1> 	; 08/01/2022
 12979                              <1> 	; 24/08/2015
 12980                              <1> 	;; temporary (01/07/2015)
 12981                              <1> 	;mov	byte [u.quant], time_count ; 4 
 12982                              <1> 	;		       ; it is not needed here !
 12983                              <1> 	;;inc	byte [u.kcall] ; 'the caller is kernel' sign
 12984 00002946 FE0D[986C0000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
 12985                              <1> 			      ; 0 = executing a system call
 12986                              <1> 	;;sys 	_msg, kernel_init_ok_msg, 255, 0
 12987                              <1> 	;
 12988                              <1> 	;;; 06/08/2015
 12989                              <1> 	;;;call	getch ; wait for a key stroke
 12990                              <1> 	;;mov 	ecx, 0FFFFFFFh	
 12991                              <1> ;;sys_init_msg_wait:
 12992                              <1> ;;	push 	ecx
 12993                              <1> ;;	mov	al, 1
 12994                              <1> ;;	mov 	ah, [ptty] ; active (current) video page
 12995                              <1> ;;	call	getc_n
 12996                              <1> ;;	pop	ecx
 12997                              <1> ;;	jnz	short sys_init_msg_ok
 12998                              <1> ;;	loop	sys_init_msg_wait
 12999                              <1> 	;
 13000                              <1> ;;sys_init_msg_ok:
 13001                              <1> 	; 28/08/2015 (initial settings for the 1st 'rswap')
 13002 0000294C 6A10                <1> 	push	KDATA ; ss
 13003 0000294E 54                  <1> 	push	esp
 13004 0000294F 9C                  <1> 	pushfd
 13005 00002950 6A08                <1> 	push	KCODE ; cs
 13006 00002952 68[7F290000]        <1> 	push	init_exec ; eip
 13007 00002957 8925[9C6C0000]      <1> 	mov	[u.sp], esp
 13008 0000295D 1E                  <1> 	push	ds
 13009 0000295E 06                  <1> 	push	es
 13010 0000295F 0FA0                <1> 	push	fs
 13011 00002961 0FA8                <1> 	push	gs	
 13012 00002963 60                  <1> 	pushad
 13013 00002964 8925[A06C0000]      <1> 	mov	[u.usp], esp
 13014 0000296A E8091D0000          <1> 	call	wswap ; save current user (u) structure, user registers
 13015                              <1> 		      ; and interrupt return components (for IRET)
 13016 0000296F 61                  <1> 	popad
 13017 00002970 6658                <1> 	pop	ax ; gs
 13018 00002972 6658                <1> 	pop	ax ; fs
 13019 00002974 6658                <1> 	pop	ax ; es
 13020 00002976 6658                <1> 	pop	ax ; ds	
 13021 00002978 58                  <1> 	pop	eax ; eip (init_exec)
 13022 00002979 6658                <1> 	pop	ax ; cs (KCODE)
 13023 0000297B 58                  <1> 	pop	eax ; E-FLAGS
 13024 0000297C 58                  <1> 	pop	eax ; esp
 13025 0000297D 6658                <1> 	pop	ax ; ss (KDATA)
 13026                              <1> 	;
 13027                              <1> 	; 26/12/2021 ([u.ppgdir] is zero already)
 13028                              <1> 	;xor	eax, eax ; 0
 13029                              <1> 	;mov	[u.ppgdir], eax ; reset (to zero) for '/etc/init'
 13030                              <1> 	;
 13031                              <1> 	; 02/07/2015
 13032                              <1> 	; [u.pgdir ] = [k_page_dir]
 13033                              <1> 	; [u.ppgdir] = 0 (page dir of the parent process)
 13034                              <1> 	;     (The caller is os kernel sign for 'sysexec')
 13035                              <1> init_exec:
 13036                              <1> 	; 13/03/2013
 13037                              <1> 	; 24/07/2013
 13038 0000297F BB[A1290000]        <1> 	mov	ebx, init_file
 13039 00002984 B9[99290000]        <1> 	mov	ecx, init_argp
 13040                              <1> 	; EBX contains 'etc/init' asciiz file name address  
 13041                              <1> 	; ECX contains address of argument list pointer
 13042                              <1> 	;
 13043                              <1> 	;dec 	byte [sysflg] ; FFh = ready for system call
 13044                              <1> 			      ; 0 = executing a system call
 13045                              <1> 	sys	_exec  ; execute file
 13046                              <2> 
 13047                              <2> 
 13048                              <2> 
 13049                              <2>  %if %0 >= 2
 13050                              <2>  mov ebx, %2
 13051                              <2>  %if %0 >= 3
 13052                              <2>  mov ecx, %3
 13053                              <2>  %if %0 = 4
 13054                              <2>  mov edx, %4
 13055                              <2>  %endif
 13056                              <2>  %endif
 13057                              <2>  %endif
 13058 00002989 B80B000000          <2>  mov eax, %1
 13059 0000298E CD30                <2>  int 30h
 13060 00002990 7319                <1> 	jnc	short panic
 13061                              <1> 	;
 13062 00002992 BE[80640000]        <1> 	mov	esi, etc_init_err_msg
 13063                              <1> 	; 22/11/2021
 13064                              <1> 	;call 	print_msg
 13065 00002997 EB17                <1> 	jmp	short key_to_reboot
 13066                              <1> 
 13067                              <1> ;align 4
 13068                              <1> init_argp:
 13069 00002999 [A1290000]00000000  <1> 	dd 	init_file, 0  ; 23/06/2015 (dw -> dd)
 13070                              <1> init_file:
 13071                              <1> 	; 24/08/2015
 13072 000029A1 2F6574632F696E6974- <1> 	db 	'/etc/init', 0
 13073 000029AA 00                  <1>
 13074                              <1> panic:
 13075                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13076                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13077 000029AB BE[65640000]        <1> 	mov 	esi, panic_msg
 13078                              <1> key_to_reboot: ; 22/11/2021
 13079 000029B0 E819000000          <1> 	call 	print_msg
 13080                              <1> ;key_to_reboot:
 13081                              <1> 	; 15/11/2015
 13082 000029B5 E8A5310000          <1> 	call 	getch 
 13083                              <1> 		; wait for a character from the current tty
 13084                              <1> 	;
 13085 000029BA B00A                <1> 	mov	al, 0Ah
 13086 000029BC 8A1D[96670000]      <1> 	mov	bl, [ptty] ; [active_page]
 13087 000029C2 B407                <1> 	mov	ah, 07h ; Black background, 
 13088                              <1> 			; light gray forecolor
 13089 000029C4 E8EBE8FFFF          <1> 	call 	write_tty
 13090 000029C9 E98AE5FFFF          <1> 	jmp	cpu_reset 
 13091                              <1> 
 13092                              <1> print_msg:
 13093                              <1> 	; 01/07/2015
 13094                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13095                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13096                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
 13097                              <1> 	;
 13098                              <1> 	;
 13099 000029CE AC                  <1> 	lodsb
 13100                              <1> pmsg1:
 13101 000029CF 56                  <1> 	push 	esi
 13102 000029D0 0FB61D[96670000]    <1> 	movzx	ebx, byte [ptty]
 13103 000029D7 B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
 13104 000029D9 E8D6E8FFFF          <1> 	call 	write_tty
 13105 000029DE 5E                  <1> 	pop	esi
 13106 000029DF AC                  <1> 	lodsb
 13107 000029E0 20C0                <1> 	and 	al, al
 13108 000029E2 75EB                <1> 	jnz 	short pmsg1
 13109 000029E4 C3                  <1> 	retn
 13110                              <1> 	
 13111                              <1> ctrlbrk:
 13112                              <1> 	; 06/02/2022
 13113                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 13114                              <1> 	; 12/11/2015
 13115                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13116                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
 13117                              <1> 	;
 13118                              <1> 	; INT 1Bh (control+break) handler		
 13119                              <1> 	;
 13120                              <1>       	; Retro Unix 8086 v1 feature only!
 13121                              <1>       	;
 13122 000029E5 66833D[F06C0000]00  <1> 	cmp 	word [u.intr], 0
 13123 000029ED 764B                <1> 	jna 	short cbrk4
 13124                              <1> cbrk0:
 13125                              <1> 	; 12/11/2015
 13126                              <1> 	; 06/12/2013
 13127 000029EF 66833D[F26C0000]00  <1> 	cmp 	word [u.quit], 0
 13128 000029F7 7441                <1> 	jz	short cbrk4
 13129                              <1> 	;
 13130                              <1> 	; 20/09/2013	
 13131                              <1> 	;push 	ax
 13132                              <1> 	; 04/12/2021
 13133 000029F9 50                  <1> 	push	eax
 13134                              <1> 
 13135                              <1> 	; 06/02/2022
 13136                              <1> 	; (repetitive ctrl+brk check) 
 13137 000029FA 66A1[F26C0000]      <1> 	mov	ax, [u.quit]
 13138 00002A00 6640                <1> 	inc	ax ; 0FFFFh -> 0
 13139 00002A02 7435                <1> 	jz	short cbrk3
 13140                              <1> 
 13141                              <1> 	; 06/12/2013
 13142 00002A04 A0[96670000]        <1> 	mov	al, [ptty]
 13143                              <1> 	;
 13144                              <1> 	; 12/11/2015
 13145                              <1> 	;
 13146                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
 13147                              <1> 	; or ctrl+break from console (pseudo) tty
 13148                              <1> 	; (!redirection!)
 13149                              <1> 	;
 13150 00002A09 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
 13151 00002A0B 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
 13152                              <1> 	;	
 13153                              <1> 	; Serial port interrupt handler sets [ptty]
 13154                              <1> 	; to the port's tty number (as temporary).
 13155                              <1> 	;
 13156                              <1> 	; If active process is using a stdin or 
 13157                              <1> 	; stdout redirection (by the shell),
 13158                              <1>         ; console tty keyboard must be available
 13159                              <1> 	; to terminate running process,
 13160                              <1> 	; in order to prevent a deadlock. 
 13161                              <1> 	;
 13162 00002A0D 52                  <1> 	push	edx
 13163 00002A0E 0FB615[F56C0000]    <1> 	movzx	edx, byte [u.uno]
 13164 00002A15 3A82[A3680000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
 13165 00002A1B 5A                  <1> 	pop	edx
 13166 00002A1C 7412                <1> 	je	short cbrk2
 13167                              <1> cbrk1:
 13168 00002A1E FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
 13169                              <1> 	; 06/12/2013
 13170 00002A20 3A05[DA6C0000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
 13171 00002A26 7408                <1> 	je	short cbrk2	
 13172 00002A28 3A05[DB6C0000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
 13173 00002A2E 7509                <1> 	jne	short cbrk3	
 13174                              <1> cbrk2:
 13175                              <1> 	;; 06/12/2013
 13176                              <1> 	;mov	ax, [u.quit]
 13177                              <1> 	;and	ax, ax
 13178                              <1> 	;jz	short cbrk3
 13179                              <1> 	;
 13180                              <1> 	;xor	ax, ax ; 0
 13181                              <1> 	;dec	ax
 13182                              <1> 	; 04/12/2021
 13183 00002A30 31C0                <1> 	xor	eax, eax ; 0
 13184 00002A32 48                  <1> 	dec	eax ; 0FFFFFFFFh
 13185                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
 13186 00002A33 66A3[F26C0000]      <1> 	mov	[u.quit], ax
 13187                              <1> cbrk3:
 13188                              <1> 	;pop	ax
 13189                              <1> 	; 04/12/2021
 13190 00002A39 58                  <1> 	pop	eax
 13191                              <1> cbrk4:
 13192 00002A3A C3                  <1> 	retn
 13193                              <1> 
 13194                              <1> com2_int:
 13195                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 13196                              <1> 	; 07/11/2015 
 13197                              <1> 	; 24/10/2015
 13198                              <1> 	; 23/10/2015
 13199                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13200                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13201                              <1> 	; < serial port 2 interrupt handler >
 13202                              <1> 	;
 13203 00002A3B 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13204                              <1> 	;;push	eax
 13205                              <1> 	; 08/01/2022
 13206 00002A3E 29C0                <1> 	sub	eax, eax
 13207 00002A40 B009                <1> 	mov	al, 9
 13208                              <1> 	;mov	ax, 9
 13209 00002A42 EB07                <1> 	jmp	short comm_int
 13210                              <1> com1_int:
 13211                              <1> 	; 07/11/2015
 13212                              <1> 	; 24/10/2015
 13213 00002A44 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13214                              <1> 	; 23/10/2015
 13215                              <1> 	;push	eax
 13216                              <1> 	; 08/01/2022
 13217 00002A47 29C0                <1> 	sub	eax, eax
 13218 00002A49 B008                <1> 	mov	al, 8
 13219                              <1> 	;mov	ax, 8
 13220                              <1> comm_int:
 13221                              <1> 	; 08/01/2022
 13222                              <1> 	; 20/11/2015
 13223                              <1> 	; 18/11/2015
 13224                              <1> 	; 17/11/2015
 13225                              <1> 	; 16/11/2015
 13226                              <1> 	; 09/11/2015
 13227                              <1> 	; 08/11/2015
 13228                              <1> 	; 07/11/2015
 13229                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
 13230                              <1> 	; 01/11/2015
 13231                              <1> 	; 26/10/2015
 13232                              <1> 	; 23/10/2015
 13233 00002A4B 53                  <1> 	push	ebx
 13234 00002A4C 56                  <1> 	push	esi
 13235 00002A4D 57                  <1> 	push	edi
 13236 00002A4E 1E                  <1> 	push 	ds
 13237 00002A4F 06                  <1> 	push 	es
 13238                              <1> 	; 18/11/2015
 13239 00002A50 0F20DB              <1> 	mov	ebx, cr3
 13240 00002A53 53                  <1> 	push	ebx ; ****
 13241                              <1> 	;
 13242 00002A54 51                  <1> 	push	ecx ; ***
 13243 00002A55 52                  <1> 	push	edx ; **
 13244                              <1> 	;
 13245 00002A56 BB10000000          <1> 	mov	ebx, KDATA
 13246 00002A5B 8EDB                <1> 	mov	ds, bx
 13247 00002A5D 8EC3                <1> 	mov	es, bx
 13248                              <1> 	;
 13249 00002A5F 8B0D[68670000]      <1> 	mov	ecx, [k_page_dir]
 13250 00002A65 0F22D9              <1> 	mov	cr3, ecx
 13251                              <1> 	; 20/11/2015
 13252                              <1> 	; Interrupt identification register
 13253 00002A68 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
 13254                              <1> 	;
 13255 00002A6C 3C08                <1> 	cmp 	al, 8 
 13256 00002A6E 7702                <1> 	ja 	short com_i0
 13257                              <1> 	;
 13258                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.1)
 13259                              <1> 	; 20/11/2015
 13260                              <1> 	; 17/11/2015
 13261                              <1> 	; 16/11/2015
 13262                              <1> 	; 15/11/2015
 13263                              <1> 	; 24/10/2015
 13264                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13265                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13266                              <1> 	; < serial port 1 interrupt handler >
 13267                              <1> 	;
 13268 00002A70 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
 13269                              <1> com_i0:
 13270                              <1> 	;push	eax ; *
 13271                              <1> 	; 07/11/2015
 13272 00002A72 A2[D6670000]        <1> 	mov 	byte [ccomport], al
 13273                              <1> 	; 09/11/2015
 13274                              <1> 	;movzx	ebx, ax ; 8 or 9
 13275                              <1> 	; 08/01/2022
 13276 00002A77 89C3                <1> 	mov	ebx, eax ; 8 or 9
 13277                              <1> 	; 17/11/2015
 13278                              <1>  	; reset request for response status
 13279 00002A79 88A3[CC670000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
 13280                              <1> 	;
 13281                              <1> 	; 20/11/2015
 13282 00002A7F EC                  <1> 	in	al, dx		; read interrupt id. register
 13283 00002A80 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13284 00002A82 2404                <1> 	and	al, 4		; received data available?	
 13285 00002A84 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
 13286                              <1> 	;
 13287                              <1> 	; 20/11/2015
 13288 00002A86 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
 13289 00002A89 EC                  <1> 	in	al, dx     	; read character
 13290                              <1> 	;JMP	$+2	   	; I/O DELAY
 13291                              <1> 	; 08/11/2015
 13292                              <1> 	; 07/11/2015
 13293 00002A8A 89DE                <1> 	mov	esi, ebx 
 13294 00002A8C 89DF                <1> 	mov	edi, ebx
 13295 00002A8E 81C6[D0670000]      <1> 	add 	esi, rchar - 8 ; points to last received char
 13296 00002A94 81C7[D2670000]      <1> 	add	edi, schar - 8 ; points to last sent char
 13297 00002A9A 8806                <1> 	mov	[esi], al ; received char (current char)
 13298                              <1> 	; query
 13299 00002A9C 20C0                <1> 	and	al, al
 13300 00002A9E 7527                <1> 	jnz	short com_i2
 13301                              <1>    	; response
 13302                              <1> 	; 17/11/2015
 13303                              <1> 	; set request for response status
 13304 00002AA0 FE83[CC670000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
 13305                              <1> 	;
 13306 00002AA6 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
 13307 00002AAA EC                  <1> 	in	al, dx	   	; read line status register 
 13308 00002AAB EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13309 00002AAD 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
 13310 00002AAF 7445                <1> 	jz	short com_eoi 	; no
 13311 00002AB1 B0FF                <1> 	mov 	al, 0FFh   	; response			
 13312 00002AB3 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
 13313 00002AB7 EE                  <1> 	out	dx, al	   	; send on serial port
 13314                              <1> 	; 17/11/2015
 13315 00002AB8 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
 13316 00002ABB 7502                <1> 	jne 	short com_i1    ; no
 13317 00002ABD 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
 13318                              <1> com_i1:
 13319                              <1> 	; 17/11/2015
 13320                              <1> 	; reset request for response status (again)
 13321 00002ABF FE8B[CC670000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
 13322 00002AC5 EB2F                <1> 	jmp	short com_eoi
 13323                              <1> com_i2:	
 13324                              <1> 	; 08/11/2015
 13325 00002AC7 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
 13326 00002AC9 7417                <1> 	je	short com_i3	; (check for response signal)
 13327                              <1> 	; 07/11/2015
 13328 00002ACB 3C04                <1> 	cmp	al, 04h	; EOT
 13329 00002ACD 751C                <1> 	jne	short com_i4	
 13330                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
 13331                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
 13332                              <1> 	; 08/11/2015
 13333                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
 13334 00002ACF 861D[96670000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
 13335 00002AD5 E80BFFFFFF          <1> 	call 	ctrlbrk
 13336 00002ADA 861D[96670000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
 13337                              <1> 	;mov	al, 04h ; EOT
 13338                              <1> 	; 08/11/2015
 13339 00002AE0 EB09                <1> 	jmp	short com_i4	
 13340                              <1> com_i3:
 13341                              <1> 	; 08/11/2015
 13342                              <1> 	; If 0FFh has been received just after a query
 13343                              <1> 	; (schar, ZERO), it is a response signal.
 13344                              <1> 	; 17/11/2015
 13345 00002AE2 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
 13346 00002AE5 7704                <1> 	ja	short com_i4 ; no
 13347                              <1> 	; reset query status (schar)
 13348 00002AE7 8807                <1> 	mov	[edi], al ; 0FFh
 13349 00002AE9 FEC0                <1> 	inc	al ; 0
 13350                              <1> com_i4:
 13351                              <1> 	; 27/07/2014
 13352                              <1> 	; 09/07/2014
 13353 00002AEB D0E3                <1> 	shl	bl, 1	
 13354 00002AED 81C3[98670000]      <1> 	add	ebx, ttychr
 13355                              <1> 	; 23/07/2014 (always overwrite)
 13356                              <1> 	;;cmp	word [ebx], 0
 13357                              <1> 	;;ja	short com_eoi
 13358                              <1> 	;
 13359 00002AF3 668903              <1> 	mov	[ebx], ax   ; Save ascii code
 13360                              <1> 			    ; scan code = 0
 13361                              <1> com_eoi:
 13362                              <1> 	;mov	al, 20h
 13363                              <1> 	;out	20h, al	   ; end of interrupt
 13364                              <1> 	;
 13365                              <1> 	; 07/11/2015
 13366                              <1>       	;pop	eax ; *
 13367 00002AF6 A0[D6670000]        <1> 	mov	al, byte [ccomport] ; current COM port
 13368                              <1> 	; al = tty number (8 or 9)
 13369 00002AFB E8521C0000          <1>         call	wakeup
 13370                              <1> com_iret:
 13371                              <1> 	; 23/10/2015
 13372 00002B00 5A                  <1> 	pop	edx ; **
 13373 00002B01 59                  <1> 	pop	ecx ; ***
 13374                              <1> 	; 18/11/2015
 13375                              <1> 	;pop	eax ; ****
 13376                              <1> 	;mov	cr3, eax
 13377                              <1> 	;jmp	iiret
 13378 00002B02 E995DEFFFF          <1> 	jmp	iiretp
 13379                              <1> 
 13380                              <1> ;iiretp: ; 01/09/2015
 13381                              <1> ;	; 28/08/2015
 13382                              <1> ;	pop	eax ; (*) page directory
 13383                              <1> ;	mov	cr3, eax
 13384                              <1> ;iiret:
 13385                              <1> ;	; 22/08/2014
 13386                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
 13387                              <1> ;	out	20h, al	; 8259 PORT
 13388                              <1> ;	;
 13389                              <1> ;	pop	es
 13390                              <1> ;	pop	ds
 13391                              <1> ;	pop	edi
 13392                              <1> ;	pop	esi
 13393                              <1> ;	pop	ebx ; 29/08/2014
 13394                              <1> ;	pop 	eax
 13395                              <1> ;	iretd
 13396                              <1> 
 13397                              <1> sp_init:
 13398                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 13399                              <1> 	; 07/11/2015
 13400                              <1> 	; 29/10/2015
 13401                              <1> 	; 26/10/2015
 13402                              <1> 	; 23/10/2015
 13403                              <1> 	; 29/06/2015
 13404                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
 13405                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
 13406                              <1> 	; Initialization of Serial Port Communication Parameters
 13407                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13408                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13409                              <1> 	;
 13410                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13411                              <1> 	;
 13412                              <1> 	; INPUT:  (29/06/2015)
 13413                              <1> 	;	AL = 0 for COM1
 13414                              <1> 	;	     1 for COM2
 13415                              <1> 	;	AH = Communication parameters	
 13416                              <1> 	;
 13417                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13418                              <1> 	;	Bit	4	3	2	1	0
 13419                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13420                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13421                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13422                              <1> 	;		11 = even
 13423                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13424                              <1> 	;		Retro UNIX 386 v1 feature only !
 13425                              <1> 	;	Bit	7    6    5  | Baud rate
 13426                              <1> 	;		------------------------
 13427                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13428                              <1> 	;		0    0    1  | 9600 (12)
 13429                              <1> 	;		0    1    0  | 19200 (6) 
 13430                              <1> 	;		0    1	  1  | 38400 (3) 
 13431                              <1> 	;		1    0	  0  | 14400 (8)
 13432                              <1> 	;		1    0	  1  | 28800 (4)
 13433                              <1> 	;		1    1    0  | 57600 (2)
 13434                              <1> 	;		1    1    1  | 115200 (1) 	
 13435                              <1> 	
 13436                              <1> 	; References:	
 13437                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
 13438                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
 13439                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
 13440                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
 13441                              <1> 	;
 13442                              <1> 	; Set communication parameters for COM1 (= 03h)	
 13443                              <1> 	;
 13444 00002B07 BB[D2670000]        <1> 	mov	ebx, com1p		; COM1 parameters  
 13445 00002B0C 66BAF803            <1> 	mov	dx, 3F8h		; COM1
 13446                              <1> 	; 29/10/2015
 13447 00002B10 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13448 00002B14 E84F000000          <1> 	call	sp_i3	; call A4	
 13449 00002B19 A880                <1> 	test	al, 80h
 13450 00002B1B 740E                <1> 	jz	short sp_i0 ; OK..
 13451                              <1> 		; Error !
 13452                              <1> 	;mov	dx, 3F8h
 13453 00002B1D 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
 13454                              <1> 	;mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13455                              <1> 	; 08/01/2022
 13456 00002B20 B10E                <1> 	mov	cl, 0Eh ; cx = 30Eh, divisor = 12 (9600 baud)
 13457 00002B22 E841000000          <1> 	call	sp_i3	; call A4	
 13458 00002B27 A880                <1> 	test	al, 80h
 13459 00002B29 7508                <1> 	jnz	short sp_i1
 13460                              <1> sp_i0:
 13461                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
 13462                              <1>         ; (INT 14h initialization code disables interrupts.)
 13463                              <1> 	;
 13464 00002B2B C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13465 00002B2E E8BF000000          <1> 	call	sp_i5 ; 29/06/2015
 13466                              <1> sp_i1:
 13467 00002B33 43                  <1> 	inc	ebx
 13468 00002B34 66BAF802            <1> 	mov	dx, 2F8h		; COM2
 13469                              <1> 	; 29/10/2015
 13470                              <1> 	;mov	cx, 301h  ; divisor = 1 (115200 baud)
 13471                              <1> 	; 08/01/2022
 13472 00002B38 B101                <1> 	mov	cl, 01h ; cx = 301h, divisor = 1 (115200 baud)
 13473 00002B3A E829000000          <1> 	call	sp_i3	; call A4	
 13474 00002B3F A880                <1> 	test	al, 80h
 13475 00002B41 740E                <1> 	jz	short sp_i2 ; OK..
 13476                              <1> 		; Error !
 13477                              <1> 	;mov	dx, 2F8h
 13478 00002B43 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
 13479                              <1> 	;mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13480                              <1> 	; 08/01/2022
 13481 00002B46 B10E                <1> 	mov	cl, 0Eh ; cx = 30Eh, divisor = 12 (9600 baud)
 13482 00002B48 E81B000000          <1> 	call	sp_i3	; call A4	
 13483 00002B4D A880                <1> 	test	al, 80h
 13484 00002B4F 7516                <1> 	jnz	short sp_i7
 13485                              <1> sp_i2:
 13486 00002B51 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13487                              <1> sp_i6:
 13488                              <1> 	;; COM2 - enabling IRQ 3
 13489                              <1> 	; 08/01/2022
 13490 00002B54 B4F7                <1> 	mov	ah, 0F7h ; enable IRQ 3 (COM2)
 13491                              <1> 	; 07/11/2015
 13492                              <1> 	; 26/10/2015
 13493                              <1> 	;pushf
 13494                              <1> 	;cli
 13495                              <1> 	;;
 13496                              <1> 	;;mov	dx, 2FCh   		; modem control register
 13497                              <1> 	;mov	dl, 0FCh ; 08/01/2022
 13498                              <1> 	;in	al, dx 	   		; read register
 13499                              <1> 	;JMP	$+2	   		; I/O DELAY
 13500                              <1> 	;or	al, 8      		; enable bit 3 (OUT2)
 13501                              <1> 	;out	dx, al     		; write back to register
 13502                              <1> 	;JMP	$+2	   		; I/O DELAY
 13503                              <1> 	;;mov	dx, 2F9h   		; interrupt enable register
 13504                              <1> 	;mov	dl, 0F9h ; 08/01/2022
 13505                              <1> 	;in	al, dx     		; read register
 13506                              <1> 	;JMP	$+2	   		; I/O DELAY
 13507                              <1> 	;;or	al, 1      		; receiver data interrupt enable and
 13508                              <1> 	;or	al, 3	   		; transmitter empty interrupt enable
 13509                              <1> 	;out	dx, al 	   		; write back to register
 13510                              <1> 	;JMP	$+2        		; I/O DELAY
 13511                              <1> 	;in	al, 21h    		; read interrupt mask register
 13512                              <1> 	;JMP	$+2	   		; I/O DELAY
 13513                              <1> 	;and	al, 0F7h   		; enable IRQ 3 (COM2)
 13514                              <1> 	;out	21h, al    		; write back to register
 13515                              <1> 	;
 13516                              <1> 	; 08/01/2022
 13517 00002B56 9C                  <1> 	pushf
 13518 00002B57 E8AA000000          <1> 	call	sp_i8
 13519                              <1> 	; 23/10/2015
 13520 00002B5C B8[3B2A0000]        <1> 	mov 	eax, com2_int
 13521 00002B61 A3[58300000]        <1> 	mov	[com2_irq3], eax
 13522                              <1> 	; 26/10/2015
 13523 00002B66 9D                  <1> 	popf	
 13524                              <1> sp_i7:
 13525 00002B67 C3                  <1> 	retn
 13526                              <1> 
 13527                              <1> sp_i3:
 13528                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
 13529                              <1> 	; 28/10/2015
 13530 00002B68 FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
 13531 00002B6A B000                <1> 	mov	al, 0
 13532 00002B6C EE                  <1> 	out	dx, al			; disable serial port interrupt
 13533 00002B6D EB00                <1> 	JMP	$+2			; I/O DELAY
 13534 00002B6F 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
 13535 00002B72 B080                <1> 	mov	al, 80h			
 13536 00002B74 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
 13537                              <1> 	;-----	SET BAUD RATE DIVISOR
 13538                              <1> 	; 26/10/2015
 13539 00002B75 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
 13540                              <1> 					; of the divisor value
 13541 00002B78 88C8                <1> 	mov	al, cl	; 1
 13542 00002B7A EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
 13543                              <1> 					; 2 = 57600 baud
 13544                              <1> 					; 3 = 38400 baud
 13545                              <1> 					; 6 = 19200 baud
 13546                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
 13547 00002B7B EB00                <1> 	JMP	$+2			; I/O DELAY
 13548 00002B7D 28C0                <1> 	sub	al, al
 13549 00002B7F FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
 13550                              <1> 					; of the divisor value
 13551 00002B81 EE                  <1> 	out	dx, al ; 0
 13552 00002B82 EB00                <1> 	JMP	$+2			; I/O DELAY
 13553                              <1> 	;	
 13554 00002B84 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
 13555                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
 13556 00002B86 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
 13557 00002B89 EE                  <1> 	out	dx, al			
 13558 00002B8A EB00                <1> 	JMP	$+2			; I/O DELAY
 13559                              <1> 	; 29/10/2015
 13560 00002B8C FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
 13561 00002B8E 30C0                <1> 	xor	al, al			; 0
 13562 00002B90 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
 13563 00002B91 EB00                <1> 	JMP	$+2	
 13564                              <1> sp_i4:
 13565                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
 13566                              <1> 	; 29/06/2015 (line status after modem status)
 13567 00002B93 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
 13568                              <1> sp_i4s:
 13569 00002B96 EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
 13570 00002B97 EB00                <1> 	JMP	$+2			; I/O DELAY
 13571 00002B99 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
 13572 00002B9B FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
 13573                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
 13574 00002B9D EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
 13575                              <1> 	; AL = Line status, AH = Modem status
 13576 00002B9E C3                  <1> 	retn
 13577                              <1> 
 13578                              <1> sp_status:
 13579                              <1> 	; 29/06/2015
 13580                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
 13581                              <1> 	; Get serial port status
 13582 00002B9F 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
 13583 00002BA3 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
 13584                              <1> 					; dx = 2FEh for COM2
 13585 00002BA5 EBEF                <1> 	jmp	short sp_i4s
 13586                              <1> 
 13587                              <1> sp_setp: ; Set serial port communication parameters
 13588                              <1> 	; 08/01/2022
 13589                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 13590                              <1> 	; 07/11/2015
 13591                              <1> 	; 29/10/2015
 13592                              <1> 	; 29/06/2015
 13593                              <1> 	; Retro UNIX 386 v1 feature only !	
 13594                              <1> 	;
 13595                              <1> 	; INPUT:
 13596                              <1> 	;	AL = 0 for COM1
 13597                              <1> 	;	     1 for COM2
 13598                              <1> 	;	AH = Communication parameters (*)
 13599                              <1> 	; OUTPUT:
 13600                              <1> 	;	CL = Line status
 13601                              <1> 	;	CH = Modem status
 13602                              <1> 	;   If cf = 1 -> Error code in [u.error]
 13603                              <1> 	;		 'invalid parameter !' 
 13604                              <1> 	;		 	 or
 13605                              <1> 	;		 'device not ready !' error
 13606                              <1> 	;	
 13607                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13608                              <1> 	;	Bit	4	3	2	1	0
 13609                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13610                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13611                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13612                              <1> 	;		11 = even
 13613                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13614                              <1> 	;		Retro UNIX 386 v1 feature only !
 13615                              <1> 	;	Bit	7    6    5  | Baud rate
 13616                              <1> 	;		------------------------
 13617                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13618                              <1> 	;		0    0    1  | 9600 (12)
 13619                              <1> 	;		0    1    0  | 19200 (6) 
 13620                              <1> 	;		0    1	  1  | 38400 (3) 
 13621                              <1> 	;		1    0	  0  | 14400 (8)
 13622                              <1> 	;		1    0	  1  | 28800 (4)
 13623                              <1> 	;		1    1    0  | 57600 (2)
 13624                              <1> 	;		1    1    1  | 115200 (1) 
 13625                              <1> 	;
 13626                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13627                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13628                              <1> 	;
 13629                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13630                              <1> 	;
 13631 00002BA7 66BAF803            <1> 	mov	dx, 3F8h
 13632 00002BAB BB[D2670000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
 13633 00002BB0 3C01                <1> 	cmp	al, 1
 13634 00002BB2 7770                <1> 	ja 	short sp_invp_err
 13635 00002BB4 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
 13636 00002BB6 FECE                <1> 	dec	dh ; 2F8h
 13637 00002BB8 43                  <1> 	inc	ebx ; COM2 control byte offset
 13638                              <1> sp_setp1:
 13639                              <1> 	; 29/10/2015
 13640 00002BB9 8823                <1> 	mov	[ebx], ah
 13641 00002BBB 0FB6CC              <1> 	movzx 	ecx, ah
 13642 00002BBE C0E905              <1> 	shr	cl, 5 ; -> baud rate index
 13643 00002BC1 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
 13644 00002BC4 8A81[332C0000]      <1> 	mov	al, [ecx+b_div_tbl]
 13645 00002BCA 6689C1              <1> 	mov	cx, ax
 13646 00002BCD E896FFFFFF          <1> 	call	sp_i3
 13647 00002BD2 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
 13648 00002BD5 A880                <1> 	test	al, 80h
 13649 00002BD7 740F                <1> 	jz	short sp_setp2
 13650 00002BD9 C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
 13651                              <1> stp_dnr_err:
 13652 00002BDC C705[186D0000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
 13653 00002BE4 0000                <1>
 13654                              <1> 	; CL = Line status, CH = Modem status
 13655 00002BE6 F9                  <1> 	stc
 13656 00002BE7 C3                  <1> 	retn
 13657                              <1> sp_setp2:
 13658 00002BE8 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
 13659                              <1>         ;jna	sp_i6
 13660                              <1> 		      ; COM1 (3F?h)
 13661                              <1> 	; 24/12/2021
 13662 00002BEB 7705                <1> 	ja	short sp_i5
 13663 00002BED E962FFFFFF          <1> 	jmp	sp_i6
 13664                              <1> sp_i5: 
 13665                              <1> 	; 08/01/2022
 13666 00002BF2 B4EF                <1> 	mov	ah, 0EFh ; enable IRQ 4 (COM1)
 13667                              <1> 	; 07/11/2015
 13668                              <1> 	; 26/10/2015
 13669                              <1> 	; 29/06/2015
 13670                              <1> 	;
 13671                              <1> 	;; COM1 - enabling IRQ 4
 13672                              <1> 	;pushf
 13673                              <1> 	;cli
 13674                              <1> 	;;mov	dx, 3FCh   		; modem control register
 13675                              <1> 	;mov	dl, 0FCh ; 08/01/2022
 13676                              <1> 	;in	al, dx 	   		; read register
 13677                              <1> 	;JMP	$+2			; I/O DELAY
 13678                              <1> 	;or	al, 8      		; enable bit 3 (OUT2)
 13679                              <1> 	;out	dx, al     		; write back to register
 13680                              <1> 	;JMP	$+2			; I/O DELAY
 13681                              <1> 	;;mov	dx, 3F9h   		; interrupt enable register
 13682                              <1> 	;mov	dl, 0F9h ; 08/01/2022
 13683                              <1> 	;in	al, dx     		; read register
 13684                              <1> 	;JMP	$+2			; I/O DELAY
 13685                              <1> 	;;or	al, 1      		; receiver data interrupt enable and
 13686                              <1> 	;or	al, 3	   		; transmitter empty interrupt enable
 13687                              <1> 	;out	dx, al 	   		; write back to register
 13688                              <1> 	;JMP	$+2        		; I/O DELAY
 13689                              <1> 	;in	al, 21h    		; read interrupt mask register
 13690                              <1> 	;JMP	$+2			; I/O DELAY
 13691                              <1> 	;and	al, 0EFh   		; enable IRQ 4 (COM1)
 13692                              <1> 	;out	21h, al    		; write back to register
 13693                              <1> 	;
 13694                              <1> 	; 08/01/2022
 13695 00002BF4 9C                  <1> 	pushf
 13696 00002BF5 E80C000000          <1> 	call	sp_i8
 13697                              <1> 	; 23/10/2015
 13698 00002BFA B8[442A0000]        <1> 	mov 	eax, com1_int
 13699 00002BFF A3[54300000]        <1> 	mov	[com1_irq4], eax
 13700                              <1> 	; 26/10/2015
 13701 00002C04 9D                  <1> 	popf
 13702 00002C05 C3                  <1> 	retn
 13703                              <1> 
 13704                              <1> sp_i8:
 13705                              <1> 	; 08/01/2022
 13706                              <1> 	;pushf
 13707 00002C06 FA                  <1> 	cli
 13708                              <1> 	;
 13709                              <1> 	;mov	dx, 2FCh  ; 3FCh	; modem control register
 13710 00002C07 B2FC                <1> 	mov	dl, 0FCh
 13711 00002C09 EC                  <1> 	in	al, dx 	   		; read register
 13712 00002C0A EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13713 00002C0C 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13714 00002C0E EE                  <1> 	out	dx, al     		; write back to register
 13715 00002C0F EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13716                              <1> 	;mov	dx, 2F9h  ; 3F9h 	; interrupt enable register
 13717 00002C11 B2F9                <1> 	mov	dl, 0F9h
 13718 00002C13 EC                  <1> 	in	al, dx     		; read register
 13719 00002C14 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13720                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13721 00002C16 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13722 00002C18 EE                  <1> 	out	dx, al 	   		; write back to register
 13723 00002C19 EB00                <1> 	JMP	$+2        		; I/O DELAY
 13724 00002C1B E421                <1> 	in	al, 21h    		; read interrupt mask register
 13725 00002C1D EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13726                              <1> 	;and	al, 0F7h  ; 0EFh	; enable IRQ 3 (COM2)
 13727 00002C1F 20E0                <1> 	and	al, ah	; 0F7h or 0EFh 
 13728 00002C21 E621                <1> 	out	21h, al    		; write back to register
 13729                              <1> 	;
 13730                              <1> 	;popf	
 13731 00002C23 C3                  <1> 	retn
 13732                              <1> 
 13733                              <1> sp_invp_err:
 13734 00002C24 C705[186D0000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 13735 00002C2C 0000                <1>
 13736 00002C2E 31C9                <1> 	xor	ecx, ecx
 13737 00002C30 49                  <1> 	dec	ecx ; 0FFFFh
 13738 00002C31 F9                  <1> 	stc
 13739 00002C32 C3                  <1> 	retn
 13740                              <1> 
 13741                              <1> ; 29/10/2015
 13742                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
 13743 00002C33 010C0603080401      <1> 	db	1, 12, 6, 3, 8, 4, 1
 13744                              <1> 
 13745                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014) 
 13746                              <1> epoch:
 13747                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 13748                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13749                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
 13750                              <1> 	; 'epoch' procedure prototype: 
 13751                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13752                              <1> 	; 14/11/2012
 13753                              <1> 	; unixboot.asm (boot file configuration)
 13754                              <1> 	; version of "epoch" procedure in "unixproc.asm"
 13755                              <1> 	; 21/7/2012
 13756                              <1> 	; 15/7/2012
 13757                              <1> 	; 14/7/2012		
 13758                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
 13759                              <1> 	; compute current date and time as UNIX Epoch/Time
 13760                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
 13761                              <1> 	;
 13762                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
 13763                              <1> 	;
 13764 00002C3A E818010000          <1> 	call 	get_rtc_time		; Return Current Time
 13765 00002C3F 86E9                <1>         xchg 	ch,cl
 13766 00002C41 66890D[D8640000]    <1>         mov 	[hour], cx
 13767 00002C48 86F2                <1>         xchg 	dh,dl
 13768 00002C4A 668915[DA640000]    <1>         mov 	[second], dx
 13769                              <1> 	;
 13770 00002C51 E832010000          <1>         call 	get_rtc_date		; Return Current Date
 13771 00002C56 86E9                <1>         xchg 	ch,cl
 13772 00002C58 66890D[D4640000]    <1>         mov 	[year], cx
 13773 00002C5F 86F2                <1>         xchg 	dh,dl
 13774 00002C61 668915[D6640000]    <1>         mov 	[month], dx
 13775                              <1> 	;
 13776 00002C68 66B93030            <1> 	mov 	cx, 3030h
 13777                              <1> 	;
 13778 00002C6C A0[D8640000]        <1> 	mov 	al, [hour] ; Hour
 13779                              <1>         	; AL <= BCD number)
 13780 00002C71 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13781                              <1> 					; AH = AL / 10h
 13782                              <1> 					; AL = AL MOD 10h
 13783 00002C73 D50A                <1>         aad 	; AX= AH*10+AL
 13784 00002C75 A2[D8640000]        <1> 	mov 	[hour], al
 13785 00002C7A A0[D9640000]        <1> 	mov 	al, [hour+1] ; Minute
 13786                              <1>         	; AL <= BCD number)
 13787 00002C7F D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13788                              <1> 					; AH = AL / 10h
 13789                              <1> 					; AL = AL MOD 10h
 13790 00002C81 D50A                <1>         aad 	; AX= AH*10+AL
 13791 00002C83 A2[D9640000]        <1> 	mov 	[minute], al
 13792 00002C88 A0[DA640000]        <1> 	mov 	al, [second] ; Second
 13793                              <1>         	; AL <= BCD number)
 13794 00002C8D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13795                              <1> 					; AH = AL / 10h
 13796                              <1> 					; AL = AL MOD 10h
 13797 00002C8F D50A                <1>         aad 	; AX= AH*10+AL
 13798 00002C91 A2[DA640000]        <1> 	mov 	[second], al
 13799 00002C96 66A1[D4640000]      <1> 	mov 	ax, [year] ; Year (century)
 13800                              <1> 	;push 	ax
 13801                              <1> 	; 04/12/2021
 13802 00002C9C 50                  <1> 	push	eax
 13803                              <1> 	   	; AL <= BCD number)
 13804 00002C9D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13805                              <1> 					; AH = AL / 10h
 13806                              <1> 					; AL = AL MOD 10h
 13807 00002C9F D50A                <1>         aad 	; AX= AH*10+AL
 13808 00002CA1 B464                <1> 	mov 	ah, 100
 13809 00002CA3 F6E4                <1> 	mul 	ah
 13810 00002CA5 66A3[D4640000]      <1> 	mov 	[year], ax
 13811                              <1> 	;pop	ax
 13812                              <1> 	; 04/12/2021
 13813 00002CAB 58                  <1> 	pop	eax
 13814 00002CAC 88E0                <1> 	mov	al, ah
 13815                              <1>         	; AL <= BCD number)
 13816 00002CAE D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13817                              <1> 					; AH = AL / 10h
 13818                              <1> 					; AL = AL MOD 10h
 13819 00002CB0 D50A                <1>         aad 	; AX= AH*10+AL
 13820 00002CB2 660105[D4640000]    <1> 	add 	[year], ax
 13821 00002CB9 A0[D6640000]        <1> 	mov 	al, [month] ; Month
 13822                              <1>            	; AL <= BCD number)
 13823 00002CBE D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13824                              <1> 					; AH = AL / 10h
 13825                              <1> 					; AL = AL MOD 10h
 13826 00002CC0 D50A                <1>         aad 	; AX= AH*10+AL
 13827 00002CC2 A2[D6640000]        <1> 	mov 	[month], al	
 13828 00002CC7 A0[D7640000]        <1>         mov     al, [month+1]      	; Day
 13829                              <1>            	; AL <= BCD number)
 13830 00002CCC D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13831                              <1> 					; AH = AL / 10h
 13832                              <1> 					; AL = AL MOD 10h
 13833 00002CCE D50A                <1>         aad 	; AX= AH*10+AL
 13834 00002CD0 A2[D7640000]        <1>         mov     [day], al
 13835                              <1> 	
 13836                              <1> _epoch:
 13837                              <1> 	; 17/07/2022
 13838                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
 13839                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1)
 13840                              <1> 	;
 13841                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
 13842                              <1> 	;
 13843                              <1> 	; Derived from DALLAS Semiconductor
 13844                              <1> 	; Application Note 31 (DS1602/DS1603)
 13845                              <1> 	; 6 May 1998
 13846 00002CD5 29C0                <1> 	sub 	eax, eax
 13847 00002CD7 66A1[D4640000]      <1> 	mov 	ax, [year]
 13848 00002CDD 662DB207            <1> 	sub 	ax, 1970
 13849 00002CE1 BA6D010000          <1> 	mov 	edx, 365
 13850 00002CE6 F7E2                <1> 	mul 	edx
 13851 00002CE8 31DB                <1> 	xor 	ebx, ebx
 13852 00002CEA 8A1D[D6640000]      <1> 	mov 	bl, [month]
 13853 00002CF0 FECB                <1> 	dec 	bl
 13854 00002CF2 D0E3                <1> 	shl 	bl, 1
 13855                              <1> 	;sub	edx, edx
 13856 00002CF4 668B93[DC640000]    <1> 	mov 	dx, [EBX+DMonth]
 13857 00002CFB 8A1D[D7640000]      <1>         mov     bl, [day]
 13858 00002D01 FECB                <1> 	dec 	bl
 13859 00002D03 01D0                <1> 	add 	eax, edx
 13860 00002D05 01D8                <1> 	add 	eax, ebx
 13861                              <1> 			; EAX = days since 1/1/1970
 13862 00002D07 668B15[D4640000]    <1> 	mov 	dx, [year]
 13863 00002D0E 6681EAB107          <1> 	sub 	dx, 1969
 13864                              <1> 	;shr 	dx, 1
 13865                              <1> 	;shr 	dx, 1		
 13866                              <1> 	; 17/07/2022
 13867 00002D13 C1EA02              <1> 	shr	edx, 2
 13868                              <1> 		; (year-1969)/4
 13869 00002D16 01D0                <1> 	add 	eax, edx
 13870                              <1> 			; + leap days since 1/1/1970
 13871 00002D18 803D[D6640000]02    <1> 	cmp 	byte [month], 2	; if past february
 13872 00002D1F 7610                <1> 	jna 	short cte1
 13873 00002D21 668B15[D4640000]    <1> 	mov 	dx, [year]
 13874 00002D28 6683E203            <1> 	and 	dx, 3 ; year mod 4
 13875 00002D2C 7503                <1> 	jnz 	short cte1		
 13876                              <1> 			; and if leap year
 13877 00002D2E 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
 13878                              <1> cte1: 			; compute seconds since 1/1/1970
 13879 00002D31 BA18000000          <1> 	mov 	edx, 24
 13880 00002D36 F7E2                <1> 	mul	edx
 13881 00002D38 8A15[D8640000]      <1> 	mov 	dl, [hour]
 13882 00002D3E 01D0                <1> 	add 	eax, edx
 13883                              <1> 		; EAX = hours since 1/1/1970 00:00:00
 13884                              <1> 	;mov	ebx, 60
 13885 00002D40 B33C                <1> 	mov	bl, 60
 13886 00002D42 F7E3                <1> 	mul	ebx
 13887 00002D44 8A15[D9640000]      <1> 	mov 	dl, [minute]
 13888 00002D4A 01D0                <1> 	add 	eax, edx
 13889                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
 13890                              <1> 	;mov 	ebx, 60
 13891 00002D4C F7E3                <1> 	mul	ebx
 13892 00002D4E 8A15[DA640000]      <1> 	mov 	dl, [second]
 13893 00002D54 01D0                <1> 	add 	eax, edx
 13894                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
 13895 00002D56 C3                  <1> 	retn
 13896                              <1> 
 13897                              <1> get_rtc_time:
 13898                              <1> 	; 15/03/2015
 13899                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13900                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13901                              <1> 	; INT 1Ah
 13902                              <1> 	; (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,	:
 13903                              <1> 	;       (CH) = HOURS IN BCD (00-23)			:
 13904                              <1> 	;       (CL) = MINUTES IN BCD (00-59)			:
 13905                              <1> 	;       (DH) = SECONDS IN BCD (00-59)			:
 13906                              <1> 	;       (DL) = DAYLIGHT SAVINGS ENABLE (00-01).		:
 13907                              <1> 	;								
 13908                              <1> RTC_20: 				; GET RTC TIME
 13909 00002D57 FA                  <1> 	cli
 13910 00002D58 E8DBDDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13911 00002D5D 7227                <1> 	JC	short RTC_29		; EXIT IF ERROR (CY= 1)
 13912                              <1> 
 13913 00002D5F B000                <1> 	MOV	AL, CMOS_SECONDS 	; SET ADDRESS OF SECONDS
 13914 00002D61 E8BCDDFFFF          <1> 	CALL	CMOS_READ		; GET SECONDS
 13915 00002D66 88C6                <1> 	MOV	DH, AL			; SAVE
 13916 00002D68 B00B                <1> 	MOV	AL, CMOS_REG_B		; ADDRESS ALARM REGISTER
 13917 00002D6A E8B3DDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13918 00002D6F 2401                <1> 	AND	AL, 00000001B		; MASK FOR VALID DSE BIT
 13919 00002D71 88C2                <1> 	MOV	DL, AL			; SET [DL] TO ZERO FOR NO DSE BIT
 13920 00002D73 B002                <1> 	MOV	AL, CMOS_MINUTES 	; SET ADDRESS OF MINUTES
 13921 00002D75 E8A8DDFFFF          <1> 	CALL	CMOS_READ		; GET MINUTES
 13922 00002D7A 88C1                <1> 	MOV	CL, AL			; SAVE
 13923 00002D7C B004                <1> 	MOV	AL, CMOS_HOURS		; SET ADDRESS OF HOURS
 13924 00002D7E E89FDDFFFF          <1> 	CALL	CMOS_READ		; GET HOURS
 13925 00002D83 88C5                <1> 	MOV	CH, AL			; SAVE
 13926 00002D85 F8                  <1> 	CLC				; SET CY= 0
 13927                              <1> RTC_29:
 13928 00002D86 FB                  <1> 	sti
 13929 00002D87 C3                  <1> 	RETn				; RETURN WITH RESULT IN CARRY FLAG
 13930                              <1> 
 13931                              <1> get_rtc_date:
 13932                              <1> 	; 15/03/2015
 13933                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13934                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13935                              <1> 	; INT 1Ah
 13936                              <1> 	; (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,:
 13937                              <1> 	;      (CH) = CENTURY IN BCD (19 OR 20) 		       :
 13938                              <1> 	;      (CL) = YEAR IN BCD (00-99)			       :
 13939                              <1> 	;      (DH) = MONTH IN BCD (01-12)			       :
 13940                              <1> 	;      (DL) = DAY IN BCD (01-31).		
 13941                              <1> 	;
 13942                              <1> RTC_40: 				; GET RTC DATE
 13943 00002D88 FA                  <1> 	cli
 13944 00002D89 E8AADDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13945 00002D8E 7225                <1> 	JC	short RTC_49		; EXIT IF ERROR (CY= 1)
 13946                              <1> 
 13947 00002D90 B007                <1> 	MOV	AL, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
 13948 00002D92 E88BDDFFFF          <1> 	CALL	CMOS_READ		; READ DAY OF MONTH
 13949 00002D97 88C2                <1> 	MOV	DL, AL			; SAVE
 13950 00002D99 B008                <1> 	MOV	AL, CMOS_MONTH		; ADDRESS MONTH
 13951 00002D9B E882DDFFFF          <1> 	CALL	CMOS_READ		; READ MONTH
 13952 00002DA0 88C6                <1> 	MOV	DH, AL			; SAVE
 13953 00002DA2 B009                <1> 	MOV	AL, CMOS_YEAR		; ADDRESS YEAR
 13954 00002DA4 E879DDFFFF          <1> 	CALL	CMOS_READ		; READ YEAR
 13955 00002DA9 88C1                <1> 	MOV	CL, AL			; SAVE
 13956 00002DAB B032                <1> 	MOV	AL, CMOS_CENTURY 	; ADDRESS CENTURY LOCATION
 13957 00002DAD E870DDFFFF          <1> 	CALL	CMOS_READ		; GET CENTURY BYTE
 13958 00002DB2 88C5                <1> 	MOV	CH, AL			; SAVE
 13959 00002DB4 F8                  <1> 	CLC				; SET CY=0
 13960                              <1> RTC_49:
 13961 00002DB5 FB                  <1> 	sti
 13962 00002DB6 C3                  <1> 	RETn				; RETURN WITH RESULTS IN CARRY FLAG
 13963                              <1> 
 13964                              <1> set_date_time:
 13965                              <1> convert_from_epoch:
 13966                              <1> 	; 02/06/2022 (BugFix)
 13967                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13968                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 13969                              <1> 	; 'convert_from_epoch' procedure prototype: 
 13970                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13971                              <1> 	;
 13972                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
 13973                              <1> 	;
 13974                              <1> 	; Derived from DALLAS Semiconductor
 13975                              <1> 	; Application Note 31 (DS1602/DS1603)
 13976                              <1> 	; 6 May 1998
 13977                              <1> 	;
 13978                              <1> 	; INPUT:
 13979                              <1> 	; EAX = Unix (Epoch) Time
 13980                              <1> 	;
 13981 00002DB7 31D2                <1> 	xor 	edx, edx
 13982                              <1> 	; 02/06/2022
 13983 00002DB9 31C9                <1> 	xor	ecx, ecx
 13984 00002DBB 31DB                <1> 	xor	ebx, ebx
 13985                              <1> 	;mov 	ecx, 60
 13986 00002DBD B13C                <1> 	mov	cl, 60
 13987 00002DBF F7F1                <1> 	div	ecx
 13988                              <1> 	;mov 	[imin], eax  ; whole minutes
 13989                              <1> 			     ; since 1/1/1970
 13990                              <1> 	;mov 	[second], dx ; leftover seconds
 13991 00002DC1 8815[DA640000]      <1> 	mov	[second], dl ; 02/06/2022
 13992 00002DC7 29D2                <1> 	sub 	edx, edx
 13993 00002DC9 F7F1                <1> 	div	ecx
 13994                              <1> 	;mov 	[ihrs], eax  ; whole hours
 13995                              <1> 	;		     ; since 1/1/1970
 13996                              <1> 	;mov 	[minute], dx ; leftover minutes
 13997 00002DCB 8815[D9640000]      <1> 	mov	[minute], dl ; 02/06/2022
 13998 00002DD1 31D2                <1> 	xor	edx, edx
 13999                              <1> 	;mov 	cx, 24
 14000 00002DD3 B118                <1> 	mov 	cl, 24
 14001 00002DD5 F7F1                <1> 	div	ecx
 14002                              <1> 	;mov 	[iday], ax   ; whole days
 14003                              <1> 			     ; since 1/1/1970
 14004                              <1> 	;mov 	[hour], dx   ; leftover hours
 14005 00002DD7 8815[D8640000]      <1> 	mov	[hour], dl   ; 02/06/2022
 14006                              <1> 
 14007 00002DDD 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
 14008                              <1> 			     ; 1/1/1968 	
 14009                              <1> 		;mov 	[iday], ax
 14010 00002DE2 50                  <1> 	push 	eax
 14011 00002DE3 29D2                <1> 	sub	edx, edx
 14012 00002DE5 B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
 14013 00002DEA F7F1                <1> 	div	ecx
 14014 00002DEC 59                  <1> 	pop 	ecx
 14015                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
 14016                              <1> 	;push	dx
 14017                              <1> 	; 02/06/2022
 14018 00002DED 52                  <1> 	push 	edx
 14019                              <1> 	;mov 	[qday], dx   ; days since quadyr began
 14020 00002DEE 6683FA3C            <1> 	cmp 	dx, 31+29    ; if past feb 29 then
 14021 00002DF2 F5                  <1> 	cmc		     ; add this quadyr's leap day
 14022 00002DF3 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
 14023                              <1> 	;mov 	[lday], ax   ; since 1968			  
 14024                              <1> 	;mov 	cx, [iday]
 14025 00002DF6 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
 14026 00002DF7 29C8                <1> 	sub 	eax, ecx     ; iday - lday
 14027 00002DF9 B96D010000          <1> 	mov 	ecx, 365
 14028 00002DFE 31D2                <1> 	xor	edx, edx
 14029                              <1> 	; EAX = iday-lday, EDX = 0
 14030 00002E00 F7F1                <1> 	div	ecx
 14031                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
 14032                              <1> 	;jday = iday - (iyrs*365) - lday
 14033                              <1> 	;mov	[jday], dx   ; days since 1/1 of current year
 14034                              <1> 	;add	eax, 1968
 14035 00002E02 6605B007            <1> 	add 	ax, 1968     ; compute year
 14036 00002E06 66A3[D4640000]      <1> 	mov 	[year], ax
 14037                              <1> 	;mov 	cx, dx
 14038                              <1> 	; 02/06/2022
 14039 00002E0C 89D1                <1> 	mov	ecx, edx
 14040                              <1> 	;mov 	dx, [qday]
 14041                              <1> 	;pop	dx
 14042                              <1> 	; 02/06/2022
 14043 00002E0E 5A                  <1> 	pop 	edx
 14044 00002E0F 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
 14045 00002E14 7709                <1> 	ja 	short cfe1   ; jday = jday +1
 14046 00002E16 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
 14047 00002E1A F5                  <1>         cmc		     ; add a leap day to the # of whole
 14048 00002E1B 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
 14049                              <1> cfe1:			
 14050                              <1> 	;mov 	[jday], cx
 14051                              <1> 	;mov 	bx, 12       ; estimate month
 14052                              <1> 	;sub	ebx, ebx
 14053                              <1> 	; 02/06/2022
 14054 00002E1F B30C                <1> 	mov	bl, 12
 14055 00002E21 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
 14056 00002E25 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
 14057                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
 14058                              <1> 	;cmp 	cx, dx       ; mday = # of days passed from 1/1
 14059                              <1> 	; 02/06/2022
 14060 00002E29 39D1                <1> 	cmp	ecx, edx 	 		
 14061 00002E2B 7319                <1> 	jnb 	short cfe3
 14062                              <1> 	;dec 	bx           ; month = month - 1
 14063 00002E2D FECB                <1> 	dec	bl			
 14064                              <1> 	;shl 	bx, 1
 14065 00002E2F D0E3                <1> 	shl	bl, 1
 14066 00002E31 668B93[DC640000]    <1> 	mov 	dx, [ebx+DMonth] ; # elapsed days at 1st of month
 14067                              <1> 	;shr 	bx, 1        ; bx = month - 1 (0 to 11)
 14068                              <1> 	; 02/06/2022
 14069 00002E38 D0EB                <1> 	shr	bl, 1
 14070 00002E3A 80FB01              <1> 	cmp	bl, 1
 14071                              <1> 	;cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
 14072 00002E3D 76EA                <1> 	jna 	short cfe2   ; then mday = mday + 1
 14073 00002E3F 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
 14074 00002E41 75E6                <1> 	jnz 	short cfe2   ; add leap day (to mday)
 14075                              <1> 	;inc 	dx           ; mday = mday + 1
 14076 00002E43 42                  <1> 	inc	edx
 14077 00002E44 EBE3                <1> 	jmp 	short cfe2
 14078                              <1> cfe3:
 14079                              <1> 	;inc 	bx	     ; -> bx = month, 1 to 12
 14080                              <1> 	; 02/06/2022
 14081 00002E46 FEC3                <1> 	inc	bl
 14082                              <1> 	;mov 	[month], bx
 14083 00002E48 881D[D6640000]      <1> 	mov	[month], bl
 14084                              <1> 	;sub 	cx, dx	     ; day = jday - mday + 1	
 14085 00002E4E 29D1                <1> 	sub	ecx, edx
 14086                              <1> 	;inc 	cx 			  
 14087 00002E50 FEC1                <1> 	inc	cl
 14088                              <1> 	;mov 	[day], cx
 14089 00002E52 880D[D7640000]      <1> 	mov	[day], cl    ; 02/06/2022
 14090                              <1> 
 14091                              <1> 	; eax, ebx, ecx, edx is changed at return
 14092                              <1> 	; output ->
 14093                              <1> 	; [year], [month], [day], [hour], [minute], [second]
 14094                              <1> 	
 14095                              <1> 	; 02/06/2022 (BugFix)	
 14096                              <1> _set_date:
 14097 00002E58 66A1[D4640000]      <1> 	mov	ax, [year]
 14098 00002E5E B520                <1> 	mov	ch, 20h ; century (bcd)
 14099 00002E60 662DD007            <1> 	sub	ax, 2000
 14100 00002E64 7306                <1> 	jnc	short set_date
 14101 00002E66 B519                <1> 	mov	ch, 19h ; century (bcd) 
 14102 00002E68 6683C064            <1> 	add	ax, 100	
 14103                              <1> 	; 02/06/2022
 14104                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 14105                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 14106                              <1> set_date:
 14107                              <1>         ;mov	al, [year+1]
 14108                              <1> 	;aam 	; ah = al / 10, al = al mod 10
 14109                              <1> 	;db 	0D5h, 10h    ; Undocumented inst. AAD
 14110                              <1> 	;		     ; AL = AH * 10h + AL
 14111                              <1> 	;mov 	ch, al ; century (BCD)
 14112                              <1> 	;mov 	al, [year]
 14113                              <1> 	; al = year (0-99) ; 01/06/2022
 14114 00002E6C D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14115 00002E6E D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
 14116                              <1> 			     ; AL = AH * 10h + AL
 14117 00002E70 88C1                <1> 	mov 	cl, al ; year (BCD)
 14118 00002E72 A0[D6640000]        <1>         mov 	al, [month]
 14119 00002E77 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14120 00002E79 D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
 14121                              <1> 			     ; AL = AH * 10h + AL
 14122 00002E7B 88C6                <1> 	mov 	dh, al ; month (BCD)
 14123 00002E7D A0[D7640000]        <1> 	mov 	al, [day]
 14124 00002E82 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14125 00002E84 D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
 14126                              <1> 			     ; AL = AH * 10h + AL
 14127                              <1> 	; 02/06/2022 (BugFix)
 14128 00002E86 88C2                <1> 	mov 	dl, al ; day (BCD)
 14129                              <1> 
 14130                              <1> 	; Set real-time clock date
 14131 00002E88 E879000000          <1> 	call	set_rtc_date
 14132                              <1> set_time:
 14133                              <1>         ; Read real-time clock time 
 14134                              <1> 	; (get day light saving time bit status)
 14135 00002E8D FA                  <1>  	cli
 14136 00002E8E E8A5DCFFFF          <1> 	CALL	UPD_IPR 	; CHECK FOR UPDATE IN PROCESS
 14137                              <1> 	; cf = 1 -> al = 0
 14138 00002E93 7207                <1>         jc      short stime1
 14139 00002E95 B00B                <1> 	MOV	AL, CMOS_REG_B	; ADDRESS ALARM REGISTER
 14140 00002E97 E886DCFFFF          <1> 	CALL	CMOS_READ	; READ CURRENT VALUE OF DSE BIT
 14141                              <1> stime1:
 14142 00002E9C FB                  <1> 	sti
 14143 00002E9D 2401                <1> 	AND	AL, 00000001B	; MASK FOR VALID DSE BIT
 14144 00002E9F 88C2                <1> 	MOV	DL, AL		; SET [DL] TO ZERO FOR NO DSE BIT
 14145                              <1> 	; DL = 1 or 0 (day light saving time)
 14146                              <1> 	;	
 14147 00002EA1 A0[D8640000]        <1> 	mov 	al, [hour]
 14148 00002EA6 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14149 00002EA8 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14150                              <1> 			     ; AL = AH * 10h + AL
 14151 00002EAA 88C5                <1> 	mov 	ch, al ; hour (BCD)
 14152 00002EAC A0[D9640000]        <1>         mov     al, [minute]
 14153 00002EB1 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14154 00002EB3 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14155                              <1> 			     ; AL = AH * 10h + AL
 14156 00002EB5 88C1                <1> 	mov 	cl, al       ; minute (BCD)
 14157 00002EB7 A0[DA640000]        <1>         mov     al, [second]
 14158 00002EBC D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14159 00002EBE D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14160                              <1> 			     ; AL = AH * 10h + AL
 14161 00002EC0 88C6                <1> 	mov 	dh, al	     ; second (BCD)
 14162                              <1> 
 14163                              <1> 	; Set real-time clock time
 14164                              <1>  	; call	set_rtc_time
 14165                              <1> set_rtc_time:
 14166                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14167                              <1> 	; 15/03/2015
 14168                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14169                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14170                              <1> 	; INT 1Ah
 14171                              <1> 	; (AH) = 03H  SET THE REAL TIME CLOCK USING,			:
 14172                              <1> 	;      (CH) = HOURS IN BCD (00-23)			       	:
 14173                              <1> 	;      (CL) = MINUTES IN BCD (00-59)			       	:
 14174                              <1> 	;      (DH) = SECONDS IN BCD (00-59)			       	:
 14175                              <1> 	;      (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.    :
 14176                              <1> 	;								:
 14177                              <1> 	;  NOTE: (DL)= 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED. :
 14178                              <1> 	;        (DL)= 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN  :
 14179                              <1> 	;         APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN :
 14180                              <1> 	;         OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.	  :
 14181                              <1> 	;
 14182                              <1> RTC_30: 				; SET RTC TIME
 14183 00002EC2 FA                  <1> 	cli
 14184 00002EC3 E870DCFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14185 00002EC8 7305                <1> 	JNC	short RTC_35		; GO AROUND IF CLOCK OPERATING
 14186 00002ECA E886000000          <1> 	CALL	RTC_STA 		; ELSE TRY INITIALIZING CLOCK
 14187                              <1> RTC_35:
 14188 00002ECF 88F4                <1> 	MOV	AH, DH			; GET TIME BYTE - SECONDS
 14189 00002ED1 B000                <1> 	MOV	AL, CMOS_SECONDS 	; ADDRESS SECONDS
 14190 00002ED3 E89D000000          <1> 	CALL	CMOS_WRITE		; UPDATE SECONDS
 14191 00002ED8 88CC                <1> 	MOV	AH, CL			; GET TIME BYTE - MINUTES
 14192 00002EDA B002                <1> 	MOV	AL, CMOS_MINUTES 	; ADDRESS MINUTES
 14193 00002EDC E894000000          <1> 	CALL	CMOS_WRITE		; UPDATE MINUTES
 14194 00002EE1 88EC                <1> 	MOV	AH, CH			; GET TIME BYTE - HOURS
 14195 00002EE3 B004                <1> 	MOV	AL, CMOS_HOURS		; ADDRESS HOURS
 14196 00002EE5 E88B000000          <1> 	CALL	CMOS_WRITE		; UPDATE ADDRESS
 14197                              <1> 	;MOV	AX, X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14198 00002EEA 66B80B0B            <1> 	MOV	AX, 257*CMOS_REG_B 	; 
 14199 00002EEE E82FDCFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT TIME
 14200 00002EF3 2462                <1> 	AND	AL, 01100010B		; MASK FOR VALID BIT POSITIONS
 14201 00002EF5 0C02                <1> 	OR	AL, 00000010B		; TURN ON 24 HOUR MODE
 14202 00002EF7 80E201              <1> 	AND	DL, 00000001B		; USE ONLY THE DSE BIT
 14203 00002EFA 08D0                <1> 	OR	AL, DL			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
 14204 00002EFC 86E0                <1> 	XCHG	AH, AL			; PLACE IN WORK REGISTER AND GET ADDRESS
 14205 00002EFE E872000000          <1> 	CALL	CMOS_WRITE		; SET NEW ALARM BITS
 14206 00002F03 F8                  <1> 	CLC				; SET CY= 0
 14207 00002F04 FB                  <1> 	sti
 14208 00002F05 C3                  <1> 	RETn				; RETURN WITH CY= 0
 14209                              <1> 
 14210                              <1> set_rtc_date:
 14211                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14212                              <1> 	; 15/03/2015
 14213                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14214                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14215                              <1> 	; INT 1Ah
 14216                              <1> 	; (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING, :
 14217                              <1> 	;     (CH) = CENTURY IN BCD (19 OR 20)			   :
 14218                              <1> 	;     (CL) = YEAR IN BCD (00-99)			   :
 14219                              <1> 	;     (DH) = MONTH IN BCD (01-12)			   :
 14220                              <1> 	;     (DL) = DAY IN BCD (01-31).
 14221                              <1> 	;
 14222                              <1> RTC_50: 				; SET RTC DATE
 14223 00002F06 FA                  <1> 	cli
 14224 00002F07 E82CDCFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14225 00002F0C 7305                <1> 	JNC	short RTC_55		; GO AROUND IF NO ERROR
 14226 00002F0E E842000000          <1> 	CALL	RTC_STA 		; ELSE INITIALIZE CLOCK
 14227                              <1> RTC_55:
 14228 00002F13 66B80600            <1> 	MOV	AX, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
 14229 00002F17 E859000000          <1> 	CALL	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
 14230 00002F1C 88D4                <1> 	MOV	AH, DL			; GET DAY OF MONTH BYTE
 14231 00002F1E B007                <1> 	MOV	AL, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
 14232 00002F20 E850000000          <1> 	CALL	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
 14233 00002F25 88F4                <1> 	MOV	AH, DH			; GET MONTH
 14234 00002F27 B008                <1> 	MOV	AL, CMOS_MONTH		; ADDRESS MONTH BYTE
 14235 00002F29 E847000000          <1> 	CALL	CMOS_WRITE		; WRITE MONTH REGISTER
 14236 00002F2E 88CC                <1> 	MOV	AH, CL			; GET YEAR BYTE
 14237 00002F30 B009                <1> 	MOV	AL, CMOS_YEAR		; ADDRESS YEAR REGISTER
 14238 00002F32 E83E000000          <1> 	CALL	CMOS_WRITE		; WRITE YEAR REGISTER
 14239 00002F37 88EC                <1> 	MOV	AH, CH			; GET CENTURY BYTE
 14240 00002F39 B032                <1> 	MOV	AL, CMOS_CENTURY 	; ADDRESS CENTURY BYTE
 14241 00002F3B E835000000          <1> 	CALL	CMOS_WRITE		; WRITE CENTURY LOCATION
 14242                              <1> 	;MOV	AX, X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14243 00002F40 66B80B0B            <1> 	MOV	AX, 257*CMOS_REG_B 	; 
 14244 00002F44 E8D9DBFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT SETTINGS
 14245 00002F49 247F                <1> 	AND	AL, 07FH 		; CLEAR 'SET BIT'
 14246 00002F4B 86E0                <1> 	XCHG	AH, AL			; MOVE TO WORK REGISTER
 14247 00002F4D E823000000          <1> 	CALL	CMOS_WRITE		; AND START CLOCK UPDATING
 14248 00002F52 F8                  <1> 	CLC				; SET CY= 0
 14249 00002F53 FB                  <1> 	sti
 14250 00002F54 C3                  <1> 	RETn				; RETURN CY=0
 14251                              <1> 
 14252                              <1> 	; 15/03/2015
 14253                              <1> RTC_STA:				; INITIALIZE REAL TIME CLOCK
 14254 00002F55 B426                <1> 	mov	ah, 26h
 14255 00002F57 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK
 14256 00002F59 E817000000          <1> 	CALL	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
 14257 00002F5E B482                <1> 	mov	ah, 82h
 14258 00002F60 B00B                <1> 	mov 	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION
 14259 00002F62 E80E000000          <1> 	CALL	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
 14260 00002F67 B00C                <1> 	MOV	AL, CMOS_REG_C		; ADDRESS REGISTER C
 14261 00002F69 E8B4DBFFFF          <1> 	CALL	CMOS_READ		; READ REGISTER C TO INITIALIZE
 14262 00002F6E B00D                <1> 	MOV	AL, CMOS_REG_D		; ADDRESS REGISTER D
 14263                              <1> 	;CALL	CMOS_READ		; READ REGISTER D TO INITIALIZE
 14264                              <1> 	;RETn
 14265                              <1> 	; 06/02/2022
 14266 00002F70 E9ADDBFFFF          <1> 	jmp	CMOS_READ
 14267                              <1> 
 14268                              <1> 	; 15/03/2015
 14269                              <1> 	; IBM PC/XT Model 286 BIOS source code ----- 10/06/85 (test4.asm)
 14270                              <1> CMOS_WRITE:			; WRITE (AH) TO LOCATION (AL)
 14271 00002F75 9C                  <1> 	pushf			; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 14272                              <1> 	;push	ax		; SAVE WORK REGISTER VALUES
 14273 00002F76 D0C0                <1> 	rol	al, 1		; MOVE NMI BIT TO LOW POSITION
 14274 00002F78 F9                  <1> 	stc			; FORCE NMI BIT ON IN CARRY FLAG
 14275 00002F79 D0D8                <1> 	rcr	al, 1		; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 14276 00002F7B FA                  <1> 	cli			; DISABLE INTERRUPTS
 14277 00002F7C E670                <1> 	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
 14278 00002F7E 88E0                <1> 	mov	al, ah		; GET THE DATA BYTE TO WRITE
 14279 00002F80 E671                <1> 	out	CMOS_DATA, al	; PLACE IN REQUESTED CMOS LOCATION
 14280 00002F82 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
 14281 00002F84 D0D8                <1> 	rcr	al, 1		; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 14282 00002F86 E670                <1> 	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
 14283 00002F88 90                  <1> 	nop			; I/O DELAY
 14284 00002F89 E471                <1> 	in	al, CMOS_DATA	; OPEN STANDBY LATCH
 14285                              <1> 	;pop	ax		; RESTORE WORK REGISTERS
 14286 00002F8B 9D                  <1> 	popf	
 14287 00002F8C C3                  <1> 	RETn
 14288                              <1> 
 14289                              <1> bf_init:
 14290                              <1> 	; 21/03/2022 (Retro UNIX 386 v1.2)
 14291                              <1> 	; 28/11/2021
 14292                              <1> 	; 14/08/2015
 14293                              <1> 	; 02/07/2015
 14294                              <1> 	; 01/07/2015
 14295                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 14296                              <1> 	; Buffer (pointer) initialization !
 14297                              <1> 	; 
 14298                              <1> 	; 17/07/2013 - 24/07/2013
 14299                              <1> 	; Retro UNIX 8086 v1 (U9.ASM)
 14300                              <1> 	; (Retro UNIX 8086 v1 feature only !)
 14301                              <1> 	;
 14302 00002F8D BF[346C0000]        <1> 	mov	edi, bufp 
 14303 00002F92 B8[E4970000]        <1> 	mov	eax, buffer + (nbuf*520) 
 14304 00002F97 29D2                <1> 	sub	edx, edx
 14305 00002F99 FECA                <1> 	dec	dl
 14306 00002F9B 31C9                <1> 	xor	ecx, ecx
 14307 00002F9D 49                  <1> 	dec	ecx
 14308                              <1> bi0:
 14309 00002F9E 2D08020000          <1> 	sub	eax, 520 ; 8 header + 512 data
 14310 00002FA3 AB                  <1> 	stosd
 14311 00002FA4 89C6                <1> 	mov	esi, eax
 14312 00002FA6 8916                <1> 	mov	[esi], edx ; 000000FFh
 14313                              <1> 			    ; Not a valid device sign
 14314 00002FA8 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14315                              <1> 		      ; Not a valid block number sign 	 	
 14316 00002FAB 3D[64770000]        <1> 	cmp	eax, buffer
 14317 00002FB0 77EC                <1> 	ja	short bi0
 14318 00002FB2 B8[4C6D0000]        <1> 	mov	eax, sb0
 14319 00002FB7 AB                  <1> 	stosd
 14320 00002FB8 B8[546F0000]        <1> 	mov	eax, sb1
 14321 00002FBD AB                  <1> 	stosd
 14322 00002FBE 89C6                <1> 	mov	esi, eax ; offset sb1
 14323 00002FC0 8916                <1> 	mov	[esi], edx ; 000000FFh
 14324                              <1> 			   ; Not a valid device sign
 14325 00002FC2 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14326                              <1> 		      ; Not a valid block number sign 	 
 14327                              <1> 	; 14/08/2015
 14328                              <1> 	;call 	rdev_init
 14329                              <1> 	;retn
 14330                              <1> 
 14331                              <1> ; ----- Root file system initialization
 14332                              <1> 	
 14333                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
 14334                              <1> 	;	(Retro UNIX -runix- v2 file system) 
 14335                              <1> 	; 28/11/2021
 14336                              <1> rdev_init: ; root device, super block buffer initialization
 14337                              <1> 	; 14/08/2015
 14338                              <1> 	; Retro UNIX 386 v1 feature only !
 14339                              <1> 	;
 14340                              <1> 	; NOTE: Disk partitions (file systems), logical
 14341                              <1> 	; drive initialization, partition's start sector etc.
 14342                              <1> 	; will be coded here, later in 'ldrv_init'	
 14343                              <1> 
 14344 00002FC5 0FB605[88620000]    <1> 	movzx	eax, byte [boot_drv]
 14345                              <1> rdi_0:
 14346 00002FCC 3C80                <1> 	cmp	al, 80h
 14347 00002FCE 7202                <1> 	jb	short rdi_1
 14348 00002FD0 2C7E                <1> 	sub	al, 7Eh ; 80h = 2 (hd0), 81h = 3 (hd1)
 14349                              <1> rdi_1:
 14350 00002FD2 A2[826C0000]        <1> 	mov	[rdev], al
 14351                              <1> 	; 21/03/2022
 14352                              <1> 	;cmp	al, 2
 14353                              <1> 	;jnb	short rdi_2
 14354 00002FD7 08C0                <1> 	or	al, al
 14355 00002FD9 7504                <1> 	jnz	short rdi_2 ; hard disk boot
 14356                              <1> 	; floppy disk boot
 14357 00002FDB 31D2                <1> 	xor	edx, edx ; device number = 0
 14358                              <1> 			 ; (& fglags = 0)
 14359                              <1> 	; eax = 0 ; boot sector address = 0
 14360                              <1> 	;jmp	short rdi_5
 14361 00002FDD EB22                <1> 	jmp	short rdi_4
 14362                              <1> rdi_2:
 14363                              <1> 	; load masterboot sector
 14364                              <1> 	; to get runix v2 partition's boot sector address
 14365                              <1> 	;	
 14366 00002FDF BB[5C710000]        <1> 	mov	ebx, mbrbuf ; masterboot buffer header addr
 14367                              <1> 	;mov	[ebx], eax
 14368 00002FE4 8803                <1> 	mov	[ebx], al
 14369                              <1> 	;sub	al, al
 14370                              <1> 	;; eax = 0
 14371                              <1> 	;mov	[ebx+4], eax ; masterboot sector address
 14372 00002FE6 E8E52A0000          <1> 	call	diskio
 14373 00002FEB 730A                <1> 	jnc	short rdi_3
 14374                              <1> rdi_err:
 14375 00002FED BE[14300000]        <1> 	mov	esi, disk_read_err_msg
 14376 00002FF2 E9B9F9FFFF          <1> 	jmp	key_to_reboot
 14377                              <1> 
 14378                              <1> rdi_3:
 14379                              <1> 	; [ebx+8] = masterboot buffer (data) address 
 14380                              <1> 	;cmp	word [ebx+8+510], 0AA55h
 14381                              <1> 	;jc	short rdi_err
 14382                              <1> 
 14383 00002FF7 8D7308              <1> 	lea	esi, [ebx+8] 
 14384 00002FFA E82D000000          <1> 	call	runix_p_bs    ; return start sector address of
 14385                              <1> 			      ; retro unix v2 partition in esi
 14386                              <1> 	;;jc	short rdi_err ; 'retn'
 14387                              <1> 	;jnc	short rdi_4 ; Runix v2 partition not found !?
 14388                              <1> 			    ; 21/03/2022	
 14389                              <1> 			    ; ((Here, if cf is 1, that means,
 14390                              <1> 			    ; runix v2 partition not found
 14391                              <1> 			    ; in the MBR partition table.
 14392                              <1> 			    ; But, at least, there is a valid
 14393                              <1> 			    ; runix v2 boot sector on the disk
 14394                              <1> 			    ; which started the kernel.
 14395                              <1> 			    ; So, runix v2 boot sector code
 14396                              <1> 			    ; may -must- be on physical sector 0
 14397                              <1> 			    ; and then the superblock may be
 14398                              <1> 			    ; -must be- on physical sector 1.)) 
 14399                              <1> 	;sub	eax, eax
 14400                              <1> 	; eax = 0
 14401                              <1> ;rdi_4:
 14402 00002FFF 8B13                <1> 	mov	edx, [ebx] ; restore device number in dl
 14403                              <1> ;rdi_5:
 14404                              <1> rdi_4:
 14405 00003001 BB[4C6D0000]        <1>         mov	ebx, sb0 ; super block buffer (header)
 14406                              <1> 
 14407 00003006 40                  <1> 	inc	eax	; default sector address of the sb
 14408                              <1> 			; (boot sector address + 1)
 14409                              <1> 
 14410                              <1> 	;mov 	[ebx], eax
 14411                              <1> 	;mov	al, 1 ; eax = 1
 14412                              <1> 	;mov	[ebx+4], eax ; super block address on disk
 14413                              <1> 	; 21/03/2022
 14414 00003007 8913                <1> 	mov	[ebx], edx ; device number in DL
 14415                              <1> 			   ; (other bytes -flags- are zero)
 14416 00003009 894304              <1> 	mov	[ebx+4], eax ; superblock address on disk
 14417                              <1> 
 14418                              <1> 	;call 	diskio
 14419                              <1> 	;retn
 14420                              <1> 	; 28/11/2021
 14421                              <1> 	;jmp	diskio
 14422                              <1> 
 14423                              <1> 	; 21/03/2022
 14424 0000300C E8BF2A0000          <1> 	call	diskio
 14425 00003011 72DA                <1> 	jc	short rdi_err
 14426                              <1> 
 14427                              <1> 	; 21/03/2022
 14428                              <1> 	; Note: If superblock is defective or SB sector
 14429                              <1> 	;	address is wrong, "ERROR: /etc/init !?"
 14430                              <1> 	;	message will appear after here.
 14431                              <1> 	;	..because /etc/init inode will not be found..
 14432                              <1> 	;	So, i am not writing SB validation
 14433                              <1> 	;	(check) code here.
 14434                              <1> 	;
 14435                              <1> 	; ((Also, if we are here, everything should be normal!))
 14436                              <1> 
 14437 00003013 C3                  <1> 	retn
 14438                              <1> 
 14439                              <1> disk_read_err_msg:
 14440                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
 14441 00003014 070D0A              <1> 	db 07h, 0Dh, 0Ah
 14442 00003017 4469736B2072656164- <1> 	db "Disk read error ! "
 14443 00003020 206572726F72202120  <1>
 14444 00003029 0D0A00              <1> 	db 0Dh, 0Ah, 0
 14445                              <1> 
 14446                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
 14447                              <1> runix_p_bs:
 14448                              <1> 	; get retro unix v2 partition's boot sector address
 14449                              <1> 	
 14450                              <1> 	; 09/05/2021
 14451                              <1> 	; 19/04/2021 - Retro UNIX 386 v2
 14452                              <1> 	; INPUT:
 14453                              <1> 	;	;;Masterboot buffer at offset mbrbuf
 14454                              <1> 	;	; 21/03/2022
 14455                              <1> 	;	esi = Masterboot buffer (data) address
 14456                              <1> 	; OUTPUT:
 14457                              <1> 	;	;;esi = start sector addr of retro unix v2 fs
 14458                              <1> 	;	; 21/03/2022
 14459                              <1> 	;	eax = start sector address of retro unix v2 fs
 14460                              <1> 	;
 14461                              <1> 	;	cf = 1 -> error, retro unix fs not found
 14462                              <1> 	;		(eax = 0)	
 14463                              <1> 	;
 14464                              <1> 	; Modified registers: esi, eax
 14465                              <1> 
 14466                              <1> 	ptBootable       equ 0
 14467                              <1> 	ptBeginHead      equ 1
 14468                              <1> 	ptBeginSector    equ 2
 14469                              <1> 	ptBeginCylinder  equ 3
 14470                              <1> 	ptFileSystemID   equ 4
 14471                              <1> 	ptEndHead        equ 5
 14472                              <1> 	ptEndSector      equ 6
 14473                              <1> 	ptEndCylinder    equ 7
 14474                              <1> 	ptStartSector    equ 8
 14475                              <1> 	ptSectors        equ 12
 14476                              <1> 
 14477                              <1> 	FS_RETROUNIX	 equ 71h ; runix v2 partition ID
 14478                              <1> 
 14479                              <1> 	;cmp	word [mbrbuf+510], 0AA55h
 14480 0000302C 6681BEFE01000055AA  <1> 	cmp	word [esi+510], 0AA55h
 14481 00003035 7515                <1> 	jne	short runix_p_nf
 14482                              <1> 
 14483                              <1> 	; partition table entries are at offset 1BEh
 14484                              <1> 	;mov	esi, mbrbuf+1BEh+ptFileSystemID
 14485 00003037 81C6C2010000        <1> 	add	esi, 1BEh+ptFileSystemID
 14486 0000303D 8D4640              <1> 	lea	eax, [esi+(4*16)] 
 14487                              <1> runix_p_bs_0:
 14488 00003040 803E71              <1> 	cmp	byte [esi], FS_RETROUNIX ; 71h
 14489 00003043 740B                <1> 	je	short runix_p_f ; it is retro unix partition
 14490 00003045 83C610              <1> 	add	esi, 16
 14491                              <1> 	;cmp	esi, mbrbuf+1BEh+ptFileSystemID+(4*16) 
 14492 00003048 39C6                <1> 	cmp	esi, eax
 14493 0000304A 72F4                <1> 	jb	short runix_p_bs_0 	  
 14494                              <1> runix_p_nf:
 14495 0000304C 29C0                <1> 	sub	eax, eax
 14496                              <1> 	; eax = 0
 14497 0000304E F9                  <1> 	stc
 14498 0000304F C3                  <1> 	retn
 14499                              <1> runix_p_f:
 14500                              <1> 	;mov	esi, [esi+ptStartSector-ptFileSystemID]
 14501 00003050 8B4604              <1> 	mov	eax, [esi+ptStartSector-ptFileSystemID]
 14502 00003053 C3                  <1> 	retn
 14503                              <1> 
 14504                              <1> ; 23/10/2015
 14505                              <1> com1_irq4:
 14506 00003054 [5C300000]          <1> 	dd dummy_retn
 14507                              <1> com2_irq3:
 14508 00003058 [5C300000]          <1> 	dd dummy_retn
 14509                              <1> 
 14510                              <1> dummy_retn:
 14511 0000305C C3                  <1> 	retn
 14512                                  %include 'u1.s'      ; 10/05/2015
 14513                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 14514                              <1> ; (re-write kernel for test by using previous version without a major defect)
 14515                              <1> ; ****************************************************************************
 14516                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS1.INC
 14517                              <1> ; Last Modification: 27/12/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.4)
 14518                              <1> ; ----------------------------------------------------------------------------
 14519                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 14520                              <1> ; (v0.1 - Beginning: 11/07/2012)
 14521                              <1> ;
 14522                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 14523                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 14524                              <1> ; <Bell Laboratories (17/3/1972)>
 14525                              <1> ; <Preliminary Release of UNIX Implementation Document>
 14526                              <1> ;
 14527                              <1> ; Retro UNIX 8086 v1 - U1.ASM (12/07/2014) //// UNIX v1 -> u1.s
 14528                              <1> ;
 14529                              <1> ; ****************************************************************************
 14530                              <1> 
 14531                              <1> unkni: ; / used for all system calls
 14532                              <1> sysent: ; < enter to system call >
 14533                              <1> 	; 27/12/2022
 14534                              <1> 	; 25/12/2021 (Retro UNIX 386 v1.2)
 14535                              <1> 	; 19/10/2015
 14536                              <1> 	; 21/09/2015
 14537                              <1> 	; 01/07/2015
 14538                              <1> 	; 19/05/2015
 14539                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14540                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 14541                              <1> 	;
 14542                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
 14543                              <1> 	; The trap type is determined and an indirect jump is made to 
 14544                              <1> 	; the appropriate system call handler. If there is a trap inside
 14545                              <1> 	; the system a jump to panic is made. All user registers are saved 
 14546                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
 14547                              <1> 	; instructor is decoded to get the the system code part (see
 14548                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
 14549                              <1> 	; the indirect jump address is calculated. If a bad system call is
 14550                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
 14551                              <1> 	; is called. If the call is legitimate control passes to the
 14552                              <1> 	; appropriate system routine.
 14553                              <1> 	;
 14554                              <1> 	; Calling sequence:
 14555                              <1> 	;	Through a trap caused by any sys call outside the system.
 14556                              <1> 	; Arguments:
 14557                              <1> 	;	Arguments of particular system call.	
 14558                              <1> 	; ...............................................................
 14559                              <1> 	;	
 14560                              <1> 	; Retro UNIX 8086 v1 modification: 
 14561                              <1> 	;       System call number is in EAX register.
 14562                              <1> 	;
 14563                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14564                              <1> 	;	registers depending of function details.
 14565                              <1>   	;
 14566                              <1> 	; 16/04/2015
 14567 0000305D 368925[9C6C0000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
 14568                              <1> 	; save user registers
 14569 00003064 1E                  <1> 	push	ds
 14570 00003065 06                  <1> 	push	es
 14571 00003066 0FA0                <1> 	push	fs
 14572 00003068 0FA8                <1> 	push	gs
 14573 0000306A 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
 14574                              <1> 	;
 14575                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
 14576                              <1> 	; 	(ESPACE is size of space in kernel stack 
 14577                              <1> 	;	for saving/restoring user registers.)
 14578                              <1> 	;
 14579 0000306B 50                  <1> 	push	eax ; 01/07/2015
 14580 0000306C 66B81000            <1> 	mov     ax, KDATA
 14581 00003070 8ED8                <1>         mov     ds, ax
 14582 00003072 8EC0                <1>         mov     es, ax
 14583 00003074 8EE0                <1>         mov     fs, ax
 14584 00003076 8EE8                <1>         mov     gs, ax
 14585 00003078 A1[68670000]        <1> 	mov	eax, [k_page_dir]
 14586 0000307D 0F22D8              <1> 	mov	cr3, eax
 14587 00003080 58                  <1> 	pop	eax ; 01/07/2015
 14588                              <1> 	; 19/10/2015
 14589 00003081 FC                  <1> 	cld
 14590                              <1> 	;
 14591 00003082 FE05[986C0000]      <1> 	inc	byte [sysflg]
 14592                              <1> 		; incb sysflg / indicate a system routine is in progress
 14593 00003088 FB                  <1>         sti 	; 18/01/2014
 14594                              <1> 	;jnz	panic ; 24/05/2013
 14595                              <1> 	; 04/12/2021
 14596 00003089 7405                <1> 	jz	short _1
 14597 0000308B E91BF9FFFF          <1> 	jmp	panic
 14598                              <1> 		; beq 1f
 14599                              <1> 		; jmp panic ; / called if trap inside system
 14600                              <1> ;1:
 14601                              <1> _1:	; 04/12/2021
 14602                              <1> 	; 16/04/2015
 14603 00003090 A3[A46C0000]        <1> 	mov	[u.r0], eax
 14604 00003095 8925[A06C0000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
 14605                              <1> 	;
 14606                              <1> 		; mov $s.syst+2,clockp
 14607                              <1> 		; mov r0,-(sp) / save user registers 
 14608                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
 14609                              <1> 			   ; / in u.r0
 14610                              <1> 		; mov r1,-(sp)
 14611                              <1> 		; mov r2,-(sp)
 14612                              <1> 		; mov r3,-(sp)
 14613                              <1> 		; mov r4,-(sp)
 14614                              <1> 		; mov r5,-(sp)
 14615                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
 14616                              <1> 		             ; / arithmetic unit
 14617                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
 14618                              <1> 		             ; / extended arithmetic unit
 14619                              <1> 		; mov sc,-(sp) / "step count" register for the extended
 14620                              <1> 		             ; / arithmetic unit
 14621                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
 14622                              <1> 		; mov 18.(sp),r0 / store pc in r0
 14623                              <1> 		; mov -(r0),r0 / sys inst in r0 10400xxx
 14624                              <1> 		; sub $sys,r0 / get xxx code
 14625 0000309B C1E002              <1> 	shl	eax, 2
 14626                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
 14627 0000309E 3DA4000000          <1> 	cmp	eax, end_of_syscalls - syscalls
 14628                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
 14629                              <1> 	;jnb	short badsys
 14630                              <1> 		; bhis badsys / yes, bad system call
 14631                              <1> 	; 25/12/2021
 14632 000030A3 7205                <1> 	jb	short _2
 14633 000030A5 E96D010000          <1> 	jmp	badsys
 14634                              <1> _2:
 14635                              <1> 	; 25/12/2021
 14636                              <1> 	;cmc
 14637                              <1> 	;pushf	
 14638                              <1> 	;push	eax
 14639 000030AA 8B2D[9C6C0000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
 14640                              <1> 	;mov	al, 0FEh ; 11111110b
 14641                              <1> 	;;adc	al, 0 ; al = al + cf
 14642                              <1> 	;and	[ebp+8], al ; flags (reset carry flag)
 14643 000030B0 806508FE            <1> 	and	byte [ebp+8], 0FEh ; 11111110b ; 25/12/2021
 14644                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
 14645                              <1> 				 ; / and clear carry bit
 14646                              <1> 	;pop	ebp ; eax
 14647 000030B4 89C5                <1> 	mov	ebp, eax ; 25/12/2021
 14648                              <1> 	;popf
 14649                              <1>         ;;jc	badsys
 14650                              <1> 	;; 04/12/2021
 14651                              <1> 	;jnc	short _3
 14652                              <1> 	;jmp	badsys
 14653                              <1> ;_3:
 14654 000030B6 A1[A46C0000]        <1> 	mov	eax, [u.r0]
 14655                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
 14656 000030BB FFA5[C1300000]      <1> 	jmp	dword [ebp+syscalls]
 14657                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
 14658                              <1> 		            ; / to proper system routine.
 14659                              <1> 
 14660                              <1> 	; 27/12/2022 (sysmemory)
 14661                              <1> 	; 09/01/2022
 14662                              <1> 	; 01/01/2022 (/etc/init error, BugFix efforts, test)
 14663                              <1> syscalls: ; 1:
 14664                              <1> 	; 21/09/2015
 14665                              <1> 	; 01/07/2015
 14666                              <1> 	; 16/04/2015 (32 bit address modification) 
 14667 000030C1 [E1310000]          <1> 	dd sysrele	; / 0
 14668 000030C5 [89320000]          <1> 	dd sysexit 	; / 1
 14669 000030C9 [B3330000]          <1> 	dd sysfork 	; / 2
 14670 000030CD [B8340000]          <1> 	dd sysread 	; / 3
 14671 000030D1 [CD340000]          <1> 	dd syswrite 	; / 4
 14672 000030D5 [30350000]          <1> 	dd sysopen 	; / 5
 14673 000030D9 [59360000]          <1> 	dd sysclose 	; / 6
 14674 000030DD [2E330000]          <1> 	dd syswait 	; / 7
 14675 000030E1 [C1350000]          <1> 	dd syscreat 	; / 8
 14676 000030E5 [0F3A0000]          <1> 	dd syslink 	; / 9
 14677 000030E9 [9D3A0000]          <1> 	dd sysunlink 	; / 10
 14678 000030ED [BD3B0000]          <1> 	dd sysexec 	; / 11
 14679 000030F1 [2A420000]          <1> 	dd syschdir 	; / 12
 14680 000030F5 [2C430000]          <1> 	dd systime 	; / 13
 14681 000030F9 [08360000]          <1> 	dd sysmkdir 	; / 14
 14682 000030FD [69420000]          <1> 	dd syschmod 	; / 15
 14683 00003101 [98420000]          <1> 	dd syschown 	; / 16
 14684 00003105 [60430000]          <1> 	dd sysbreak 	; / 17
 14685 00003109 [603F0000]          <1> 	dd sysstat 	; / 18
 14686 0000310D [6E440000]          <1> 	dd sysseek 	; / 19
 14687 00003111 [80440000]          <1> 	dd systell 	; / 20
 14688 00003115 [2E540000]          <1> 	dd sysmount 	; / 21
 14689 00003119 [47550000]          <1> 	dd sysumount 	; / 22
 14690 0000311D [F1440000]          <1> 	dd syssetuid 	; / 23
 14691 00003121 [26450000]          <1> 	dd sysgetuid 	; / 24
 14692 00003125 [3B430000]          <1> 	dd sysstime 	; / 25
 14693 00003129 [E5440000]          <1> 	dd sysquit 	; / 26
 14694 0000312D [D9440000]          <1> 	dd sysintr 	; / 27
 14695 00003131 [473F0000]          <1> 	dd sysfstat 	; / 28
 14696 00003135 [74360000]          <1> 	dd sysemt 	; / 29
 14697 00003139 [C2360000]          <1> 	dd sysmdate 	; / 30
 14698 0000313D [1F370000]          <1> 	dd sysstty 	; / 31
 14699 00003141 [09390000]          <1> 	dd sysgtty 	; / 32
 14700 00003145 [BD360000]          <1> 	dd sysilgins 	; / 33
 14701 00003149 [FA5C0000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
 14702                              <1> 			     ; 11/06/2014
 14703 0000314D [275D0000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
 14704                              <1> 			     ; 01/07/2015
 14705 00003151 [FF5D0000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
 14706                              <1> 			     ; 21/09/2015 - get last error number
 14707                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 14708                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 14709 00003155 [3F450000]          <1> 	dd syssetgid	; 37
 14710 00003159 [62450000]          <1> 	dd sysgetgid	; 38
 14711                              <1> 	; 18/06/2021 - Retro UNIX 386 v2 (ref: TRDOS 386 v2)
 14712 0000315D [77450000]          <1> 	dd sysver	; 39 ; (get) Retro Unix 386 version
 14713                              <1> 	; 27/12/2022 - Retro UNIX 386 v1.2
 14714 00003161 [265E0000]          <1> 	dd sysmemory	; 40 ; get available (total&free) memory 	
 14715                              <1> 
 14716                              <1> end_of_syscalls:
 14717                              <1> 
 14718                              <1> error:
 14719                              <1> 	; 11/12/2021 (Retro UNIX 386 v1.2)
 14720                              <1> 	; 17/09/2015
 14721                              <1> 	; 03/09/2015
 14722                              <1> 	; 01/09/2015
 14723                              <1> 	; 09/06/2015
 14724                              <1> 	; 13/05/2015
 14725                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14726                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 14727                              <1> 	;
 14728                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
 14729                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
 14730                              <1> 	;
 14731                              <1> 	; INPUTS -> none
 14732                              <1> 	; OUTPUTS ->
 14733                              <1> 	;	processor status - carry (c) bit is set (means error)
 14734                              <1> 	;
 14735                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
 14736                              <1> 	; 	      Because, jumps to error procedure
 14737                              <1> 	;	      disrupts push-pop nesting balance)
 14738                              <1> 	;
 14739 00003165 8B2D[9C6C0000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
 14740 0000316B 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
 14741                              <1> 				 ; (system call will return with cf = 1)
 14742                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
 14743                              <1> 		               ; / users stack
 14744                              <1> 	; 17/09/2015
 14745 0000316F 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
 14746                              <1> 				 ; for saving/restoring user registers	
 14747                              <1> 	;cmp	ebp, [u.usp]
 14748                              <1> 	;je	short err0	
 14749 00003172 892D[A06C0000]      <1> 	mov	[u.usp], ebp
 14750                              <1> ;err0:
 14751                              <1> 	; 01/09/2015
 14752 00003178 8B25[A06C0000]      <1> 	mov	esp, [u.usp]	; Retro Unix 8086 v1 modification!
 14753                              <1> 				; 10/04/2013
 14754                              <1> 				; (If an I/O error occurs during disk I/O,
 14755                              <1> 				; related procedures will jump to 'error'
 14756                              <1> 				; procedure directly without returning to 
 14757                              <1> 				; the caller procedure. So, stack pointer
 14758                              <1> 				; must be restored here.)
 14759                              <1> 	; 13/05/2015
 14760                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
 14761                              <1> 	;	'get last error' system call later. 	
 14762                              <1> 
 14763                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
 14764 0000317E C605[166D0000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
 14765                              <1> 
 14766                              <1> sysret: ; < return from system call>
 14767                              <1> 	; 11/12/2021
 14768                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 14769                              <1> 	; 30/11/2021
 14770                              <1> 	; 10/09/2015
 14771                              <1> 	; 29/07/2015
 14772                              <1> 	; 25/06/2015
 14773                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14774                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 14775                              <1> 	;
 14776                              <1> 	; 'sysret' first checks to see if process is about to be 
 14777                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
 14778                              <1> 	; If not, following happens:	 
 14779                              <1> 	; 	1) The user's stack pointer is restored.
 14780                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
 14781                              <1> 	;	   i-node has been modified. If it has, it is written out
 14782                              <1> 	;	   via 'ppoke'.
 14783                              <1> 	;	3) If the super block has been modified, it is written out
 14784                              <1> 	;	   via 'ppoke'.				
 14785                              <1> 	;	4) If the dismountable file system's super block has been
 14786                              <1> 	;	   modified, it is written out to the specified device
 14787                              <1> 	;	   via 'ppoke'.
 14788                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
 14789                              <1> 	;	   during his execution. If so, 'tswap' is called to give
 14790                              <1> 	;	   another user a chance to run.
 14791                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
 14792                              <1> 	;	    (See 'sysrele' for conclusion.)		
 14793                              <1> 	;
 14794                              <1> 	; Calling sequence:
 14795                              <1> 	;	jump table or 'br sysret'
 14796                              <1> 	; Arguments: 
 14797                              <1> 	;	-	
 14798                              <1> 	; ...............................................................
 14799                              <1> 	;	
 14800                              <1> 	; ((AX=r1 for 'iget' input))
 14801                              <1> 	;	
 14802                              <1> 	;xor	ax, ax ; 04/05/2013
 14803                              <1> 	; 30/11/2021
 14804 00003185 31C0                <1> 	xor	eax, eax
 14805                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
 14806 00003187 FEC0                <1> 	inc	al ; 04/05/2013
 14807 00003189 3805[F46C0000]      <1> 	cmp	[u.bsys], al ; 1
 14808                              <1> 		; tstb u.bsys / is a process about to be terminated because
 14809                              <1> 	;jnb	sysexit ; 04/05/2013
 14810                              <1> 	;	; bne sysexit / of an error? yes, go to sysexit
 14811                              <1> 	; 04/12/2021
 14812 0000318F 720F                <1> 	jb	short _3
 14813                              <1> 	; 11/12/2021
 14814 00003191 C705[186D0000]0100- <1> 	mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
 14815 00003199 0000                <1>
 14816 0000319B E9E9000000          <1> 	jmp	sysexit
 14817                              <1> _3:
 14818                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
 14819                              <1> 		; mov u.sp,sp / no point stack to users stack
 14820 000031A0 FEC8                <1> 	dec 	al ; mov ax, 0
 14821                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
 14822 000031A2 E8CE190000          <1> 	call	iget
 14823                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
 14824                              <1> 		            ; / it is written out
 14825                              <1> 	;xor 	ax, ax ; 0
 14826                              <1> 	; 30/11/2021
 14827 000031A7 31C0                <1> 	xor	eax, eax
 14828 000031A9 3805[966C0000]      <1> 	cmp	[smod], al ; 0
 14829                              <1> 		; tstb	smod / has the super block been modified
 14830 000031AF 7614                <1> 	jna	short sysret1
 14831                              <1> 		; beq	1f / no, 1f
 14832 000031B1 A2[966C0000]        <1> 	mov	[smod], al ; 0
 14833                              <1> 		; clrb smod / yes, clear smod
 14834 000031B6 BB[4C6D0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
 14835 000031BB 66810B0002          <1>    	or	word [ebx], 200h ;;
 14836                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
 14837                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
 14838                              <1> 		      	      ; / output
 14839                              <1> 	; AX = 0
 14840 000031C0 E86F280000          <1> 	call 	poke ; 07/08/2013
 14841                              <1> 	;call	ppoke
 14842                              <1> 	; AX = 0
 14843                              <1> 		; jsr r0,ppoke / write out modified super block to disk
 14844                              <1> sysret1: ;1:
 14845 000031C5 3805[976C0000]      <1> 	cmp	[mmod], al ; 0
 14846                              <1> 		; tstb	mmod / has the super block for the dismountable file
 14847                              <1> 		           ; / system
 14848 000031CB 7614                <1> 	jna	short sysrel0
 14849                              <1> 		; beq 1f / been modified?  no, 1f
 14850 000031CD A2[976C0000]        <1> 	mov	[mmod], al ; 0	
 14851                              <1> 		; clrb	mmod / yes, clear mmod
 14852                              <1>         ;mov    ax, [mntd]
 14853                              <1>         ;;mov   al, [mdev] ; 26/04/2013
 14854 000031D2 BB[546F0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
 14855                              <1>         ;;mov	[ebx], al
 14856                              <1> 	;mov    [sb1], al
 14857                              <1> 		; movb	mntd,sb1 / set the I/O queue
 14858 000031D7 66810B0002          <1> 	or	word [ebx], 200h
 14859                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
 14860                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
 14861 000031DC E853280000          <1> 	call	poke ; 07/08/2013
 14862                              <1> 	;call	ppoke 
 14863                              <1> 		; jsr r0,ppoke / write it out to its device
 14864                              <1>         ;xor    al, al ; 26/04/2013       
 14865                              <1> ;1:
 14866                              <1> 		; tstb uquant / is the time quantum 0?
 14867                              <1> 		; bne 1f / no, don't swap it out
 14868                              <1> 
 14869                              <1> sysrele: ; < release >
 14870                              <1> 	; 14/10/2015
 14871                              <1> 	; 01/09/2015
 14872                              <1> 	; 24/07/2015
 14873                              <1> 	; 14/05/2015
 14874                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14875                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
 14876                              <1> 	;
 14877                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
 14878                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
 14879                              <1> 	; turns off the system flag. It then checked to see if there is
 14880                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
 14881                              <1> 	; the output gets flashed (see isintr) and interrupt action is
 14882                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
 14883                              <1> 	; the user, a rti is made.
 14884                              <1> 	;
 14885                              <1> 	; Calling sequence:
 14886                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
 14887                              <1> 	; Arguments:
 14888                              <1> 	;	-	
 14889                              <1> 	; ...............................................................
 14890                              <1> 	;	
 14891                              <1> 	; 23/02/2014 (swapret)
 14892                              <1> 	; 22/09/2013
 14893                              <1> sysrel0: ;1:
 14894 000031E1 803D[EC6C0000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
 14895                              <1> 		; tstb uquant / is the time quantum 0?
 14896 000031E8 7705                <1>         ja      short swapret
 14897                              <1> 		; bne 1f / no, don't swap it out
 14898                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
 14899 000031EA E808140000          <1> 	call	tswap
 14900                              <1> 		; jsr r0,tswap / yes, swap it out
 14901                              <1> ;
 14902                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
 14903                              <1> swapret: ;1:
 14904                              <1> 	; 10/09/2015
 14905                              <1> 	; 01/09/2015
 14906                              <1> 	; 14/05/2015
 14907                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
 14908                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
 14909                              <1> 	; cli
 14910                              <1> 	; 24/07/2015
 14911                              <1> 	;
 14912                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
 14913                              <1> 	;; mov	esp, [u.usp]
 14914                              <1> 
 14915                              <1> 	; 22/09/2013
 14916 000031EF E8DA150000          <1> 	call	isintr
 14917                              <1> 	; 20/10/2013
 14918 000031F4 7405                <1> 	jz	short sysrel1
 14919 000031F6 E877000000          <1> 	call	intract
 14920                              <1> 		; jsr r0,isintr / is there an interrupt from the user
 14921                              <1> 		;     br intract / yes, output gets flushed, take interrupt
 14922                              <1> 		               ; / action
 14923                              <1> sysrel1:
 14924 000031FB FA                  <1> 	cli ; 14/10/2015
 14925 000031FC FE0D[986C0000]      <1> 	dec	byte [sysflg]
 14926                              <1> 		; decb sysflg / turn system flag off
 14927 00003202 A1[046D0000]        <1> 	mov     eax, [u.pgdir]
 14928 00003207 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
 14929                              <1> 			  ; (others are different than kernel page tables) 
 14930                              <1> 	; 10/09/2015
 14931 0000320A 61                  <1> 	popad ; edi, esi, ebp, temp (increment esp by 4), ebx, edx, ecx, eax
 14932                              <1> 		; mov (sp)+,sc / restore user registers
 14933                              <1> 		; mov (sp)+,mq
 14934                              <1> 		; mov (sp)+,ac
 14935                              <1> 		; mov (sp)+,r5
 14936                              <1> 		; mov (sp)+,r4
 14937                              <1> 		; mov (sp)+,r3
 14938                              <1> 		; mov (sp)+,r2
 14939                              <1> 	;
 14940 0000320B A1[A46C0000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
 14941 00003210 0FA9                <1> 	pop	gs
 14942 00003212 0FA1                <1> 	pop	fs
 14943 00003214 07                  <1> 	pop	es
 14944 00003215 1F                  <1> 	pop	ds
 14945 00003216 CF                  <1> 	iretd	
 14946                              <1> 		; rti / no, return from interrupt
 14947                              <1> 
 14948                              <1> badsys:
 14949                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14950                              <1> 	; (Major Modification: 'core' dumping procedure in
 14951                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
 14952                              <1> 	;	has been changed to print 'Invalid System Call !'
 14953                              <1> 	;	message on the user's console tty.)
 14954                              <1> 	; (EIP, EAX values will be shown on screen with error message)
 14955                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
 14956                              <1> 	; (EAX = Function number)  
 14957                              <1> 	;
 14958 00003217 FE05[F46C0000]      <1> 	inc	byte [u.bsys]
 14959                              <1> 	;
 14960 0000321D 8B1D[9C6C0000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
 14961 00003223 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
 14962 00003225 E8B8E3FFFF          <1> 	call	dwordtohex
 14963 0000322A 8915[C8640000]      <1> 	mov	[bsys_msg_eip], edx
 14964 00003230 A3[CC640000]        <1> 	mov	[bsys_msg_eip+4], eax
 14965 00003235 A1[A46C0000]        <1> 	mov	eax, [u.r0]
 14966 0000323A E8A3E3FFFF          <1> 	call	dwordtohex
 14967 0000323F 8915[B8640000]      <1> 	mov	[bsys_msg_eax], edx
 14968 00003245 A3[BC640000]        <1> 	mov	[bsys_msg_eax+4], eax
 14969                              <1> 	; 11/12/2021
 14970                              <1> 	;xor	eax, eax
 14971                              <1> 	;mov	dword [u.base], badsys_msg ; "Invalid System Call !"
 14972                              <1> 	;mov	ebx, [u.fofp]
 14973                              <1> 	;mov	[ebx], eax
 14974                              <1> 	;;mov	eax, 1 ; inode number of console tty (for user)	
 14975                              <1> 	;inc	eax
 14976                              <1> 	; 11/12/2021 - Retro UNIX 386 v2 fs compatibility 
 14977                              <1> 	; (Retro UNIX 386 v1.2)
 14978                              <1> 	;mov	al, 8 ; /dev/tty inode number (runix v2 fs)
 14979                              <1> 	;; eax = 8 ; inode number of console tty (for user)	
 14980                              <1> 	;mov	dword [u.count], BSYS_M_SIZE
 14981                              <1> 		; writei
 14982                              <1> 		; INPUTS ->
 14983                              <1> 		;    r1 - inode number
 14984                              <1> 		;    u.count - byte count to be written
 14985                              <1> 		;    u.base - points to user buffer
 14986                              <1> 		;    u.fofp - points to word with current file offset
 14987                              <1> 		; OUTPUTS ->
 14988                              <1> 		;    u.count - cleared
 14989                              <1> 		;    u.nread - accumulates total bytes passed back	
 14990                              <1> 		;
 14991                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
 14992                              <1> 	;call	writei
 14993                              <1> 	;;mov	eax, 1
 14994                              <1> 	;jmp	sysexit
 14995                              <1> 
 14996                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 14997 0000324A BE[99640000]        <1> 	mov	esi, badsys_msg ; "Invalid System Call !"
 14998 0000324F 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 14999 00003256 8A83[A3680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 15000 0000325C C605[97670000]0F    <1> 	mov	byte [ccolor], 0Fh ; white (message) color
 15001 00003263 A2[D96C0000]        <1> 	mov 	[u.ttyn], al ; current (active) tty (for user)
 15002 00003268 E8772B0000          <1> 	call	print_cmsg
 15003                              <1> 	;mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
 15004 0000326D E9F3FEFFFF          <1> 	jmp	error
 15005                              <1> 
 15006                              <1> 		; incb u.bsys / turn on the user's bad-system flag
 15007                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
 15008                              <1> 		; jsr r0,namei / get the i-number for the core image file
 15009                              <1> 		; br 1f / error
 15010                              <1> 		; neg r1 / negate the i-number to open the core image file
 15011                              <1> 		       ; / for writing
 15012                              <1> 		; jsr r0,iopen / open the core image file
 15013                              <1> 		; jsr r0,itrunc / free all associated blocks
 15014                              <1> 		; br 2f
 15015                              <1> ;1:
 15016                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
 15017                              <1> 		; jsr r0,maknod / make an i-node
 15018                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
 15019                              <1> ;2:
 15020                              <1> 		; mov $core,u.base / move address core to u.base
 15021                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
 15022                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
 15023                              <1> 		; clr u.off / clear user offset
 15024                              <1> 		; jsr r0,writei / write out the core image to the user
 15025                              <1> 		; mov $user,u.base / pt. u.base to user
 15026                              <1> 		; mov $64.,u.count / u.count = 64
 15027                              <1> 		; jsr r0,writei / write out all the user parameters
 15028                              <1> 		; neg r1 / make i-number positive
 15029                              <1> 		; jsr r0,iclose / close the core image file
 15030                              <1> 		; br sysexit /
 15031                              <1> ;3:
 15032                              <1> 		; <core\0\0>
 15033                              <1> 
 15034                              <1> intract: ; / interrupt action
 15035                              <1> 	; 14/10/2015
 15036                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15037                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
 15038                              <1> 	;
 15039                              <1> 	; Retro UNIX 8086 v1 modification !
 15040                              <1> 	; (Process/task switching and quit routine by using
 15041                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 15042                              <1> 	;
 15043                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
 15044                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
 15045                              <1> 	;		'intract' will jump to 'sysexit'.
 15046                              <1> 	;	    Intract will return to the caller 
 15047                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
 15048                              <1> 	; 14/10/2015
 15049 00003272 FB                  <1> 	sti
 15050                              <1> 	; 07/12/2013	
 15051 00003273 66FF05[F26C0000]    <1> 	inc 	word [u.quit]
 15052 0000327A 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
 15053 0000327C 66FF0D[F26C0000]    <1> 	dec	word [u.quit]
 15054                              <1> 	; 16/04/2015
 15055 00003283 C3                  <1> 	retn
 15056                              <1> intrct0:	
 15057 00003284 58                  <1> 	pop	eax ; call intract -> retn
 15058                              <1> 	;
 15059 00003285 31C0                <1> 	xor 	eax, eax
 15060 00003287 FEC0                <1> 	inc	al  ; mov ax, 1
 15061                              <1> ;;;
 15062                              <1> 	; UNIX v1 original 'intract' routine... 
 15063                              <1> 	; / interrupt action
 15064                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
 15065                              <1> 		; bne 1f / no, 1f
 15066                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
 15067                              <1> 	; 1: / now in user area
 15068                              <1> 		; mov r1,-(sp) / save r1
 15069                              <1> 		; mov u.ttyp,r1 
 15070                              <1> 			; / pointer to tty buffer in control-to r1
 15071                              <1> 		; cmpb 6(r1),$177
 15072                              <1> 			; / is the interrupt char equal to "del"
 15073                              <1> 		; beq 1f / yes, 1f
 15074                              <1> 		; clrb 6(r1) 
 15075                              <1> 		        ; / no, clear the byte 
 15076                              <1> 			; / (must be a quit character)
 15077                              <1> 		; mov (sp)+,r1 / restore r1
 15078                              <1> 		; clr u.quit / clear quit flag
 15079                              <1> 		; bis $20,2(sp) 
 15080                              <1> 		    	; / set trace for quit (sets t bit of 
 15081                              <1> 			; / ps-trace trap)
 15082                              <1> 		; rti   ;  / return from interrupt
 15083                              <1> 	; 1: / interrupt char = del
 15084                              <1> 		; clrb 6(r1) / clear the interrupt byte 
 15085                              <1> 			   ; / in the buffer
 15086                              <1> 		; mov (sp)+,r1 / restore r1
 15087                              <1> 		; cmp u.intr,$core / should control be 
 15088                              <1> 				; / transferred to loc core?
 15089                              <1> 		; blo 1f
 15090                              <1> 		; jmp *u.intr / user to do rti yes, 
 15091                              <1> 				; / transfer to loc core
 15092                              <1> 	; 1:
 15093                              <1> 		; sys 1 / exit
 15094                              <1> 
 15095                              <1> sysexit: ; <terminate process>
 15096                              <1> 	; 17/07/2022
 15097                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
 15098                              <1> 	; 01/09/2015
 15099                              <1> 	; 31/08/2015
 15100                              <1> 	; 14/05/2015
 15101                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15102                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 15103                              <1> 	;
 15104                              <1> 	; 'sysexit' terminates a process. First each file that
 15105                              <1> 	; the process has opened is closed by 'flose'. The process
 15106                              <1> 	; status is then set to unused. The 'p.pid' table is then
 15107                              <1> 	; searched to find children of the dying process. If any of
 15108                              <1> 	; children are zombies (died by not waited for), they are
 15109                              <1> 	; set free. The 'p.pid' table is then searched to find the
 15110                              <1> 	; dying process's parent. When the parent is found, it is
 15111                              <1> 	; checked to see if it is free or it is a zombie. If it is
 15112                              <1> 	; one of these, the dying process just dies. If it is waiting
 15113                              <1> 	; for a child process to die, it notified that it doesn't 
 15114                              <1> 	; have to wait anymore by setting it's status from 2 to 1
 15115                              <1> 	; (waiting to active). It is awakened and put on runq by
 15116                              <1> 	; 'putlu'. The dying process enters a zombie state in which
 15117                              <1> 	; it will never be run again but stays around until a 'wait'
 15118                              <1> 	; is completed by it's parent process. If the parent is not
 15119                              <1> 	; found, process just dies. This means 'swap' is called with
 15120                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
 15121                              <1> 	; to write out the process and 'rswap' reads the new process
 15122                              <1> 	; over the one that dies..i.e., the dying process is 
 15123                              <1> 	; overwritten and destroyed.	
 15124                              <1>  	;
 15125                              <1> 	; Calling sequence:
 15126                              <1> 	;	sysexit or conditional branch.
 15127                              <1> 	; Arguments:
 15128                              <1> 	;	-	
 15129                              <1> 	; ...............................................................
 15130                              <1> 	;	
 15131                              <1> 	; Retro UNIX 8086 v1 modification: 
 15132                              <1> 	;       System call number (=1) is in EAX register.
 15133                              <1> 	;
 15134                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 15135                              <1> 	;       registers depending of function details.
 15136                              <1> 	;
 15137                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
 15138                              <1> 	;
 15139                              <1> ; / terminate process
 15140                              <1> 	; AX = 1
 15141                              <1> 	;dec 	ax ; 0
 15142                              <1> 	; 30/11/2021
 15143 00003289 48                  <1> 	dec	eax ; 0
 15144 0000328A 66A3[F06C0000]      <1> 	mov	[u.intr], ax ; 0
 15145                              <1> 		; clr u.intr / clear interrupt control word
 15146                              <1> 		; clr r1 / clear r1
 15147                              <1> 	; AX = 0
 15148                              <1> sysexit_1: ; 1:
 15149                              <1> 	; AX = File descriptor
 15150                              <1> 		; / r1 has file descriptor (index to u.fp list)
 15151                              <1> 		; / Search the whole list
 15152 00003290 E8690D0000          <1> 	call	fclose
 15153                              <1> 		; jsr r0,fclose / close all files the process opened
 15154                              <1> 	;; ignore error return
 15155                              <1> 		; br .+2 / ignore error return
 15156                              <1> 	;inc	ax
 15157 00003295 FEC0                <1> 	inc	al
 15158                              <1> 		; inc r1 / increment file descriptor
 15159                              <1> 	;cmp	ax, 10
 15160 00003297 3C0A                <1> 	cmp	al, 10
 15161                              <1> 		; cmp r1,$10. / end of u.fp list?
 15162 00003299 72F5                <1> 	jb	short sysexit_1
 15163                              <1> 		; blt 1b / no, go back
 15164 0000329B 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 15165                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
 15166 000032A2 88A3[C3680000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 15167                              <1> 		; clrb p.stat-1(r1) / free the process
 15168                              <1> 	;shl	bx, 1
 15169 000032A8 D0E3                <1> 	shl	bl, 1
 15170                              <1> 		; asl r1 / use r1 for index into the below tables
 15171 000032AA 668B8B[62680000]    <1> 	mov	cx, [ebx+p.pid-2]
 15172                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
 15173 000032B1 668B93[82680000]    <1> 	mov	dx, [ebx+p.ppid-2]
 15174                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
 15175                              <1> 	; xor 	bx, bx ; 0
 15176 000032B8 30DB                <1> 	xor	bl, bl ; 0
 15177                              <1> 		; clr r2
 15178 000032BA 31F6                <1> 	xor	esi, esi ; 0
 15179                              <1> 		; clr r5 / initialize reg
 15180                              <1> sysexit_2: ; 1:
 15181                              <1> 	        ; / find children of this dying process, 
 15182                              <1> 		; / if they are zombies, free them
 15183                              <1> 	;add	bx, 2
 15184 000032BC 80C302              <1> 	add	bl, 2
 15185                              <1> 		; add $2,r2 / search parent process table 
 15186                              <1> 		          ; / for dying process's name
 15187 000032BF 66398B[82680000]    <1> 	cmp	[ebx+p.ppid-2], cx
 15188                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
 15189 000032C6 7513                <1> 	jne	short sysexit_4
 15190                              <1> 		; bne 3f / no
 15191                              <1> 	;shr	bx, 1
 15192 000032C8 D0EB                <1> 	shr	bl, 1
 15193                              <1> 		; asr r2 / yes, it is a parent
 15194 000032CA 80BB[C3680000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
 15195                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
 15196                              <1> 				     ; / dying process a zombie
 15197 000032D1 7506                <1> 	jne	short sysexit_3 
 15198                              <1> 		; bne 2f / no
 15199 000032D3 88A3[C3680000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 15200                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
 15201                              <1> sysexit_3: ; 2:
 15202                              <1> 	;shr	bx, 1
 15203 000032D9 D0E3                <1> 	shl	bl, 1
 15204                              <1> 		; asl r2
 15205                              <1> sysexit_4: ; 3:
 15206                              <1> 		; / search the process name table 
 15207                              <1> 		; / for the dying process's parent
 15208 000032DB 663993[62680000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
 15209                              <1> 		; cmp p.pid-2(r2),r4 / found it?
 15210 000032E2 7502                <1> 	jne	short sysexit_5
 15211                              <1> 		; bne 3f / no
 15212 000032E4 89DE                <1> 	mov	esi, ebx
 15213                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
 15214                              <1> 		          ; / process # x2) in r5
 15215                              <1> sysexit_5: ; 3:
 15216                              <1> 	;cmp	bx, nproc + nproc
 15217 000032E6 80FB20              <1> 	cmp	bl, nproc + nproc
 15218                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
 15219 000032E9 72D1                <1> 	jb	short sysexit_2
 15220                              <1> 		; blt 1b / no, go back
 15221                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
 15222 000032EB 21F6                <1> 	and	esi, esi ; r5=r1
 15223 000032ED 7430                <1> 	jz	short sysexit_6
 15224                              <1> 		; beq 2f / no parent has been found. 
 15225                              <1> 		       ; / The process just dies
 15226                              <1> 	;shr	si, 1
 15227                              <1> 	; 17/07/2022
 15228 000032EF D1EE                <1> 	shr	esi, 1
 15229                              <1> 		; asr r1 / set up index to p.stat
 15230 000032F1 8A86[C3680000]      <1> 	mov	al, [esi+p.stat-1]
 15231                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
 15232 000032F7 20C0                <1> 	and	al, al
 15233 000032F9 7424                <1> 	jz	short sysexit_6
 15234                              <1> 		; beq 2f / if its been freed, 2f
 15235 000032FB 3C03                <1> 	cmp	al, 3
 15236                              <1> 		; cmp r2,$3 / is parent a zombie?
 15237 000032FD 7420                <1> 	je	short sysexit_6
 15238                              <1> 		; beq 2f / yes, 2f
 15239                              <1> 	; BH = 0
 15240 000032FF 8A1D[F56C0000]      <1> 	mov	bl, [u.uno]
 15241                              <1> 		; movb u.uno,r3 / move dying process's number to r3
 15242 00003305 C683[C3680000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
 15243                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
 15244                              <1> 	; 05/02/2014
 15245 0000330C 3C01                <1> 	cmp	al, 1 ; SRUN
 15246 0000330E 740F                <1> 	je	short sysexit_6
 15247                              <1> 	;cmp	al, 2
 15248                              <1> 		; cmp r2,$2 / is the parent waiting for 
 15249                              <1> 			  ; / this child to die
 15250                              <1> 	;jne	short sysexit_6	
 15251                              <1> 		; bne 2f / yes, notify parent not to wait any more
 15252                              <1> 	; 05/02/2014
 15253                              <1> 	; p.stat = 2 --> waiting
 15254                              <1> 	; p.stat = 4 --> sleeping
 15255 00003310 C686[C3680000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
 15256                              <1> 	;dec	byte [esi+p.stat-1]
 15257                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
 15258 00003317 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
 15259                              <1> 	; 
 15260                              <1> 	;mov	ebx, runq + 4
 15261                              <1> 		; mov $runq+4,r2 / on the runq
 15262 0000331A E8AF130000          <1> 	call	putlu
 15263                              <1> 		; jsr r0, putlu
 15264                              <1> sysexit_6: ; 2:
 15265                              <1> 	; 31/08/2015
 15266                              <1> 		; / the process dies
 15267 0000331F C605[F56C0000]00    <1> 	mov	byte [u.uno], 0
 15268                              <1> 		; clrb u.uno / put zero as the process number, 
 15269                              <1> 	           ; / so "swap" will
 15270 00003326 E8D6120000          <1> 	call	swap
 15271                              <1> 		; jsr r0,swap / overwrite process with another process
 15272                              <1> hlt_sys:
 15273                              <1> 	;sti ; 18/01/2014
 15274                              <1> hlts0:
 15275 0000332B F4                  <1> 	hlt
 15276 0000332C EBFD                <1> 	jmp	short hlts0
 15277                              <1> 		; 0 / and thereby kill it; halt?
 15278                              <1> 
 15279                              <1> syswait: ; < wait for a processs to die >
 15280                              <1> 	; 09/02/2022
 15281                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 15282                              <1> 	; 17/09/2015
 15283                              <1> 	; 02/09/2015
 15284                              <1> 	; 01/09/2015
 15285                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15286                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
 15287                              <1> 	;
 15288                              <1> 	; 'syswait' waits for a process die. 
 15289                              <1> 	; It works in following way:
 15290                              <1> 	;    1) From the parent process number, the parent's 
 15291                              <1> 	; 	process name is found. The p.ppid table of parent
 15292                              <1> 	;	names is then searched for this process name.
 15293                              <1> 	;	If a match occurs, r2 contains child's process
 15294                              <1> 	;	number. The child status is checked to see if it is
 15295                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
 15296                              <1> 	;	If it is, the child process is freed and it's name
 15297                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
 15298                              <1> 	;	If the child is not a zombie, nothing happens and
 15299                              <1> 	;	the search goes on through the p.ppid table until
 15300                              <1> 	;	all processes are checked or a zombie is found.
 15301                              <1> 	;    2) If no zombies are found, a check is made to see if
 15302                              <1> 	;	there are any children at all. If there are none,
 15303                              <1> 	;	an error return is made. If there are, the parent's
 15304                              <1> 	;	status is set to 2 (waiting for child to die),
 15305                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
 15306                              <1> 	;	is made to wait on the next process.
 15307                              <1> 	;
 15308                              <1> 	; Calling sequence:
 15309                              <1> 	;	?
 15310                              <1> 	; Arguments:
 15311                              <1> 	;	-
 15312                              <1> 	; Inputs: - 
 15313                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
 15314                              <1> 	; ...............................................................
 15315                              <1> 	;				
 15316                              <1> 	
 15317                              <1> ; / wait for a process to die
 15318                              <1> 
 15319                              <1> syswait_0:
 15320 0000332E 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 15321                              <1> 		; movb u.uno,r1 / put parents process number in r1
 15322 00003335 D0E3                <1> 	shl	bl, 1
 15323                              <1> 	;shl	bx, 1
 15324                              <1> 		; asl r1 / x2 to get index into p.pid table
 15325 00003337 668B83[62680000]    <1> 	mov	ax, [ebx+p.pid-2]
 15326                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
 15327 0000333E 31F6                <1> 	xor	esi, esi
 15328                              <1> 		; clr r2
 15329 00003340 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
 15330                              <1> 	;xor 	cl, cl
 15331                              <1> 		; clr r3 / initialize reg 3
 15332                              <1> syswait_1: ; 1:
 15333                              <1> 	; 09/02/2022
 15334 00003342 46                  <1> 	inc	esi
 15335 00003343 46                  <1> 	inc	esi
 15336                              <1> 	;add	si, 2
 15337                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
 15338                              <1> 			  ; / search table of parent processes 
 15339                              <1> 			  ; / for this process name
 15340 00003344 663B86[82680000]    <1> 	cmp	ax, [esi+p.ppid-2]
 15341                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
 15342                              <1> 			            ; / process number
 15343 0000334B 7531                <1> 	jne	short syswait_3
 15344                              <1> 		; bne 3f / branch if no match of parent process name
 15345                              <1> 	;inc	cx
 15346 0000334D FEC1                <1> 	inc	cl
 15347                              <1> 		; inc r3 / yes, a match, r3 indicates number of children
 15348                              <1> 	; 09/02/2022
 15349 0000334F D1EE                <1> 	shr	esi, 1
 15350                              <1> 	;shr	si, 1
 15351                              <1> 		; asr r2 / r2/2 to get index to p.stat table
 15352                              <1> 	; The possible states ('p.stat' values) of a process are:
 15353                              <1> 	;	0 = free or unused
 15354                              <1> 	;	1 = active
 15355                              <1> 	;	2 = waiting for a child process to die
 15356                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
 15357 00003351 80BE[C3680000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
 15358                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
 15359 00003358 7522                <1> 	jne	short syswait_2
 15360                              <1> 		; bne 2f / no, skip it
 15361 0000335A 88BE[C3680000]      <1> 	mov	[esi+p.stat-1], bh ; 0
 15362                              <1> 		; clrb p.stat-1(r2) / yes, free it
 15363                              <1> 	; 09/02/2022
 15364 00003360 D1E6                <1> 	shl	esi, 1
 15365                              <1> 	;shl	si, 1
 15366                              <1> 		; asl r2 / r2x2 to get index into p.pid table
 15367 00003362 0FB786[62680000]    <1> 	movzx	eax, word [esi+p.pid-2]
 15368 00003369 A3[A46C0000]        <1> 	mov	[u.r0], eax
 15369                              <1> 		; mov p.pid-2(r2),*u.r0 
 15370                              <1> 			      ; / put childs process name in (u.r0)
 15371                              <1> 	;
 15372                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
 15373                              <1> 	;
 15374                              <1> 	; Parent process ID -p.ppid- field (of the child process)
 15375                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
 15376                              <1> 	; system call loop from the application/program if it calls
 15377                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
 15378                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
 15379                              <1> 	;
 15380                              <1> 	; Note: syswait will return with error if there is not a
 15381                              <1> 	;       zombie or running process to wait.	
 15382                              <1> 	;
 15383                              <1> 	;sub	ax, ax
 15384                              <1> 	; 08/01/2022
 15385 0000336E 29C0                <1> 	sub	eax, eax
 15386 00003370 668986[82680000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
 15387 00003377 E90BFEFFFF          <1> 	jmp	sysret0 ; ax = 0
 15388                              <1> 	;
 15389                              <1> 	;jmp	sysret
 15390                              <1> 		; br sysret1 / return cause child is dead
 15391                              <1> syswait_2: ; 2:
 15392                              <1> 	; 09/02/2022
 15393 0000337C D1E6                <1> 	shl	esi, 1
 15394                              <1> 	;shl	si, 1
 15395                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
 15396                              <1> syswait_3: ; 3:
 15397 0000337E 6683FE20            <1> 	cmp	si, nproc+nproc
 15398                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
 15399 00003382 72BE                <1> 	jb	short syswait_1
 15400                              <1> 		; blt 1b / no, continue search
 15401                              <1> 	;and	cx, cx
 15402 00003384 20C9                <1> 	and	cl, cl
 15403                              <1> 		; tst r3 / one gets here if there are no children 
 15404                              <1> 		       ; / or children that are still active
 15405                              <1> 	; 30/10/2013
 15406 00003386 7515                <1> 	jnz	short syswait_4
 15407                              <1> 	;jz	error
 15408                              <1> 		; beq error1 / there are no children, error
 15409 00003388 890D[A46C0000]      <1> 	mov	[u.r0], ecx ; 0
 15410                              <1> 	; 09/02/2022
 15411 0000338E C705[186D0000]1B00- <1> 	mov	dword [u.error], ERR_MISC ; 27
 15412 00003396 0000                <1>
 15413                              <1> 			; miscellaneous/other errors
 15414 00003398 E9C8FDFFFF          <1> 	jmp	error
 15415                              <1> syswait_4:
 15416 0000339D 8A1D[F56C0000]      <1> 	mov	bl, [u.uno]
 15417                              <1> 		; movb u.uno,r1 / there are children so put 
 15418                              <1> 			      ; / parent process number in r1
 15419 000033A3 FE83[C3680000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
 15420                              <1> 		; incb p.stat-1(r1) / it is waiting for 
 15421                              <1> 				  ; / other children to die
 15422                              <1> 	; 04/11/2013
 15423 000033A9 E853120000          <1> 	call	swap
 15424                              <1> 		; jsr r0,swap / swap it out, because it's waiting
 15425 000033AE E97BFFFFFF          <1> 	jmp	syswait_0
 15426                              <1> 		; br syswait / wait on next process
 15427                              <1> 
 15428                              <1> sysfork: ; < create a new process >
 15429                              <1> 	; 27/02/2022
 15430                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 15431                              <1> 	; 18/09/2015
 15432                              <1> 	; 04/09/2015
 15433                              <1> 	; 02/09/2015
 15434                              <1> 	; 01/09/2015
 15435                              <1> 	; 28/08/2015
 15436                              <1> 	; 14/05/2015
 15437                              <1> 	; 10/05/2015
 15438                              <1> 	; 09/05/2015
 15439                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
 15440                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 15441                              <1> 	;
 15442                              <1> 	; 'sysfork' creates a new process. This process is referred
 15443                              <1> 	; to as the child process. This new process core image is
 15444                              <1> 	; a copy of that of the caller of 'sysfork'. The only
 15445                              <1> 	; distinction is the return location and the fact that (u.r0)
 15446                              <1> 	; in the old process (parent) contains the process id (p.pid)
 15447                              <1> 	; of the new process (child). This id is used by 'syswait'.
 15448                              <1> 	; 'sysfork' works in the following manner: 	
 15449                              <1> 	;    1) The process status table (p.stat) is searched to find
 15450                              <1> 	;	a process number that is unused. If none are found
 15451                              <1> 	;	an error occurs.
 15452                              <1> 	;    2) when one is found, it becomes the child process number
 15453                              <1> 	;	and it's status (p.stat) is set to active.
 15454                              <1> 	;    3) If the parent had a control tty, the interrupt 
 15455                              <1> 	;	character in that tty buffer is cleared.
 15456                              <1> 	;    4) The child process is put on the lowest priority run 
 15457                              <1> 	;	queue via 'putlu'.
 15458                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
 15459                              <1> 	;	it is a unique number) and is put in the child's unique
 15460                              <1> 	;	identifier; process id (p.pid).
 15461                              <1> 	;    6) The process name of the parent is then obtained and
 15462                              <1> 	;	placed in the unique identifier of the parent process
 15463                              <1> 	;	name is then put in 'u.r0'.	
 15464                              <1> 	;    7) The child process is then written out on disk by
 15465                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
 15466                              <1> 	;	and the child is born. (The child process is written 
 15467                              <1> 	;	out on disk/drum with 'u.uno' being the child process
 15468                              <1> 	;	number.)
 15469                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
 15470                              <1> 	;    9) The child process name is put in 'u.r0'.
 15471                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
 15472                              <1> 	;	create the return address for the parent process.
 15473                              <1> 	;   11) The 'u.fp' list as then searched to see what files
 15474                              <1> 	;	the parent has opened. For each file the parent has
 15475                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
 15476                              <1> 	;	to indicate that the child process also has opened
 15477                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
 15478                              <1> 	;
 15479                              <1> 	; Calling sequence:
 15480                              <1> 	;	from shell ?
 15481                              <1> 	; Arguments:
 15482                              <1> 	;	-
 15483                              <1> 	; Inputs: -
 15484                              <1> 	; Outputs: *u.r0 - child process name
 15485                              <1> 	; ...............................................................
 15486                              <1> 	;	
 15487                              <1> 	; Retro UNIX 8086 v1 modification: 
 15488                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
 15489                              <1> 	;	= process id of child a parent process returns
 15490                              <1> 	;	= process id of parent when a child process returns
 15491                              <1> 	;
 15492                              <1> 	;       In original UNIX v1, sysfork is called and returns as
 15493                              <1> 	;	in following manner: (with an example: c library, fork)
 15494                              <1> 	;	
 15495                              <1> 	;	1:
 15496                              <1> 	;		sys	fork
 15497                              <1> 	;			br 1f  / child process returns here
 15498                              <1> 	;		bes	2f     / parent process returns here
 15499                              <1> 	;		/ pid of new process in r0
 15500                              <1> 	;		rts	pc
 15501                              <1> 	;	2: / parent process condionally branches here
 15502                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
 15503                              <1> 	;		rts	pc
 15504                              <1> 	;
 15505                              <1> 	;	1: / child process brances here
 15506                              <1> 	;		clr	r0   / pid = 0 in child process
 15507                              <1> 	;		rts	pc
 15508                              <1> 	;
 15509                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
 15510                              <1> 	;		// pid = fork();
 15511                              <1> 	;		//
 15512                              <1> 	;		// pid == 0 in child process; 
 15513                              <1> 	;		// pid == -1 means error return
 15514                              <1> 	;		// in child, 
 15515                              <1> 	;		//	parents id is in par_uid if needed
 15516                              <1> 	;		
 15517                              <1> 	;		_fork:
 15518                              <1> 	;			mov	$.fork,eax
 15519                              <1> 	;			int	$0x30
 15520                              <1> 	;			jmp	1f
 15521                              <1> 	;			jnc	2f
 15522                              <1> 	;			jmp	cerror
 15523                              <1> 	;		1:
 15524                              <1> 	;			mov	eax,_par_uid
 15525                              <1> 	;			xor	eax,eax
 15526                              <1> 	;		2:
 15527                              <1> 	;			ret
 15528                              <1> 	;
 15529                              <1> 	;	In Retro UNIX 8086 v1,
 15530                              <1> 	;	'sysfork' returns in following manner:
 15531                              <1> 	;	
 15532                              <1> 	;		mov	ax, sys_fork
 15533                              <1> 	;		mov	bx, offset @f ; routine for child
 15534                              <1> 	;		int	20h
 15535                              <1> 	;		jc	error
 15536                              <1> 	;		
 15537                              <1> 	;	; Routine for parent process here (just after 'jc')
 15538                              <1> 	;		mov	word ptr [pid_of_child], ax
 15539                              <1> 	;		jmp	next_routine_for_parent	
 15540                              <1> 	;
 15541                              <1> 	;	@@: ; routine for child process here				
 15542                              <1> 	;		....	
 15543                              <1> 	;	NOTE: 'sysfork' returns to specified offset
 15544                              <1> 	;	       for child process by using BX input.
 15545                              <1> 	;	      (at first, parent process will return then 
 15546                              <1> 	;	      child process will return -after swapped in-
 15547                              <1> 	;	      'syswait' is needed in parent process
 15548                              <1> 	;	      if return from child process will be waited for.)
 15549                              <1> 	;	  				
 15550                              <1> 	
 15551                              <1> ; / create a new process
 15552                              <1> 	; EBX = return address for child process 
 15553                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
 15554 000033B3 31F6                <1> 	xor 	esi, esi
 15555                              <1> 		; clr r1
 15556                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
 15557 000033B5 46                  <1> 	inc	esi
 15558                              <1> 		; inc r1
 15559 000033B6 80BE[C3680000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
 15560                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
 15561 000033BD 760B                <1> 	jna	short sysfork_2	
 15562                              <1> 		; beq 1f / it's unused so branch
 15563 000033BF 6683FE10            <1> 	cmp	si, nproc
 15564                              <1> 		; cmp r1,$nproc / all processes checked
 15565 000033C3 72F0                <1> 	jb	short sysfork_1
 15566                              <1> 		; blt 1b / no, branch back
 15567                              <1> 	;
 15568                              <1> 	; Retro UNIX 8086 v1. modification:
 15569                              <1> 	;	Parent process returns from 'sysfork' to address 
 15570                              <1> 	;	which is just after 'sysfork' system call in parent
 15571                              <1> 	;	process. Child process returns to address which is put
 15572                              <1> 	;	in BX register by parent process for 'sysfork'. 
 15573                              <1> 	;
 15574                              <1> 		; add $2,18.(sp) / add 2 to pc when trap occured, points
 15575                              <1> 		             ; / to old process return
 15576                              <1> 		; br error1 / no room for a new process
 15577                              <1> sysfork_0:
 15578 000033C5 E99BFDFFFF          <1> 	jmp	error
 15579                              <1> sysfork_2: ; 1:
 15580 000033CA E810F0FFFF          <1> 	call	allocate_page
 15581                              <1> 	;jc	error
 15582                              <1> 	; 08/01/2022
 15583 000033CF 72F4                <1> 	jc	short sysfork_0
 15584                              <1> 
 15585 000033D1 50                  <1> 	push	eax   ; UPAGE (user structure page) address
 15586                              <1> 	; Retro UNIX 386 v1 modification!
 15587 000033D2 E8FFF1FFFF          <1> 	call	duplicate_page_dir
 15588                              <1> 		; EAX = New page directory 
 15589 000033D7 7308                <1> 	jnc	short sysfork_3
 15590 000033D9 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15591 000033DA E8C6F1FFFF          <1> 	call 	deallocate_page
 15592                              <1> 	;jmp	error
 15593                              <1> 	; 08/01/2022
 15594 000033DF EBE4                <1> 	jmp	short sysfork_0  ; error
 15595                              <1> sysfork_3:
 15596                              <1> 	; Retro UNIX 386 v1 modification !
 15597 000033E1 56                  <1> 	push	esi
 15598 000033E2 E891120000          <1> 	call	wswap ; save current user (u) structure, user registers
 15599                              <1> 		      ; and interrupt return components (for IRET)
 15600 000033E7 8705[046D0000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
 15601 000033ED A3[086D0000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
 15602 000033F2 5E                  <1> 	pop	esi
 15603 000033F3 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15604                              <1> 		; [u.usp] = esp
 15605 000033F4 89F7                <1> 	mov	edi, esi
 15606                              <1> 	;shl	di, 2
 15607                              <1> 	; 08/01/2022
 15608 000033F6 C1E702              <1> 	shl	edi, 2
 15609 000033F9 8987[D0680000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
 15610 000033FF A3[006D0000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
 15611                              <1> 	; 28/08/2015
 15612 00003404 0FB605[F56C0000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
 15613                              <1> 		; movb u.uno,-(sp) / save parent process number
 15614 0000340B 89C7                <1> 	mov	edi, eax
 15615 0000340D 50                  <1>         push	eax ; ** 
 15616 0000340E 8A87[A3680000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
 15617                              <1> 	; 18/09/2015 (27/02/2022)
 15618 00003414 8886[A3680000]      <1> 	mov	[esi+p.ttyc-1], al ; set child's console tty
 15619                              <1> 	; 27/02/2022 (p.waitc is not used)
 15620                              <1> 	;mov	[esi+p.waitc-1], ah ; 0 ; reset child's wait channel
 15621                              <1> 	; 27/02/2022 (BugFix)
 15622                              <1> 	;mov	[esi+p.ttyc-1], ax ; al - set child's console tty
 15623                              <1> 	;			   ; ah - reset child's wait channel
 15624 0000341A 89F0                <1> 	mov	eax, esi
 15625 0000341C A2[F56C0000]        <1> 	mov	[u.uno], al ; child process number
 15626                              <1> 		;movb r1,u.uno / set child process number to r1
 15627 00003421 FE86[C3680000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
 15628                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
 15629                              <1> 				; / process to active status
 15630                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
 15631                              <1> 			      ; / control tty buffer in r2
 15632                              <1>                 ; beq 2f / branch, if no such tty assigned
 15633                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
 15634                              <1> 	; 2:
 15635 00003427 53                  <1> 	push	ebx  ; * return address for the child process
 15636                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15637                              <1> 	; (Retro UNIX 8086 v1 modification!)
 15638                              <1> 		; mov $runq+4,r2
 15639 00003428 E8A1120000          <1> 	call	putlu 
 15640                              <1>  		; jsr r0,putlu / put child process on lowest priority 
 15641                              <1> 			   ; / run queue
 15642                              <1> 	; 08/01/2022
 15643 0000342D D1E6                <1> 	shl	esi, 1
 15644                              <1> 	;shl	si, 1
 15645                              <1> 		; asl r1 / multiply r1 by 2 to get index 
 15646                              <1> 		       ; / into p.pid table
 15647 0000342F 66FF05[846C0000]    <1> 	inc	word [mpid]
 15648                              <1> 		; inc mpid / increment m.pid; get a new process name
 15649 00003436 66A1[846C0000]      <1> 	mov	ax, [mpid]
 15650 0000343C 668986[62680000]    <1> 	mov	[esi+p.pid-2], ax
 15651                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
 15652                              <1> 				    ; / in child process' name slot
 15653 00003443 5A                  <1> 	pop	edx  ; * return address for the child process
 15654                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15655 00003444 5B                  <1>   	pop	ebx  ; **
 15656                              <1> 	;mov	ebx, [esp] ; ** parent process number
 15657                              <1> 		; movb (sp),r2 / put parent process number in r2
 15658                              <1> 	; 08/01/2022
 15659 00003445 D1E3                <1> 	shl	ebx, 1
 15660                              <1> 	;shl 	bx, 1
 15661                              <1> 		; asl r2 / multiply by 2 to get index into below tables
 15662                              <1> 	;movzx eax, word [ebx+p.pid-2]
 15663 00003447 668B83[62680000]    <1> 	mov	ax, [ebx+p.pid-2]
 15664                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
 15665                              <1> 				   ; / process
 15666 0000344E 668986[82680000]    <1> 	mov	[esi+p.ppid-2], ax
 15667                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
 15668                              <1> 			  ; / in parent process slot for child
 15669 00003455 A3[A46C0000]        <1> 	mov	[u.r0], eax	
 15670                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
 15671                              <1> 			     ; / at location where r0 was saved
 15672 0000345A 8B2D[9C6C0000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
 15673 00003460 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
 15674                              <1> 			   ; * return address for the child process
 15675                              <1> 		; mov $sysret1,-(sp) /
 15676                              <1> 		; mov sp,u.usp / contents of sp at the time when 
 15677                              <1> 			      ; / user is swapped out
 15678                              <1> 		; mov $sstack,sp / point sp to swapping stack space
 15679                              <1> 	; 04/09/2015 - 01/09/2015
 15680                              <1> 	; [u.usp] = esp
 15681 00003463 68[85310000]        <1> 	push	sysret ; ***
 15682 00003468 8925[A06C0000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
 15683                              <1> 			     ; (for child process)	
 15684 0000346E 31C0                <1> 	xor 	eax, eax
 15685 00003470 66A3[DA6C0000]      <1> 	mov 	[u.ttyp], ax ; 0
 15686                              <1> 	;
 15687 00003476 E8FD110000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
 15688                              <1> 		;jsr r0,wswap / put child process out on drum
 15689                              <1> 		;jsr r0,unpack / unpack user stack
 15690                              <1> 		;mov u.usp,sp / restore user stack pointer
 15691                              <1> 		; tst (sp)+ / bump stack pointer
 15692                              <1> 	; Retro UNIX 386 v1 modification !
 15693 0000347B 58                  <1> 	pop	eax ; ***
 15694                              <1> 	; 08/01/2022
 15695 0000347C D1E3                <1> 	shl	ebx, 1
 15696                              <1> 	;shl 	bx, 1
 15697 0000347E 8B83[D0680000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
 15698 00003484 E818120000          <1> 	call	rswap ; restore parent process 'u' structure, 
 15699                              <1> 		      ; registers and return address (for IRET)
 15700                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
 15701 00003489 0FB705[846C0000]    <1>         movzx   eax, word [mpid]
 15702 00003490 A3[A46C0000]        <1> 	mov	[u.r0], eax
 15703                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
 15704                              <1> 			       ; / where r0 was saved
 15705                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
 15706                              <1> 			          ; / process return
 15707                              <1> 	;xor	ebx, ebx
 15708 00003495 31F6                <1> 	xor     esi, esi
 15709                              <1> 		;clr r1
 15710                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
 15711                              <1> 	      ; / opened by the parent process
 15712                              <1> 	; 08/01/2022
 15713                              <1> 	; 01/09/2015
 15714 00003497 30FF                <1> 	xor	bh, bh
 15715 00003499 8A9E[AE6C0000]      <1> 	mov 	bl, [esi+u.fp]
 15716                              <1> 	; 08/01/2022
 15717                              <1> 	;mov 	al, [esi+u.fp]
 15718                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
 15719 0000349F 08DB                <1> 	or	bl, bl
 15720                              <1> 	; 08/01/2022
 15721                              <1> 	;or	al, al
 15722 000034A1 7409                <1> 	jz	short sysfork_5	
 15723                              <1> 		; beq 2f / file has not been opened by parent, 
 15724                              <1> 		       ; / so branch
 15725                              <1> 	;mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
 15726                              <1> 	; 08/01/2022
 15727                              <1> 	;mov	ah, 16 ; Retro UNIX 386 v2 fsp structure size = 16 bytes
 15728                              <1> 	;mul	ah
 15729                              <1> 	;;movzx	ebx, ax
 15730                              <1> 	;mov	bx, ax
 15731                              <1> 	;mov	ebx, eax ; 08/01/2022
 15732                              <1> 	;shl	bx, 3
 15733                              <1> 		; asl r2 / multiply by 8
 15734                              <1>        		; asl r2 / to get index into fsp table
 15735                              <1>        		; asl r2
 15736                              <1> 	; 08/01/2022
 15737 000034A3 C1E304              <1> 	shl	ebx, 4 ; multiply by 16
 15738                              <1> 	; 08/01/2022
 15739 000034A6 FE83[0A690000]      <1> 	inc	byte [ebx+fsp-10] ; Retro UNIX 386 v2 fs fsp structure
 15740                              <1>   	;inc	byte [ebx+fsp-2]
 15741                              <1> 		; incb fsp-2(r2) / increment number of processes
 15742                              <1> 			     ; / using file, because child will now be
 15743                              <1> 			     ; / using this file
 15744                              <1> sysfork_5: ; 2:
 15745 000034AC 46                  <1>         inc     esi
 15746                              <1> 		; inc r1 / get next open file
 15747 000034AD 6683FE0A            <1>         cmp     si, 10
 15748                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
 15749                              <1> 			  ; / can be opened
 15750 000034B1 72E4                <1> 	jb	short sysfork_4	
 15751                              <1> 		; blt 1b / check next entry
 15752 000034B3 E9CDFCFFFF          <1> 	jmp	sysret
 15753                              <1> 		; br sysret1
 15754                              <1> 
 15755                              <1> sysread: ; < read from file >
 15756                              <1> 	; 24/12/2021
 15757                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 15758                              <1> 	; 27/03/2020
 15759                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15760                              <1> 	; 13/05/2015
 15761                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15762                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15763                              <1> 	;
 15764                              <1> 	; 'sysread' is given a buffer to read into and the number of
 15765                              <1> 	; characters to be read. If finds the file from the file
 15766                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
 15767                              <1> 	; is returned from a successful open call (sysopen).
 15768                              <1> 	; The i-number of file is obtained via 'rw1' and the data
 15769                              <1> 	; is read into core via 'readi'.
 15770                              <1> 	;
 15771                              <1> 	; Calling sequence:
 15772                              <1> 	;	sysread; buffer; nchars
 15773                              <1> 	; Arguments:
 15774                              <1> 	;	buffer - location of contiguous bytes where 
 15775                              <1> 	;		 input will be placed.
 15776                              <1> 	;	nchars - number of bytes or characters to be read.
 15777                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15778                              <1> 	; Outputs: *u.r0 - number of bytes read.	
 15779                              <1> 	; ...............................................................
 15780                              <1> 	;				
 15781                              <1> 	; Retro UNIX 8086 v1 modification: 
 15782                              <1> 	;       'sysread' system call has three arguments; so,
 15783                              <1> 	;	* 1st argument, file descriptor is in BX register
 15784                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15785                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15786                              <1> 	;
 15787                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15788                              <1> 	;	to the user with number of bytes read. 
 15789                              <1> 	;
 15790                              <1> 
 15791 000034B8 E839000000          <1> 	call	rw1
 15792                              <1> 	;jc	error ; 13/05/2015, ax < 1
 15793                              <1> 	;	; jsr r0,rw1 / get i-number of file to be read into r1
 15794                              <1>        	; 04/12/2021
 15795 000034BD 7209                <1> 	jc	short sysread_err
 15796 000034BF 7529                <1> 	jnz	short rw3 ; error ! (permission denied)
 15797                              <1> 	;		; read a file while it is open for write!
 15798                              <1> 
 15799                              <1> 	; eax = inode number
 15800                              <1> 
 15801                              <1> 	; 04/12/2021
 15802                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
 15803                              <1> 	;test	ah, 80h
 15804                              <1> 	;	; tst r1 / negative i-number?
 15805                              <1> 	;;jnz	error
 15806                              <1> 	;;	; ble error1 / yes, error 1 to read
 15807                              <1> 	;;		   ; / it should be positive
 15808                              <1> 	;; 04/12/2021
 15809                              <1> 	;jnz	short sysread_err
 15810                              <1> 
 15811 000034C1 E81B1A0000          <1> 	call	readi
 15812                              <1> 		; jsr r0,readi / read data into core
 15813 000034C6 EB13                <1> 	jmp	short rw0
 15814                              <1> 		; br 1f
 15815                              <1> sysread_err:
 15816                              <1> syswrite_err:
 15817                              <1> 	; 04/12/2021
 15818 000034C8 E998FCFFFF          <1> 	jmp	error
 15819                              <1> 
 15820                              <1> syswrite: ; < write to file >
 15821                              <1> 	; 24/12/2021
 15822                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 15823                              <1> 	; 27/03/2020
 15824                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15825                              <1> 	; 13/05/2015
 15826                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15827                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15828                              <1> 	;
 15829                              <1> 	; 'syswrite' is given a buffer to write onto an output file
 15830                              <1> 	; and the number of characters to write. If finds the file
 15831                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
 15832                              <1> 	; descriptor is returned from a successful open or create call
 15833                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
 15834                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
 15835                              <1> 	;
 15836                              <1> 	; Calling sequence:
 15837                              <1> 	;	syswrite; buffer; nchars
 15838                              <1> 	; Arguments:
 15839                              <1> 	;	buffer - location of contiguous bytes to be writtten.
 15840                              <1> 	;	nchars - number of characters to be written.
 15841                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15842                              <1> 	; Outputs: *u.r0 - number of bytes written.	
 15843                              <1> 	; ...............................................................
 15844                              <1> 	;				
 15845                              <1> 	; Retro UNIX 8086 v1 modification: 
 15846                              <1> 	;       'syswrite' system call has three arguments; so,
 15847                              <1> 	;	* 1st argument, file descriptor is in BX register
 15848                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15849                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15850                              <1> 	;
 15851                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15852                              <1> 	;	to the user with number of bytes written. 
 15853                              <1> 	;
 15854                              <1> 
 15855 000034CD E824000000          <1> 	call	rw1
 15856                              <1> 	;jc	error ; 13/05/2015, ax < 1
 15857                              <1> 	;	; jsr r0,rw1 / get i-number in r1 of file to write
 15858                              <1>        	; 04/12/2021
 15859 000034D2 72F4                <1> 	jc	short syswrite_err
 15860 000034D4 7414                <1> 	jz	short rw3 ; error ! (permission denied)
 15861                              <1> 			; write to a file while it is open for read
 15862                              <1> 	; eax = inode number
 15863                              <1> 	
 15864                              <1> 	; 04/12/2021
 15865                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
 15866                              <1> 	;test	ah, 80h
 15867                              <1> 	;	; tst r1 / positive i-number ?
 15868                              <1>         ;jz	short rw3 ; 13/05/2015
 15869                              <1> 	;;jz	error
 15870                              <1> 	;	; bge error1 / yes, error 1 
 15871                              <1> 	;		   ; / negative i-number means write
 15872                              <1>         ;neg	ax
 15873                              <1> 	;	; neg r1 / make it positive
 15874                              <1> 	
 15875 000034D6 E81A1C0000          <1> 	call	writei
 15876                              <1>         	; jsr r0,writei / write data
 15877                              <1> rw0: ; 1:
 15878 000034DB A1[D06C0000]        <1>         mov	eax, [u.nread]
 15879 000034E0 A3[A46C0000]        <1> 	mov	[u.r0], eax
 15880                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
 15881                              <1> 				  ; / into (u.r0)
 15882 000034E5 E99BFCFFFF          <1> 	jmp	sysret
 15883                              <1>         	; br sysret1
 15884                              <1> rw3: 
 15885                              <1> 	; 13/05/2015
 15886 000034EA C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 15887 000034F2 0000                <1>
 15888                              <1> 	;stc
 15889                              <1> 	;retn
 15890                              <1> 	; 24/12/2021 - Retro UNIX 386 v1.2
 15891 000034F4 EBD2                <1> 	jmp	short syswrite_err
 15892                              <1> 
 15893                              <1> rw1:	
 15894                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 15895                              <1> 	; 27/03/2020
 15896                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15897                              <1> 	; 14/05/2015
 15898                              <1> 	; 13/05/2015
 15899                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15900                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
 15901                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
 15902                              <1> 	;
 15903                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
 15904                              <1> 				;(in the user's virtual memory space)
 15905                              <1> 	;mov	[u.count], edx 
 15906                              <1> 		; jsr r0,arg; u.base / get buffer pointer
 15907                              <1>         	; jsr r0,arg; u.count / get no. of characters
 15908                              <1> 	;;mov	eax, ebx ; file descriptor
 15909                              <1> 		; mov *u.r0,r1 / put file descriptor 
 15910                              <1> 		             ; / (index to u.fp table) in r1
 15911                              <1> 	; 13/05/2015
 15912 000034F6 C705[A46C0000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
 15913 000034FE 0000                <1>
 15914                              <1> 	;
 15915                              <1> 	;; call	getf
 15916                              <1>         ; ebx = File descriptor
 15917 00003500 E8410B0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
 15918                              <1> 		; jsr r0,getf / get i-number of the file in r1
 15919                              <1> 	; AX = I-number of the file ; negative i-number means write
 15920                              <1> 
 15921                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 15922                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15923                              <1> 	; BL = open mode & status flag (0 = read, 1 = write)
 15924                              <1> 	; eax = inode number (ax)
 15925                              <1> 	; 27/03/2020
 15926                              <1> 	; [cdev] = logical drive number 	
 15927                              <1> 
 15928                              <1> 	; 13/05/2015
 15929 00003505 6683F801            <1> 	cmp 	ax, 1
 15930 00003509 721A                <1> 	jb	short rw2
 15931                              <1> 	;
 15932 0000350B 890D[C86C0000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
 15933                              <1> 				;(in the user's virtual memory space)
 15934 00003511 8915[CC6C0000]      <1> 	mov	[u.count], edx 
 15935                              <1> 	; 14/05/2015
 15936 00003517 C705[186D0000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
 15937 0000351F 0000                <1>
 15938                              <1> 
 15939                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 15940                              <1> 	; 27/03/2020 - Retro UNIX 386 v2
 15941 00003521 80E301              <1> 	and	bl, 1
 15942                              <1> 		; zf = 0 -> open for write	
 15943                              <1> 		; zf = 1 -> open for read
 15944 00003524 C3                  <1> 	retn
 15945                              <1>         	; rts r0
 15946                              <1> rw2:
 15947                              <1> 	; 13/05/2015
 15948 00003525 C705[186D0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 15949 0000352D 0000                <1>
 15950 0000352F C3                  <1> 	retn
 15951                              <1> 
 15952                              <1> 	; 18/04/2022
 15953                              <1> 	; 08/01/2022
 15954                              <1> 	; 02/01/2022
 15955                              <1> 	; 01/01/2022
 15956                              <1> 	; 27/12/2021
 15957                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility code
 15958                              <1> sysopen: ;<open file>
 15959                              <1> 	; 04/12/2021
 15960                              <1> 	; 07/08/2020 (Retro UNIX 386 v2)
 15961                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15962                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
 15963                              <1> 	;
 15964                              <1> 	; 'sysopen' opens a file in following manner:
 15965                              <1> 	;    1) The second argument in a sysopen says whether to
 15966                              <1> 	;	open the file ro read (0) or write (>0).
 15967                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
 15968                              <1> 	;    3) The file is opened by 'iopen'.
 15969                              <1> 	;    4) Next housekeeping is performed on the fsp table
 15970                              <1> 	;	and the user's open file list - u.fp.
 15971                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
 15972                              <1> 	;	b) An entry for the file is created in the fsp table.
 15973                              <1> 	;	c) The number of this entry is put on u.fp list.
 15974                              <1> 	;	d) The file descriptor index to u.fp list is pointed
 15975                              <1> 	;	   to by u.r0.
 15976                              <1> 	;
 15977                              <1> 	; Calling sequence:
 15978                              <1> 	;	sysopen; name; mode
 15979                              <1> 	; Arguments:
 15980                              <1> 	;	name - file name or path name
 15981                              <1> 	;	mode - 0 to open for reading
 15982                              <1> 	;	       1 to open for writing
 15983                              <1> 	; Inputs: (arguments)
 15984                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
 15985                              <1> 	;		  is put into r0's location on the stack.	
 15986                              <1> 	; ...............................................................
 15987                              <1> 	;				
 15988                              <1> 	; Retro UNIX 8086 v1 modification: 
 15989                              <1> 	;       'sysopen' system call has two arguments; so,
 15990                              <1> 	;	* 1st argument, name is pointed to by BX register
 15991                              <1> 	;	* 2nd argument, mode is in CX register
 15992                              <1> 	;
 15993                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15994                              <1> 	;	to the user with the file descriptor/number 
 15995                              <1> 	;	(index to u.fp list).
 15996                              <1> 	;
 15997                              <1> 	;call	arg2
 15998                              <1> 	; * name - 'u.namep' points to address of file/path name
 15999                              <1> 	;          in the user's program segment ('u.segmnt')
 16000                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16001                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16002                              <1> 	;          which is on top of stack.
 16003                              <1> 	;
 16004                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
 16005                              <1> 	;
 16006                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
 16007                              <1> 
 16008 00003530 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 16009 00003536 51                  <1> 	push	ecx ; * ; 04/12/2021 (cx -> ecx)
 16010 00003537 E8400B0000          <1> 	call	namei
 16011                              <1> 		; jsr r0,namei / i-number of file in r1
 16012                              <1>      	;and	ax, ax
 16013                              <1> 	;jz	error ; File not found
 16014 0000353C 722B                <1> 	jc	short fnotfound ; 14/05/2015
 16015                              <1> 	;jc	error ; 27/05/2013
 16016                              <1> 		; br  error2 / file not found
 16017                              <1>    	;pop	edx ; * ; mode ; 04/12/2021
 16018                              <1> 	;push	edx ; *
 16019                              <1> 	;;or	dx, dx
 16020                              <1> 	;or	dl, dl
 16021                              <1> 	;	; tst (sp) / is mode = 0 (2nd arg of call;
 16022                              <1> 	;	         ; / 0 means, open for read)
 16023                              <1> 	;;jz	short sysopen_0
 16024                              <1> 	;;	; beq 1f / yes, leave i-number positive
 16025                              <1> 	
 16026 0000353E 8B1424              <1> 	mov	edx, [esp] ; *
 16027                              <1> 	; edx = open mode (0 or 1)
 16028                              <1> 
 16029                              <1> ;syscreat_0: ;op0: ; 27/12/2015
 16030                              <1> ;	neg	ax
 16031                              <1> ;        	; neg r1 / open for writing so make i-number negative
 16032                              <1> 
 16033                              <1> sysopen_0: ;1:
 16034 00003541 E8A0200000          <1> 	call	iopen
 16035                              <1> 		; jsr r0,iopen / open file whose i-number is in r1
 16036 00003546 5A                  <1> 	pop	edx ; * ; mode ; 04/12/2021
 16037                              <1> 	;;and	dx, dx
 16038                              <1> 	;and	dl, dl
 16039                              <1>         ;	; tst (sp)+ / pop the stack and test the mode
 16040                              <1> 	;jz	short sysopen_2
 16041                              <1>         ;	; beq op1 / is open for read op1
 16042                              <1> ;sysopen_1: ;op0:
 16043                              <1> 	;neg	ax
 16044                              <1>         ;	; neg r1 
 16045                              <1> 	;	     ;/ make i-number positive if open for writing [???]
 16046                              <1> 
 16047                              <1> 	;; NOTE: iopen always make i-number positive.
 16048                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
 16049                              <1> sysopen_1: ; 04/12/2021
 16050                              <1> sysopen_2: ;op1:
 16051 00003547 31F6                <1>         xor     esi, esi
 16052                              <1>         	; clr r2 / clear registers
 16053 00003549 31DB                <1>         xor     ebx, ebx
 16054                              <1> 		; clr r3
 16055                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
 16056 0000354B 389E[AE6C0000]      <1>         cmp     [esi+u.fp], bl ; 0
 16057                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
 16058 00003551 7625                <1> 	jna	short sysopen_4
 16059                              <1> 		; beq 1f / if byte in list is 0 branch
 16060 00003553 46                  <1>         inc     esi
 16061                              <1> 		; inc r2 / bump r2 so next byte can be checked
 16062                              <1> 	; 02/01/2022
 16063                              <1> 	;cmp	si, OPENFILES ; 04/12/2021
 16064 00003554 6683FE0A            <1> 	cmp	si, 10
 16065                              <1> 		; cmp r2,$10. / reached end of list?
 16066 00003558 72F1                <1> 	jb	short sysopen_3
 16067                              <1> 		; blt 1b / no, go back
 16068                              <1> toomanyf:
 16069                              <1> 	; 14/05/2015
 16070 0000355A C705[186D0000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
 16071 00003562 0000                <1>
 16072 00003564 E9FCFBFFFF          <1> 	jmp	error
 16073                              <1>         	; br error2 / yes, error (no files open)
 16074                              <1> fnotfound: 
 16075                              <1> 	; 14/05/2015
 16076 00003569 C705[186D0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
 16077 00003571 0000                <1>
 16078 00003573 E9EDFBFFFF          <1> 	jmp	error
 16079                              <1> 
 16080                              <1> sysopen_4: ; 1:
 16081 00003578 6683BB[14690000]00  <1>         cmp     word [ebx+fsp], 0
 16082                              <1> 		; tst fsp(r3) / scan fsp entries
 16083 00003580 760D                <1>         jna     short sysopen_5
 16084                              <1> 		; beq 1f / if 0 branch
 16085                              <1> 	;; 14/05/2015 - Retro UNIX 386 v1 modification !
 16086                              <1> 	;add	bx, 10 ; fsp structure size = 10 bytes/entry
 16087                              <1> 		; add $8.,r3 / add 8 to r3 
 16088                              <1> 			; / to bump it to next entry mfsp table
 16089                              <1> 	; 01/01/2022
 16090                              <1> 	; 07/08/2020 - Retro UNIX 386 v2
 16091 00003582 6683C310            <1> 	add	bx, 16 ; fsp structure size = 16 bytes/entry ; runix v2
 16092                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 16093                              <1> 	;add	bx, fp.size
 16094                              <1> 
 16095                              <1> 	; 22/11/2021
 16096                              <1> 	;cmp	bx, NFILES*fp.size ; NFILES*16
 16097                              <1> 	; 02/01/2022
 16098 00003586 6681FB2003          <1> 	cmp	bx, nfiles*16
 16099                              <1> 	; 01/01/2022
 16100                              <1> 	;cmp	bx, NFILES*16 ; NFILES*fp.size
 16101                              <1> 	;;cmp	bx, nfiles*10
 16102                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
 16103 0000358B 72EB                <1> 	jb	short sysopen_4
 16104                              <1>        		; blt 1b / no, back
 16105                              <1> 	;jmp	error
 16106                              <1>         ;	; br error2 / yes, error
 16107                              <1> 	; 04/12/2021
 16108                              <1> 	; 07/08/2020
 16109 0000358D EBCB                <1> 	jmp	short toomanyf
 16110                              <1> 
 16111                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
 16112 0000358F 668983[14690000]    <1>         mov     [ebx+fsp], ax
 16113                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
 16114                              <1> 			; / into next available entry in fsp table,
 16115                              <1> 	;mov	di, [cdev] ; word ? byte ?
 16116                              <1>         ;mov	[ebx+fsp+2], di ; device number
 16117                              <1> 	;	; mov cdev,fsp+2(r3) / put # of device in next word
 16118                              <1> 
 16119                              <1> 	; 18/04/2022
 16120                              <1> 	; 04/12/2021        
 16121                              <1> 	;mov	al, [cdev]
 16122                              <1> 	;mov	ah, dl ; open mode, 0 = read, 1 = write
 16123                              <1> 	;mov	[ebx+fsp+4], ax ; device number & open mode
 16124                              <1> 
 16125                              <1> 	;xor	edi, edi
 16126                              <1>         ;mov	[ebx+fsp+4], edi ; offset pointer (0)
 16127                              <1> 	;	; clr fsp+4(r3)
 16128                              <1>         ;mov	[ebx+fsp+8], di ; open count (0), deleted flag (0)
 16129                              <1>        	;	; clr fsp+6(r3) / clear the next two words
 16130                              <1> 
 16131                              <1> 	; 04/12/2021 
 16132 00003596 31C0                <1> 	xor	eax, eax
 16133 00003598 8983[1C690000]      <1>   	mov	[ebx+fsp+8], eax ; offset pointer = 0
 16134                              <1> 
 16135                              <1> 	;;inc	word [ebx+fsp+6]
 16136                              <1> 	;inc	byte [ebx+fsp+6] ; open count = open count + 1	
 16137                              <1> 	; 18/04/2022
 16138                              <1> 	;mov	word [ebx+fsp+6], ax ; open count = 0 
 16139                              <1> 				     ; (sysfork increases open count)
 16140                              <1> 	; 18/04/2022		     ; reserved (mnt) flag = 0
 16141 0000359E A0[816C0000]        <1> 	mov	al, [cdev]
 16142 000035A3 88D4                <1> 	mov	ah, dl ; open mode, 0 = read, 1 = write
 16143 000035A5 8983[18690000]      <1> 	mov	[ebx+fsp+4], eax ; device number (al)
 16144                              <1> 				 ; & open mode (ah)
 16145                              <1> 				 ; (& open count = 0)
 16146                              <1>   	;mov	eax, ebx
 16147                              <1> 	;mov	bl, 10
 16148                              <1> 	;div	bl 
 16149                              <1> 	;	; asr r3
 16150                              <1> 	;	; asr r3 / divide by 8 
 16151                              <1> 	;	; asr r3 ; / to get number of the fsp entry-1
 16152                              <1> 	;inc	al
 16153                              <1>         ;	; inc r3 / add 1 to get fsp entry number
 16154                              <1>         ;mov	[esi+u.fp], al
 16155                              <1> 	;	; movb r3,u.fp(r2) / move entry number into 
 16156                              <1> 			; / next available slot in u.fp list
 16157                              <1> 	; 04/12/2021
 16158 000035AB C1EB04              <1> 	shr	ebx, 4	; / 16
 16159                              <1> 	;shr	bx, 4	; bx = fsp entry number (index)	
 16160                              <1> 			; bx <= 49 for current runix 386 version
 16161 000035AE FEC3                <1> 	inc 	bl	; bl = 1 to 50
 16162 000035B0 889E[AE6C0000]      <1> 	mov	[esi+u.fp], bl 	
 16163                              <1> 
 16164 000035B6 8935[A46C0000]      <1>         mov     [u.r0], esi
 16165                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
 16166                              <1> 			     ; / into r0 loc on stack
 16167 000035BC E9C4FBFFFF          <1>         jmp	sysret
 16168                              <1> 		; br sysret2
 16169                              <1> 
 16170                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
 16171                              <1> ;
 16172                              <1> ;         15                    7                   0
 16173                              <1> ;  1     |-------------------------------------------|
 16174                              <1> ;        |   	     i-number of open file           |
 16175                              <1> ;        |-------------------------------------------| 
 16176                              <1> ;        |        high word of 32 bit i-number       |
 16177                              <1> ;        |-------------------------------------------|
 16178                              <1> ;        | open mode & status  |   device number     |
 16179                              <1> ;        |-------------------------------------------|			
 16180                              <1> ;        |    reserved byte    |     open count      |
 16181                              <1> ;        |-------------------------------------------| 
 16182                              <1> ;        | offset pointer, i.e., r/w pointer to file |
 16183                              <1> ;        |-------------------------------------------|
 16184                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
 16185                              <1> ;        |-------------------------------------------|
 16186                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
 16187                              <1> ;        |-------------------------------------------|
 16188                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
 16189                              <1> ;        |-------------------------------------------|
 16190                              <1> ;  2     |                                           |
 16191                              <1> ;        |-------------------------------------------| 
 16192                              <1> ;        |                                           |
 16193                              <1> ;        |-------------------------------------------|
 16194                              <1> ;        |                                           |
 16195                              <1> ;        |-------------------------------------------|
 16196                              <1> ;        |                                           |
 16197                              <1> ;        |-------------------------------------------| 
 16198                              <1> ;        |                                           | 
 16199                              <1> 
 16200                              <1> 	;
 16201                              <1> 	; 'fsp' table (10 bytes/entry)
 16202                              <1> 	; bit 15				   bit 0
 16203                              <1> 	; ---|-------------------------------------------
 16204                              <1> 	; r/w|		i-number of open file
 16205                              <1> 	; ---|-------------------------------------------
 16206                              <1> 	;		   device number
 16207                              <1> 	; -----------------------------------------------
 16208                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 16209                              <1> 	; -----------------------------------------------
 16210                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 16211                              <1> 	; ----------------------|------------------------
 16212                              <1> 	;  flag that says file 	| number of processes
 16213                              <1> 	;   has been deleted	| that have file open 
 16214                              <1> 	; ----------------------|------------------------
 16215                              <1> 	;
 16216                              <1> 
 16217                              <1> 	; 12/03/2022
 16218                              <1> 	; 11/02/2022
 16219                              <1> 	; 01/01/2022
 16220                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16221                              <1> syscreat: ; < create file >
 16222                              <1> 	; 12/03/2022
 16223                              <1> 	; 11/02/2022
 16224                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16225                              <1> 	; 04/04/2021
 16226                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
 16227                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
 16228                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16229                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
 16230                              <1> 	;
 16231                              <1> 	; 'syscreat' called with two arguments; name and mode.
 16232                              <1> 	; u.namep points to name of the file and mode is put
 16233                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
 16234                              <1> 	; If the file aready exists, it's mode and owner remain 
 16235                              <1> 	; unchanged, but it is truncated to zero length. If the file
 16236                              <1> 	; did not exist, an i-node is created with the new mode via
 16237                              <1> 	; 'maknod' whether or not the file already existed, it is
 16238                              <1> 	; open for writing. The fsp table is then searched for a free
 16239                              <1> 	; entry. When a free entry is found, proper data is placed
 16240                              <1> 	; in it and the number of this entry is put in the u.fp list.
 16241                              <1> 	; The index to the u.fp (also know as the file descriptor)
 16242                              <1> 	; is put in the user's r0. 			
 16243                              <1> 	;
 16244                              <1> 	; Calling sequence:
 16245                              <1> 	;	syscreate; name; mode
 16246                              <1> 	; Arguments:
 16247                              <1> 	;	name - name of the file to be created
 16248                              <1> 	;	mode - mode of the file to be created
 16249                              <1> 	; Inputs: (arguments)
 16250                              <1> 	; Outputs: *u.r0 - index to u.fp list 
 16251                              <1> 	;		   (the file descriptor of new file)
 16252                              <1> 	; ...............................................................
 16253                              <1> 	;				
 16254                              <1> 	; Retro UNIX 8086 v1 modification: 
 16255                              <1> 	;       'syscreate' system call has two arguments; so,
 16256                              <1> 	;	* 1st argument, name is pointed to by BX register
 16257                              <1> 	;	* 2nd argument, mode is in CX register
 16258                              <1> 	;
 16259                              <1> 	;	AX register (will be restored via 'u.r0') will return
 16260                              <1> 	;	to the user with the file descriptor/number 
 16261                              <1> 	;	(index to u.fp list).
 16262                              <1> 	;
 16263                              <1> 	;call	arg2
 16264                              <1> 	; * name - 'u.namep' points to address of file/path name
 16265                              <1> 	;          in the user's program segment ('u.segmnt')
 16266                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16267                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16268                              <1> 	;          which is on top of stack.
 16269                              <1> 	;
 16270                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
 16271                              <1> 			    ; / on stack
 16272 000035C1 891D[C06C0000]      <1> 	mov	[u.namep], ebx ; file name address
 16273                              <1> 	;push	cx ; mode
 16274                              <1> 	; 04/12/2021
 16275 000035C7 51                  <1> 	push	ecx ; cx = mode (permission flags)
 16276 000035C8 E8AF0A0000          <1> 	call 	namei        	
 16277                              <1> 		; jsr r0,namei / get the i-number
 16278                              <1>         ;and	ax, ax
 16279                              <1> 	;jz	short syscreat_1	       	
 16280 000035CD 7216                <1> 	jc	short syscreat_1
 16281                              <1> 		; br 2f / if file doesn't exist 2f
 16282                              <1> 	; 27/12/2015
 16283                              <1> 	;cmp	ax, 41 ; device inode ?
 16284                              <1>         ;jb	syscreat_0 ; yes
 16285                              <1> 	;
 16286                              <1> 	;neg 	ax
 16287                              <1>         ;	; neg r1 / if file already exists make i-number 
 16288                              <1> 		       ; / negative (open for writing)
 16289                              <1> 	; 11/02/2022
 16290                              <1> 	; Truncate existing file
 16291                              <1> ;syscreate_2:
 16292                              <1> 	;; 27/03/2021
 16293                              <1> 	;;xor	edx, edx ; 0
 16294                              <1> 	;;inc	dl ; DL = 1 ; create/truncate (open for write)
 16295                              <1> 	;mov	dl, 1
 16296                              <1> 	; 11/02/2022
 16297 000035CF B202                <1> 	mov	dl, 2 ; create file (call from syscreat)
 16298 000035D1 E810200000          <1> 	call	iopen
 16299                              <1>          	; jsr r0,iopen
 16300                              <1> 	; 11/02/2022
 16301                              <1> 	; cpu will return here if inode in eax is regular file inode
 16302                              <1> 	; (if it is device or dir inode, cpu will jumpt to 'error')
 16303                              <1> 	;
 16304                              <1> 	; 12/03/2022
 16305 000035D6 50                  <1> 	push	eax ; * ; save inode number
 16306                              <1> 	; 
 16307                              <1> 	; truncate file to zero length
 16308                              <1> 	;call	itrunc
 16309                              <1>         	; jsr r0,itrunc / truncate to 0 length
 16310                              <1> 	; 11/02/2022
 16311                              <1> 	; (iget and regular file check -in 'itrunc'- is not needed) 
 16312 000035D7 E891170000          <1> 	call	itrunc_1
 16313                              <1> 	; 12/03/2022
 16314 000035DC 58                  <1> 	pop	eax ; * ; restore inode number in eax
 16315                              <1> 	;
 16316                              <1> 	;pop	cx ; pop mode (did not exist in original Unix v1 !?)
 16317                              <1> 	; 04/12/2021
 16318 000035DD 59                  <1> 	pop	ecx
 16319                              <1> syscreat_2:
 16320 000035DE B201                <1> 	mov	dl, 1 ; open for writing
 16321 000035E0 E962FFFFFF          <1>         jmp     sysopen_1
 16322                              <1>         	; br op0
 16323                              <1> syscreat_1: ; 2: / file doesn't exist
 16324                              <1> 	;pop	ax
 16325                              <1>         ;	; mov (sp)+,r1 / put the mode in r1
 16326                              <1> 	; 27/03/2021
 16327 000035E5 58                  <1> 	pop	eax  ; ax = mode (permission flags)
 16328                              <1> 	;xor	ah, ah	
 16329                              <1>         ;	; bic $!377,r1 / clear upper byte
 16330                              <1> 	; 27/03/2021
 16331                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
 16332                              <1> 	; clear bits 15,14,13,12,9 of mode (input from user)
 16333 000035E6 80E40D              <1> 	and	ah, 0Dh ; ISUID (800h) & ISGID (400h) & IREAD (100h)
 16334                              <1> 	; 11/02/2022
 16335 000035E9 80CC80              <1> 	or	ah, 80h	; IFREG (8000h) ; Regular file
 16336 000035EC E8B40D0000          <1> 	call 	maknod
 16337                              <1>         	; jsr r0,maknod / make an i-node for this file
 16338                              <1> 	;sub	eax, eax ; 04/12/2021
 16339 000035F1 66A1[DC6C0000]      <1> 	mov	ax, [u.dirbuf]
 16340                              <1>         	; mov u.dirbuf,r1 / put i-number 
 16341                              <1> 			        ; / for this new file in r1
 16342                              <1> 	; 04/04/2021
 16343                              <1> 	;mov	dl, 1 ; open for writing
 16344                              <1>         ;
 16345                              <1> 	;jmp	sysopen_1
 16346                              <1>         ;	; br op0 / open the file
 16347                              <1> 	; 04/04/2021
 16348 000035F7 EBE5                <1> 	jmp	short syscreat_2
 16349                              <1> 
 16350                              <1> 	; 11/02/2022
 16351                              <1> 	; 04/12/2021
 16352                              <1> dir_access_err:	; 13/03/2022
 16353                              <1> ;	; 14/05/2015
 16354                              <1> ;	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 16355                              <1> ;f_create_error:
 16356                              <1> 	; 27/03/2021
 16357 000035F9 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; permission denied !	
 16358 00003601 0000                <1>
 16359 00003603 E95DFBFFFF          <1> 	jmp	error
 16360                              <1> 
 16361                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16362                              <1> sysmkdir: ; < make directory >
 16363                              <1> 	; 13/03/2022
 16364                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16365                              <1> 	; 02/04/2021
 16366                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
 16367                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16368                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16369                              <1> 	;
 16370                              <1> 	; 'sysmkdir' creates an empty directory whose name is
 16371                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
 16372                              <1> 	; The special entries '.' and '..' are not present.
 16373                              <1> 	; Errors are indicated if the directory already exists or		
 16374                              <1> 	; user is not the super user. 
 16375                              <1> 	;
 16376                              <1> 	; Calling sequence:
 16377                              <1> 	;	sysmkdir; name; mode
 16378                              <1> 	; Arguments:
 16379                              <1> 	;	name - points to the name of the directory
 16380                              <1> 	;	mode - mode of the directory
 16381                              <1> 	; Inputs: (arguments)
 16382                              <1> 	; Outputs: -
 16383                              <1> 	;    (sets 'directory' flag to 1; 
 16384                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
 16385                              <1> 	; ...............................................................
 16386                              <1> 	;				
 16387                              <1> 	; Retro UNIX 8086 v1 modification: 
 16388                              <1> 	;       'sysmkdir' system call has two arguments; so,
 16389                              <1> 	;	* 1st argument, name is pointed to by BX register
 16390                              <1> 	;	* 2nd argument, mode is in CX register
 16391                              <1> 	;
 16392                              <1> 		
 16393                              <1> ; / make a directory
 16394                              <1> 
 16395                              <1> 	;call	arg2
 16396                              <1> 	; * name - 'u.namep' points to address of file/path name
 16397                              <1> 	;          in the user's program segment ('u.segmnt')
 16398                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16399                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16400                              <1> 	;          which is on top of stack.
 16401                              <1> 
 16402                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
 16403                              <1> 			    ; / on stack
 16404 00003608 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 16405                              <1> 	;push	cx ; mode
 16406                              <1> 	; 27/03/2021
 16407 0000360E 51                  <1> 	push	ecx ; cx = mode
 16408 0000360F E8680A0000          <1> 	call	namei
 16409                              <1>         	; jsr r0,namei / get the i-number
 16410                              <1>         	;     br .+4 / if file not found branch around error
 16411                              <1>         ;xor 	ax, ax
 16412                              <1> 	;jnz	error
 16413 00003614 7334                <1> 	jnc	short dir_exists ; 14/05/2015
 16414                              <1> 	;jnc	error	
 16415                              <1> 		; br error2 / directory already exists (error)
 16416                              <1> 
 16417                              <1> 	;cmp	byte [u.uid], 0 ; 02/08/2013
 16418                              <1>         ;	;tstb u.uid / is user the super user
 16419                              <1> 	;jna	short dir_access_err ; 14/05/2015
 16420                              <1> 	;;jna	error
 16421                              <1>         ;	;bne error2 / no, not allowed
 16422                              <1> 	;pop	ax
 16423                              <1>         ;	;mov (sp)+,r1 / put the mode in r1
 16424                              <1> 	;and	ax, 0FFCFh ; 1111111111001111b
 16425                              <1>         ;	;bic $!317,r1 / all but su and ex
 16426                              <1> 	;;or	ax, 4000h ; 1011111111111111b
 16427                              <1> 	;or	ah, 40h ; Set bit 14 to 1
 16428                              <1>         ; 	;bis $40000,r1 / directory flag
 16429                              <1> 
 16430                              <1> 	; 02/04/2021
 16431                              <1> 	;cmp	word [u.uid], 0
 16432                              <1> 	;;ja	error
 16433                              <1> 	;ja	short dir_access_err
 16434                              <1> 
 16435                              <1> 	; 13/03/2022
 16436                              <1> 	; NOTE:
 16437                              <1> 	; Unix v5-v7 kernels do not allow (ordinary) users
 16438                              <1> 	; (except root/superuser) --if [u.uid] > 0--
 16439                              <1> 	; to make a sub directory. (ref: sys2.c, 'mknod')
 16440                              <1> 	;
 16441                              <1> 	; But, Retro UNIX 386 v1.2 will allow the owner of
 16442                              <1> 	; the parent directory to make a sub directory, here.
 16443                              <1> 
 16444                              <1> 	; 13/03/2022
 16445 00003616 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0
 16446 0000361E 7618                <1> 	jna	short sysmkdir1 ; root (superuser)
 16447                              <1> 
 16448                              <1> 	; Here..
 16449                              <1> 	; (current) inode buffer contains inode structure
 16450                              <1> 	; of the parent directory (at the return of 'namei').
 16451                              <1> 
 16452 00003620 66A1[28680000]      <1> 	mov	ax, [i.uid] ; owner ID of the parent dir
 16453 00003626 663B05[F66C0000]    <1> 	cmp	ax, [u.uid] ; user ID of current user/process
 16454 0000362D 75CA                <1> 	jne	short dir_access_err
 16455                              <1> 	; 13/03/2022
 16456                              <1> 	; additional checking (may or may not be necessary!?)
 16457 0000362F 663B05[F86C0000]    <1> 	cmp	ax, [u.ruid] 
 16458                              <1> 			; real (login) user ID must be same
 16459 00003636 75C1                <1> 	jne	short dir_access_err
 16460                              <1> 
 16461                              <1> 	; 02/04/2021
 16462                              <1> 	; ('mkdir' procedure will be called from 'maknod'
 16463                              <1> 	; and then 'mkdir' will check write access permission) 
 16464                              <1> 	; ((so, 'access_w' call is not needed here.))
 16465                              <1> 
 16466                              <1> 	;; 02/04/2021
 16467                              <1> 	;; ('make directory' user permission check)
 16468                              <1> 	;; ((current directory's write permission flags
 16469                              <1> 	;;  will be checked against user's 'uid' & gid'))
 16470                              <1> 	;mov	dx, 80h ; IWRITE
 16471                              <1> 	;call	access_w  ; (in 'access', 'u5.s')
 16472                              <1> 	;; (If cpu will return here, the user has write permission)
 16473                              <1> 
 16474                              <1> sysmkdir1:
 16475                              <1> 	; 27/03/2021
 16476 00003638 58                  <1> 	pop	eax  ; ax = mode
 16477                              <1> 	; [ii] = current directory's inode number
 16478                              <1> 
 16479                              <1> 	; 27/03/2021
 16480                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
 16481                              <1> 	; clear bits 13,12,11,10,9,6,3,0 of mode (input from user)
 16482                              <1> 	;and	ax, 0C1B6h ; bits 15,14,8,7,5,4,2,1
 16483 00003639 6625B601            <1> 	and	ax, 01B6h
 16484 0000363D 80CCC0              <1> 	or	ah, 0C0h ; IFREG (8000h) + IFDIR (4000h) 
 16485                              <1> 			 ; Directory
 16486 00003640 E8600D0000          <1> 	call	maknod
 16487                              <1>         	;jsr r0,maknod / make the i-node for the directory
 16488 00003645 E93BFBFFFF          <1> 	jmp	sysret
 16489                              <1>         	;br sysret2 /
 16490                              <1> dir_exists:
 16491                              <1> 	; 27/03/2021
 16492                              <1> 	; (same error number for files and directories)
 16493                              <1> 	; Error Number: 14 (ERR_DIR_EXISTS)
 16494 0000364A C705[186D0000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS
 16495 00003652 0000                <1>
 16496                              <1> 				; 'file already exists !' error
 16497                              <1> 	; 04/12/2021
 16498 00003654 E90CFBFFFF          <1> 	jmp	error
 16499                              <1> ;dir_access_err:
 16500                              <1> ;	; 14/05/2015
 16501                              <1> ;	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 16502                              <1> ;	jmp	error
 16503                              <1> 
 16504                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16505                              <1> sysclose: ;<close file>
 16506                              <1> 	; 02/03/2022
 16507                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16508                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16509                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
 16510                              <1> 	;
 16511                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
 16512                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
 16513                              <1> 	; is put in r1 and 'fclose' is called.
 16514                              <1> 	;
 16515                              <1> 	; Calling sequence:
 16516                              <1> 	;	sysclose
 16517                              <1> 	; Arguments:
 16518                              <1> 	;	-  
 16519                              <1> 	; Inputs: *u.r0 - file descriptor
 16520                              <1> 	; Outputs: -
 16521                              <1> 	; ...............................................................
 16522                              <1> 	;				
 16523                              <1> 	; Retro UNIX 8086 v1 modification:
 16524                              <1> 	;	 The user/application program puts file descriptor
 16525                              <1> 	;        in BX register as 'sysclose' system call argument.
 16526                              <1> 	; 	 (argument transfer method 1)
 16527                              <1> 
 16528                              <1> 	; / close the file
 16529                              <1> 	
 16530                              <1> 	;mov 	eax, ebx
 16531                              <1> 	; 04/12/2021
 16532                              <1> 	; ebx = file descriptor/number
 16533                              <1> 	;call 	fclose
 16534                              <1> 	; 02/03/2022
 16535 00003659 E8A2090000          <1> 	call	_fclose
 16536                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
 16537                              <1> 		; jsr r0,fclose / close the file
 16538                              <1>                	; br error2 / unknown file descriptor
 16539                              <1> 		; br sysret2
 16540                              <1> 	;; 14/05/2015
 16541                              <1> 	;jnc	sysret
 16542                              <1> 	; 04/12/2021
 16543 0000365E 7205                <1> 	jc	short sysclose_err
 16544 00003660 E920FBFFFF          <1> 	jmp	sysret
 16545                              <1> sysclose_err:
 16546 00003665 C705[186D0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 16547 0000366D 0000                <1>
 16548 0000366F E9F1FAFFFF          <1> 	jmp	error
 16549                              <1> 
 16550                              <1> 	; 23/02/2022
 16551                              <1> 	; 19/12/2021
 16552                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16553                              <1> sysemt:
 16554                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16555                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16556                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
 16557                              <1> 	;
 16558                              <1> 	; Retro UNIX 8086 v1 modification: 
 16559                              <1> 	;	'Enable Multi Tasking' system call instead 
 16560                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
 16561                              <1> 	;
 16562                              <1> 	; Retro UNIX 8086 v1 feature only!
 16563                              <1> 	;	Using purpose: Kernel will start without time-out
 16564                              <1> 	;	(internal clock/timer) functionality.
 16565                              <1> 	;	Then etc/init will enable clock/timer for
 16566                              <1> 	;	multi tasking. (Then it will not be disabled again
 16567                              <1> 	;	except hardware reset/restart.)
 16568                              <1> 	;
 16569                              <1> 	
 16570                              <1> 	;cmp	byte [u.uid], 0 ; root ?
 16571                              <1> 	;;ja	error
 16572                              <1> 	;ja	badsys ; 14/05/2015
 16573                              <1> 	; 04/12/2021
 16574 00003674 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0 ; root ?
 16575 0000367C 7605                <1> 	jna	short emt_0 
 16576 0000367E E994FBFFFF          <1> 	jmp	badsys
 16577                              <1> emt_0:
 16578 00003683 FA                  <1> 	cli	; 23/02/2022
 16579 00003684 21DB                <1> 	and	ebx, ebx
 16580 00003686 7429                <1> 	jz	short emt_2
 16581                              <1> 	; Enable multi tasking -time sharing-
 16582 00003688 B8[16470000]        <1> 	mov	eax, clock ; enable multi tasking clock/timer
 16583                              <1> 	; 23/02/2022
 16584 0000368D BA[440A0000]        <1> 	mov	edx, rtci_default ; disable rtc (digital) printing
 16585                              <1> emt_1:
 16586 00003692 A3[09070000]        <1> 	mov	[x_timer], eax
 16587                              <1> 	; 23/02/2022 (Temporary)
 16588 00003697 8915[0D070000]      <1> 	mov	[x_rtci], edx
 16589 0000369D B306                <1> 	mov	bl, 6  ; timer interrupt page, video page 6
 16590 0000369F E855020000          <1> 	call	wttyc  ; clear video page
 16591 000036A4 B307                <1> 	mov	bl, 7  ; rtc interrupt page, video page 7
 16592 000036A6 E84E020000          <1> 	call	wttyc  ; clear video page
 16593                              <1> 	;
 16594 000036AB FB                  <1> 	sti	; 23/02/2022
 16595 000036AC E9D4FAFFFF          <1> 	jmp	sysret
 16596                              <1> emt_2:
 16597                              <1> 	; Disable multi tasking -time sharing-
 16598 000036B1 B8[15070000]        <1> 	mov	eax, u_timer ; enable timer tick printing
 16599                              <1> 	; 23/02/2022
 16600 000036B6 BA[4B0A0000]        <1> 	mov	edx, rtc_p   ; enable rtc (digital) printing
 16601                              <1> 	;
 16602 000036BB EBD5                <1> 	jmp	short emt_1
 16603                              <1> 
 16604                              <1> 	; Original UNIX v1 'sysemt' routine
 16605                              <1> ;sysemt:
 16606                              <1>         ;
 16607                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
 16608                              <1> 			 ; / in loc 30
 16609                              <1>         ;cmp    30,$core / was the argument a lower address 
 16610                              <1> 			; / than core
 16611                              <1>         ;blo    1f / yes, rtssym
 16612                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
 16613                              <1> 			; / and less than "ecore"
 16614                              <1>         ;blo    2f / yes, sysret2
 16615                              <1> ;1:
 16616                              <1>         ;mov    $rtssym,30
 16617                              <1> ;2:
 16618                              <1>         ;br     sysret2
 16619                              <1> 
 16620                              <1> sysilgins:
 16621                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16622                              <1> 	; 03/06/2013
 16623                              <1> 	; Retro UNIX 8086 v1 modification: 
 16624                              <1> 	;	not a valid system call ! (not in use)
 16625                              <1> 	;
 16626 000036BD E955FBFFFF          <1> 	jmp	badsys
 16627                              <1> 	;jmp	error
 16628                              <1> 	;;jmp 	sysret
 16629                              <1> 
 16630                              <1> 	; Original UNIX v1 'sysemt' routine
 16631                              <1> ;sysilgins: / calculate proper illegal instruction trap address
 16632                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
 16633                              <1> 			  ;/ put it in loc 8.,
 16634                              <1>         ;cmp    10,$core / making it the illegal instruction 
 16635                              <1> 		       ; / trap address
 16636                              <1>         ;blo    1f / is the address a user core address?  
 16637                              <1> 		; / yes, go to 2f
 16638                              <1>         ;cmp    10,$ecore
 16639                              <1>         ;blo    2f
 16640                              <1> ;1:
 16641                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
 16642                              <1> 		    ; / instruction trap address for the system
 16643                              <1> ;2:
 16644                              <1>         ;br     sysret2 / return to the caller via 'sysret'
 16645                              <1> 
 16646                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16647                              <1> sysmdate: ; < change the modification time of a file >
 16648                              <1> 	; 23/02/2022 (Retro UNIX 386 v1 feature/modification)
 16649                              <1> 	;	(ECX input)
 16650                              <1> 	; 24/12/2021
 16651                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16652                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 16653                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16654                              <1> 	;
 16655                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
 16656                              <1> 	; file into core. The user is checked if he is the owner 
 16657                              <1> 	; or super user. If he is neither an error occurs.
 16658                              <1> 	; 'setimod' is then called to set the i-node modification
 16659                              <1> 	; byte and the modification time, but the modification time
 16660                              <1> 	; is overwritten by whatever get put on the stack during
 16661                              <1> 	; a 'systime' system call. This calls are restricted to
 16662                              <1> 	; the super user.		
 16663                              <1> 	;
 16664                              <1> 	; Calling sequence:
 16665                              <1> 	;	sysmdate; name
 16666                              <1> 	; Arguments:
 16667                              <1> 	;	name - points to the name of file
 16668                              <1> 	; Inputs: (arguments)
 16669                              <1> 	; Outputs: -
 16670                              <1> 	; ...............................................................
 16671                              <1> 	;				
 16672                              <1> 	; Retro UNIX 8086 v1 modification: 
 16673                              <1> 	;	 The user/application program puts address 
 16674                              <1> 	;	 of the file name in BX register 
 16675                              <1> 	;	 as 'sysmdate' system call argument.
 16676                              <1> 	;
 16677                              <1> ; / change the modification time of a file
 16678                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
 16679 000036C2 891D[C06C0000]      <1>         mov	[u.namep], ebx
 16680                              <1> 	; 23/02/2022 - (Retro UNIX 386 v1 modification on unix v1 code)
 16681 000036C8 890D[B0670000]      <1> 	mov	[p_time], ecx ; save new modification time to be set 
 16682 000036CE E8A9090000          <1> 	call	namei
 16683                              <1> 		; jsr r0,namei / get its i-number
 16684                              <1> 	;;jc	error       
 16685                              <1> 	;	; br error2 / no, such file
 16686                              <1> 	;jc	fnotfound ; file not found !
 16687                              <1> 	; 24/12/2021
 16688 000036D3 7305                <1> 	jnc	short mdate_0
 16689 000036D5 E98FFEFFFF          <1> 	jmp	fnotfound
 16690                              <1> mdate_0: 
 16691 000036DA E896140000          <1> 	call	iget
 16692                              <1> 		; jsr r0,iget / get i-node into core
 16693                              <1> 	;mov	al, [u.uid]
 16694                              <1> 	;cmp	al, [i.uid]
 16695                              <1>         ;	; cmpb u.uid,i.uid / is user same as owner
 16696                              <1> 	;je	short mdate_1
 16697                              <1>         ;	; beq 1f / yes
 16698                              <1> 	;and	al, al
 16699                              <1> 	;	; tstb u.uid / no, is user the super user
 16700                              <1> 	;;jnz	error
 16701                              <1> 	;	; bne error2 / no, error
 16702                              <1> 	;jz	short mdate_1
 16703                              <1> 	; 04/12/2021
 16704 000036DF 66A1[F66C0000]      <1> 	mov	ax, [u.uid]
 16705 000036E5 663B05[28680000]    <1> 	cmp	ax, [i.uid]
 16706 000036EC 7414                <1> 	je	short mdate_1	
 16707 000036EE 6621C0              <1> 	and	ax, ax
 16708 000036F1 740F                <1> 	jz	short mdate_1
 16709                              <1> 
 16710 000036F3 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 16711 000036FB 0000                <1>
 16712                              <1> sysstty_err:	; 06/02/2022
 16713 000036FD E963FAFFFF          <1> 	jmp	error
 16714                              <1> mdate_1: ;1:
 16715 00003702 E8FF150000          <1> 	call	setimod
 16716                              <1>         	; jsr r0,setimod / fill in modification data,
 16717                              <1> 		               ; / time etc.
 16718 00003707 BE[B0670000]        <1> 	mov	esi, p_time
 16719 0000370C BF[5C680000]        <1> 	mov	edi, i.mtim
 16720 00003711 A5                  <1> 	movsd
 16721                              <1> 		; mov 4(sp),i.mtim / move present time to
 16722                              <1>         	; mov 2(sp),i.mtim+2 / modification time
 16723 00003712 E96EFAFFFF          <1>         jmp	sysret
 16724                              <1> 		; br sysret2
 16725                              <1> 
 16726                              <1> 	; 06/02/2022
 16727                              <1> sysstty_err_s:
 16728 00003717 880D[A46C0000]      <1> 	mov	byte [u.r0], cl ; serial port's tty number
 16729 0000371D EBDE                <1> 	jmp	short sysstty_err
 16730                              <1> 
 16731                              <1> sysstty: ; < set tty status and mode >
 16732                              <1> 	; 22/02/2022
 16733                              <1> 	; 21/02/2022
 16734                              <1> 	; 06/02/2022 (Retro UNIX 286 v1.2)
 16735                              <1> 	; 04/02/2022 (Retro UNIX 386 v1.1, Kernel v0.2.1.2)
 16736                              <1> 	; 02/02/2022 (Retro UNIX 386 v1, Kernel v0.2.0.18)
 16737                              <1> 	; 01/02/2022 (Retro UNIX 386 v1) -clear screen-
 16738                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
 16739                              <1> 	;	    ((32 bit reg push/pop))
 16740                              <1> 	; 17/11/2015
 16741                              <1> 	; 12/11/2015
 16742                              <1> 	; 29/10/2015
 16743                              <1> 	; 17/10/2015
 16744                              <1> 	; 13/10/2015
 16745                              <1> 	; 29/06/2015
 16746                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
 16747                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 16748                              <1> 	;
 16749                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
 16750                              <1> 	; whose file descriptor is in (u.r0).
 16751                              <1> 	;
 16752                              <1> 	; Calling sequence:
 16753                              <1> 	;	sysstty; arg
 16754                              <1> 	; Arguments:
 16755                              <1> 	;	arg - address of 3 consequitive words that contain
 16756                              <1> 	;	      the source of status data	
 16757                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
 16758                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 16759                              <1> 	; ...............................................................
 16760                              <1> 	;	
 16761                              <1> 	; Retro UNIX 8086 v1 modification: 
 16762                              <1> 	;	'sysstty' system call will set the tty
 16763                              <1> 	;	(clear keyboard buffer and set cursor position)
 16764                              <1> 	;	 in following manner:
 16765                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
 16766                              <1> 	;
 16767                              <1> 	; Inputs:
 16768                              <1> 	;	BX = 0 --> means
 16769                              <1> 	;	   If CL = FFh (& DX <> 0FFFFh) ; 01/02/2022
 16770                              <1> 	;	      set cursor position for console tty, only 
 16771                              <1> 	;	      CH will be ignored (char. will not be written)
 16772                              <1> 	;	   If CH = 0 (& DX <> 0FFFFh & CL < FFh) ; 01/02/20222
 16773                              <1> 	;	      set console tty for (current) process
 16774                              <1> 	;	      CL = tty number (0 to 9)
 16775                              <1> 	;	      (If CH = 0, character will not be written)
 16776                              <1> 	;          If CH > 0 (CL < FFh)	
 16777                              <1> 	;             CL = tty number (0 to 9)
 16778                              <1> 	;	      CH = character will be written
 16779                              <1> 	;	        at requested cursor position (in DX)
 16780                              <1> 	;	   DX = cursor position for tty number 0 to 7.
 16781                              <1>   	;		(only tty number 0 to 7) 
 16782                              <1> 	;          DL = communication parameters (for serial ports)
 16783                              <1> 	;	        (only for COM1 and COM2 serial ports)
 16784                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
 16785                              <1> 	;			or set cursor position	
 16786                              <1> 	;	   DH = 0FFh -> DL is not valid
 16787                              <1> 	;		do not set serial port parameters 
 16788                              <1> 	;		or do not set cursor position
 16789                              <1> 	;
 16790                              <1> 	;	BX > 0 --> points to name of tty
 16791                              <1> 	;    	   CH > 0 -->
 16792                              <1> 	;		CH = character will be written in current 
 16793                              <1> 	;            	cursor position (for tty number from 0 to 7)
 16794                              <1> 	;	     	or character will be sent to serial port
 16795                              <1> 	;	     	(for tty number 8 or 9)
 16796                              <1> 	;		CL = color of the character if tty number < 8.
 16797                              <1> 	;    	   CH = 0 --> Do not write a character, 
 16798                              <1> 	;		set mode (tty 8 to 9) or 
 16799                              <1> 	;		set current cursor positions (tty 0 to 7) only.
 16800                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
 16801                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
 16802                              <1> 	;		(DL is not valid)
 16803                              <1> 	;	   DL = communication parameters 
 16804                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
 16805                              <1> 	;
 16806                              <1> 	;	01/02/2022 - Retro UNIX 386 v1 - 2022 modification
 16807                              <1> 	;	(30/01/2022 - Retro UNIX 8086 - 2022 modification)
 16808                              <1> 	;	If CH = 0 & DX = 0FFFFh -> 
 16809                              <1> 	;	   clear screen (video page) & set cursor pos to 0,0.
 16810                              <1> 	;	   (for tty number 0 to 7, CL <= 7)
 16811                              <1> 	;	   (if CL = 0FFh -> clear console tty)	
 16812                              <1> 	;
 16813                              <1> 	; Outputs:
 16814                              <1> 	;	cf = 0 -> OK
 16815                              <1> 	;	     AL = tty number (0 to 9)
 16816                              <1> 	;	     AH = line status if tty number is 8 or 9
 16817                              <1> 	;	     AH = process number (of the caller)
 16818                              <1> 	;	cf = 1 means error (requested tty is not ready)
 16819                              <1> 	;	     AH = FFh if the tty is locked 
 16820                              <1> 	;		  (owned by another process)
 16821                              <1> 	;	        = process number (of the caller) 
 16822                              <1> 	;		  (if < FFh and tty number < 8)
 16823                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 16824                              <1> 	;	     AH = line status if tty number is 8 or 9
 16825                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
 16826                              <1> 	;	
 16827                              <1> 
 16828                              <1> 	; 27/06/2015 (32 bit modifications)
 16829                              <1> 	; 14/01/2014
 16830 0000371F 31C0                <1> 	xor 	eax, eax
 16831 00003721 6648                <1> 	dec	ax ; 17/10/2015
 16832 00003723 A3[A46C0000]        <1> 	mov	[u.r0], eax ; 0FFFFh
 16833                              <1> 	;;;
 16834                              <1> 	; 01/02/2022
 16835 00003728 FEC1                <1> 	inc	cl  ; 0FFh -> 0, 7 -> 8
 16836 0000372A 39C2                <1> 	cmp	edx, eax
 16837                              <1> 	;cmp	dx, ax ; 0FFFFh
 16838 0000372C 7521                <1> 	jne	short sysstty_18
 16839                              <1> 	; clear video page
 16840                              <1> 	; (CH must be 0)
 16841 0000372E 08ED                <1> 	or	ch, ch
 16842 00003730 75CB                <1> 	jnz	short sysstty_err ; invalid parameters
 16843 00003732 80F908              <1> 	cmp	cl, 8 ; > tty7 (serial port?)
 16844 00003735 77C6                <1> 	ja	short sysstty_err ; invalid parameters
 16845 00003737 20C9                <1> 	and	cl, cl
 16846 00003739 7514                <1> 	jnz	short sysstty_18 ; actual tty (video page) num + 1
 16847 0000373B 0FB635[F56C0000]    <1> 	movzx	esi, byte [u.uno]
 16848 00003742 8A8E[A3680000]      <1> 	mov	cl, byte [esi+p.ttyc-1] ; current/console tty
 16849 00003748 80F907              <1> 	cmp	cl, 7
 16850 0000374B 77CA                <1> 	ja	short sysstty_err_s ; serial port !	 
 16851                              <1> 	; here CL contains (actual) tty number (tty0 to tty7) 
 16852 0000374D FEC1                <1> 	inc	cl  ; 0 -> 1, 7 -> 8 
 16853                              <1> sysstty_18:
 16854 0000374F FEC9                <1> 	dec	cl  ; 8 -> 7, 1 -> 0
 16855                              <1> 	; cl = video page (tty) number
 16856                              <1> 	;;;
 16857 00003751 21DB                <1> 	and	ebx, ebx
 16858                              <1> 	;jnz	sysstty_6
 16859                              <1> 	; 01/02/2022
 16860 00003753 7405                <1> 	jz	short sysstty_19
 16861 00003755 E9C2000000          <1> 	jmp	sysstty_6
 16862                              <1> sysstty_19:
 16863                              <1> 	; set console tty
 16864                              <1> 	; 29/10/2015
 16865                              <1> 	; 17/01/2014 
 16866 0000375A 80F909              <1> 	cmp	cl, 9
 16867 0000375D 7613                <1> 	jna	short sysstty_0
 16868                              <1> 	; 17/11/2015
 16869 0000375F 80F9FF              <1> 	cmp	cl, 0FFh
 16870 00003762 7202                <1> 	jb	short sysstty_13
 16871 00003764 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
 16872                              <1> sysstty_13:
 16873 00003766 8A1D[F56C0000]      <1> 	mov	bl, [u.uno] ; process number
 16874 0000376C 8A8B[A3680000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
 16875                              <1> sysstty_0:
 16876                              <1> 	; 29/06/2015
 16877 00003772 52                  <1> 	push	edx ; 24/12/2021
 16878 00003773 51                  <1> 	push	ecx
 16879 00003774 30D2                <1> 	xor 	dl, dl	; sysstty call sign
 16880 00003776 88C8                <1> 	mov	al, cl
 16881 00003778 A2[A46C0000]        <1> 	mov	[u.r0], al ; tty number (0 to 9)
 16882 0000377D E8311F0000          <1> 	call	ottyp
 16883 00003782 59                  <1> 	pop	ecx
 16884 00003783 5A                  <1> 	pop	edx
 16885                              <1> 	;
 16886 00003784 7220                <1> 	jc	short sysstty_pd_err
 16887                              <1> 	;
 16888                              <1> 	; 22/02/2022 (Bug!, BugFix)
 16889                              <1> 	; (ebx = ?, modified in ottyp, it may be > 255)
 16890                              <1> 	;
 16891 00003786 80F908              <1> 	cmp	cl, 8
 16892 00003789 720C                <1> 	jb	short sysstty_2
 16893                              <1> 	;
 16894 0000378B 80FEFF              <1> 	cmp	dh, 0FFh
 16895 0000378E 7407                <1> 	je	short sysstty_2
 16896                              <1> 
 16897                              <1> ; 01/02/2022
 16898                              <1> ;	; 29/10/2015
 16899                              <1> ;	mov	ah, dl ; communication parameters
 16900                              <1> ;		; ah = 0E3h = 11100011b = 115200 baud,
 16901                              <1> ;		;			 THRE int + RDA int 
 16902                              <1> ;		; ah = 23h = 00100011b = 9600 baud,
 16903                              <1> ;		;			 THRE int + RDA int 
 16904                              <1> ;	sub	al, al ; 0
 16905                              <1> ;	; 12/07/2014
 16906                              <1> ;	cmp	cl, 9
 16907                              <1> ;	jb	short sysstty_1
 16908                              <1> ;	inc	al
 16909                              <1> ;sysstty_1:
 16910                              <1> ;	; 01/02/2022
 16911                              <1> ;	push	ecx
 16912                              <1> ;	; 29/06/2015	
 16913                              <1> ;	call 	sp_setp ; Set serial port communication parameters
 16914                              <1> ;	mov	[u.r0+1], cx ; Line status (ah)
 16915                              <1> ;			     ; Modem status (EAX bits 16 to 23)
 16916                              <1> ;	; 01/02/2022
 16917                              <1> ;	pop	ecx	
 16918                              <1> ;       jc      short sysstty_tmout_err ; 29/10/2015
 16919                              <1> 
 16920                              <1> 	; 01/02/2022
 16921 00003790 E831010000          <1> 	call	sysstty_scp
 16922 00003795 7276                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 16923                              <1> 
 16924                              <1> sysstty_2:
 16925                              <1> 	; 17/01/2014
 16926 00003797 20ED                <1> 	and	ch, ch 	; set cursor position 
 16927                              <1> 			; or comm. parameters ONLY
 16928 00003799 7527                <1> 	jnz	short sysstty_3
 16929                              <1> 	; 01/02/2022
 16930 0000379B 6683FAFF            <1> 	cmp	dx, 0FFFFh
 16931 0000379F 7214                <1> 	jb	short sysstty_20
 16932                              <1> 	; clear screen (video page)
 16933 000037A1 E93C010000          <1> 	jmp	sysstty_14
 16934                              <1> 
 16935                              <1> sysstty_pd_err: ; 29/06/2015
 16936                              <1> 	; 'permission denied !' error
 16937 000037A6 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
 16938 000037AE 0000                <1>
 16939 000037B0 E9B0F9FFFF          <1> 	jmp	error
 16940                              <1> 
 16941                              <1> sysstty_20:
 16942 000037B5 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16943 000037BC 888B[A3680000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
 16944                              <1> sysstty_3:
 16945                              <1> 	; 16/01/2014
 16946 000037C2 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
 16947                              <1> 	; 17/11/2015
 16948 000037C4 B507                <1> 	mov 	ch, 7  ; Default color (light gray)
 16949 000037C6 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
 16950                              <1>         ;jna	sysstty_9
 16951                              <1> 	; 24/12/2021
 16952 000037C8 7705                <1> 	ja	short sysstty_12
 16953 000037CA E9C6000000          <1> 	jmp	sysstty_9
 16954                              <1> 
 16955                              <1> sysstty_12:
 16956                              <1> 	;; BX = 0, CL = 8 or CL = 9
 16957                              <1> 	; (Set specified serial port as console tty port)
 16958                              <1> 	; CH = character to be written
 16959                              <1> 	; 15/04/2014
 16960                              <1> 	; CH = 0 --> initialization only
 16961                              <1> 	; AL = character
 16962                              <1> 	; 26/06/2014
 16963 000037CF 880D[D96C0000]      <1> 	mov	[u.ttyn], cl
 16964                              <1> 	; 12/07/2014
 16965 000037D5 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
 16966                              <1> 	; 02/02/2022
 16967 000037D7 FEC0                <1> 	inc	al  ; 0FFh -> 0, 0 -> 1
 16968 000037D9 740B                <1> 	jz	short sysstty_4 ; al = ch = 0
 16969 000037DB FEC8                <1> 	dec	al  ; 1 -> 0	
 16970                              <1> 	;and	al, al
 16971 000037DD 7407                <1> 	jz	short sysstty_4 ; al = ch = 0
 16972                              <1>  	; 04/07/2014
 16973 000037DF E802240000          <1> 	call 	sndc
 16974                              <1> 	; 12/07/2014
 16975 000037E4 EB0C                <1> 	jmp	short sysstty_5
 16976                              <1> 
 16977                              <1> sysstty_4:
 16978                              <1> 	; 12/07/2014
 16979                              <1> 	;xchg 	ah, al ; al = 0 -> al = ah, ah = 0
 16980 000037E6 88E0                <1> 	mov	al, ah ; 29/06/2015
 16981 000037E8 2C08                <1> 	sub	al, 8
 16982                              <1> 	; 27/06/2015
 16983 000037EA E8B0F3FFFF          <1> 	call	sp_status ; get serial port status
 16984                              <1> 	; AL = Line status, AH = Modem status
 16985                              <1> 	; 12/11/2015
 16986 000037EF 3C80                <1> 	cmp	al, 80h
 16987 000037F1 F5                  <1> 	cmc
 16988                              <1> sysstty_5:
 16989 000037F2 66A3[A56C0000]      <1> 	mov	[u.r0+1], ax ; ah = line status
 16990                              <1> 		; EAX bits 16-23 = modem status	
 16991 000037F8 9C                  <1> 	pushf
 16992 000037F9 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16993 000037FB A0[D96C0000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
 16994 00003800 E8E11F0000          <1> 	call	cttyp
 16995 00003805 9D                  <1> 	popf
 16996                              <1> 	;jnc	sysret ; time out error 
 16997                              <1> 	; 01/02/2022
 16998 00003806 7205                <1> 	jc	short sysstty_tmout_err
 16999 00003808 E978F9FFFF          <1> 	jmp	sysret
 17000                              <1> 
 17001                              <1> 	; time out error 
 17002                              <1> sysstty_tmout_err:
 17003 0000380D C705[186D0000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
 17004 00003815 0000                <1>
 17005 00003817 E949F9FFFF          <1> 	jmp	error
 17006                              <1> 
 17007                              <1> sysstty_6:
 17008 0000381C 52                  <1> 	push	edx ; 24/12/2021
 17009 0000381D 51                  <1> 	push	ecx
 17010 0000381E 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 17011 00003824 E853080000          <1> 	call	namei
 17012 00003829 59                  <1> 	pop	ecx
 17013 0000382A 5A                  <1> 	pop	edx
 17014 0000382B 7259                <1> 	jc	short sysstty_inv_dn
 17015                              <1> 	;
 17016                              <1> 	; 21/02/2022
 17017                              <1> 	;cmp	ax, 19  ; inode number of /dev/COM2
 17018                              <1> 	;ja	short sysstty_inv_dn ; 27/06/2015
 17019                              <1> 	;;
 17020                              <1> 	;cmp	al, 10 ; /dev/tty0 .. /dev/tty7
 17021                              <1> 	;	       ; /dev/COM1, /dev/COM2
 17022                              <1> 	;jb	short sysstty_7
 17023                              <1> 	;sub	al, 10
 17024                              <1> 	;jmp	short sysstty_8
 17025                              <1> 	;
 17026                              <1> 	; 21/02/2022
 17027                              <1> 	; (Retro UNIX 386 v2 file system inode numbers)
 17028 0000382D 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 17029 00003830 7754                <1> 	ja	short sysstty_inv_dn
 17030                              <1> 	;cmp	al, 8	; /dev/tty inode number is 8
 17031                              <1> 	;jb	short sysstty_inv_dn
 17032 00003832 2C08                <1> 	sub	al, 8
 17033 00003834 7250                <1> 	jb	short sysstty_inv_dn
 17034 00003836 7408                <1> 	jz	short sysstty_7 ; /dev/tty inode number is 8
 17035                              <1> 	; convert inode number to tty number (tty0 to tty9)
 17036 00003838 2C09                <1> 	sub	al, 9
 17037 0000383A 724A                <1> 	jb	short sysstty_inv_dn
 17038                              <1> 	; al = 0 to 9
 17039 0000383C 29DB                <1> 	sub	ebx, ebx ; 22/02/2022
 17040 0000383E EB0D                <1> 	jmp	short sysstty_8 
 17041                              <1> sysstty_7:
 17042                              <1> 	; 21/02/2022
 17043                              <1> 	;cmp	al, 1 ; /dev/tty
 17044                              <1> 	;jne	short sysstty_inv_dn ; 27/06/2015
 17045 00003840 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 17046 00003847 8A83[A3680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
 17047                              <1> sysstty_8:
 17048                              <1> 	; 22/02/2022
 17049                              <1> 	; (ebx < 256)	
 17050 0000384D A2[A46C0000]        <1> 	mov	[u.r0], al
 17051 00003852 52                  <1> 	push	edx ; 24/12/2021
 17052 00003853 50                  <1> 	push	eax
 17053 00003854 51                  <1> 	push	ecx	
 17054 00003855 E8591E0000          <1> 	call	ottyp
 17055 0000385A 59                  <1> 	pop	ecx
 17056 0000385B 58                  <1> 	pop	eax
 17057 0000385C 5A                  <1> 	pop	edx
 17058                              <1>         ;jc	sysstty_pd_err ; 'permission denied !'
 17059                              <1> 	; 06/02/2022
 17060 0000385D 7305                <1> 	jnc	short sysstty_21
 17061                              <1> 	; 'permission denied !'
 17062 0000385F E942FFFFFF          <1> 	jmp	sysstty_pd_err
 17063                              <1> sysstty_21:
 17064                              <1> 	; 29/10/2015
 17065 00003864 86E9                <1> 	xchg 	ch, cl
 17066                              <1> 		; cl = character, ch = color code
 17067 00003866 86C1                <1> 	xchg	al, cl
 17068                              <1> 		; al = character, cl = tty number
 17069 00003868 80F907              <1> 	cmp	cl, 7
 17070                              <1> 	;ja	sysstty_12
 17071                              <1> 	; 06/02/2022
 17072 0000386B 7628                <1> 	jna	short sysstty_16
 17073                              <1> ;;
 17074 0000386D 80FEFF              <1> 	cmp	dh, 0FFh
 17075 00003870 740B                <1> 	je	short sysstty_22 ; do not set comm. parameters
 17076                              <1> 
 17077                              <1> ; 01/02/2022
 17078                              <1> ;	; 29/10/2015
 17079                              <1> ;	mov	ah, dl ; communication parameters
 17080                              <1> ;		; ah = 0E3h = 11100011b = 115200 baud,
 17081                              <1> ;		;			 THRE int + RDA int 
 17082                              <1> ;		; ah = 23h = 00100011b = 9600 baud,
 17083                              <1> ;		;			 THRE int + RDA int 
 17084                              <1> ;	sub	al, al ; 0
 17085                              <1> ;	; 12/07/2014
 17086                              <1> ;	cmp	cl, 9
 17087                              <1> ;	jb	short sysstty_1
 17088                              <1> ;	inc	al
 17089                              <1> ;sysstty_1:
 17090                              <1> ;	; 01/02/2022
 17091                              <1> ;	push	ecx
 17092                              <1> ;	; 29/06/2015	
 17093                              <1> ;	call 	sp_setp ; Set serial port communication parameters
 17094                              <1> ;	mov	[u.r0+1], cx ; Line status (ah)
 17095                              <1> ;			     ; Modem status (EAX bits 16 to 23)
 17096                              <1> ;	; 01/02/2022
 17097                              <1> ;	pop	ecx	
 17098                              <1> ;       jc      short sysstty_tmout_err ; 29/10/2015
 17099                              <1> 
 17100                              <1> 	; 02/02/2022
 17101 00003872 88C5                <1> 	mov	ch, al ; save char
 17102                              <1> 	; 01/02/2022
 17103 00003874 E84D000000          <1> 	call	sysstty_scp
 17104 00003879 7292                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 17105                              <1> 	; 02/02/2022
 17106 0000387B 88E8                <1> 	mov	al, ch ; restore char
 17107                              <1> sysstty_22:
 17108                              <1> 	; 01/02/2022
 17109 0000387D 08ED                <1> 	or	ch, ch
 17110 0000387F 7437                <1> 	jz	short sysstty_11 ; do not send char to terminal
 17111                              <1> 	; send char to (serial port) terminal
 17112                              <1> 	; al = character
 17113                              <1> 	; cl = tty number (8 or 9)
 17114 00003881 E949FFFFFF          <1> 	jmp	sysstty_12 ; (tty8 or tty9)
 17115                              <1> 
 17116                              <1> sysstty_inv_dn: 
 17117                              <1> 	; 27/06/2015
 17118                              <1> 	; Invalid device name (not a tty) ! error
 17119                              <1> 	; (Device is not a tty or device name not found)
 17120 00003886 C705[186D0000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 17121 0000388E 0000                <1>
 17122 00003890 E9D0F8FFFF          <1> 	jmp	error
 17123                              <1> 
 17124                              <1> sysstty_16:
 17125                              <1> 	; 22/02/2022
 17126                              <1> 	; 16/01/2014
 17127                              <1> 	;xor	bh, bh
 17128                              <1> sysstty_9: 	; tty 0 to tty 7
 17129                              <1> 	; al = character
 17130                              <1> 	; ch = color/attribute ; 01/02/2022
 17131                              <1> 	;
 17132                              <1>  	; 22/02/2022 (BugFix)
 17133                              <1> 	; (ebx may be > 255 here!? due to 'ottyp')
 17134 00003895 29DB                <1> 	sub	ebx, ebx ; *
 17135 00003897 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
 17136                              <1> 	;
 17137 00003899 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
 17138 0000389C 7409                <1> 	je	short sysstty_10
 17139                              <1> 	; 24/12/2021
 17140 0000389E 51                  <1> 	push	ecx
 17141 0000389F 50                  <1> 	push	eax
 17142                              <1> 	; 22/02/2022	
 17143                              <1> 	;;movzx	ebx, cl ; *
 17144                              <1> 	;mov	bl, cl ; (tty number = video page number)
 17145 000038A0 E819DBFFFF          <1> 	call	set_cpos
 17146 000038A5 58                  <1> 	pop	eax
 17147 000038A6 59                  <1> 	pop	ecx
 17148                              <1> sysstty_10: 
 17149                              <1> 	; 22/02/2022
 17150                              <1> 	; bl = video page (tty) number 
 17151                              <1> 	;
 17152                              <1> 	; 29/10/2015
 17153 000038A7 08C0                <1> 	or	al, al ; character
 17154 000038A9 740D                <1> 	jz      short sysstty_11 ; al = 0
 17155                              <1> 	; 17/11/2015
 17156 000038AB 3CFF                <1> 	cmp	al, 0FFh
 17157 000038AD 7309                <1> 	jnb	short sysstty_11
 17158                              <1> 		; ch > 0 and ch < FFh
 17159                              <1> 	; write a character at current cursor position
 17160 000038AF 88EC                <1> 	mov	ah, ch ; color/attribute
 17161                              <1> 	; 12/07/2014
 17162 000038B1 51                  <1> 	push	ecx ; 24/12/2021
 17163 000038B2 E8EFDBFFFF          <1> 	call	write_c_current
 17164 000038B7 59                  <1> 	pop	ecx
 17165                              <1> sysstty_11:
 17166                              <1> 	; 14/01/2014
 17167 000038B8 30D2                <1> 	xor	dl, dl ; sysstty call sign
 17168                              <1> 	; 18/01/2014
 17169                              <1> 	;movzx	eax, cl ; 27/06/2015
 17170 000038BA 88C8                <1> 	mov	al, cl
 17171 000038BC E8251F0000          <1> 	call	cttyp
 17172 000038C1 E9BFF8FFFF          <1> 	jmp	sysret
 17173                              <1> 
 17174                              <1> 	; 06/02/2022 (Retro UNIX 386 v1.2)
 17175                              <1> sysstty_scp:
 17176                              <1> 	; 02/02/2022
 17177                              <1> 	; set communication parameters (for COM1 or COM2)
 17178                              <1> 	; 01/02/2022
 17179                              <1> 	;
 17180                              <1> 	; 29/10/2015
 17181 000038C6 88D4                <1> 	mov	ah, dl ; communication parameters
 17182                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
 17183                              <1> 		;			 THRE int + RDA int 
 17184                              <1> 		; ah = 23h = 00100011b = 9600 baud,
 17185                              <1> 		;			 THRE int + RDA int 
 17186 000038C8 28C0                <1> 	sub	al, al ; 0
 17187                              <1> 	; 12/07/2014
 17188 000038CA 80F909              <1> 	cmp	cl, 9
 17189 000038CD 7202                <1> 	jb	short sysstty_1
 17190 000038CF FEC0                <1> 	inc	al
 17191                              <1> sysstty_1:
 17192                              <1> 	; 02/02/2022
 17193 000038D1 52                  <1> 	push	edx
 17194                              <1> 	; 01/02/2022
 17195 000038D2 51                  <1> 	push	ecx
 17196                              <1> 	; 29/06/2015	
 17197 000038D3 E8CFF2FFFF          <1> 	call 	sp_setp ; Set serial port communication parameters
 17198 000038D8 66890D[A56C0000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
 17199                              <1> 			     ; Modem status (EAX bits 16 to 23)
 17200                              <1> 	; 01/02/2022
 17201 000038DF 59                  <1> 	pop	ecx	
 17202 000038E0 5A                  <1> 	pop	edx ; 02/02/2022
 17203                              <1> 	; 01/02/2022
 17204                              <1> 	; if cf = 1 -> sysstty_tmout_err
 17205 000038E1 C3                  <1> 	retn
 17206                              <1> 
 17207                              <1> 	; 06/02/2022 (Retro UNIX 386 v1.2)
 17208                              <1> sysstty_14:
 17209                              <1> 	; 23/02/2022
 17210                              <1> 	; 02/02/2022
 17211                              <1> 	; ch = 0
 17212                              <1> 	; cl = video page
 17213                              <1> 	;
 17214                              <1> 	; dx = 0FFFFh
 17215                              <1> 	; clear screen (video page)
 17216                              <1> 	;
 17217                              <1> 
 17218                              <1> 	; 02/02/2022
 17219                              <1> 	; clear screen
 17220                              <1> 	;
 17221                              <1> 	; (modified registers: eax, ebx, ecx, edx, esi, edi)
 17222                              <1> 
 17223                              <1> 	; 23/02/2022
 17224 000038E2 88CB                <1> 	mov 	bl, cl ; CL = tty number (0 to 7)
 17225                              <1> 
 17226                              <1> 	; clear video page
 17227 000038E4 E810000000          <1> 	call	wttyc ; 23/02/2022
 17228                              <1> 
 17229                              <1> 	; 23/02/2022
 17230 000038E9 88D8                <1> 	mov	al, bl
 17231 000038EB 8A25[F56C0000]      <1> 	mov	ah, [u.uno]
 17232 000038F1 66A3[A46C0000]      <1> 	mov	[u.r0], ax
 17233 000038F7 EBBF                <1> 	jmp	short sysstty_11
 17234                              <1> 
 17235                              <1> wttyc:
 17236                              <1> 	; 23/02/2022
 17237                              <1> 	; (clear video page)
 17238                              <1> 	; INPUT:
 17239                              <1> 	;  bl = video page (0 to 7)
 17240                              <1> 	;
 17241                              <1> 	; Modified registers: eax, ecx, edx, esi, edi
 17242                              <1> 
 17243                              <1> 	;xor	dx, dx ; column 0, row 0
 17244                              <1> 	;;inc	dx ; 0 ; 23/02/2022
 17245                              <1> 	;
 17246                              <1> ;	movzx	ebx, cl
 17247                              <1> ;	mov 	bl, cl ; CL = tty number (0 to 7) ; 23/02/2022
 17248                              <1> 
 17249                              <1> ;	shl 	bl, 1 
 17250                              <1> ;	mov 	al, byte ptr [ebx+ttyl]
 17251                              <1> ;		; AL = lock value (0 or process number)
 17252                              <1> ;	or	al, al
 17253                              <1> ;	jz	short @f
 17254                              <1> ;	cmp	al, byte ptr [u.uno] ; process number
 17255                              <1> ;	jne	short sysstty_15
 17256                              <1> ;		; only the owner can clear its video page
 17257                              <1> ;	xor	al, al ; 0
 17258                              <1> ;@@:
 17259                              <1> ;	;mov	bl, cl		
 17260                              <1> ;	shr	bl, 1 
 17261                              <1> 
 17262 000038F9 30C0                <1> 	xor	al, al	; 0
 17263 000038FB B407                <1> 	mov 	ah, 07h	; attribute/color (default)
 17264                              <1> 
 17265                              <1> 	; scroll_up input:
 17266                              <1> 	;
 17267                              <1> 	; al = line count (0 or 1) ((0 == clear video page))
 17268                              <1> 	; 	((al = 1 for write_tty (putc) procedure))
 17269                              <1> 	; ah = attribute to be used on blanked line
 17270                              <1> 	; bl = video page number (0 to 7)
 17271                              <1> 
 17272 000038FD E842DBFFFF          <1> 	call	scroll_up ; clear video page (al=0)
 17273                              <1> 
 17274                              <1> 	; (modified registers: eax, ecx, edx, esi, edi)
 17275                              <1> 
 17276                              <1> 	; bl = video page number (0 to 7)
 17277                              <1> 	;xor	dx, dx ; column 0, row 0
 17278                              <1> 	; 02/02/2022
 17279 00003902 31D2                <1> 	xor	edx, edx
 17280                              <1> 	; 23/02/2022
 17281                              <1> 	;call	set_cpos
 17282                              <1> 	;retn
 17283 00003904 E9B5DAFFFF          <1> 	jmp	set_cpos
 17284                              <1> 
 17285                              <1> 	;mov	al, bl
 17286                              <1> 	;mov	ah, [u.uno]
 17287                              <1> 	;mov	[u.r0], ax
 17288                              <1> 	;jmp	short sysstty_11
 17289                              <1> 
 17290                              <1> ;sysstty_15:
 17291                              <1> ;	; 30/01/2022
 17292                              <1> ;	; permission (denied) error
 17293                              <1> ;	;xor	dl, dl ; sysstty call sign
 17294                              <1> ;	mov	al, cl
 17295                              <1> ;	sub	ah, ah ; 0
 17296                              <1> ;	call	cttyp
 17297                              <1> ;	jmp	error
 17298                              <1> 
 17299                              <1> ; Original UNIX v1 'sysstty' routine:
 17300                              <1> ; gtty:
 17301                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
 17302                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
 17303                              <1> 	; 		/ r2 has source
 17304                              <1>         ;mov    r2,-(sp)
 17305                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
 17306                              <1> ;1: / flush the clist wait till typewriter is quiescent
 17307                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
 17308                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
 17309                              <1>         ;mov    $240,*$ps / set processor priority to 5
 17310                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
 17311                              <1>         ;       br .+4 / list empty, skip branch
 17312                              <1>         ;br     1b / get another character until list is empty
 17313                              <1>         ;mov    0b,r1 / move cc offset to r1
 17314                              <1>         ;inc    r1 / bump it for output clist
 17315                              <1>         ;tstb   cc(r1) / is it 0
 17316                              <1>         ;beq    1f / yes, no characters to output
 17317                              <1>  	;mov    r1,0f / no, put offset in sleep arg
 17318                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
 17319                              <1>         ;br     1b / try to calm it down again
 17320                              <1> ;1:
 17321                              <1>         ;mov    (sp)+,r1
 17322                              <1>         ;mov    (sp)+,r2 / restore registers
 17323                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
 17324                              <1>         ;beq    1f / if 0, 1f
 17325                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
 17326                              <1>         ;                   / control status register
 17327                              <1> ;1:
 17328                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
 17329                              <1>         ;beq    1f / if 0 1f
 17330                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
 17331                              <1> 	;		    / control status reg
 17332                              <1> ;1:
 17333                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
 17334                              <1>         ;jmp     sysret2 / return to user
 17335                              <1> 
 17336                              <1> sysgtty: ; < get tty status >
 17337                              <1> 	; 22/02/2022
 17338                              <1> 	; 21/02/2022 
 17339                              <1> 	;	(Retro UNIX 386 v1.2, inode number modifications)
 17340                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
 17341                              <1> 	;	    ((32 bit reg push/pop))
 17342                              <1> 	; 23/11/2015
 17343                              <1> 	; 29/10/2015
 17344                              <1> 	; 17/10/2015
 17345                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
 17346                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 17347                              <1> 	;
 17348                              <1> 	; 'sysgtty' gets the status of tty in question. 
 17349                              <1> 	; It stores in the three words addressed by it's argument
 17350                              <1> 	; the status of the typewriter whose file descriptor
 17351                              <1> 	; in (u.r0).
 17352                              <1> 	;
 17353                              <1> 	; Calling sequence:
 17354                              <1> 	;	sysgtty; arg
 17355                              <1> 	; Arguments:
 17356                              <1> 	;	arg - address of 3 words destination of the status
 17357                              <1> 	; Inputs: ((*u.r0 - file descriptor))
 17358                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 17359                              <1> 	; ...............................................................
 17360                              <1> 	;	
 17361                              <1> 	; Retro UNIX 8086 v1 modification: 
 17362                              <1> 	;	'sysgtty' system call will return status of tty
 17363                              <1> 	;	(keyboard, serial port and video page status)
 17364                              <1> 	;	 in following manner:
 17365                              <1> 	;
 17366                              <1> 	; Inputs:
 17367                              <1> 	;	BX = 0 --> means 
 17368                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
 17369                              <1> 	;	                 for (current) process
 17370                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
 17371                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
 17372                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
 17373                              <1> 	;	     CH > 0 -->	tty number + 1
 17374                              <1> 	;
 17375                              <1> 	;	BX > 0 --> points to name of tty
 17376                              <1> 	;	     CL = 0 --> return keyboard status
 17377                              <1> 	;	     CL = 1 --> return video page status
 17378                              <1> 	;	     CH = undefined		 
 17379                              <1> 	;
 17380                              <1> 	; Outputs:
 17381                              <1> 	;	cf = 0 ->
 17382                              <1> 	;
 17383                              <1> 	;	     AL = tty number from 0 to 9
 17384                              <1> 	;		  (0 to 7 is also the video page of the tty)	
 17385                              <1> 	;	     AH = 0 if the tty is free/unused
 17386                              <1> 	;	     AH = the process number of the caller 
 17387                              <1>  	;	     AH = FFh if the tty is locked by another process
 17388                              <1> 	;
 17389                              <1> 	;	  (if calling is for serial port status)
 17390                              <1> 	;	     BX = serial port status if tty number is 8 or 9
 17391                              <1> 	;		  (BH = modem status, BL = Line status)
 17392                              <1> 	;	     CX = 0FFFFh (if data is ready)
 17393                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
 17394                              <1> 	;
 17395                              <1> 	;	  (if calling is for keyboard status)
 17396                              <1> 	;	     BX = current character in tty/keyboard buffer
 17397                              <1> 	;		  (BH = scan code, BL = ascii code)
 17398                              <1> 	;		  (BX=0 if there is not a waiting character)
 17399                              <1> 	;	     CX  is undefined
 17400                              <1> 	;
 17401                              <1> 	;	  (if calling is for video page status)	
 17402                              <1> 	;	     BX = cursor position on the video page
 17403                              <1> 	;		  if tty number < 8
 17404                              <1> 	;		  (BH = row, BL = column)
 17405                              <1> 	;	     CX = current character (in cursor position)
 17406                              <1> 	;		  on the video page of the tty 
 17407                              <1> 	;		  if tty number < 8
 17408                              <1> 	;		  (CH = color, CL = character)
 17409                              <1> 	;	
 17410                              <1> 	;	cf = 1 means error (requested tty is not ready)
 17411                              <1> 	;
 17412                              <1> 	;	     AH = FFh if the caller is not owner of
 17413                              <1> 	;		  specified tty or console tty
 17414                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 17415                              <1> 	;	     BX, CX are undefined if cf = 1
 17416                              <1> 	;
 17417                              <1> 	;	  (If tty number is 8 or 9)
 17418                              <1> 	;	     AL = tty number 
 17419                              <1> 	;	     AH = the process number of the caller 
 17420                              <1> 	;	     BX = serial port status
 17421                              <1> 	;  		 (BH = modem status, BL = Line status)
 17422                              <1> 	;	     CX = 0
 17423                              <1> 	;
 17424                              <1> 		
 17425                              <1> gtty:   ; get (requested) tty number
 17426                              <1> 	; 22/02/2022
 17427                              <1> 	; 21/02/2022 (Retro UNIX 386 v1.2, inode number modifications)
 17428                              <1> 	; 17/10/2015
 17429                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 17430                              <1> 	; 30/05/2013 - 12/07/2014
 17431                              <1> 	; Retro UNIX 8086 v1 modification ! 
 17432                              <1> 	;
 17433                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
 17434                              <1> 	;
 17435                              <1> 	; 28/06/2015 (32 bit modifications)
 17436                              <1> 	; 16/01/2014
 17437 00003909 31C0                <1> 	xor 	eax, eax
 17438 0000390B 6648                <1> 	dec	ax ; 17/10/2015
 17439 0000390D A3[A46C0000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
 17440 00003912 80F901              <1> 	cmp	cl, 1
 17441 00003915 760F                <1> 	jna	short sysgtty_0
 17442                              <1> sysgtty_invp:
 17443                              <1> 	; 28/06/2015
 17444 00003917 C705[186D0000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 17445 0000391F 0000                <1>
 17446 00003921 E93FF8FFFF          <1> 	jmp	error
 17447                              <1> sysgtty_0:	
 17448 00003926 21DB                <1> 	and	ebx, ebx
 17449 00003928 7427                <1> 	jz	short sysgtty_1
 17450                              <1> 	;
 17451 0000392A 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 17452                              <1> 	;push	cx ; 23/11/2015
 17453 00003930 51                  <1> 	push	ecx ; 24/12/2021
 17454 00003931 E846070000          <1> 	call	namei
 17455 00003936 59                  <1> 	pop	ecx
 17456                              <1> 	;pop	cx ; 23/11/2015
 17457 00003937 7213                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
 17458                              <1> 	;
 17459                              <1> 	; 21/02/2022
 17460                              <1> 	;cmp	ax, 1
 17461                              <1> 	;jna	short sysgtty_2
 17462                              <1> 	;sub	ax, 10
 17463                              <1> 	;cmp	ax, 9
 17464                              <1> 	;;ja	short sysgtty_inv_dn
 17465                              <1> 	;;mov	ch, al
 17466                              <1> 	;;jmp	short sysgtty_4
 17467                              <1> 	;; 23/11/2015
 17468                              <1> 	;jna	short sysgtty_4
 17469                              <1> 	;
 17470                              <1> 	; 21/02/2022
 17471                              <1> 	; (Retro UNIX 386 v2 file system inode numbers)
 17472 00003939 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 17473 0000393C 770E                <1> 	ja	short sysgtty_inv_dn
 17474                              <1> 	;cmp	al, 8	; /dev/tty inode number is 8
 17475                              <1> 	;jb	short sysgtty_inv_dn
 17476 0000393E 2C08                <1> 	sub	al, 8
 17477 00003940 720A                <1> 	jb	short sysgtty_inv_dn
 17478 00003942 7416                <1> 	jz	short sysgtty_2 ; /dev/tty inode number is 8
 17479                              <1> 	; convert inode number to tty number (tty0 to tty9)
 17480 00003944 2C09                <1> 	sub	al, 9
 17481 00003946 7204                <1> 	jb	short sysgtty_inv_dn
 17482                              <1> 	; al = 0 to 9
 17483 00003948 29DB                <1> 	sub	ebx, ebx ; 22/02/2022
 17484 0000394A EB1F                <1> 	jmp	short sysgtty_4
 17485                              <1> 	
 17486                              <1> sysgtty_inv_dn: 
 17487                              <1> 	;; 28/06/2015
 17488                              <1> 	;; Invalid device name (not a tty) ! error
 17489                              <1> 	;; (Device is not a tty or device name not found)
 17490                              <1> 	;mov	dword [u.error], ERR_INV_DEV_NAME
 17491                              <1> 	;jmp	error
 17492                              <1> 	; 21/02/2022
 17493 0000394C E935FFFFFF          <1> 	jmp	sysstty_inv_dn
 17494                              <1> 
 17495                              <1> sysgtty_1:
 17496                              <1> 	; 16/01/2014
 17497 00003951 80FD0A              <1> 	cmp	ch, 10
 17498 00003954 77C1                <1> 	ja	short sysgtty_invp ; 28/06/2015
 17499 00003956 FECD                <1> 	dec	ch ; 0 -> FFh (negative)
 17500 00003958 790F                <1> 	jns	short sysgtty_3 ; not negative
 17501                              <1> sysgtty_2:
 17502                              <1> 	; get tty number of console tty
 17503 0000395A 8A25[F56C0000]      <1> 	mov	ah, [u.uno]
 17504                              <1>  	; 28/06/2015
 17505 00003960 0FB6DC              <1> 	movzx 	ebx, ah
 17506 00003963 8AAB[A3680000]      <1> 	mov	ch, [ebx+p.ttyc-1]
 17507                              <1> sysgtty_3:
 17508 00003969 88E8                <1> 	mov	al, ch
 17509                              <1> sysgtty_4:
 17510 0000396B A2[A46C0000]        <1> 	mov	[u.r0], al
 17511                              <1>  	; 28/06/2015
 17512                              <1> 	;cmp	al, 9
 17513                              <1> 	;ja	short sysgtty_invp
 17514 00003970 8B2D[A06C0000]      <1> 	mov	ebp, [u.usp]
 17515                              <1> 	; 23/11/2015
 17516 00003976 20C9                <1> 	and	cl, cl
 17517 00003978 7432                <1> 	jz	short sysgtty_6 ; keyboard status
 17518 0000397A 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
 17519 0000397C 722E                <1> 	jb	short sysgtty_6 ; video page status
 17520                              <1> 	; serial port status
 17521                              <1> 	; 12/07/2014
 17522                              <1> 	;mov	dx, 0
 17523                              <1> 	;je	short sysgtty_5
 17524                              <1> 	;inc	dl
 17525                              <1> ;sysgtty_5:
 17526                              <1> 	; 28/06/2015
 17527 0000397E 2C08                <1> 	sub	al, 8
 17528 00003980 E81AF2FFFF          <1> 	call	sp_status ; serial (COM) port (line) status
 17529                              <1> 	; AL = Line status, AH = Modem status
 17530 00003985 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
 17531 00003989 8A25[F56C0000]      <1> 	mov	ah, [u.uno]
 17532 0000398F 8825[A56C0000]      <1>         mov     [u.r0+1], ah
 17533                              <1> 	; 24/12/2021
 17534 00003995 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)
 17535                              <1> 				; (in ECX)
 17536 0000399B A880                <1> 	test	al, 80h
 17537 0000399D 7561                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
 17538 0000399F A801                <1> 	test	al, 1
 17539                              <1> 	;jz	sysret
 17540 000039A1 7404                <1> 	jz	short sysgtty_10
 17541 000039A3 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)
 17542                              <1> sysgtty_10:
 17543 000039A7 E9D9F7FFFF          <1> 	jmp	sysret
 17544                              <1> sysgtty_6:
 17545 000039AC A2[D96C0000]        <1> 	mov	[u.ttyn], al ; tty number
 17546                              <1> 	;movzx	ebx, al
 17547 000039B1 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
 17548 000039B3 D0E3                <1> 	shl 	bl, 1  ; aligned to word
 17549                              <1> 	; 22/04/2014 - 29/06/2015
 17550 000039B5 81C3[B4670000]      <1>         add     ebx, ttyl
 17551 000039BB 8A23                <1>  	mov	ah, [ebx]
 17552 000039BD 3A25[F56C0000]      <1> 	cmp	ah, [u.uno]
 17553 000039C3 7404                <1> 	je	short sysgtty_7
 17554 000039C5 20E4                <1> 	and	ah, ah
 17555                              <1> 	;jz	short sysgtty_7
 17556 000039C7 7506                <1> 	jnz	short sysgtty_8
 17557                              <1> 	;mov	ah, 0FFh
 17558                              <1> sysgtty_7:
 17559 000039C9 8825[A56C0000]      <1>         mov     [u.r0+1], ah
 17560                              <1> sysgtty_8:
 17561 000039CF 08C9                <1> 	or	cl, cl
 17562 000039D1 7510                <1> 	jnz	short sysgtty_9
 17563 000039D3 B001                <1> 	mov	al, 1  ; test a key is available
 17564 000039D5 E88F210000          <1> 	call	getc
 17565 000039DA 66894510            <1> 	mov	[ebp+16], ax ; bx, character
 17566 000039DE E9A2F7FFFF          <1> 	jmp	sysret
 17567                              <1> sysgtty_9:
 17568 000039E3 8A1D[D96C0000]      <1> 	mov	bl, [u.ttyn]
 17569                              <1> 	; bl = video page number
 17570 000039E9 E8EC220000          <1> 	call 	get_cpos
 17571                              <1> 	; dx = cursor position
 17572 000039EE 66895510            <1> 	mov	[ebp+16], dx ; bx
 17573                              <1> 	;mov	bl, [u.ttyn]
 17574                              <1> 	; bl = video page number
 17575 000039F2 E8F4220000          <1> 	call	read_ac_current
 17576                              <1> 	; ax = character and attribute/color
 17577 000039F7 66894518            <1> 	mov	[ebp+24], ax ; cx
 17578 000039FB E985F7FFFF          <1> 	jmp	sysret
 17579                              <1> sysgtty_dnr_err:
 17580                              <1> 	; 'device not responding !' error	
 17581                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
 17582 00003A00 C705[186D0000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ; 25
 17583 00003A08 0000                <1>
 17584 00003A0A E956F7FFFF          <1> 	jmp	error	
 17585                              <1> 
 17586                              <1> ; Original UNIX v1 'sysgtty' routine:
 17587                              <1> ; sysgtty:
 17588                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
 17589                              <1> 	;	       / r2 has destination
 17590                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
 17591                              <1> 	;                     / in 1st word of dest
 17592                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
 17593                              <1> 	;                     / in 2nd word of dest
 17594                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
 17595                              <1>         ;jmp    sysret2 / return to user
 17596                              <1> 	
 17597                              <1> ; Original UNIX v1 'gtty' routine:
 17598                              <1> ; gtty:
 17599                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
 17600                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
 17601                              <1>         ;jsr    r0,getf / get the i-number of the file
 17602                              <1>         ;tst    r1 / is it open for reading
 17603                              <1>         ;bgt    1f / yes
 17604                              <1>         ;neg    r1 / no, i-number is negative, 
 17605                              <1> 	;          / so make it positive
 17606                              <1> ;1:
 17607                              <1>         ;sub    $14.,r1 / get i-number of tty0
 17608                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
 17609                              <1>         ;bhis   error9 / no, error
 17610                              <1>         ;asl    r1 / 0%2
 17611                              <1>         ;asl    r1 / 0%4 / yes
 17612                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
 17613                              <1> 	;	       ; / tty block
 17614                              <1>         ;mov    u.off,r2 / put argument in r2
 17615                              <1>         ;rts    r0 / return
 17616                                  %include 'u2.s'      ; 11/05/2015
 17617                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 17618                              <1> ; (re-write kernel for test by using previous version without a major defect)
 17619                              <1> ; ****************************************************************************
 17620                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS2.INC
 17621                              <1> ; Last Modification: 18/07/2022
 17622                              <1> ; ----------------------------------------------------------------------------
 17623                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 17624                              <1> ; (v0.1 - Beginning: 11/07/2012)
 17625                              <1> ;
 17626                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 17627                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 17628                              <1> ; <Bell Laboratories (17/3/1972)>
 17629                              <1> ; <Preliminary Release of UNIX Implementation Document>
 17630                              <1> ;
 17631                              <1> ; Retro UNIX 8086 v1 - U2.ASM (24/03/2014) //// UNIX v1 -> u2.s
 17632                              <1> ;
 17633                              <1> ; ****************************************************************************
 17634                              <1> 
 17635                              <1> syslink:
 17636                              <1> 	; 12/01/2022
 17637                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 17638                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17639                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17640                              <1> 	;
 17641                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
 17642                              <1> 	; name 1 is a file that already exists. name 2 is the name
 17643                              <1> 	; given to the entry that will go in the current directory.
 17644                              <1> 	; name2 will then be a link to the name 1 file. The i-number
 17645                              <1> 	; in the name 2 entry of current directory is the same
 17646                              <1> 	; i-number for the name 1 file.
 17647                              <1> 	;
 17648                              <1> 	; Calling sequence:
 17649                              <1> 	;	syslink; name 1; name 2
 17650                              <1> 	; Arguments:
 17651                              <1> 	;	name 1 - file name to which link will be created.
 17652                              <1> 	;	name 2 - name of entry in current directory that
 17653                              <1> 	;		 links to name 1.
 17654                              <1> 	; Inputs: -
 17655                              <1> 	; Outputs: -
 17656                              <1> 	; ...............................................................
 17657                              <1> 	;	
 17658                              <1> 	; Retro UNIX 8086 v1 modification: 
 17659                              <1> 	;       'syslink' system call has two arguments; so,
 17660                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
 17661                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
 17662                              <1> 	;
 17663                              <1> 		; / name1, name2
 17664                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
 17665 00003A0F 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 17666 00003A15 51                  <1> 	push	ecx
 17667 00003A16 E861060000          <1> 	call	namei
 17668                              <1> 		; jsr r0,namei / find the i-number associated with
 17669                              <1> 			     ; / the 1st path name
 17670                              <1>      	;;and	ax, ax
 17671                              <1> 	;;jz	error ; File not found
 17672                              <1> 	;jc	error 
 17673                              <1> 		; br error9 / cannot be found
 17674 00003A1B 730F                <1> 	jnc	short syslink0
 17675                              <1> 	;pop 	ecx
 17676                              <1> 	; 'file not found !' error
 17677 00003A1D C705[186D0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17678 00003A25 0000                <1>
 17679 00003A27 E939F7FFFF          <1> 	jmp	error
 17680                              <1> syslink0:
 17681 00003A2C E844110000          <1> 	call	iget
 17682                              <1> 		; jsr r0,iget / get the i-node into core
 17683 00003A31 8F05[C06C0000]      <1> 	pop	dword [u.namep] ; ecx
 17684                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
 17685                              <1> 	; 24/12/2021
 17686 00003A37 50                  <1> 	push	eax ; *
 17687                              <1> 	;push	ax
 17688                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
 17689                              <1> 			    ; / (a link to this file is to be created)
 17690                              <1> 	; 24/12/2021
 17691 00003A38 8A0D[816C0000]      <1> 	mov	cl, [cdev]
 17692 00003A3E 51                  <1> 	push	ecx ; **
 17693                              <1> 	;push	word [cdev]
 17694                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
 17695 00003A3F E8AC000000          <1> 	call	isdir
 17696                              <1> 		; jsr r0,isdir / is it a directory
 17697 00003A44 E833060000          <1> 	call	namei
 17698                              <1> 		; jsr r0,namei / no, get i-number of name2
 17699                              <1> 	;jnc	error
 17700                              <1> 		; br .+4   / not found 
 17701                              <1> 			 ; / so r1 = i-number of current directory
 17702                              <1> 			 ; / ii = i-number of current directory
 17703                              <1> 		; br error9 / file already exists., error
 17704 00003A49 720F                <1> 	jc	short syslink1
 17705                              <1> 	; pop eax ; 24/12/2021
 17706                              <1> 	; pop eax
 17707                              <1> 	; 'file exists !' error
 17708 00003A4B C705[186D0000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
 17709 00003A53 0000                <1>
 17710 00003A55 E90BF7FFFF          <1> 	jmp	error
 17711                              <1> syslink1:
 17712                              <1> 	;pop	cx
 17713                              <1> 	; 24/12/2021
 17714 00003A5A 59                  <1> 	pop	ecx ; **
 17715                              <1> 	;cmp	cx, [cdev]
 17716 00003A5B 3A0D[816C0000]      <1> 	cmp	cl, [cdev]
 17717                              <1> 	;jne	error
 17718                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
 17719                              <1> 			       ; / end of current directory
 17720                              <1> 	        ; bne error9
 17721 00003A61 740F                <1> 	je	short syslink2
 17722                              <1> 	; 'not same drive !' error
 17723 00003A63 C705[186D0000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
 17724 00003A6B 0000                <1>
 17725 00003A6D E9F3F6FFFF          <1> 	jmp	error
 17726                              <1> syslink2:
 17727                              <1> 	;pop	eax ; 24/12/2021
 17728                              <1> 	;push	eax
 17729                              <1> 	; 24/12/2021
 17730 00003A72 8B0424              <1> 	mov	eax, [esp] ; *
 17731 00003A75 66A3[DC6C0000]      <1> 	mov	[u.dirbuf], ax
 17732                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
 17733 00003A7B E8C5000000          <1> 	call	mkdir
 17734                              <1> 		; jsr r0,mkdir / make directory entry for name2 
 17735                              <1> 		 	     ; / in current directory
 17736                              <1> 	; 24/12/2021
 17737 00003A80 58                  <1> 	pop	eax ; *
 17738                              <1> 	;pop	ax
 17739                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
 17740 00003A81 E8EF100000          <1> 	call	iget
 17741                              <1> 		; jsr r0,iget / get i-node into core
 17742 00003A86 FE05[26680000]      <1> 	inc	byte [i.nlks]
 17743                              <1> 		; incb i.nlks / add 1 to its number of links
 17744                              <1> sysunlink_2:
 17745                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 17746 00003A8C C605[956C0000]01    <1> 	mov	byte [imodx], 1	; (flag means file data is same
 17747                              <1> 				;  but inode's itself has been modified)
 17748 00003A93 E86E120000          <1> 	call	setimod
 17749                              <1> 		; jsr r0,setimod / set the i-node modified flag
 17750 00003A98 E9E8F6FFFF          <1> 	jmp	sysret
 17751                              <1> 
 17752                              <1> sysunlink:
 17753                              <1> 	; 12/01/2022
 17754                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 17755                              <1> 	; 04/12/2015 (14 byte file names)
 17756                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17757                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17758                              <1> 	;
 17759                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
 17760                              <1> 	; name from its directory. If this entry was the last link
 17761                              <1> 	; to the file, the contents of the file are freed and the
 17762                              <1> 	; file is destroyed. If, however, the file was open in any
 17763                              <1> 	; process, the actual destruction is delayed until it is 
 17764                              <1> 	; closed, even though the directory entry has disappeared.
 17765                              <1> 	; 
 17766                              <1> 	; The error bit (e-bit) is set to indicate that the file	
 17767                              <1> 	; does not exist or that its directory can not be written.
 17768                              <1> 	; Write permission is not required on the file itself.
 17769                              <1> 	; It is also illegal to unlink a directory (except for
 17770                              <1> 	; the superuser).
 17771                              <1> 	;
 17772                              <1> 	; Calling sequence:
 17773                              <1> 	;	sysunlink; name
 17774                              <1> 	; Arguments:
 17775                              <1> 	;	name - name of directory entry to be removed 
 17776                              <1> 	; Inputs: -
 17777                              <1> 	; Outputs: -
 17778                              <1> 	; ...............................................................
 17779                              <1> 	;				
 17780                              <1> 	; Retro UNIX 8086 v1 modification:
 17781                              <1> 	;	 The user/application program puts address of the name
 17782                              <1> 	;        in BX register as 'sysunlink' system call argument.
 17783                              <1> 
 17784                              <1> 	; / name - remove link name
 17785 00003A9D 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 17786                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
 17787 00003AA3 E8D4050000          <1> 	call	namei
 17788                              <1> 		; jsr r0,namei / find the i-number associated 
 17789                              <1> 			     ; / with the path name
 17790                              <1> 	;jc	error
 17791                              <1> 		; br error9 / not found
 17792 00003AA8 730F                <1> 	jnc	short sysunlink1
 17793                              <1> 	; 'file not found !' error
 17794 00003AAA C705[186D0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17795 00003AB2 0000                <1>
 17796 00003AB4 E9ACF6FFFF          <1> 	jmp	error
 17797                              <1> sysunlink1:
 17798 00003AB9 50                  <1> 	push	eax ; 24/12/2021
 17799                              <1> 	;push	ax
 17800                              <1> 		; mov r1,-(sp) / put its i-number on the stack
 17801 00003ABA E831000000          <1> 	call	isdir
 17802                              <1> 		; jsr r0,isdir / is it a directory
 17803                              <1> 	;xor 	ax, ax
 17804                              <1> 	; 24/12/2021
 17805 00003ABF 31C0                <1> 	xor	eax, eax
 17806 00003AC1 66A3[DC6C0000]      <1> 	mov	[u.dirbuf], ax ; 0
 17807                              <1> 		; clr u.dirbuf / no, clear the location that will
 17808                              <1> 			   ; / get written into the i-number portion
 17809                              <1> 			 ; / of the entry
 17810 00003AC7 832D[C46C0000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
 17811                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
 17812 00003ACE E8BD000000          <1> 	call	wdir
 17813                              <1> 		; jsr r0,wdir / free the directory entry
 17814 00003AD3 58                  <1> 	pop	eax ; 24/12/2021
 17815                              <1> 	;pop	ax
 17816                              <1> 		; mov (sp)+,r1 / get i-number back
 17817 00003AD4 E89C100000          <1> 	call	iget
 17818                              <1> 		; jsr r0,iget / get i-node
 17819                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 17820                              <1> 	;call	setimod
 17821                              <1> 	;	; jsr r0,setimod / set modified flag
 17822                              <1> 	;	
 17823 00003AD9 FE0D[26680000]      <1> 	dec	byte [i.nlks]
 17824                              <1> 		; decb i.nlks / decrement the number of links
 17825                              <1> 	; 24/12/2021
 17826 00003ADF 75AB                <1> 	jnz	short sysunlink_2
 17827                              <1> 	;jnz	sysret
 17828                              <1> 		; bgt sysret9 / if this was not the last link
 17829                              <1> 			    ; / to file return
 17830                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 17831 00003AE1 E820120000          <1> 	call	setimod
 17832                              <1> 		; jsr r0,setimod / set modified flag
 17833                              <1> 	; AX = r1 = i-number
 17834 00003AE6 E89B0A0000          <1> 	call	anyi
 17835                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
 17836                              <1> 			 ; / Then free contents of file and destroy it.
 17837 00003AEB E995F6FFFF          <1> 	jmp	sysret
 17838                              <1> 		; br sysret9
 17839                              <1> ;sysunlink_2:
 17840                              <1> 	;; 12/01/2022 - Retro UNIX 386 v1.2
 17841                              <1> 	;mov	byte [imodx], 1	; (flag means file data is same
 17842                              <1> 	;			;  but inode's itself has been modified)
 17843                              <1> 	;call	setimod
 17844                              <1> 	;	; jsr r0,setimod / set the i-node modified flag
 17845                              <1> 	;jmp	sysret
 17846                              <1> 
 17847                              <1> isdir:
 17848                              <1> 	; 13/03/2022
 17849                              <1> 	; 08/01/2022
 17850                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode)
 17851                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 17852                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 17853                              <1> 	;
 17854                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
 17855                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
 17856                              <1> 	;  called by syslink and sysunlink to make sure directories
 17857                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
 17858                              <1> 	; 'isdir' does not bother checking. The current i-node
 17859                              <1> 	;  is not disturbed.			
 17860                              <1> 	;		
 17861                              <1> 	; INPUTS ->
 17862                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
 17863                              <1> 	;    u.uid - user id
 17864                              <1> 	; OUTPUTS ->
 17865                              <1> 	;    r1 - contains current i-number upon exit
 17866                              <1> 	;    	 (current i-node back in core) 
 17867                              <1> 	;	
 17868                              <1> 	; ((AX = R1))
 17869                              <1> 	;
 17870                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 17871                              <1> 	;
 17872                              <1> 
 17873                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
 17874                              <1> 	; / there is an error unless super user made the call
 17875                              <1> 	
 17876                              <1> 	; 01/01/2022
 17877 00003AF0 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0 ; 16 bit uid (runix v2 fs inode)
 17878                              <1> 	;cmp	byte [u.uid], 0 
 17879                              <1> 		; tstb u.uid / super user
 17880 00003AF8 764A                <1> 	jna	short isdir1
 17881                              <1> 		; beq 1f / yes, don't care
 17882                              <1> 	; 08/01/2022
 17883 00003AFA FF35[7C6C0000]      <1> 	push	dword [ii]
 17884                              <1> 	;push	word [ii]
 17885                              <1> 		; mov ii,-(sp) / put current i-number on stack
 17886 00003B00 E870100000          <1> 	call	iget
 17887                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
 17888                              <1> 	; 01/01/2022 (runix v2 fs inode flags)
 17889 00003B05 F605[25680000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file ?
 17890 00003B0C 7421                <1> 	jz	short isdir2 ; no, error!
 17891 00003B0E F605[25680000]40    <1> 	test	byte [i.flgs+1], 40h ; directory flag
 17892                              <1> 	;test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
 17893                              <1> 		; bit $40000,i.flgs / is it a directory
 17894                              <1> 	;jnz	error
 17895                              <1> 		; bne error9 / yes, error
 17896 00003B15 7427                <1> 	jz	short isdir0
 17897                              <1> 
 17898                              <1> 	; 13/03/2022
 17899                              <1> 	; NOTE:
 17900                              <1> 	; Unix v5-v7 kernels do not allow (ordinary) users
 17901                              <1> 	; (except root/superuser) --if [u.uid] > 0--
 17902                              <1> 	; to link a directory. (ref: sys2.c, 'link')
 17903                              <1> 	;
 17904                              <1> 	; But, Retro UNIX 386 v1.2 will allow the owner of
 17905                              <1> 	; the directory to link it.
 17906                              <1> 
 17907 00003B17 66A1[28680000]      <1> 	mov	ax, [i.uid] ; owner ID of the parent dir
 17908 00003B1D 663B05[F66C0000]    <1> 	cmp	ax, [u.uid] ; user ID of current user/process
 17909 00003B24 7509                <1> 	jne	short isdir2
 17910                              <1> 	; 13/03/2022
 17911                              <1> 	; additional checking (may or may not be necessary!?)
 17912 00003B26 663B05[F86C0000]    <1> 	cmp	ax, [u.ruid] 
 17913                              <1> 			; real (login) user ID must be same
 17914 00003B2D 740F                <1> 	je	short isdir0
 17915                              <1> 
 17916                              <1> isdir2:
 17917 00003B2F C705[186D0000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
 17918 00003B37 0000                <1>
 17919                              <1> 				; 'permission denied !' error
 17920                              <1> 	;pop	ax
 17921 00003B39 E927F6FFFF          <1> 	jmp	error	
 17922                              <1> isdir0:	
 17923                              <1> 	; 08/01/2022
 17924 00003B3E 58                  <1> 	pop	eax
 17925                              <1> 	;pop	ax
 17926                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
 17927 00003B3F E831100000          <1> 	call	iget
 17928                              <1> 		; jsr r0,iget / get it back in
 17929                              <1> isdir1: ; 1:
 17930 00003B44 C3                  <1> 	retn
 17931                              <1> 		; rts r0
 17932                              <1> 
 17933                              <1> mkdir:
 17934                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 17935                              <1> 	; 04/12/2015 (14 byte directory names)
 17936                              <1> 	; 12/10/2015
 17937                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
 17938                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 17939                              <1> 	;
 17940                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
 17941                              <1> 	; by u.namep into the current directory.
 17942                              <1> 	;
 17943                              <1> 	; INPUTS ->
 17944                              <1> 	;    u.namep - points to a file name 
 17945                              <1> 	;	           that is about to be a directory entry.
 17946                              <1> 	;    ii - current directory's i-number.	
 17947                              <1> 	; OUTPUTS ->
 17948                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
 17949                              <1> 	;    u.off - points to entry to be filled 
 17950                              <1> 	;	     in the current directory		
 17951                              <1> 	;    u.base - points to start of u.dirbuf.
 17952                              <1> 	;    r1 - contains i-number of current directory 
 17953                              <1> 	;	
 17954                              <1> 	; ((AX = R1)) output
 17955                              <1> 	;
 17956                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
 17957                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 17958                              <1> 	;
 17959                              <1> 
 17960                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 17961 00003B45 31C0                <1> 	xor 	eax, eax
 17962 00003B47 BF[DE6C0000]        <1> 	mov     edi, u.dirbuf+2
 17963 00003B4C 89FE                <1> 	mov	esi, edi
 17964 00003B4E AB                  <1> 	stosd
 17965 00003B4F AB                  <1> 	stosd
 17966                              <1> 	; 04/12/2015 (14 byte directory names)
 17967 00003B50 AB                  <1> 	stosd
 17968 00003B51 66AB                <1> 	stosw
 17969                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
 17970 00003B53 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
 17971                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 17972                              <1> 	;mov 	ebp, [u.namep]
 17973 00003B55 E881060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 17974                              <1> 		; esi = physical address (page start + offset)
 17975                              <1> 		; ecx = byte count in the page (1 - 4096)
 17976                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 17977                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
 17978                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
 17979                              <1> mkdir_1: ; 1: 
 17980 00003B5A 45                  <1> 	inc	ebp ; 12/10/2015
 17981                              <1> 	;
 17982                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
 17983                              <1> 	; 01/08/2013
 17984 00003B5B AC                  <1> 	lodsb
 17985                              <1> 		; movb (r2)+,r1 / move character in name to r1
 17986 00003B5C 20C0                <1> 	and 	al, al
 17987 00003B5E 7426                <1> 	jz 	short mkdir_3 	  
 17988                              <1> 		; beq 1f / if null, done
 17989 00003B60 3C2F                <1> 	cmp	al, '/'
 17990                              <1> 		; cmp r1,$'/ / is it a "/"?
 17991 00003B62 7413                <1> 	je	short mkdir_err
 17992                              <1> 	;je	error
 17993                              <1> 		; beq error9 / yes, error
 17994                              <1> 	; 12/10/2015
 17995                              <1> 	;dec	cx
 17996 00003B64 49                  <1> 	dec	ecx ; 24/12/2021
 17997 00003B65 7505                <1> 	jnz	short mkdir_2
 17998                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 17999 00003B67 E875060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 18000                              <1> 		; esi = physical address (page start + offset)
 18001                              <1> 		; ecx = byte count in the page
 18002                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 18003                              <1> mkdir_2:
 18004 00003B6C 81FF[EC6C0000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
 18005                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
 18006                              <1> 				     ; / a char?
 18007 00003B72 74E6                <1> 	je	short mkdir_1
 18008                              <1> 		; beq 1b / yes, go back
 18009 00003B74 AA                  <1> 	stosb
 18010                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
 18011 00003B75 EBE3                <1> 	jmp 	short mkdir_1
 18012                              <1> 		; br 1b / get next char
 18013                              <1> mkdir_err:
 18014                              <1> 	; 17/06/2015
 18015 00003B77 C705[186D0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 18016 00003B7F 0000                <1>
 18017 00003B81 E9DFF5FFFF          <1> 	jmp	error
 18018                              <1> 
 18019                              <1> mkdir_3: ; 1:
 18020 00003B86 A1[BC6C0000]        <1> 	mov	eax, [u.dirp]
 18021 00003B8B A3[C46C0000]        <1> 	mov	[u.off], eax
 18022                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
 18023                              <1> 				 ; / slot to u.off
 18024                              <1> 	; 08/01/2022
 18025                              <1> wdir:	; 24/12/2021 (Retro UNIX 386 v1.2)
 18026                              <1> 	; 29/04/2013
 18027 00003B90 C705[C86C0000]-     <1>         mov     dword [u.base], u.dirbuf
 18028 00003B96 [DC6C0000]          <1>
 18029                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
 18030 00003B9A C705[CC6C0000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
 18031 00003BA2 0000                <1>
 18032                              <1> 		; mov $10.,u.count / u.count = 10
 18033                              <1> 	; 08/01/2022
 18034 00003BA4 A1[7C6C0000]        <1> 	mov	eax, [ii]
 18035                              <1> 	;mov	ax, [ii] 
 18036                              <1> 		; mov ii,r1 / r1 has i-number of current directory
 18037                              <1> 	;mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
 18038                              <1> 	; 08/01/2022 (Retro UNIX 386 v2 file system inode)
 18039 00003BA9 66BA8000            <1> 	mov	dx, 80h	; mov dx, IWRITE
 18040 00003BAD E8AD100000          <1> 	call 	access
 18041                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
 18042                              <1> 				 ; / for writing
 18043                              <1> 	; AX = i-number of current directory
 18044                              <1> 	; 01/08/2013
 18045 00003BB2 FE05[166D0000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
 18046                              <1> 	;call	writei
 18047                              <1> 	;	; jsr r0,writei / write into directory
 18048                              <1> 	;retn	
 18049                              <1> 	;	; rts r0
 18050                              <1> 	; 24/12/2021
 18051 00003BB8 E938150000          <1> 	jmp	writei
 18052                              <1> 
 18053                              <1> 
 18054                              <1> 	; 09/05/2022 
 18055                              <1> 	;	(Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 18056                              <1> 	; 06/02/2022
 18057                              <1> 	; 12/01/2022
 18058                              <1> 	; 01/01/2022
 18059                              <1> 	; 24/12/2021
 18060                              <1> 	; 11/12/2021
 18061                              <1> 	; 04/12/2021
 18062                              <1> 	; 30/11/2021
 18063                              <1> 	; 28/11/2021 - Retro UNIX 386 v1.2
 18064                              <1> 	;	(Retro UNIX 386 v2 fs compatibility modification)
 18065                              <1> sysexec:
 18066                              <1> 	; 02/05/2021
 18067                              <1> 	; 27/03/2021
 18068                              <1> 	; 26/03/2021
 18069                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 18070                              <1> 	; 23/10/2015
 18071                              <1> 	; 10/10/2015, 18/10/2015, 19/10/2015
 18072                              <1> 	; 29/07/2015, 05/08/2015, 05/08/2015
 18073                              <1> 	; 21/07/2015, 24/07/2015, 25/07/2015
 18074                              <1> 	; 01/07/2015, 02/07/2015, 20/07,2015
 18075                              <1> 	; 24/06/2015, 25/06/2021
 18076                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18077                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 18078                              <1> 	;
 18079                              <1> 	; 'sysexec' initiates execution of a file whose path name if
 18080                              <1> 	; pointed to by 'name' in the sysexec call. 
 18081                              <1> 	; 'sysexec' performs the following operations:
 18082                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
 18083                              <1> 	;    2. obtains i-node of file to be executed via 'iget'.
 18084                              <1> 	;    3. sets trap vectors to system routines.
 18085                              <1> 	;    4. loads arguments to be passed to executing file into
 18086                              <1> 	;	highest locations of user's core
 18087                              <1> 	;    5. puts pointers to arguments in locations immediately
 18088                              <1> 	;	following arguments.
 18089                              <1> 	;    6.	saves number of arguments in next location.
 18090                              <1> 	;    7. initializes user's stack area so that all registers
 18091                              <1> 	;	will be zeroed and the PS is cleared and the PC set
 18092                              <1> 	;	to core when 'sysret' restores registers 
 18093                              <1> 	;	and does an rti.
 18094                              <1> 	;    8. inializes u.r0 and u.sp
 18095                              <1> 	;    9. zeros user's core down to u.r0
 18096                              <1> 	;   10.	reads executable file from storage device into core
 18097                              <1> 	;	starting at location 'core'.
 18098                              <1> 	;   11.	sets u.break to point to end of user's code with
 18099                              <1> 	;	data area appended.
 18100                              <1> 	;   12.	calls 'sysret' which returns control at location
 18101                              <1> 	;	'core' via 'rti' instruction.
 18102                              <1> 	;
 18103                              <1> 	; Calling sequence:
 18104                              <1> 	;	sysexec; namep; argp
 18105                              <1> 	; Arguments:
 18106                              <1> 	;	namep - points to pathname of file to be executed
 18107                              <1> 	;	argp  - address of table of argument pointers
 18108                              <1> 	;	argp1... argpn - table of argument pointers
 18109                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
 18110                              <1> 	; Inputs: (arguments)
 18111                              <1> 	; Outputs: -	
 18112                              <1> 	; ...............................................................
 18113                              <1> 	;
 18114                              <1> 	; Retro UNIX 386 v1 modification: 
 18115                              <1> 	;	User application runs in it's own virtual space 
 18116                              <1> 	;	which is izolated from kernel memory (and other
 18117                              <1> 	;	memory pages) via 80386	paging in ring 3 
 18118                              <1> 	;	privilige mode. Virtual start address is always 0.
 18119                              <1> 	;	User's core memory starts at linear address 400000h
 18120                              <1> 	;	(the end of the 1st 4MB).
 18121                              <1> 	;
 18122                              <1> 	; Retro UNIX 8086 v1 modification: 
 18123                              <1> 	;	user/application segment and system/kernel segment
 18124                              <1> 	;	are different and sysenter/sysret/sysrele routines
 18125                              <1> 	;	are different (user's registers are saved to 
 18126                              <1> 	;	and then restored from system's stack.)
 18127                              <1> 	;
 18128                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 18129                              <1> 	;	      arguments which were in these registers;
 18130                              <1> 	;	      but, it returns by putting the 1st argument
 18131                              <1> 	;	      in 'u.namep' and the 2nd argument
 18132                              <1> 	;	      on top of stack. (1st argument is offset of the
 18133                              <1> 	;	      file/path name in the user's program segment.)
 18134                              <1> 	
 18135                              <1> 	;call	arg2
 18136                              <1> 	; * name - 'u.namep' points to address of file/path name
 18137                              <1> 	;          in the user's program segment ('u.segmnt')
 18138                              <1> 	;          with offset in BX register (as sysopen argument 1).
 18139                              <1> 	; * argp - sysexec argument 2 is in CX register 
 18140                              <1> 	;          which is on top of stack.
 18141                              <1> 	;
 18142                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
 18143                              <1> 
 18144                              <1> 	; 23/06/2015 (32 bit modifications)
 18145                              <1> 
 18146 00003BBD 891D[C06C0000]      <1> 	mov	[u.namep], ebx ; argument 1
 18147                              <1>         ; 18/10/2015
 18148 00003BC3 890D[346D0000]      <1> 	mov     [argv], ecx  ; * ; argument 2
 18149 00003BC9 E8AE040000          <1> 	call	namei
 18150                              <1> 		; jsr r0,namei / namei returns i-number of file 
 18151                              <1> 			     ; / named in sysexec call in r1
 18152                              <1> 	;jc	error
 18153                              <1> 		; br error9
 18154 00003BCE 730F                <1> 	jnc	short sysexec_0
 18155                              <1> 	;
 18156                              <1> 	; 'file not found !' error
 18157 00003BD0 C705[186D0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
 18158 00003BD8 0000                <1>
 18159 00003BDA E986F5FFFF          <1> 	jmp	error
 18160                              <1> 
 18161                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 18162                              <1> 	; (executable file flag is checked in 'access')
 18163                              <1> 	; (following error message is in 'access' subroutine)
 18164                              <1> ;sysexec_not_exf:
 18165                              <1> 	;; 'not executable file !' error
 18166                              <1> 	;mov	dword [u.error], ERR_NOT_EXECUTABLE
 18167                              <1> 	;jmp	error 
 18168                              <1> sysexec_0:
 18169                              <1> 	; 26/03/2021 ('iget' will be called in 'access')
 18170                              <1> 	;call	iget
 18171                              <1> 	;	; jsr r0,iget / get i-node for file to be executed
 18172                              <1> 	;
 18173                              <1> 	;test	byte [i.flgs], 10h
 18174                              <1> 	;;test	word [i.flgs], 10h
 18175                              <1> 	;	; bit $20,i.flgs / is file executable
 18176                              <1> 	;jz	short sysexec_not_exf
 18177                              <1> 	;;jz	error
 18178                              <1> 	;	; beq error9
 18179                              <1> 	; 26/03/2021
 18180 00003BDF 66BA4000            <1> 	mov	dx, 40h ; IEXEC - execute, owner
 18181 00003BE3 E877100000          <1> 	call	access
 18182                              <1> 	; ! we are here because there is execute permission !
 18183                              <1> 	; ('iopen' is not needed for regular files, from now on)
 18184                              <1> 
 18185                              <1> 	; 26/03/2021
 18186                              <1> 	;; 25/03/2021
 18187                              <1> 	;; (ref: Retro UNIX 386 v2, 'ux.s')
 18188                              <1> 	;mov	dx, 40h ; IEXEC - execute, owner
 18189                              <1> 	;;
 18190                              <1> 	;call	iopen
 18191                              <1> 	;	; jsr r0,iopen / gets i-node for file with i-number
 18192                              <1> 	;		     ; / given in r1 (opens file)
 18193                              <1> 	
 18194                              <1> 	; 26/03/2021
 18195                              <1> 	; AX = i-number of the file
 18196                              <1> 	;test	byte [i.flgs], 20h
 18197                              <1> 	;;test	word [i.flgs], 20h
 18198                              <1> 	;	; bit $40,i.flgs / test user id on execution bit
 18199                              <1> 	;jz	short sysexec_1
 18200                              <1> 	;	; beq 1f
 18201                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013
 18202                              <1> 	;	; tstb u.uid / test user id
 18203                              <1> 	;jna	short sysexec_1
 18204                              <1> 	;	; beq 1f / super user
 18205                              <1> 
 18206                              <1> 	;mov	cl, [i.uid]
 18207                              <1> 	;mov	[u.uid], cl ; 02/08/2013
 18208                              <1> 	;	; movb i.uid,u.uid / put user id of owner of file
 18209                              <1> 				 ; / as process user id
 18210                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 18211                              <1> 	;mov	al, [i.flgs+1]
 18212 00003BE8 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0	; super user (root) ?
 18213                              <1> 	;jna	short sysexec_19 ; yes, super user
 18214                              <1> 	;; 02/05/2021
 18215 00003BF0 7625                <1> 	jna	short sysexec_1	; don't set UID or GID
 18216                              <1> 
 18217                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2
 18218 00003BF2 A0[25680000]        <1> 	mov	al, [i.flgs+1]
 18219                              <1> 
 18220                              <1> 	; test set user id on execution bit 
 18221 00003BF7 A808                <1> 	test	al, 08h ; ISUID flag (800h)
 18222                              <1> 	;jz	short sysexec_19
 18223                              <1> 	; 02/05/2021
 18224 00003BF9 741C                <1> 	jz	short sysexec_1 ; do not set group ID
 18225                              <1> 				; (if user ID will not be set)
 18226                              <1> 				; (02/05/2021)	
 18227                              <1> 	; set user id on exec (800h)
 18228                              <1> 	; 26/03/2021
 18229                              <1> sysexec_setuid:
 18230                              <1> 	;; 27/03/2021
 18231                              <1> 	;cmp	word [u.uid], 0
 18232                              <1> 	;;jna	short sysexec_19 ; super user
 18233                              <1> 	;; 02/05/2021
 18234                              <1> 	;jna	short sysexec_1 ; do not set group ID
 18235                              <1> 	;			; (if user ID will not be set)
 18236                              <1> 	;			; (02/05/2021)
 18237 00003BFB 668B0D[28680000]    <1> 	mov	cx, [i.uid]
 18238 00003C02 66890D[F66C0000]    <1> 	mov	[u.uid], cx
 18239                              <1> sysexec_19:
 18240                              <1> 	; test set group id on execution bit 
 18241 00003C09 A804                <1> 	test	al, 04h ; ISGID flag (400h)
 18242 00003C0B 740A                <1> 	jz	short sysexec_1
 18243                              <1> sysexec_setgid:
 18244                              <1> 	; set group id on exec (400h)
 18245 00003C0D A0[2A680000]        <1> 	mov	al, [i.gid]
 18246 00003C12 A2[FA6C0000]        <1> 	mov	[u.gid], al
 18247                              <1> 	;
 18248                              <1> sysexec_1:
 18249                              <1> 	; 06/02/2022
 18250                              <1> 	; 12/01/2022
 18251                              <1> 	; 24/12/2021
 18252                              <1> 	; 11/12/2021
 18253                              <1> 	; 04/12/2021
 18254                              <1> 	; 10/10/2015, 18/10/2015
 18255                              <1> 	; 21/07/2015, 24/07/2015
 18256                              <1> 	; 24/06/2015, 25/06/2015
 18257                              <1>         ; Moving arguments to the end of [u.upage]
 18258                              <1> 	; (by regarding page borders in user's memory space)
 18259                              <1> 	;
 18260                              <1> 	; 10/10/2015
 18261                              <1> 	; 21/07/2015
 18262 00003C17 89E5                <1> 	mov	ebp, esp ; (**)
 18263                              <1> 	; 18/10/2015
 18264 00003C19 89EF                <1> 	mov 	edi, ebp
 18265 00003C1B B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
 18266                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
 18267 00003C20 29CF                <1> 	sub	edi, ecx
 18268 00003C22 89FC                <1> 	mov	esp, edi
 18269 00003C24 31C0                <1> 	xor	eax, eax
 18270 00003C26 A3[D06C0000]        <1> 	mov 	[u.nread], eax ; 0
 18271                              <1> 	; 12/01/2022
 18272                              <1> 	; ([argc] must be cleared because previous 'sysexec'
 18273                              <1> 	; may leave it with any value after an error))
 18274 00003C2B A3[306D0000]        <1> 	mov	[argc], eax ; 0
 18275                              <1> 	;
 18276 00003C30 49                  <1> 	dec	ecx ; 256 - 1
 18277 00003C31 890D[CC6C0000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
 18278                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
 18279                              <1> 	; 24/12/2021
 18280                              <1> sysexec_2:
 18281 00003C37 8B35[346D0000]      <1> 	mov	esi, [argv] ; 18/10/2015
 18282 00003C3D E85C020000          <1> 	call	get_argp
 18283                              <1> 	;mov	ecx, 4 
 18284                              <1> 	; 06/02/2022
 18285 00003C42 31C9                <1> 	xor	ecx, ecx
 18286 00003C44 B104                <1> 	mov	cl, 4
 18287                              <1> sysexec_3:
 18288 00003C46 21C0                <1> 	and	eax, eax
 18289 00003C48 7454                <1> 	jz	short sysexec_6
 18290                              <1> 	; 18/10/2015
 18291 00003C4A 010D[346D0000]      <1> 	add	[argv], ecx ; 4
 18292                              <1> 	;;inc	word [argc]
 18293                              <1> 	; 11/12/2021
 18294                              <1> 	;inc	dword [argc]
 18295                              <1> 	; 12/01/2022
 18296 00003C50 FE05[306D0000]      <1> 	inc	byte [argc]
 18297                              <1> 	;
 18298 00003C56 A3[C86C0000]        <1> 	mov	[u.base], eax
 18299                              <1>  	; 23/10/2015
 18300 00003C5B 66C705[106D0000]00- <1> 	mov	word [u.pcount], 0
 18301 00003C63 00                  <1>
 18302                              <1> sysexec_4:
 18303 00003C64 E8C4160000          <1> 	call	cpass ; get a character from user's core memory
 18304 00003C69 750B                <1>         jnz	short sysexec_5
 18305                              <1> 		; (max. 255 chars + null)
 18306                              <1> 	; 18/10/2015
 18307 00003C6B 28C0                <1> 	sub 	al, al
 18308 00003C6D AA                  <1> 	stosb
 18309 00003C6E FF05[D06C0000]      <1> 	inc	dword [u.nread]
 18310 00003C74 EB28                <1> 	jmp	short sysexec_6
 18311                              <1> sysexec_5:
 18312 00003C76 AA                  <1> 	stosb
 18313 00003C77 20C0                <1> 	and 	al, al
 18314 00003C79 75E9                <1> 	jnz	short sysexec_4
 18315 00003C7B B904000000          <1> 	mov	ecx, 4
 18316 00003C80 390D[2C6D0000]      <1> 	cmp	[ncount], ecx ; 4
 18317 00003C86 72AF                <1> 	jb	short sysexec_2
 18318 00003C88 8B35[286D0000]      <1> 	mov	esi, [nbase]
 18319 00003C8E 010D[286D0000]      <1> 	add	[nbase], ecx ; 4	
 18320                              <1> 	;sub	[ncount], cx 
 18321                              <1> 	; 11/12/2021
 18322 00003C94 290D[2C6D0000]      <1> 	sub	[ncount], ecx
 18323 00003C9A 8B06                <1> 	mov	eax, [esi]
 18324 00003C9C EBA8                <1> 	jmp	short sysexec_3
 18325                              <1> sysexec_6:
 18326                              <1> 	; 24/12/2021
 18327                              <1> 	; 18/10/2015
 18328                              <1> 	; argument list transfer from user's core memory to
 18329                              <1> 	; kernel stack frame is OK here.
 18330                              <1> 	; [u.nread] = argument list length
 18331                              <1> 	;mov	[argv], esp ; start address of argument list
 18332                              <1> 	;
 18333                              <1> 	; 18/10/2015
 18334                              <1> 	; 24/07/2015
 18335                              <1>         ; 21/07/2015
 18336                              <1> 	; 02/07/2015
 18337                              <1> 	; 25/06/2015
 18338                              <1> 	; 24/06/2015
 18339                              <1> 	; 23/06/2015
 18340                              <1> 	;
 18341 00003C9E 8B1D[086D0000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
 18342 00003CA4 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
 18343 00003CA6 740A                <1> 	jz	short sysexec_7
 18344 00003CA8 A1[046D0000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
 18345 00003CAD E85DE8FFFF          <1> 	call	deallocate_page_dir
 18346                              <1> sysexec_7:
 18347 00003CB2 E88DE7FFFF          <1> 	call	make_page_dir
 18348                              <1> 	;jc	short sysexec_14
 18349                              <1> 	;jc	panic  ; allocation error 
 18350                              <1> 	;	       ; after a deallocation would be nonsence !?
 18351                              <1> 	; 26/03/2021
 18352 00003CB7 7243                <1> 	jc	short sysexec_panic
 18353                              <1> 	
 18354                              <1> 	; 24/07/2015
 18355                              <1> 	; map kernel pages (1st 4MB) to PDE 0
 18356                              <1> 	;     of the user's page directory
 18357                              <1> 	;     (It is needed for interrupts!)
 18358                              <1> 	; 18/10/2015
 18359 00003CB9 8B15[68670000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
 18360 00003CBF 8B02                <1> 	mov	eax, [edx] ; physical address of
 18361                              <1> 			   ; kernel's first page table (1st 4 MB)
 18362                              <1> 			   ; (PDE 0 of kernel's page directory)
 18363 00003CC1 8B15[046D0000]      <1> 	mov 	edx, [u.pgdir]
 18364 00003CC7 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
 18365                              <1> 	;
 18366                              <1> 	; 20/07/2015
 18367 00003CC9 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
 18368                              <1> 	; 18/10/2015
 18369 00003CCE BE[206D0000]        <1> 	mov	esi, pcore ; physical start address
 18370                              <1> sysexec_8:	
 18371 00003CD3 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
 18372 00003CD8 E885E7FFFF          <1> 	call	make_page_table
 18373                              <1> 	;jc	panic
 18374                              <1> 	; 26/03/2021
 18375 00003CDD 721D                <1> 	jc	short sysexec_panic
 18376                              <1> 	;
 18377                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
 18378 00003CDF E88CE7FFFF          <1> 	call	make_page ; make new page, clear and set the pte
 18379                              <1> 	;jc	panic
 18380                              <1> 	; 26/03/2021
 18381 00003CE4 7216                <1> 	jc	short sysexec_panic
 18382                              <1> 	;
 18383 00003CE6 8906                <1> 	mov	[esi], eax ; 24/06/2015
 18384                              <1> 	; ebx = virtual address (24/07/2015)
 18385                              <1> 	; 30/11/2021
 18386                              <1> 	;call 	add_to_swap_queue
 18387                              <1> 	; 18/10/2015
 18388 00003CE8 81FE[246D0000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
 18389 00003CEE 7411                <1> 	je	short sysexec_9 ; yes
 18390 00003CF0 BE[246D0000]        <1> 	mov	esi, ecore  ; physical address of the last page
 18391                              <1> 	; 20/07/2015
 18392 00003CF5 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
 18393                              <1> 	; ebx = virtual end address + segment base address - 4K
 18394 00003CFA EBD7                <1>         jmp     short sysexec_8
 18395                              <1> sysexec_panic:
 18396                              <1> 	; 26/03/2021
 18397 00003CFC E9AAECFFFF          <1> 	jmp	panic
 18398                              <1> 
 18399                              <1> sysexec_9:
 18400                              <1> 	; 12/01/2022
 18401                              <1> 	; 11/12/2021
 18402                              <1> 	; 18/10/2015
 18403                              <1> 	; 26/08/2015
 18404                              <1> 	; 25/06/2015
 18405                              <1> 	; move arguments from kernel stack to [ecore]
 18406                              <1> 	; (argument list/line will be copied from kernel stack
 18407                              <1> 	; frame to the last (stack) page of user's core memory)
 18408                              <1> 	; 18/10/2015
 18409 00003D01 8B3D[246D0000]      <1> 	mov	edi, [ecore]
 18410 00003D07 81C700100000        <1> 	add	edi, PAGE_SIZE
 18411                              <1> 	;movzx	eax, word [argc]
 18412                              <1> 	; 12/01/2022
 18413                              <1> 	;xor	eax, eax
 18414                              <1> 	;mov	al, [argc]
 18415                              <1> 	; [argc] < 32
 18416                              <1> 	; 11/12/2021
 18417 00003D0D A1[306D0000]        <1> 	mov	eax, [argc]
 18418 00003D12 09C0                <1> 	or	eax, eax
 18419 00003D14 7509                <1> 	jnz	short sysexec_10
 18420 00003D16 89FB                <1> 	mov 	ebx, edi
 18421 00003D18 83EB04              <1> 	sub	ebx, 4 
 18422 00003D1B 8903                <1> 	mov	[ebx], eax ; 0
 18423 00003D1D EB43                <1> 	jmp 	short sysexec_13
 18424                              <1> sysexec_10:
 18425 00003D1F 8B0D[D06C0000]      <1> 	mov	ecx, [u.nread]
 18426                              <1> 	;mov 	esi, [argv]
 18427 00003D25 89E6                <1> 	mov	esi, esp ; start address of argument list
 18428 00003D27 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
 18429                              <1> 
 18430                              <1> 	;;;;
 18431                              <1> 	; 09/05/2022
 18432                              <1> 	; (move edi -backward- to dword boundary)
 18433                              <1> 	; ((this will prevent 'general protection fault' error
 18434                              <1> 	;  as result of a lodsd or dword move instruction
 18435                              <1> 	;  at the end of argument list))
 18436 00003D29 83EF03              <1> 	sub	edi, 3
 18437 00003D2C 83E7FC              <1> 	and	edi, ~3 ; (*)
 18438                              <1> 	;;;
 18439                              <1> 
 18440 00003D2F 89C2                <1> 	mov	edx, eax
 18441                              <1> 	; 03/02/2022 ; ([argc] < 32)
 18442 00003D31 FEC2                <1> 	inc	dl ; argument count + 1 for argc value
 18443 00003D33 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
 18444                              <1> 	; edx <= 128
 18445 00003D36 89FB                <1> 	mov	ebx, edi
 18446                              <1> 	; 09/05/2022 (*) - edi is already dword aligned -
 18447                              <1> 	;and	bl, 0FCh ; 32 bit (dword) alignment
 18448 00003D38 29D3                <1> 	sub 	ebx, edx
 18449 00003D3A 89FA                <1> 	mov	edx, edi
 18450 00003D3C F3A4                <1> 	rep	movsb
 18451 00003D3E 89D6                <1> 	mov 	esi, edx
 18452 00003D40 89DF                <1> 	mov 	edi, ebx
 18453 00003D42 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
 18454 00003D47 2B15[246D0000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
 18455 00003D4D AB                  <1> 	stosd	; eax = argument count
 18456                              <1> sysexec_11:
 18457 00003D4E 89F0                <1> 	mov	eax, esi
 18458 00003D50 01D0                <1> 	add	eax, edx
 18459 00003D52 AB                  <1> 	stosd  ; eax = virtual address
 18460 00003D53 FE0D[306D0000]      <1> 	dec	byte [argc]
 18461 00003D59 7407                <1> 	jz	short sysexec_13
 18462                              <1> sysexec_12:
 18463 00003D5B AC                  <1> 	lodsb
 18464 00003D5C 20C0                <1> 	and	al, al
 18465 00003D5E 75FB                <1> 	jnz	short sysexec_12
 18466 00003D60 EBEC                <1> 	jmp	short sysexec_11
 18467                              <1> 	;
 18468                              <1> 	; 1:
 18469                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
 18470                              <1> 			     ; / pointers to arguments to be passed
 18471                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
 18472                              <1> 			      ; / u.quit = 1 take quit
 18473                              <1> 		; mov $1,u.intr / u.intr determines handling of 
 18474                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
 18475                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
 18476                              <1> 			       ; / system routine
 18477                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector
 18478                              <1> 			       ; / set to take system routine
 18479                              <1> 		; mov $sstack,sp / stack space used during swapping
 18480                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
 18481                              <1> 		; mov $ecore,r5 / r5 has end of core
 18482                              <1> 		; mov $core,r4 / r4 has start of users core
 18483                              <1> 		; mov r4,u.base / u.base has start of users core
 18484                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
 18485                              <1> 	; 1:
 18486                              <1> 		; tst (r2)+ / argument char = "nul"
 18487                              <1> 		; bne 1b
 18488                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of
 18489                              <1> 			  ; / end of argument pointer list
 18490                              <1> 	; 1:
 18491                              <1> 	     ; / move arguments to bottom of users core
 18492                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 18493                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
 18494                              <1> 			    ; / ptr list
 18495                              <1> 		; blo 1f / branch to 1f when all arguments
 18496                              <1> 		       ; / are moved
 18497                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 18498                              <1> 	; 2:
 18499                              <1> 		; tstb (r3)+
 18500                              <1> 		; bne 2b / scan argument for \0 (nul)
 18501                              <1> 
 18502                              <1> 	; 2:
 18503                              <1> 		; movb -(r3),-(r5) / move argument char 
 18504                              <1> 				 ; / by char starting at "ecore"
 18505                              <1> 		; cmp r3,(r2) / moved all characters in 
 18506                              <1> 			    ; / this argument
 18507                              <1> 		; bhi 2b / branch 2b if not
 18508                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
 18509                              <1> 			     ; / r5 has pointer to nth arg
 18510                              <1> 		; br 1b / string
 18511                              <1> 	; 1:
 18512                              <1> 		; clrb -(r5)
 18513                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
 18514                              <1> 			; / last word of argument strings
 18515                              <1> 		; mov $core,r2
 18516                              <1> 	
 18517                              <1> 	; 1: / move argument pointers into core following 
 18518                              <1> 	      ; / argument strings
 18519                              <1> 		; cmp r2,r4
 18520                              <1> 		; bhis 1f / branch to 1f when all pointers
 18521                              <1> 			; / are moved
 18522                              <1> 		; mov (r2)+,-(r5)
 18523                              <1> 		; br 1b
 18524                              <1> 	; 1:
 18525                              <1> 		; sub $core,r4 / gives number of arguments *2
 18526                              <1> 		; asr r4 / divide r4 by 2 to calculate 
 18527                              <1> 		       ; / the number of args stored
 18528                              <1> 		; mov r4,-(r5) / save number of arguments ahead
 18529                              <1> 			     ; / of the argument pointers
 18530                              <1> sysexec_13:
 18531                              <1> 	; 30/11/2021
 18532                              <1> 	; 28/11/2021
 18533                              <1> 	; 19/10/2015
 18534                              <1> 	; 18/10/2015
 18535                              <1> 	; 29/07/2015
 18536                              <1> 	; 25/07/2015
 18537                              <1> 	; 24/07/2015
 18538                              <1> 	; 20/07/2015
 18539                              <1> 	; 25/06/2015
 18540                              <1> 	; 24/06/2015
 18541                              <1> 	; 23/06/2015
 18542                              <1> 	;
 18543                              <1> 	; moving arguments to [ecore] is OK here..
 18544                              <1> 	; 18/10/2015
 18545 00003D62 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
 18546                              <1> 	; ebx = beginning address of argument list pointers
 18547                              <1> 	;	in user's stack
 18548                              <1> 	; 19/10/2015
 18549 00003D64 2B1D[246D0000]      <1> 	sub 	ebx, [ecore]
 18550 00003D6A 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
 18551                              <1> 			; end of core - 4096 (last page)
 18552                              <1> 			; (virtual address)
 18553 00003D70 891D[346D0000]      <1> 	mov	[argv], ebx
 18554 00003D76 891D[D46C0000]      <1> 	mov	[u.break], ebx ; available user memory
 18555                              <1> 	;
 18556 00003D7C 29C0                <1> 	sub	eax, eax
 18557 00003D7E C705[CC6C0000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
 18558 00003D86 0000                <1>
 18559                              <1> 		; mov $14,u.count
 18560 00003D88 C705[B86C0000]-     <1> 	mov	dword [u.fofp], u.off
 18561 00003D8E [C46C0000]          <1>
 18562                              <1> 		; mov $u.off,u.fofp
 18563 00003D92 A3[C46C0000]        <1> 	mov	[u.off], eax ; 0
 18564                              <1> 		; clr u.off / set offset in file to be read to zero
 18565                              <1> 	; 25/07/2015
 18566 00003D97 A3[C86C0000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
 18567                              <1> 	; 25/06/2015 
 18568 00003D9C A1[7C6C0000]        <1> 	mov	eax, [ii] ; 28/11/2021 (32 bit inode number)
 18569                              <1> 	; AX = i-number of the executable file
 18570 00003DA1 E83B110000          <1> 	call	readi
 18571                              <1> 		; jsr r0,readi / read in first six words of 
 18572                              <1> 			; / user's file, starting at $core
 18573                              <1> 		; mov sp,r5 / put users stack address in r5
 18574                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
 18575                              <1> 				; / from r5 (leaves number of words
 18576                              <1> 				; / less 26 available for
 18577                              <1> 			     	; / program in user core
 18578                              <1> 		; mov r5,u.count /
 18579                              <1> 	; 25/06/2015
 18580 00003DA6 8B0D[D46C0000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
 18581 00003DAC 890D[CC6C0000]      <1> 	mov	[u.count], ecx ; save for overrun check
 18582                              <1> 	;
 18583 00003DB2 8B0D[D06C0000]      <1> 	mov	ecx, [u.nread]
 18584 00003DB8 890D[D46C0000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
 18585 00003DBE 80F920              <1> 	cmp	cl, 32
 18586 00003DC1 7540                <1>         jne     short sysexec_15
 18587                              <1> 	;:
 18588                              <1> 	; 25/06/2015
 18589                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
 18590                              <1> 	; 18/10/2015
 18591 00003DC3 8B35[206D0000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
 18592                              <1> 		             ; (phys. start addr. of the exec. file)
 18593 00003DC9 AD                  <1> 	lodsd
 18594 00003DCA 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBh, 1Eh -> jump to +32
 18595 00003DCE 7533                <1> 	jne	short sysexec_15
 18596                              <1> 		; cmp core,$405 / br .+14 is first instruction 
 18597                              <1> 			      ; / if file is standard a.out format
 18598                              <1> 		; bne 1f / branch, if not standard format
 18599 00003DD0 AD                  <1> 	lodsd
 18600 00003DD1 89C1                <1> 	mov	ecx, eax ; text (code) section size
 18601 00003DD3 AD                  <1> 	lodsd
 18602 00003DD4 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
 18603                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
 18604                              <1> 		              ; / number of bytes in program text
 18605                              <1> 		; sub $14,r5 / subtract 12
 18606 00003DD6 89CB                <1> 	mov	ebx, ecx
 18607                              <1> 	;
 18608                              <1> 	; 25/06/2015
 18609                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
 18610                              <1> 	;	and SINGLIX operating systems (as code template).
 18611                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
 18612                              <1> 	;	due to RUFS (floppy disk file system) restriction...
 18613                              <1> 	;	Overrun is not possible for current version.
 18614                              <1> 	;
 18615 00003DD8 AD                  <1> 	lodsd	
 18616 00003DD9 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
 18617 00003DDB 3B1D[CC6C0000]      <1> 	cmp	ebx, [u.count]
 18618 00003DE1 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
 18619                              <1> 	;
 18620                              <1> 	; 24/07/2015
 18621                              <1> 	; add bss section size to [u.break]
 18622 00003DE3 0105[D46C0000]      <1> 	add 	[u.break], eax
 18623                              <1> 	;
 18624 00003DE9 83E920              <1> 	sub	ecx, 32 ; header size (already loaded)
 18625                              <1> 	;cmp	ecx, [u.count]
 18626                              <1> 	;jnb	short sysexec_16
 18627                              <1> 		; cmp r5,u.count /
 18628                              <1> 		; bgt 1f / branch if r5 greater than u.count
 18629 00003DEC 890D[CC6C0000]      <1> 	mov	[u.count], ecx ; required read count
 18630                              <1> 		; mov r5,u.count
 18631                              <1> 	;
 18632 00003DF2 EB29                <1> 	jmp	short sysexec_16
 18633                              <1> 	;
 18634                              <1> sysexec_14:
 18635                              <1> 	; 23/06/2015
 18636                              <1> 	; insufficient (out of) memory
 18637 00003DF4 C705[186D0000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
 18638 00003DFC 0000                <1>
 18639 00003DFE E962F3FFFF          <1> 	jmp	error
 18640                              <1> 	;
 18641                              <1> sysexec_15:
 18642                              <1> 	; 25/06/2015
 18643                              <1>         ;movzx   edx, word [i.size] ; file size
 18644                              <1> 	; 30/11/2021
 18645 00003E03 8B15[2C680000]      <1> 	mov	edx, [i.size] ; file size
 18646 00003E09 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
 18647 00003E0B 7626                <1> 	jna	short sysexec_17 ; no need to next read
 18648 00003E0D 01D1                <1> 	add	ecx, edx ; [i.size]
 18649 00003E0F 3B0D[CC6C0000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
 18650 00003E15 77DD                <1> 	ja	short sysexec_14
 18651 00003E17 8915[CC6C0000]      <1> 	mov	[u.count], edx
 18652                              <1> sysexec_16:
 18653                              <1> 	;mov	ax, [ii] ; i-number
 18654                              <1> 	; 28/11/2021
 18655 00003E1D A1[7C6C0000]        <1> 	mov	eax, [ii] ; 32 bit inode number
 18656 00003E22 E8BA100000          <1> 	call	readi
 18657                              <1> 		; add core+10,u.nread / add size of user data area
 18658                              <1> 		                    ; / to u.nread
 18659                              <1> 		; br 2f
 18660                              <1> 	; 1:
 18661                              <1> 		; jsr r0,readi / read in rest of file
 18662                              <1> 	; 2:
 18663 00003E27 8B0D[D06C0000]      <1> 	mov	ecx, [u.nread]
 18664 00003E2D 010D[D46C0000]      <1> 	add	[u.break], ecx
 18665                              <1> 		; mov u.nread,u.break / set users program break to end of
 18666                              <1> 				    ; / user code
 18667                              <1> 		; add $core+14,u.break / plus data area
 18668                              <1> 	; 20/07/2015
 18669                              <1> sysexec_17:
 18670                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 18671                              <1> 	; ('iclose' is not needed for regular files, from now on)
 18672                              <1> 	;;mov	ax, [ii] ; i-number
 18673                              <1> 	;call	iclose
 18674                              <1> 	;	; jsr r0,iclose / does nothing
 18675 00003E33 31C0                <1>         xor     eax, eax
 18676 00003E35 FEC0                <1> 	inc	al
 18677 00003E37 66A3[F06C0000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
 18678 00003E3D 66A3[F26C0000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
 18679                              <1> 	; 30/11/2021
 18680 00003E43 FEC8                <1> 	dec	al  ; eax = 0
 18681                              <1> 	; 02/07/2015
 18682                              <1>         ;cmp	dword [u.ppgdir], 0 ; is the caller sys_init (kernel) ?
 18683 00003E45 3905[086D0000]      <1> 	cmp	[u.ppgdir], eax ; 0 ; is the caller sys_init (kernel) ?
 18684 00003E4B 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
 18685                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
 18686 00003E4D 8B15[68670000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
 18687 00003E53 8915[086D0000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here
 18688                              <1> sysexec_18:
 18689                              <1> 	; 18/10/2015
 18690                              <1> 	; 05/08/2015
 18691                              <1> 	; 29/07/2015
 18692 00003E59 8B2D[346D0000]      <1> 	mov	ebp, [argv] ; user's stack pointer must points to argument
 18693                              <1> 			    ; list pointers (argument count)
 18694 00003E5F FA                  <1> 	cli
 18695 00003E60 8B25[04670000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
 18696                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
 18697                              <1> 			    ; for this process	 
 18698                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
 18699                              <1> 	;;xor	eax, eax ; 0
 18700                              <1> 	;dec	al ; eax = 0
 18701                              <1> 	; eax = 0 ; 30/11/2021 
 18702 00003E66 66BA2300            <1> 	mov	dx, UDATA
 18703 00003E6A 6652                <1> 	push	dx  ; user's stack segment
 18704 00003E6C 55                  <1> 	push	ebp ; user's stack pointer
 18705                              <1> 		    ; (points to number of arguments)
 18706 00003E6D FB                  <1> 	sti
 18707 00003E6E 9C                  <1> 	pushfd	; EFLAGS
 18708                              <1> 		; Set IF for enabling interrupts in user mode
 18709                              <1> 	;or	dword [esp], 200h 
 18710                              <1> 	;
 18711                              <1> 	;mov	bx, UCODE
 18712                              <1> 	;push	bx ; user's code segment
 18713 00003E6F 6A1B                <1> 	push	UCODE
 18714                              <1> 	;push	0
 18715 00003E71 50                  <1> 	push	eax ; EIP (=0) - start address -
 18716                              <1> 		; clr -(r5) / popped into ps when rti in 
 18717                              <1> 			  ; / sysrele is executed
 18718                              <1> 		; mov $core,-(r5) / popped into pc when rti 
 18719                              <1> 		                ; / in sysrele is executed
 18720                              <1> 		;mov r5,0f / load second copyz argument
 18721                              <1> 		;tst -(r5) / decrement r5
 18722 00003E72 8925[9C6C0000]      <1> 	mov	[u.sp], esp ; 29/07/2015
 18723                              <1> 	; 05/08/2015
 18724                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
 18725                              <1> 	; ('push dx' would cause to general protection fault, 
 18726                              <1> 	; after 'pop ds' etc.)
 18727                              <1> 	;
 18728                              <1> 	;; push dx ; ds (UDATA)
 18729                              <1> 	;; push dx ; es (UDATA)
 18730                              <1> 	;; push dx ; fs (UDATA)
 18731                              <1> 	;; push dx ; gs (UDATA)
 18732                              <1> 	;
 18733                              <1> 	; This is a trick to prevent general protection fault
 18734                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
 18735 00003E78 8EC2                <1> 	mov 	es, dx ; UDATA
 18736 00003E7A 06                  <1> 	push 	es ; ds (UDATA)
 18737 00003E7B 06                  <1> 	push 	es ; es (UDATA)
 18738 00003E7C 06                  <1> 	push 	es ; fs (UDATA)
 18739 00003E7D 06                  <1> 	push	es ; gs (UDATA)
 18740 00003E7E 66BA1000            <1> 	mov	dx, KDATA
 18741 00003E82 8EC2                <1> 	mov	es, dx
 18742                              <1> 	;
 18743                              <1> 	;; pushad simulation
 18744 00003E84 89E5                <1> 	mov	ebp, esp ; esp before pushad
 18745 00003E86 50                  <1> 	push	eax ; eax (0)
 18746 00003E87 50                  <1> 	push	eax ; ecx (0)
 18747 00003E88 50                  <1> 	push	eax ; edx (0)
 18748 00003E89 50                  <1> 	push	eax ; ebx (0)
 18749 00003E8A 55                  <1> 	push	ebp ; esp before pushad
 18750 00003E8B 50                  <1> 	push	eax ; ebp (0)
 18751 00003E8C 50                  <1> 	push	eax ; esi (0)		
 18752 00003E8D 50                  <1> 	push	eax ; edi (0)	
 18753                              <1> 	;
 18754 00003E8E A3[A46C0000]        <1> 	mov	[u.r0], eax ; eax = 0
 18755 00003E93 8925[A06C0000]      <1> 	mov	[u.usp], esp
 18756                              <1> 		; mov r5,u.r0 /
 18757                              <1> 		; sub $16.,r5 / skip 8 words
 18758                              <1> 		; mov r5,u.sp / assign user stack pointer value,
 18759                              <1> 		;             / effectively zeroes all regs
 18760                              <1> 			    ; / when sysrele is executed
 18761                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
 18762                              <1> 		; clr u.break
 18763                              <1> 		; mov r5,sp / point sp to user's stack
 18764                              <1> 	;
 18765 00003E99 E9E9F2FFFF          <1> 	jmp	sysret0
 18766                              <1> 	;jmp	sysret
 18767                              <1> 		; br sysret3 / return to core image at $core
 18768                              <1> 
 18769                              <1> get_argp:
 18770                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 18771                              <1> 	; 18/10/2015 (nbase, ncount)
 18772                              <1> 	; 21/07/2015
 18773                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
 18774                              <1> 	; Get (virtual) address of argument from user's core memory
 18775                              <1> 	;
 18776                              <1> 	; INPUT:
 18777                              <1> 	;	esi = virtual address of argument pointer
 18778                              <1> 	; OUTPUT:
 18779                              <1> 	;	eax = virtual address of argument
 18780                              <1> 	;
 18781                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
 18782                              <1> 	;
 18783 00003E9E 833D[086D0000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
 18784                              <1> 				    ; (the caller is kernel)
 18785 00003EA5 767C                <1>         jna     short get_argpk 
 18786                              <1> 	;
 18787 00003EA7 89F3                <1>      	mov	ebx, esi
 18788 00003EA9 E819E9FFFF          <1> 	call	get_physical_addr ; get physical address
 18789 00003EAE 7254                <1>         jc	short get_argp_err ; 11/12/2021
 18790 00003EB0 A3[286D0000]        <1> 	mov 	[nbase], eax ; physical address	
 18791                              <1> 	;mov	[ncount], cx ; remain byte count in page (1-4096)
 18792                              <1> 	; 11/12/2021
 18793 00003EB5 890D[2C6D0000]      <1> 	mov	[ncount], ecx
 18794 00003EBB B804000000          <1> 	mov	eax, 4 ; 21/07/2015
 18795                              <1> 	;cmp	cx, ax ; 4
 18796                              <1> 	; 11/12/2021
 18797 00003EC0 39C1                <1> 	cmp	ecx, eax ; 4
 18798 00003EC2 734A                <1> 	jnb	short get_argp2
 18799 00003EC4 89F3                <1> 	mov	ebx, esi
 18800 00003EC6 01CB                <1> 	add	ebx, ecx
 18801 00003EC8 E8FAE8FFFF          <1> 	call	get_physical_addr ; get physical address
 18802 00003ECD 7235                <1> 	jc	short get_argp_err
 18803                              <1> 	;push	esi
 18804 00003ECF 89C6                <1> 	mov	esi, eax
 18805                              <1> 	;xchg	cx, [ncount]
 18806                              <1> 	; 11/12/2021
 18807 00003ED1 870D[2C6D0000]      <1> 	xchg	ecx, [ncount]
 18808 00003ED7 8735[286D0000]      <1> 	xchg	esi, [nbase]
 18809 00003EDD B504                <1> 	mov	ch, 4
 18810 00003EDF 28CD                <1> 	sub	ch, cl
 18811                              <1> get_argp0:
 18812 00003EE1 AC                  <1> 	lodsb
 18813                              <1> 	;push	ax
 18814                              <1> 	; 11/12/2021
 18815 00003EE2 50                  <1> 	push	eax
 18816 00003EE3 FEC9                <1> 	dec	cl
 18817 00003EE5 75FA                <1>         jnz     short get_argp0
 18818 00003EE7 8B35[286D0000]      <1> 	mov	esi, [nbase]
 18819                              <1> 	; 21/07/2015
 18820 00003EED 0FB6C5              <1> 	movzx	eax, ch
 18821 00003EF0 0105[286D0000]      <1> 	add	[nbase], eax
 18822                              <1> 	;sub	[ncount], ax
 18823                              <1> 	; 11/12/2021
 18824 00003EF6 2905[2C6D0000]      <1> 	sub	[ncount], eax
 18825                              <1> get_argp1:
 18826 00003EFC AC                  <1> 	lodsb
 18827 00003EFD FECD                <1> 	dec	ch
 18828 00003EFF 743B                <1>         jz      short get_argp3
 18829                              <1>         ;push	ax
 18830                              <1> 	; 11/12/2021
 18831 00003F01 50                  <1> 	push	eax
 18832 00003F02 EBF8                <1> 	jmp     short get_argp1
 18833                              <1> get_argp_err:
 18834 00003F04 A3[186D0000]        <1> 	mov	[u.error], eax
 18835 00003F09 E957F2FFFF          <1> 	jmp	error
 18836                              <1> get_argp2:
 18837                              <1> 	; 21/07/2015
 18838                              <1> 	;mov	eax, 4
 18839 00003F0E 8B15[286D0000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
 18840 00003F14 0105[286D0000]      <1> 	add	[nbase], eax
 18841                              <1> 	;sub	[ncount], ax
 18842                              <1> 	; 11/12/2021
 18843 00003F1A 2905[2C6D0000]      <1> 	sub	[ncount], eax
 18844                              <1> 	;
 18845 00003F20 8B02                <1> 	mov	eax, [edx]
 18846 00003F22 C3                  <1> 	retn
 18847                              <1> get_argpk:
 18848                              <1> 	; Argument is in kernel's memory space
 18849 00003F23 66C705[2C6D0000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
 18850 00003F2B 10                  <1>
 18851 00003F2C 8935[286D0000]      <1> 	mov	[nbase], esi
 18852 00003F32 8305[286D0000]04    <1> 	add	dword [nbase], 4
 18853 00003F39 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physical addr.
 18854 00003F3B C3                  <1> 	retn
 18855                              <1> get_argp3:
 18856 00003F3C B103                <1> 	mov	cl, 3
 18857                              <1> get_argp4:
 18858 00003F3E C1E008              <1> 	shl	eax, 8
 18859                              <1> 	;pop	dx
 18860                              <1> 	; 11/12/2021
 18861 00003F41 5A                  <1> 	pop	edx
 18862 00003F42 88D0                <1> 	mov 	al, dl
 18863 00003F44 E2F8                <1>         loop    get_argp4
 18864                              <1> 	;pop	esi
 18865 00003F46 C3                  <1> 	retn	
 18866                              <1> 
 18867                              <1> sysfstat:
 18868                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 18869                              <1> 	;	([idev] return in eax)
 18870                              <1> 	;	0 = root device
 18871                              <1> 	;	1 = mounted device (>0)
 18872                              <1> 	; 06/02/2022 
 18873                              <1> 	; 08/01/2022
 18874                              <1> 	; 26/12/2021 (Retro UNIX 386 v1.2) 
 18875                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18876                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18877                              <1> 	;
 18878                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
 18879                              <1> 	; on open files instead of files given by name. It puts the
 18880                              <1> 	; buffer address on the stack, gets the i-number and
 18881                              <1> 	; checks to see if the file is open for reading or writing.
 18882                              <1> 	; If the file is open for writing (i-number is negative)
 18883                              <1> 	; the i-number is set positive and a branch into 'sysstat'
 18884                              <1> 	; is made.	
 18885                              <1> 	;
 18886                              <1> 	; Calling sequence:
 18887                              <1> 	;	sysfstat; buf
 18888                              <1> 	; Arguments:
 18889                              <1> 	;	buf - buffer address
 18890                              <1> 	;
 18891                              <1> 	; Inputs: *u.r0 - file descriptor
 18892                              <1> 	; Outputs: buffer is loaded with file information
 18893                              <1> 	; ...............................................................
 18894                              <1> 	;				
 18895                              <1> 	; Retro UNIX 8086 v1 modification:
 18896                              <1> 	;       'sysfstat' system call has two arguments; so,
 18897                              <1> 	;	* 1st argument, file descriptor is in BX register
 18898                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 18899                              <1> 
 18900                              <1> 	; / set status of open file
 18901                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
 18902 00003F47 51                  <1> 	push	ecx ; *
 18903                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
 18904                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
 18905                              <1> 		; jsr r0,getf / get the files i-number
 18906                              <1> 	; BX = file descriptor (file number)
 18907 00003F48 E8F9000000          <1> 	call	getf1
 18908                              <1> 	; 06/02/2022
 18909 00003F4D 21C0                <1> 	and	eax, eax
 18910                              <1> 	;and	ax, ax ; i-number of the file
 18911                              <1> 		; tst	r1 / is it 0?
 18912                              <1> 	;jz	error
 18913                              <1> 		; beq error3 / yes, error
 18914                              <1> 	;jnz	short sysfstat1
 18915                              <1> 	; 26/12/2021 - Retro UNIX 386 v1.2 (runix v2 file system)
 18916 00003F4F 752C                <1> 	jnz	short sysstat1
 18917 00003F51 C705[186D0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 18918 00003F59 0000                <1>
 18919 00003F5B E905F2FFFF          <1> 	jmp	error
 18920                              <1> 	; 26/12/2021
 18921                              <1> ;sysfstat1:
 18922                              <1> 	;cmp	ah, 80h
 18923                              <1>         ;jb      short sysstat1
 18924                              <1> 	;	; bgt 1f / if i-number is negative (open for writing)
 18925                              <1> 	;neg	ax
 18926                              <1> 	;	; neg r1 / make it positive, then branch
 18927                              <1> 	; 08/01/2022
 18928                              <1> 	;jmp	short sysstat1
 18929                              <1> 		; br 1f / to 1f
 18930                              <1> sysstat:
 18931                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.1, Kernel v0.2.1.3)
 18932                              <1> 	;	([idev] return in eax)
 18933                              <1> 	;	0 = root device
 18934                              <1> 	;	1 = mounted device (>0)
 18935                              <1> 	; 26/12/2021 (Retro UNIX 386 v1.2) 
 18936                              <1> 	; 18/10/2015
 18937                              <1> 	; 07/10/2015
 18938                              <1> 	; 02/09/2015
 18939                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18940                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18941                              <1> 	;
 18942                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
 18943                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
 18944                              <1> 	; long and information about the file placed in it.	
 18945                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
 18946                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
 18947                              <1> 	; is then loaded and the results are given in the UNIX
 18948                              <1> 	; Programmers Manual sysstat (II).	
 18949                              <1> 	;
 18950                              <1> 	; Calling sequence:
 18951                              <1> 	;	sysstat; name; buf
 18952                              <1> 	; Arguments:
 18953                              <1> 	;	name - points to the name of the file
 18954                              <1> 	;	buf - address of a 34 bytes buffer
 18955                              <1> 	; Inputs: -
 18956                              <1> 	; Outputs: buffer is loaded with file information
 18957                              <1> 	; ...............................................................
 18958                              <1> 	;				
 18959                              <1> 	; Retro UNIX 8086 v1 modification: 
 18960                              <1> 	;       'sysstat' system call has two arguments; so,
 18961                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 18962                              <1> 	;	to get sysstat system call arguments from the user;
 18963                              <1> 	;	* 1st argument, name is pointed to by BX register
 18964                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 18965                              <1> 	;
 18966                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 18967                              <1> 	;	      arguments which were in these registers;
 18968                              <1> 	;	      but, it returns by putting the 1st argument
 18969                              <1> 	;	      in 'u.namep' and the 2nd argument
 18970                              <1> 	;	      on top of stack. (1st argument is offset of the
 18971                              <1> 	;	      file/path name in the user's program segment.)		 	
 18972                              <1> 	
 18973                              <1> 	; / ; name of file; buffer - get files status
 18974                              <1> 		; jsr r0,arg2 / get the 2 arguments
 18975 00003F60 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 18976 00003F66 51                  <1> 	push	ecx ; *
 18977 00003F67 E810010000          <1> 	call	namei
 18978                              <1> 		; jsr r0,namei / get the i-number for the file
 18979                              <1> 	;jc	error
 18980                              <1> 		; br error3 / no such file, error
 18981 00003F6C 730F                <1> 	jnc	short sysstat1
 18982                              <1> 	; pop 	ecx
 18983                              <1> sysstat_err0:
 18984                              <1> 	; 'file not found !' error
 18985 00003F6E C705[186D0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 18986 00003F76 0000                <1>
 18987 00003F78 E9E8F1FFFF          <1> 	jmp	error
 18988                              <1> 
 18989                              <1> sysstat1: ; 1:
 18990 00003F7D E8F30B0000          <1> 	call	iget
 18991                              <1> 		; jsr r0,iget / get the i-node into core
 18992                              <1> 	; 07/10/2015 (ax = [ii], inode number)
 18993                              <1> 	; 02/09/2015
 18994 00003F82 8F05[C86C0000]      <1> 	pop	dword [u.base] ; *
 18995                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
 18996 00003F88 E861000000          <1> 	call	sysstat_gpa ; get physical address
 18997 00003F8D 730A                <1> 	jnc 	short sysstat2
 18998                              <1> sysstat_err1:
 18999 00003F8F A3[186D0000]        <1> 	mov	dword [u.error], eax ; error code
 19000 00003F94 E9CCF1FFFF          <1> 	jmp	error
 19001                              <1> sysstat2:
 19002 00003F99 A0[7C6C0000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
 19003 00003F9E AA                  <1> 	stosb
 19004 00003F9F FF05[C86C0000]      <1> 	inc 	dword [u.base]
 19005                              <1> 	;dec 	cx
 19006 00003FA5 49                  <1> 	dec	ecx ; 26/12/2021
 19007 00003FA6 7505                <1> 	jnz	short sysstat3
 19008 00003FA8 E841000000          <1> 	call	sysstat_gpa
 19009                              <1> 	;jc	short sysstat_err1
 19010                              <1> sysstat3:
 19011 00003FAD A0[7D6C0000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
 19012 00003FB2 AA                  <1> 	stosb
 19013                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
 19014 00003FB3 FF05[C86C0000]      <1> 	inc 	dword [u.base]
 19015                              <1> 	;;dec 	word [u.pcount]
 19016                              <1> 	;dec	cx
 19017 00003FB9 49                  <1> 	dec	ecx ; 26/12/2021
 19018 00003FBA 7505                <1> 	jnz	short sysstat4
 19019 00003FBC E82D000000          <1> 	call	sysstat_gpa
 19020                              <1> 	;jc	short sysstat_err1	
 19021                              <1> sysstat4:
 19022 00003FC1 BE[24680000]        <1> 	mov	esi, inode
 19023                              <1> 		; mov $inode,r2 / r2 points to i-node
 19024                              <1> sysstat5: ; 1:
 19025 00003FC6 A4                  <1> 	movsb
 19026                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
 19027 00003FC7 FF05[C86C0000]      <1> 	inc 	dword [u.base]
 19028                              <1> 	;;dec 	word [u.pcount]
 19029                              <1> 	;dec	cx
 19030 00003FCD 49                  <1> 	dec	ecx ; 26/12/2021
 19031 00003FCE 7505                <1> 	jnz	short sysstat6
 19032 00003FD0 E819000000          <1> 	call	sysstat_gpa
 19033                              <1> 	;jc	short sysstat_err1
 19034                              <1> sysstat6:
 19035                              <1> 	; 26/12/2021 - Retro UNIX 386 v1.2
 19036 00003FD5 81FE[64680000]      <1> 	cmp	esi, inode + 64 ; Retro UNIX v2 inode		
 19037                              <1> 	;cmp	esi, inode + 32
 19038                              <1> 		; cmp r2,$inode+32 / done?
 19039 00003FDB 75E9                <1> 	jne	short sysstat5
 19040                              <1> 		; bne 1b / no, go back
 19041                              <1> 
 19042                              <1> 	;;;
 19043                              <1> 	; 09/05/2022
 19044                              <1> 	;*** additional feature *** -retro unix only- 
 19045                              <1> 	;
 19046                              <1> 	; !! return device number -of current inode- in eax !!
 19047                              <1> 	;
 19048                              <1> 	; (modification reason/purpose:
 19049                              <1> 	; to improve 'pwd' command's pathname output/result
 19050                              <1> 	; and to correct 'cp' command's 'can not copy file itself'
 19051                              <1> 	; error due to same inode numbers in root file system
 19052                              <1> 	; and mounted file system.)
 19053                              <1> 	;
 19054 00003FDD 29C0                <1> 	sub	eax, eax
 19055 00003FDF A0[806C0000]        <1> 	mov	al, [idev] ; [cdev]
 19056 00003FE4 A3[A46C0000]        <1> 	mov	[u.r0], eax
 19057                              <1> 	;;;  
 19058                              <1> 
 19059 00003FE9 E997F1FFFF          <1> 	jmp	sysret
 19060                              <1> 		; br sysret3 / return through sysret
 19061                              <1> 	;
 19062                              <1> sysstat_gpa: ; get physical address of file status buffer
 19063                              <1> 	; 02/09/2015
 19064 00003FEE 8B1D[C86C0000]      <1> 	mov 	ebx, [u.base]
 19065                              <1> 	; 07/10/2015
 19066 00003FF4 E8CEE7FFFF          <1> 	call	get_physical_addr ; get physical address
 19067                              <1> 	;jc	short sysstat_gpa1
 19068 00003FF9 7294                <1> 	jc	short sysstat_err1
 19069                              <1> 	; 18/10/2015
 19070 00003FFB 89C7                <1> 	mov	edi, eax ; physical address
 19071                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
 19072                              <1> ;sysstat_gpa1:
 19073 00003FFD C3                  <1> 	retn
 19074                              <1> 
 19075                              <1> fclose:
 19076                              <1> 	; 12/03/2022
 19077                              <1> 	; 11/02/2022
 19078                              <1> 	; 08/01/2022
 19079                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 19080                              <1> 	; 08/04/2021
 19081                              <1> 	; 04/04/2021
 19082                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
 19083                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
 19084                              <1> 	;            (32 bit offset pointer modification)
 19085                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
 19086                              <1> 	;
 19087                              <1> 	; Given the file descriptor (index to the u.fp list)
 19088                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
 19089                              <1> 	; If i-node is active (i-number > 0) the entry in 
 19090                              <1> 	; u.fp list is cleared. If all the processes that opened
 19091                              <1> 	; that file close it, then fsp etry is freed and the file
 19092                              <1> 	; is closed. If not a return is taken. 
 19093                              <1> 	; If the file has been deleted while open, 'anyi' is called
 19094                              <1> 	; to see anyone else has it open, i.e., see if it is appears
 19095                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
 19096                              <1> 	; a check is made to see if the file is special.	
 19097                              <1> 	;
 19098                              <1> 	; INPUTS ->
 19099                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
 19100                              <1> 	;    u.fp - list of entries in the fsp table
 19101                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
 19102                              <1> 	; OUTPUTS ->
 19103                              <1> 	;    r1 - contains the same file descriptor
 19104                              <1> 	;    r2 - contains i-number
 19105                              <1> 	;
 19106                              <1> 	; ((AX = R1))
 19107                              <1> 	; ((Modified registers: edx, ebx, ecx, esi, edi, ebp))
 19108                              <1> 	;
 19109                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
 19110                              <1> 	;              if i-number of the file is 0. (error)
 19111                              <1> 
 19112                              <1> 	; 08/04/2021
 19113                              <1> 	; INPUT:
 19114                              <1> 	;	eax = file descriptor
 19115                              <1> 	; OUTPUT:
 19116                              <1> 	;	cf = 0 -> eax = file descriptor
 19117                              <1> 	;	cf = 1 -> file not open ; 11/02/2022
 19118                              <1> 
 19119                              <1> 	; 18/08/2020
 19120                              <1> 	;movzx	edx, ax ; **
 19121 00003FFE 89C3                <1> 	mov	ebx, eax
 19122                              <1> 
 19123                              <1> 	; 18/08/2020
 19124                              <1> _fclose:
 19125 00004000 53                  <1> 	push	ebx ; ***  ; file descriptor (index to u.fp)
 19126                              <1> 
 19127                              <1> 	;push	ax ; ***
 19128                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
 19129                              <1> 			     ; / the index to u.fp list)
 19130                              <1> 	; ebx = file descriptor/number
 19131 00004001 E840000000          <1> 	call	getf
 19132                              <1> 		; jsr r0,getf / r1 contains i-number, 
 19133                              <1> 			    ; / cdev has device =, u.fofp 
 19134                              <1> 			    ; / points to 3rd word of fsp entry
 19135                              <1> 	;cmp	eax, 1 ; 18/08/2020
 19136 00004006 6683F801            <1> 	cmp	ax, 1 ; r1
 19137                              <1> 		; tst r1 / is i-number 0?
 19138 0000400A 7238                <1> 	jb	short fclose_2
 19139                              <1> 		; beq 1f / yes, i-node not active so return
 19140                              <1> 		; tst (r0)+ / no, jump over error return
 19141                              <1> 	
 19142                              <1> 	;mov	ebx, edx ; **
 19143                              <1>  	; 18/08/2020
 19144 0000400C 8B1C24              <1> 	mov	ebx, [esp]
 19145                              <1> 	;mov	edx, eax 
 19146                              <1> 	;;mov 	dx, ax ; *
 19147                              <1> 		; mov r1,r2 / move i-number to r2 ;*
 19148                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
 19149                              <1> 			    ; / which is index to u.fp ; **
 19150 0000400F C683[AE6C0000]00    <1> 	mov	byte [ebx+u.fp], 0
 19151                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
 19152 00004016 8B1D[B86C0000]      <1> 	mov	ebx, [u.fofp]
 19153                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
 19154                              <1> 
 19155                              <1> 	; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
 19156                              <1> 	; ebx = 5th word of fsp entry (64 bit file offset)
 19157                              <1> fclose_0:
 19158                              <1> 	; 08/01/2022
 19159 0000401C FE4BFE              <1> 	dec	byte [ebx-2] ; 18/08/2020 - Retro UNIX 386 v2
 19160                              <1> 	;dec	byte [ebx+4] ; 18/06/2015
 19161                              <1> 		; decb 2(r1) / decrement the number of processes 
 19162                              <1> 			   ; / that have opened the file
 19163 0000401F 7923                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
 19164                              <1> 		; bge 1f / if all processes haven't closed the file, return
 19165                              <1> 	;
 19166                              <1> 	;push	dx ; *
 19167                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
 19168                              <1> 	;;xor	ax, ax ; 0
 19169                              <1> 	;xor	eax, eax ; 18/08/2020
 19170                              <1> 		; clear 1st word of fsp entry
 19171                              <1> 	;mov	[ebx-8], ax ; 0 ; 18/08/2020
 19172                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
 19173 00004021 66C743F80000        <1> 	mov	word [ebx-8], 0 ; clear 1st word of fsp entry ; i-number
 19174                              <1> 			; Note: 32 bit i-node number field is ready but
 19175                              <1> 			;	it is not used in current runix version.	
 19176                              <1> 
 19177                              <1> 	;;mov	[ebx-4], ax ; 0
 19178                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
 19179                              <1> 	;mov	al, [ebx+5] ; 18/06/2015
 19180                              <1> 	;	; tstb	3(r1) / has this file been deleted
 19181                              <1> 	;and	al, al
 19182                              <1> 	;jz	short fclose_1
 19183                              <1> 	;	; beq 2f / no, branch
 19184                              <1> 
 19185                              <1> 	;push	edx ; * ; 18/08/2020
 19186                              <1> 	;mov	eax, edx ; * ; 18/08/2020
 19187                              <1> 
 19188                              <1> 	;; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
 19189                              <1> 	;;test	byte [ebx-3], 80h ; open mode & status flags
 19190                              <1> 	; 04/04/2021 - Retro UNIX 386 v2 (new fsp structure)
 19191                              <1> 	;test	byte [ebx-4], 80h ; open mode & status flags 
 19192                              <1> 	;jz	short fclose_1	; deleted file flag (bit 7)
 19193                              <1> 
 19194                              <1> 	; 04/04/2021
 19195 00004027 31D2                <1> 	xor	edx, edx
 19196                              <1> 	; 08/01/2022
 19197 00004029 8A53FD              <1> 	mov	dl, [ebx-3] ; open mode & status flags
 19198 0000402C F6C280              <1> 	test	dl, 80h	    ; deleted file flag (bit 7)
 19199 0000402F 7409                <1> 	jz	short fclose_1 ; (not deleted -while open-)
 19200 00004031 52                  <1> 	push	edx
 19201                              <1> 	; 12/03/2022
 19202 00004032 50                  <1> 	push	eax ; inode number 
 19203                              <1> 
 19204                              <1> 	; deleted file !
 19205                              <1> 
 19206                              <1> 	;mov	ax, dx ; *
 19207                              <1> 		; mov r2,r1 / yes, put i-number back into r1
 19208                              <1> 	; AX = inode number
 19209 00004033 E84E050000          <1> 	call	anyi
 19210                              <1> 		; jsr r0,anyi / free all blocks related to i-number
 19211                              <1> 			    ; / check if file appears in fsp again
 19212                              <1> 	; 12/03/2022
 19213 00004038 58                  <1> 	pop	eax ; inode number
 19214                              <1> 	; 04/04/2021
 19215 00004039 5A                  <1> 	pop	edx
 19216                              <1> 	; 11/02/2022
 19217                              <1> 	;(cpu will come here if anyi returns -without error-)
 19218                              <1> 	;; 08/04/2021
 19219                              <1> 	;jc	short fclose_3 ; error code in eax	
 19220                              <1> 	;; 18/08/2020
 19221                              <1> 	;;jmp	short fclose_2
 19222                              <1> 
 19223                              <1> 	; ax = inode number
 19224                              <1> fclose_1: ; 2:
 19225                              <1> 	; 04/04/2021
 19226 0000403A 80E201              <1> 	and	dl, 1
 19227 0000403D FEC2                <1> 	inc	dl ; 0 -> 1 (open for read), 1 -> 2 (open for write)
 19228                              <1> 	
 19229                              <1> 	;pop	eax ; * ; 18/08/2020 
 19230                              <1> 	;;pop	ax ; *
 19231                              <1> 		; mov (sp)+,r1 / put i-number back into r1
 19232 0000403F E814170000          <1> 	call	iclose ; close if it is special file 
 19233                              <1> 		; jsr r0,iclose / check to see if it is a special file
 19234                              <1> 	; 11/02/2022
 19235                              <1> 	;(cpu will come here if iclose returns -without error-)
 19236                              <1> 	;; 08/04/2021
 19237                              <1> 	;jnc	short fclose_2
 19238                              <1> ;fclose_3:
 19239                              <1> ;	pop	ebx ; ***  ; file descriptor
 19240                              <1> ;	; eax = error code
 19241                              <1> ;	retn
 19242                              <1> fclose_2: ; 1:
 19243 00004044 58                  <1> 	pop	eax ; *** ; 18/08/2020
 19244                              <1> 	;pop	ax ; ***
 19245                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
 19246 00004045 C3                  <1> 	retn
 19247                              <1> 		; rts r0
 19248                              <1> 
 19249                              <1> 	; 08/01/2022
 19250                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 19251                              <1> getf:	; / get the device number and the i-number of an open file
 19252                              <1> 	; 13/05/2015
 19253                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 19254                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 19255                              <1> 
 19256                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 19257                              <1> 	;
 19258                              <1> 	; 16/05/2021
 19259                              <1> 	; 27/03/2020 - Retro UNIX 386 v2 
 19260                              <1> 	;	(new open files -fsp- structure)
 19261                              <1> 	; 13/05/2015
 19262                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 19263                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 19264                              <1> 	
 19265                              <1> 	; INPUT: 
 19266                              <1> 	;    ;eax = file descriptor/number
 19267                              <1> 	;     ebx = file descriptor/number ; 18/08/2020 	
 19268                              <1> 	; OUTPUT:
 19269                              <1> 	;     bl = open mode & status flag ; 27/03/2020
 19270                              <1> 	;        (bit 0 open mode flag, 0 = read, 1 = write)  
 19271                              <1> 	;    eax = inode number (in AX)
 19272                              <1> 	;          If eax = 0 -> file not open
 19273                              <1> 	;   byte [cdev] = logical drive number (of inode in eax)
 19274                              <1> 	;	
 19275                              <1> 	; Modified registers: eax, ebx
 19276                              <1> 
 19277                              <1> 	; 16/05/2021 ('getf' procedure, unix v7 x86 'fio.c')
 19278                              <1> 	; /*
 19279                              <1> 	;  * Convert a user supplied
 19280                              <1> 	;  * file descriptor into a pointer
 19281                              <1> 	;  * to a file structure.
 19282                              <1> 	;  * Only task is to check range
 19283                              <1> 	;  * of the descriptor.
 19284                              <1> 	;  */
 19285                              <1> 	; struct file *
 19286                              <1> 	; getf(f)
 19287                              <1> 	;
 19288                              <1> 	; 18/08/2020
 19289                              <1> 	; 	ebx = file descriptor/number
 19290                              <1> 
 19291                              <1> 	; 16/05/2021
 19292                              <1> 	;NOFILE	equ 10 ; 08/01/2022
 19293                              <1> 
 19294                              <1> 	; 18/08/2020
 19295                              <1> 	;mov	ebx, eax
 19296                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
 19297                              <1> 
 19298                              <1> 	; ebx = file descriptor/number
 19299                              <1> 
 19300                              <1> 	; 18/08/2020
 19301 00004046 29C0                <1> 	sub	eax, eax ; eax = 0
 19302                              <1>  
 19303 00004048 83FB0A              <1> 	cmp	ebx, 10 ; cmp ebx, NOFILE ; 16/05/2021
 19304                              <1> 		; cmp r1,$10. / user limited to 10 open files
 19305 0000404B 732E                <1>         jnb	short getf2 ; 13/05/2015
 19306                              <1> 	;jnb	error
 19307                              <1> 		; bhis error3 / u.fp is table of users open files,
 19308                              <1> 			    ; / index in fsp table
 19309                              <1> 	; 08/01/2022
 19310 0000404D 8A83[AE6C0000]      <1> 	mov	al, [ebx+u.fp]
 19311                              <1> 	;mov	bl, [ebx+u.fp]
 19312                              <1> 		; movb u.fp(r1),r1 / r1 contains number of entry 
 19313                              <1> 		                 ; / in fsp table
 19314 00004053 08C0                <1> 	or	al, al ; 08/01/2022
 19315                              <1> 	;or	bl, bl
 19316                              <1> 	;jnz	short getf3
 19317 00004055 7424                <1> 	jz	short getf2 ; 18/08/2020
 19318                              <1> 	;;jz	short getf4
 19319                              <1> 		; beq 1f / if its zero return
 19320                              <1> ;getf2:
 19321                              <1> ;	; 'File not open !' error (ax=0)
 19322                              <1> ;	;sub	eax, eax ; 18/08/2020
 19323                              <1> ;	retn
 19324                              <1> ;getf3:	
 19325                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
 19326                              <1> 	;
 19327                              <1> 	; 'fsp' table (10 bytes/entry)
 19328                              <1> 	; bit 15				   bit 0
 19329                              <1> 	; ---|-------------------------------------------
 19330                              <1> 	; r/w|		i-number of open file
 19331                              <1> 	; ---|-------------------------------------------
 19332                              <1> 	;		   device number
 19333                              <1> 	; -----------------------------------------------
 19334                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 19335                              <1> 	; -----------------------------------------------
 19336                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 19337                              <1> 	; ----------------------|------------------------
 19338                              <1> 	;  flag that says file 	| number of processes
 19339                              <1> 	;   has been deleted	| that have file open 
 19340                              <1> 	; ----------------------|------------------------
 19341                              <1> 
 19342                              <1> 	; Retro UNIX 386 v2 modification ! (27/03/2020)
 19343                              <1> 
 19344                              <1> 	; bit 15 				    bit 0
 19345                              <1> 	; ----------------------------------------------- byte 0
 19346                              <1> 	;    	       i-number of open file           
 19347                              <1> 	; ----------------------------------------------- byte 2
 19348                              <1> 	;          high word of 32 bit i-number       
 19349                              <1> 	; ----------------------------------------------- byte 4
 19350                              <1> 	;    open mode & status  |   device number     
 19351                              <1> 	; ----------------------------------------------- byte 6
 19352                              <1> 	;       reserved byte    |    open count  
 19353                              <1> 	; ----------------------------------------------- byte 8
 19354                              <1> 	;   offset pointer, i.e., r/w pointer to file 
 19355                              <1> 	; ----------------------------------------------- byte 10
 19356                              <1> 	;     64 bit file offset pointer (bit 16-31)  
 19357                              <1> 	; ----------------------------------------------- byte 12
 19358                              <1> 	;     64 bit file offset pointer (bit 32-47)   
 19359                              <1> 	; ----------------------------------------------- byte 14
 19360                              <1> 	;     64 bit file offset pointer (bit 48-63)  
 19361                              <1> 	; ----------------------------------------------- byte 16
 19362                              <1> 	
 19363                              <1> 	; 11/05/2015 - Retro UNIX 386 v1
 19364                              <1> 	;mov	eax, 10
 19365                              <1> 
 19366                              <1> 	; 27/03/2020 - Retro UNIX 386 v2	
 19367                              <1> 	;mov	eax, opfls.size ; mov eax, 16
 19368                              <1> 	
 19369                              <1> 	;sub	eax, eax ; 18/08/2020 ; eax = 0
 19370                              <1> 
 19371                              <1> 	;mov	al, opfls.size  ; mov al, 16
 19372                              <1> 	;
 19373                              <1> 	;mul	bl
 19374                              <1> 	;;mov	ebx, fsp-6 ; the 3rd word in the fsp entry
 19375                              <1> 	;; 27/03/2020
 19376                              <1> 	;mov	ebx, fsp-(opfls.size-opfls.offset) ; fsp-8
 19377                              <1> 	
 19378                              <1> 	;add	ebx, eax
 19379                              <1> 		; asl r1
 19380                              <1> 		; asl r1 / multiply by 8 to get index into 
 19381                              <1> 		       ; / fsp table entry
 19382                              <1> 		; asl r1
 19383                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
 19384                              <1> 			      ; / in the fsp entry
 19385                              <1> 	; 08/01/2022
 19386 00004057 88C3                <1> 	mov	bl, al
 19387                              <1> 	; 18/08/2020
 19388 00004059 FECB                <1> 	dec	bl ; zero based fsp table entry number
 19389                              <1> 	;shl	bl, 4 ; * 16 ; opfls.size
 19390                              <1> 	; 08/01/2022
 19391 0000405B C1E304              <1> 	shl	ebx, 4 ; * 16 ; opfls.size
 19392 0000405E 81C3[1C690000]      <1> 	add	ebx, fsp+8 ; opfls.offset	
 19393                              <1> 	; ebx = address of the file offset pointer 
 19394                              <1> 	;	(not file offset! not fsp entry address !)
 19395                              <1> 
 19396 00004064 891D[B86C0000]      <1> 	mov	[u.fofp], ebx
 19397                              <1> 		; mov r1,u.fofp / save address of 3rd word 
 19398                              <1> 			     ; / in fsp entry in u.fofp
 19399                              <1> 	; 18/08/2020
 19400 0000406A 8A43FD              <1> 	mov	al, [ebx-3]  ; open mode & status flags
 19401                              <1> 
 19402 0000406D 50                  <1> 	push	eax
 19403                              <1> 
 19404                              <1> 	;mov	ax, [ebx]
 19405                              <1> 	;;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
 19406                              <1> 	;mov	[cdev], ax ; ;;in fact (!) 
 19407                              <1> 			     ;;dev number is in 1 byte
 19408                              <1> 		; mov -(r1),cdev / remove the device number cdev
 19409                              <1> 
 19410                              <1> 	; 18/08/2020
 19411 0000406E 8A43FC              <1> 	mov	al, [ebx-4]  ; logical drive number
 19412                              <1> 
 19413 00004071 A2[816C0000]        <1> 	mov	[cdev], al
 19414                              <1> 
 19415                              <1> 	;dec	ebx
 19416                              <1> 	;dec	ebx
 19417                              <1> 	; 18/08/2020
 19418 00004076 668B43F8            <1> 	mov	ax, [ebx-8]
 19419                              <1> 		; mov -(r1),r1 / and the i-number r1
 19420                              <1> 
 19421 0000407A 5B                  <1> 	pop	ebx ; ebx = bl = open mode and status flag
 19422                              <1> 		; (bit 0 is open mode flag, 0 = read, 1 = write)
 19423                              <1> 	; eax = inode number (in ax)	
 19424                              <1> 
 19425                              <1> getf2:	; 18/08/2020
 19426                              <1> getf4:	; 1: ; 08/01/2022
 19427 0000407B C3                  <1> 	retn
 19428                              <1> 		; rts r0
 19429                              <1> 
 19430                              <1> 	; 15/05/2022
 19431                              <1> 	; 08/01/2022
 19432                              <1> 	; 19/12/2021
 19433                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 19434                              <1> namei:
 19435                              <1> 	; 18/10/2021
 19436                              <1> 	; 12/06/2021
 19437                              <1> 	; 01/05/2021
 19438                              <1> 	; 26/03/2021
 19439                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 19440                              <1> 	; 04/12/2015 (14 byte file names)
 19441                              <1> 	; 18/10/2015 (nbase, ncount)
 19442                              <1> 	; 12/10/2015
 19443                              <1> 	; 21/08/2015
 19444                              <1> 	; 18/07/2015
 19445                              <1> 	; 02/07/2015
 19446                              <1> 	; 17/06/2015
 19447                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
 19448                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 19449                              <1> 	;
 19450                              <1> 	; 'namei' takes a file path name and returns i-number of
 19451                              <1> 	; the file in the current directory or the root directory
 19452                              <1> 	; (if the first character of the pathname is '/').	
 19453                              <1> 	;
 19454                              <1> 	; INPUTS ->
 19455                              <1> 	;    u.namep - points to a file path name
 19456                              <1> 	;    u.cdir - i-number of users directory
 19457                              <1> 	;    u.cdev - device number on which user directory resides	
 19458                              <1> 	; OUTPUTS ->
 19459                              <1> 	;    r1 - i-number of file
 19460                              <1> 	;    cdev
 19461                              <1> 	;    u.dirbuf - points to directory entry where a match 
 19462                              <1> 	;               occurs in the search for file path name.
 19463                              <1> 	;	        If no match u.dirp points to the end of 
 19464                              <1> 	;               the directory and r1 = i-number of the current
 19465                              <1> 	;	        directory.	
 19466                              <1> 	; ((AX = R1))
 19467                              <1> 	;
 19468                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
 19469                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 19470                              <1> 	;
 19471                              <1> 
 19472                              <1> 	;mov	ax, [u.cdir]
 19473                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
 19474                              <1> 			      ; / in r1
 19475                              <1> 	; 01/05/2021
 19476 0000407C A1[A86C0000]        <1> 	mov	eax, [u.cdir]	
 19477 00004081 8A15[AC6C0000]      <1> 	mov	dl, [u.cdrv]
 19478 00004087 8815[816C0000]      <1> 	mov	[cdev], dl
 19479                              <1> 	;mov	dx, [u.cdrv]
 19480                              <1> 	;mov	[cdev], dx	; NOTE: Retro UNIX 8086 v1 
 19481                              <1> 				; device/drive number is in 1 byte, 
 19482                              <1> 				; not in 1 word!
 19483                              <1> 		; mov u.cdev,cdev / device number for users directory 
 19484                              <1> 				; / into cdev
 19485                              <1> 	; 12/10/2015
 19486                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 19487                              <1>       	; convert virtual (pathname) addr to physical address
 19488 0000408D E849010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
 19489                              <1> 		; esi = physical address of [u.namep]
 19490                              <1> 		; ecx = byte count in the page
 19491 00004092 803E2F              <1> 	cmp	byte [esi], '/'
 19492                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
 19493 00004095 751C                <1> 	jne	short namei_1
 19494                              <1> 		; bne 1f
 19495 00004097 FF05[C06C0000]      <1> 	inc	dword [u.namep]
 19496                              <1> 		; inc u.namep / go to next char
 19497                              <1> 	;dec	cx ; remain byte count in the page
 19498 0000409D 49                  <1> 	dec	ecx ; 18/10/2021
 19499 0000409E 7506                <1> 	jnz	short namei_0
 19500                              <1> 	; 12/10/2015
 19501 000040A0 E836010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 19502                              <1> 		; esi = physical address (page start + offset)
 19503                              <1> 		; ecx = byte count in the page
 19504 000040A5 4E                  <1> 	dec	esi
 19505                              <1> namei_0:
 19506 000040A6 46                  <1> 	inc 	esi  ; go to next char
 19507                              <1> 	;mov	ax, [rootdir] ; 09/07/2013
 19508                              <1> 	; 18/10/2021
 19509 000040A7 A1[866C0000]        <1> 	mov	eax, [rootdir]
 19510                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
 19511 000040AC C605[816C0000]00    <1> 	mov	byte [cdev], 0
 19512                              <1> 		; clr cdev / clear device number
 19513                              <1> namei_1: ; 1:
 19514 000040B3 F606FF              <1> 	test	byte [esi], 0FFh
 19515                              <1> 	;jz	short getf4
 19516                              <1> 	; 26/03/2021
 19517                              <1> 	;jz	short getf2 ; retn
 19518                              <1> 	;;jz	nig
 19519                              <1> 		; tstb *u.namep / is the character in file name a nul
 19520                              <1> 		; beq nig / yes, end of file name reached; 
 19521                              <1> 			; / branch to "nig"
 19522                              <1> 	; 19/12/2021
 19523                              <1> namei_9:
 19524                              <1> 	; 12/06/2021
 19525                              <1> 	;jnz	short namei_2
 19526                              <1> 	;retn
 19527                              <1> 	; 08/01/2022
 19528 000040B6 74C3                <1> 	jz	short getf4
 19529                              <1> namei_2: ; 1:
 19530                              <1> 	; 18/10/2015
 19531 000040B8 8935[286D0000]      <1> 	mov 	[nbase], esi
 19532                              <1> 	;mov 	[ncount], cx
 19533                              <1> 	; 18/10/2021
 19534 000040BE 890D[2C6D0000]      <1> 	mov	[ncount], ecx
 19535                              <1> 	;
 19536                              <1> 	;;mov	dx, 2
 19537                              <1> 	;mov	dl, 2 ; user flag (read, non-owner)
 19538                              <1> 	; 25/03/2021
 19539                              <1> 	;mov	dx, 100h ; IREAD - read, owner 
 19540                              <1> 	; 18/10/2021
 19541 000040C4 29D2                <1> 	sub	edx, edx
 19542 000040C6 FEC6                <1> 	inc	dh ; dx = 100h ; IREAD - read, owner 
 19543 000040C8 E8920B0000          <1> 	call	access
 19544                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
 19545                              <1> 	; 'access' will not return here if user has not "r" permission !
 19546                              <1> 
 19547                              <1> 	;test 	word [i.flgs], 4000h
 19548                              <1> 	;	; bit $40000,i.flgs / directory i-node?
 19549                              <1>         ;jz	short namei_err
 19550                              <1> 		; beq error3 / no, got an error
 19551                              <1> 	; 26/03/2021 
 19552                              <1> ;	mov	al, [i.flgs+1]
 19553                              <1> ;	;test	al, 80h ; IFREG ; 80h
 19554                              <1> ;	;jz	short namei_err ; not a regular file ! (device!?)
 19555                              <1> ;	;and	al, 40h ; IFDIR ; 40h
 19556                              <1> ;	;jz	short namei_err ; not a sub directory !
 19557                              <1> ;	shl	al, 1 ; 80h (IFREG flag) -> cf = 1
 19558                              <1> ;	jnc	short namei_err ; not a regular file ! (device!?)
 19559                              <1> ;	shl	al, 1 ; 80h (IFDIR flag) -> cf = 1
 19560                              <1> ;	jnc	short namei_err ; not a sub directory !
 19561                              <1> 
 19562                              <1> 	; 27/03/2021
 19563 000040CD E83A010000          <1> 	call	chk_dir ; check for directory, jump to 'error' if not
 19564                              <1> 	; CPU will be here if the inode is a (valid) directory inode
 19565                              <1> 
 19566                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 19567                              <1> 	;xor	eax, eax
 19568                              <1> 	;mov	[u.off], eax ; 0
 19569                              <1> 	; 01/05/2021 - Retro UNIX 386 v2 inode structure
 19570 000040D2 A1[2C680000]        <1> 	mov	eax, [i.size]
 19571                              <1> 	;mov	ax, [i.size]
 19572 000040D7 A3[BC6C0000]        <1> 	mov	[u.dirp], eax
 19573                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
 19574                              <1> 		; clr u.off / u.off is file offset used by user
 19575                              <1> 	; 18/10/2021
 19576 000040DC 31C0                <1> 	xor	eax, eax
 19577                              <1> 	;mov	[u.off], eax ; 0
 19578 000040DE BB[C46C0000]        <1> 	mov	ebx, u.off
 19579 000040E3 8903                <1> 	mov	[ebx], eax ; mov dword [u.off], 0
 19580                              <1> 	;
 19581 000040E5 891D[B86C0000]      <1> 	mov	[u.fofp], ebx ; u.off ; 18/10/2021
 19582                              <1> 	;mov	dword [u.fofp], u.off
 19583                              <1> 			; mov $u.off,u.fofp / u.fofp is a pointer to 
 19584                              <1> 				  ; / the offset portion of fsp entry
 19585                              <1> namei_3: ; 2:
 19586 000040EB C705[C86C0000]-     <1> 	mov	dword [u.base], u.dirbuf
 19587 000040F1 [DC6C0000]          <1>
 19588                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
 19589                              <1> 				    ; / copied from a directory
 19590 000040F5 C705[CC6C0000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
 19591 000040FD 0000                <1>
 19592                              <1>  		; mov $10.,u.count / u.count is byte count 
 19593                              <1> 				 ; / for reads and writes
 19594                              <1> 	;mov 	ax, [ii]
 19595                              <1> 	; 18/10/2021
 19596 000040FF A1[7C6C0000]        <1> 	mov	eax, [ii] ; (32 bit inode number)
 19597                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
 19598 00004104 FE05[166D0000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
 19599 0000410A E8D20D0000          <1>     	call	readi
 19600                              <1> 		; jsr r0,readi / read 10. bytes of file 
 19601                              <1> 		      ; with i-number (r1); i.e. read a directory entry
 19602                              <1> 
 19603 0000410F 8B0D[D06C0000]      <1> 	mov 	ecx, [u.nread]
 19604 00004115 09C9                <1> 	or 	ecx, ecx
 19605                              <1> 		; tst u.nread
 19606 00004117 741A                <1> 	jz	short nib
 19607                              <1> 		; ble nib / gives error return
 19608                              <1> 	;
 19609                              <1> 	;mov 	bx, [u.dirbuf]
 19610                              <1> 	;and 	bx, bx       
 19611                              <1> 	; 18/10/2021
 19612 00004119 66F705[DC6C0000]FF- <1> 	test	word [u.dirbuf], 0FFFFh
 19613 00004121 FF                  <1>
 19614                              <1> 		; tst u.dirbuf /
 19615 00004122 7513                <1> 	jnz	short namei_4
 19616                              <1> 		; bne 3f / branch when active directory entry 
 19617                              <1> 		       ; / (i-node word in entry non zero)
 19618 00004124 A1[C46C0000]        <1> 	mov	eax, [u.off]
 19619 00004129 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
 19620 0000412C A3[BC6C0000]        <1> 	mov	[u.dirp], eax
 19621                              <1> 		; mov u.off,u.dirp
 19622                              <1> 		; sub $10.,u.dirp
 19623 00004131 EBB8                <1> 	jmp	short namei_3
 19624                              <1> 		; br 2b
 19625                              <1> 
 19626                              <1> 	; 18/07/2013
 19627                              <1> nib: 
 19628 00004133 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
 19629 00004135 F9                  <1> 	stc
 19630                              <1> nig:
 19631 00004136 C3                  <1> 	retn
 19632                              <1> 
 19633                              <1> 	; 27/03/2021
 19634                              <1> ;namei_err:
 19635                              <1> 	; 16/06/2015
 19636                              <1> ;	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
 19637                              <1> ;	jmp	error
 19638                              <1> 
 19639                              <1> namei_4: ; 3:
 19640                              <1> 	; 18/10/2015
 19641                              <1> 	; 12/10/2015
 19642                              <1> 	; 21/08/2015
 19643                              <1> 	; 18/07/2015
 19644 00004137 8B2D[C06C0000]      <1> 	mov	ebp, [u.namep]
 19645                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
 19646 0000413D BF[DE6C0000]        <1> 	mov 	edi, u.dirbuf + 2
 19647                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
 19648                              <1> 	; 18/10/2015
 19649 00004142 8B35[286D0000]      <1> 	mov	esi, [nbase]
 19650                              <1> 	;mov	cx, [ncount]
 19651                              <1> 	;and	cx, cx
 19652                              <1> 	; 18/10/2021
 19653 00004148 8B0D[2C6D0000]      <1> 	mov	ecx, [ncount]
 19654 0000414E 21C9                <1> 	and	ecx, ecx
 19655 00004150 7505                <1> 	jnz	short namei_5	
 19656                              <1> 	;
 19657 00004152 E88A000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 19658                              <1> 		; esi = physical address (page start + offset)
 19659                              <1> 		; ecx = byte count in the page
 19660                              <1> namei_5: ; 3:
 19661 00004157 45                  <1> 	inc	ebp ; 18/07/2015
 19662 00004158 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
 19663                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
 19664 00004159 08C0                <1> 	or 	al, al
 19665 0000415B 741C                <1> 	jz 	short namei_7
 19666                              <1> 		; beq 3f / if char is nul, then the last char in string
 19667                              <1> 			; / has been moved
 19668 0000415D 3C2F                <1> 	cmp	al, '/'
 19669                              <1> 		; cmp r4,$'/ / is char a </>
 19670 0000415F 7418                <1> 	je 	short namei_7
 19671                              <1> 		; beq 3f	
 19672                              <1> 	; 12/10/2015
 19673                              <1> 	;dec	cx ; remain byte count in the page
 19674 00004161 49                  <1> 	dec	ecx ; 18/10/2021
 19675 00004162 7505                <1> 	jnz	short namei_6
 19676 00004164 E878000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 19677                              <1> 		; esi = physical address (page start + offset)
 19678                              <1> 		; ecx = byte count in the page
 19679                              <1> namei_6:
 19680 00004169 81FF[EC6C0000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 19681                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
 19682                              <1> 				     ; / all 8 bytes of file name
 19683 0000416F 74E6                <1> 	je	short namei_5
 19684                              <1> 		; beq 3b
 19685 00004171 AE                  <1> 	scasb	
 19686                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
 19687                              <1> 			      ; / char read from directory
 19688 00004172 74E3                <1> 	je 	short namei_5
 19689                              <1> 		; beq 3b / branch if chars match
 19690                              <1> namei_10:
 19691 00004174 E972FFFFFF          <1>         jmp	namei_3 ; 2b
 19692                              <1> 		; br 2b / file names do not match go to next directory entry
 19693                              <1> namei_7: ; 3:
 19694 00004179 81FF[EC6C0000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 19695                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
 19696 0000417F 7405                <1> 	je	short namei_8
 19697                              <1> 		; beq 3f
 19698                              <1> 	;mov 	ah, [edi]
 19699                              <1> 	;;inc 	edi 
 19700                              <1> 	;and 	ah, ah
 19701                              <1> 	;	; tstb (r3)+ /
 19702                              <1>         ; 18/10/2021
 19703 00004181 F607FF              <1> 	test	byte [edi], 0FFh
 19704                              <1> 	; 08/01/2021
 19705 00004184 75EE                <1> 	jnz	short namei_10 
 19706                              <1> 	;jnz	namei_3
 19707                              <1> 		; bne 2b
 19708                              <1> namei_8: ; 3
 19709 00004186 892D[C06C0000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
 19710                              <1> 		; mov r2,u.namep / u.namep points to char 
 19711                              <1> 			       ; / following a / or nul
 19712                              <1> 	;mov	bx, [u.dirbuf]
 19713                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
 19714                              <1> 				; / entry to r1
 19715                              <1> 
 19716                              <1> 	;;;;
 19717                              <1> 	; 15/05/2022 - Retro UNIX (8086/386) feature only !
 19718                              <1> 	; ! 'pwd' utility modification !
 19719                              <1> 	; ((if directory entry name is a dotdot)))
 19720                              <1> 	;; check if it is mounted device's root directory inode
 19721                              <1> 	; and if so, replace it with parent dir inode number
 19722                              <1> 	;  of mounting directory in [mntp].
 19723                              <1> 
 19724 0000418C 0FB71D[DC6C0000]    <1> 	movzx	ebx, word [u.dirbuf]
 19725                              <1> 
 19726 00004193 6683FB01            <1> 	cmp	bx, 1 ; root directory inode number
 19727 00004197 7539                <1> 	jne	short namei_11
 19728                              <1> 
 19729 00004199 3B1D[7C6C0000]      <1> 	cmp	ebx, [ii] ; for root dir, '.' & '..' is 1
 19730 0000419F 7531                <1> 	jne	short namei_11 ; not root dir (of mounted dev)
 19731                              <1> 
 19732                              <1> 	;cmp	[idev], bh ; 0
 19733 000041A1 383D[816C0000]      <1> 	cmp	[cdev], bh ; 0
 19734                              <1> 			; 0 = root fs, dev num in [rdev]
 19735                              <1> 			; 1 = mounted, dev num in [mdev]
 19736 000041A7 7629                <1> 	jna	short namei_11
 19737                              <1> 
 19738                              <1> 	; dotdot (parent directory link) check
 19739 000041A9 66813D[DE6C0000]2E- <1> 	cmp	word [u.dirbuf+2], '..'
 19740 000041B1 2E                  <1>
 19741 000041B2 751E                <1> 	jne	short namei_11
 19742 000041B4 803D[E06C0000]00    <1> 	cmp	byte [u.dirbuf+4], 0
 19743 000041BB 7515                <1> 	jne	short namei_11
 19744                              <1> 	
 19745                              <1> 	; (This may not be necessary because [idev] = 1
 19746                              <1> 	; and [mnti] is expected as a sub dir inode number)
 19747 000041BD 391D[8A6C0000]      <1> 	cmp	[mnti], ebx ; 1
 19748 000041C3 760D                <1> 	jna	short namei_11
 19749                              <1> 	
 19750                              <1> 	; change inumber to parent dir inum of mount directory
 19751 000041C5 8B1D[8E6C0000]      <1> 	mov	ebx, [mntp]
 19752 000041CB C605[816C0000]00    <1> 	mov	byte [cdev], 0 ; root fs
 19753                              <1> namei_11:
 19754                              <1> 	;;;;
 19755                              <1> 
 19756 000041D2 20C0                <1> 	and 	al, al
 19757                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
 19758                              <1> 		      ;  / if r4 = </> then go to next directory
 19759                              <1> 	; 15/05/2022
 19760 000041D4 89D8                <1> 	mov	eax, ebx
 19761                              <1> 	;;mov	ax, bx
 19762                              <1> 	;;mov 	ax, [u.dirbuf] ; 17/06/2015
 19763                              <1>         ;; 18/10/2021 (16 bit inode number in 32 bit register)
 19764                              <1> 	;movzx	eax, word [u.dirbuf] 
 19765                              <1> 	; 19/12/2021
 19766 000041D6 E9DBFEFFFF          <1> 	jmp	namei_9 ; eax = inode number
 19767                              <1> ;	jnz	namei_2 
 19768                              <1> ;		; bne 1b
 19769                              <1> ;	; AX = i-number of the file
 19770                              <1> ;;;nig:
 19771                              <1> ;	retn
 19772                              <1> 		; tst (r0)+ / gives non-error return
 19773                              <1> ;;nib:
 19774                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
 19775                              <1> 		       ; ax = 0 -> file not found 
 19776                              <1> ;;	stc	; 27/05/2013
 19777                              <1> ;;	retn
 19778                              <1> 		; rts r0
 19779                              <1> 
 19780                              <1> trans_addr_nmbp:
 19781                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 19782                              <1> 	; 18/10/2015
 19783                              <1> 	; 12/10/2015
 19784 000041DB 8B2D[C06C0000]      <1> 	mov 	ebp, [u.namep]
 19785                              <1> trans_addr_nm: 
 19786                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 19787                              <1> 	; Convert virtual (pathname) address to physical address
 19788                              <1> 	; (Retro UNIX 386 v1 feature only !)
 19789                              <1> 	; 18/10/2015
 19790                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
 19791                              <1> 	; 02/07/2015
 19792                              <1> 	; 17/06/2015
 19793                              <1> 	; 16/06/2015
 19794                              <1> 	;
 19795                              <1> 	; INPUTS: 
 19796                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
 19797                              <1> 	;	[u.pgdir] = user's page directory
 19798                              <1> 	; OUTPUT:
 19799                              <1> 	;       esi = physical address of the pathname
 19800                              <1> 	;	ecx = remain byte count in the page
 19801                              <1> 	;
 19802                              <1> 	; (Modified registers: EBX, ECX, EDX, ESI) ; 18/10/2021
 19803                              <1> 	;
 19804                              <1> 
 19805                              <1> 	; 18/10/2021
 19806 000041E1 29C9                <1> 	sub	ecx, ecx
 19807                              <1> 	;
 19808                              <1>         ;cmp	dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
 19809 000041E3 390D[086D0000]      <1> 	cmp	[u.ppgdir], ecx ; 0 ; 18/10/2021
 19810 000041E9 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
 19811                              <1> 				     ; it is already physical address
 19812 000041EB 50                  <1>    	push	eax	
 19813 000041EC 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
 19814 000041EE E8D4E5FFFF          <1>        	call	get_physical_addr ; get physical address
 19815 000041F3 7204                <1> 	jc	short tr_addr_nm_err
 19816                              <1> 	; 18/10/2015
 19817                              <1> 	; eax = physical address 
 19818                              <1> 	; ecx = remain byte count in page (1-4096) ; 18/10/2021
 19819                              <1> 		; 12/10/2015 (cx = [u.pncount])
 19820 000041F5 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
 19821 000041F7 58                  <1> 	pop	eax 
 19822 000041F8 C3                  <1> 	retn
 19823                              <1> 
 19824                              <1> tr_addr_nm_err:
 19825 000041F9 A3[186D0000]        <1> 	mov	[u.error], eax
 19826                              <1> 	;pop 	eax
 19827 000041FE E962EFFFFF          <1> 	jmp	error
 19828                              <1> 
 19829                              <1> trans_addr_nmk:
 19830                              <1> 	; 12/10/2015
 19831                              <1> 	; 02/07/2015
 19832 00004203 8B35[C06C0000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
 19833                              <1> 	;mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
 19834                              <1> 	; 18/10/2021
 19835 00004209 B510                <1> 	mov	ch, PAGE_SIZE/256
 19836 0000420B C3                  <1> 	retn
 19837                              <1> 
 19838                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 19839                              <1> chk_dir:
 19840                              <1> 	; 12/06/2021
 19841                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
 19842                              <1> 	; Check for directory inode
 19843                              <1> 
 19844 0000420C 8A0D[25680000]      <1> 	mov	cl, [i.flgs+1]
 19845                              <1> 	;test	cl, 80h ; IFREG ; 80h
 19846                              <1> 	;jz	short chk_dir_err ; not a regular file ! (device!?)
 19847                              <1> 	;and	cl, 40h ; IFDIR ; 40h
 19848                              <1> 	;jz	short chk_dir_err ; not a sub directory !
 19849 00004212 D0E1                <1> 	shl	cl, 1 ; 80h (IFREG flag) -> cf = 1
 19850 00004214 7305                <1> 	jnc	short chk_dir_err ; not a regular file ! (device!?)
 19851 00004216 D0E1                <1> 	shl	cl, 1 ; 40h (IFDIR flag) -> cf = 1
 19852 00004218 7301                <1> 	jnc	short chk_dir_err ; not a sub directory !
 19853                              <1> 	; 12/06/2021
 19854 0000421A C3                  <1> 	retn
 19855                              <1> chk_dir_err:
 19856 0000421B C705[186D0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 19857 00004223 0000                <1>
 19858 00004225 E93BEFFFFF          <1> 	jmp	error
 19859                              <1> 
 19860                              <1> 	; 06/02/2022
 19861                              <1> 	; 08/01/2022
 19862                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode)
 19863                              <1> syschdir:
 19864                              <1> 	; / makes the directory specified in the argument
 19865                              <1> 	; / the current directory
 19866                              <1> 	;
 19867                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 19868                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19869                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 19870                              <1> 	;
 19871                              <1> 	; 'syschdir' makes the directory specified in its argument
 19872                              <1> 	; the current working directory.
 19873                              <1> 	;
 19874                              <1> 	; Calling sequence:
 19875                              <1> 	;	syschdir; name
 19876                              <1> 	; Arguments:
 19877                              <1> 	;	name - address of the path name of a directory
 19878                              <1> 	;	       terminated by nul byte.	
 19879                              <1> 	; Inputs: -
 19880                              <1> 	; Outputs: -
 19881                              <1> 	; ...............................................................
 19882                              <1> 	;				
 19883                              <1> 	; Retro UNIX 8086 v1 modification:
 19884                              <1> 	;	 The user/application program puts address of 
 19885                              <1> 	;	 the path name in BX register as 'syschdir' 
 19886                              <1> 	; 	 system call argument.
 19887                              <1> 
 19888 0000422A 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 19889                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
 19890 00004230 E847FEFFFF          <1> 	call	namei
 19891                              <1> 		; jsr r0,namei / find its i-number
 19892                              <1> 	;jc	error
 19893                              <1> 		; br error3
 19894 00004235 730F                <1> 	jnc	short syschdir0
 19895                              <1> 	; 'directory not found !' error
 19896 00004237 C705[186D0000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
 19897 0000423F 0000                <1>
 19898 00004241 E91FEFFFFF          <1> 	jmp	error
 19899                              <1> syschdir0:
 19900                              <1> 	; 08/01/2022
 19901 00004246 66BA0001            <1> 	mov	dx, 100h  ; read access ; IREAD (100h)
 19902 0000424A E8100A0000          <1> 	call	access
 19903                              <1> 		; jsr r0,access; 2 / get i-node into core
 19904                              <1> 	
 19905                              <1> 	; 06/02/2022
 19906                              <1> 	;; 01/01/2022 (runix v2 fs inode flag)
 19907                              <1> 	;test	byte [i.flgs+1], 80h ; regular file ?
 19908                              <1> 	;jz	short syschdir2 ; no, error!
 19909                              <1> 	;test	byte [i.flgs+1], 40h ; directory flag ?
 19910                              <1> 	;;test	word [i.flgs], 4000h
 19911                              <1> 	;	; bit $40000,i.flgs / is it a directory?
 19912                              <1> 	;;jz	error 
 19913                              <1> 	;	; beq error3 / no error
 19914                              <1> 	;jnz	short syschdir1
 19915                              <1> ;syschdir2:
 19916                              <1> 	;mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 19917                              <1> 	;jmp	error
 19918                              <1> 
 19919                              <1> 	; 06/02/2022
 19920                              <1> 	; check for directory, jump to 'error' if not
 19921 0000424F E8B8FFFFFF          <1> 	call	chk_dir
 19922                              <1> 	; (cpu will not return here
 19923                              <1> 	;  if the inode it is not a valid dir inode)
 19924                              <1> 
 19925                              <1> syschdir1:
 19926 00004254 66A3[A86C0000]      <1> 	mov	[u.cdir], ax
 19927                              <1> 		; mov r1,u.cdir / move i-number to users 
 19928                              <1> 			      ; / current directory
 19929                              <1> 	;mov	ax, [cdev]
 19930                              <1> 	;mov	[u.cdrv], ax
 19931                              <1> 	; 08/01/2022
 19932 0000425A A0[816C0000]        <1> 	mov	al, [cdev]
 19933 0000425F A2[AC6C0000]        <1> 	mov	[u.cdrv], al
 19934                              <1> 		; mov cdev,u.cdev / move its device to users 
 19935                              <1> 			        ; / current device
 19936 00004264 E91CEFFFFF          <1> 	jmp	sysret
 19937                              <1> 		; br sysret3
 19938                              <1> 
 19939                              <1> syschmod: ; < change mode of file >
 19940                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 19941                              <1> 	; 01/05/2021
 19942                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 19943                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19944                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 19945                              <1> 	;
 19946                              <1> 	; 'syschmod' changes mode of the file whose name is given as
 19947                              <1> 	; null terminated string pointed to by 'name' has it's mode 
 19948                              <1> 	; changed to 'mode'.
 19949                              <1> 	;
 19950                              <1> 	; Calling sequence:
 19951                              <1> 	;	syschmod; name; mode
 19952                              <1> 	; Arguments:
 19953                              <1> 	;	name - address of the file name
 19954                              <1> 	;	       terminated by null byte.
 19955                              <1> 	;	mode - (new) mode/flags < attributes >
 19956                              <1> 	;	
 19957                              <1> 	; Inputs: -
 19958                              <1> 	; Outputs: -
 19959                              <1> 	; ...............................................................
 19960                              <1> 	;				
 19961                              <1> 	; Retro UNIX 8086 v1 modification: 
 19962                              <1> 	;       'syschmod' system call has two arguments; so,
 19963                              <1> 	;	* 1st argument, name is pointed to by BX register
 19964                              <1> 	;	* 2nd argument, mode is in CX register
 19965                              <1> 	;
 19966                              <1> 	; Mode bits (Flags):
 19967                              <1> 	;	bit 15 - 'i-node is allocated' flag (8000h)
 19968                              <1> 	;	bit 14 - directory flag (4000h)
 19969                              <1> 	;	bit 13 - file has modified flag (always on) (2000h)
 19970                              <1> 	;	bit 12 - large file flag (1000h)
 19971                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
 19972                              <1> 	;	bit 5 - set user ID on execution flag (20h) 
 19973                              <1> 	;	bit 4 - executable flag (10h)
 19974                              <1> 	;	bit 3 - read permission for owner (08h)
 19975                              <1> 	;	bit 2 - write permission for owner (04h)
 19976                              <1> 	;	bit 1 - read permission for non-owner (02h)
 19977                              <1> 	;	bit 0 - write permission for non-owner (01h)
 19978                              <1> 
 19979                              <1> 	; 01/05/2021 (07/02/2020)
 19980                              <1> 	; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
 19981                              <1> 	; 	bit 15 - IFREG - regular file (8000h)
 19982                              <1> 	;	bit 14 - IFDIR - directory (4000h)
 19983                              <1> 	;	bit 13 - IRSVD - 0 - reserved/mounted bit (2000h)
 19984                              <1> 	; 	bit 12 - ILARG - large file addressing bit (1000h)
 19985                              <1> 	; 	bit 11 - ISUID - set user id on exec (800h)
 19986                              <1> 	;	bit 10 - ISGID - set group id on exec (400h)
 19987                              <1> 	; 	bit  9 - IEXTT - 0 - use extents (200h)
 19988                              <1> 	;	bit  8 - IREAD - read, owner (100h)
 19989                              <1> 	;	bit  7 - IWRITE - write, owner (80h)
 19990                              <1> 	;	bit  6 - IEXEC - execute, owner (40h)
 19991                              <1> 	; 	bit  5 - read, group (20h)
 19992                              <1> 	; 	bit  4 - write, group (10h)
 19993                              <1> 	; 	bit  3 - execute, group (08h)
 19994                              <1> 	;	bit  2 - read, others (04h)
 19995                              <1> 	; 	bit  1 - write, others (02h)
 19996                              <1> 	; 	bit  0 - execute, others (01h)
 19997                              <1> 	;
 19998                              <1> 	; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
 19999                              <1> 	;	bit 15 - IFREG - 0 - device file (8000h)
 20000                              <1> 	; 	bit 14 - IFBLK - block device (4000h)
 20001                              <1> 	; 	bit 13 - IFCHR - 1 - character special (2000h)
 20002                              <1> 	;	bit 12 - IFIFO - fifo special (1000h)
 20003                              <1> 	; 	bit 11 - IPIPE - pipe special (800h)
 20004                              <1> 	;	bit 10 - IREDIR - redirected (400h)
 20005                              <1> 	;	bit  9 - IEXTR - external device driver (200h)
 20006                              <1> 	;	bit  8 - IREAD - read, owner (100h)
 20007                              <1> 	;	bit  7 - IWRITE - write, owner (80h)
 20008                              <1> 	;	bit  6 - IEXEC - execute, owner (40h)
 20009                              <1> 	; 	bit  5 - read, group (20h)
 20010                              <1> 	; 	bit  4 - write, group (10h)
 20011                              <1> 	; 	bit  3 - execute, group (08h)
 20012                              <1> 	;	bit  2 - read, others (04h)
 20013                              <1> 	; 	bit  1 - write, others (02h)
 20014                              <1> 	; 	bit  0 - execute, others (01h)
 20015                              <1> 
 20016                              <1> 	; / name; mode
 20017 00004269 E877000000          <1> 	call	isown
 20018                              <1> 		; jsr r0,isown / get the i-node and check user status
 20019                              <1> 
 20020                              <1> 	; 25/05/2020
 20021                              <1> 	; AL = new mode (return form 'isown', ecx -> eax)
 20022                              <1> 
 20023                              <1> 	;test	word [i.flgs], 4000h
 20024                              <1> 	;	; bit $40000,i.flgs / directory?
 20025                              <1> 	;jz	short syschmod1
 20026                              <1> 	;	; beq 2f / no
 20027                              <1> 	;; AL = (new) mode
 20028                              <1> 	;and	al, 0CFh ; 11001111b (clears bit 4 & 5)
 20029                              <1> 	;	; bic $60,r2 / su & ex / yes, clear set user id and 
 20030                              <1> 	;		   ; / executable modes
 20031                              <1> 
 20032                              <1> 	; 01/05/2021
 20033                              <1> 	; AX = new mode (9 bits for devices or 12 bits files)
 20034 0000426E 8A15[25680000]      <1> 	mov	dl, [i.flgs+1]
 20035                              <1> 	; 09/01/2022
 20036 00004274 F6C280              <1> 	test	dl, 80h ; regular file
 20037 00004277 7416                <1> 	jz	short syschmod1 ; device file
 20038 00004279 F6C240              <1> 	test	dl, 40h ; directory
 20039 0000427C 7511                <1> 	jnz	short syschmod1
 20040                              <1> 	; regular file
 20041 0000427E 6625FF0D            <1> 	and	ax, 0DFFh ; clear bit 9, 12-15 (of new mode)
 20042                              <1> 	; clear bit 8,10,11 of current mode/flags
 20043 00004282 80E2F2              <1> 	and	dl, 0F2h ; and dl, 11110010b
 20044                              <1> syschmod0:
 20045 00004285 08D4                <1> 	or	ah, dl
 20046 00004287 66A3[24680000]      <1> 	mov	[i.flgs], ax	
 20047 0000428D EB45                <1> 	jmp	short syschmod2
 20048                              <1> syschmod1: 
 20049                              <1> 	; device or directory	
 20050 0000428F 6625B601            <1> 	and	ax, 1B6h ; clear bit 9-15 & bit 0,3,6 (EXEC bits)
 20051                              <1> 	; clear bit 8 (IREAD) of current mode/flags
 20052                              <1> 	;	 (dl contains flag bits 8-15)
 20053 00004293 80E2FE              <1> 	and	dl, ~1 ; and dl, 11111110b 
 20054 00004296 EBED                <1> 	jmp	short syschmod0
 20055                              <1> 
 20056                              <1> ;syschmod1: ; 2:
 20057                              <1> 	;mov	[i.flgs], al	
 20058                              <1> 	;	; movb r2,i.flgs / move remaining mode to i.flgs
 20059                              <1> 
 20060                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 20061                              <1> 	;mov	byte [imodx], 1 ; (flag means file data is same
 20062                              <1> 	;			;  but inode's itself has been modified)
 20063                              <1> 	;call	setimod
 20064                              <1> 	;jmp	sysret
 20065                              <1> 
 20066                              <1> 	; 25/05/2020
 20067                              <1> 	;jmp	short syschmod2
 20068                              <1> 
 20069                              <1> syschown: ; < change owner of file >
 20070                              <1> 	; 13/03/2022
 20071                              <1> 	; 11/03/2022
 20072                              <1> 	; 14/02/2022
 20073                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20074                              <1> 	; 01/05/2021
 20075                              <1> 	;	(change owner and group ID of file)
 20076                              <1> 	; 02/04/2021
 20077                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 20078                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20079                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 20080                              <1> 	;
 20081                              <1> 	; 'syschown' changes the owner of the file whose name is given
 20082                              <1> 	; as null terminated string pointed to by 'name' has it's owner
 20083                              <1> 	; changed to 'owner'
 20084                              <1> 	;
 20085                              <1> 	; Calling sequence:
 20086                              <1> 	;	syschown; name; owner
 20087                              <1> 	; Arguments:
 20088                              <1> 	;	name - address of the file name
 20089                              <1> 	;	       terminated by null byte.
 20090                              <1> 	;	owner - (new) owner (number/ID)
 20091                              <1> 	;	
 20092                              <1> 	; Inputs: -
 20093                              <1> 	; Outputs: -
 20094                              <1> 	; ...............................................................
 20095                              <1> 	;				
 20096                              <1> 	; Retro UNIX 8086 v1 modification: 
 20097                              <1> 	;       'syschown' system call has two arguments; so,
 20098                              <1> 	;	* 1st argument, name is pointed to by BX register
 20099                              <1> 	;	* 2nd argument, owner number is in CX register
 20100                              <1> 	;
 20101                              <1> 	; / name; owner
 20102 00004298 E848000000          <1> 	call	isown
 20103                              <1> 		; jsr r0,isown / get the i-node and check user status
 20104                              <1> 	
 20105                              <1> 	; 25/05/2020
 20106                              <1> 	; AL = owner number (return form 'isown', ecx -> eax)
 20107                              <1> 	; 02/04/2021
 20108                              <1> 	; AX = owner number
 20109                              <1> 	; 01/05/2021
 20110                              <1> 	; byte 2 of EAX is group number
 20111                              <1> 
 20112                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013 
 20113                              <1> 	;	; tstb u.uid / super user
 20114                              <1> 	;jz	short syschown1
 20115                              <1> 	;	; beq 2f / yes, 2f
 20116 0000429D 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0
 20117 000042A5 741F                <1> 	jz	short syschown1
 20118                              <1> 
 20119                              <1> 	;test	byte [i.flgs], 20h ; 32
 20120                              <1> 	;	; bit $40,i.flgs / no, set userid on execution?
 20121                              <1> 	;;jnz	error
 20122                              <1> 	;	; bne 3f / yes error, could create Trojan Horses
 20123                              <1> 	;jz	short syschown1
 20124                              <1> 	; 01/05/2021
 20125                              <1> 	; check set user id on execution flag
 20126                              <1> 	; (protection against Trojan Horses)
 20127                              <1> 
 20128                              <1> 	; ((Note: UNIX v7 x86 'chown' source code in 'sys4.c'
 20129                              <1> 	;        does not contain this protection)) 
 20130                              <1> 
 20131                              <1> 	; 14/02/2022
 20132 000042A7 8A15[25680000]      <1> 	mov	dl, [i.flgs+1]
 20133 000042AD F6C280              <1> 	test	dl, 80h ; IFREG ; RUNIX v2 inode flags  	
 20134 000042B0 7405                <1> 	jz	short syschown_err ; device file !
 20135                              <1> 	; 09/01/2022
 20136                              <1> 	;test	byte [i.flgs+1], 08h ; ISUID ; RUNIX v2 inode flags  	
 20137                              <1> 	; 14/02/2022
 20138 000042B2 F6C208              <1> 	test	dl, 08h	; set user id on execution
 20139 000042B5 740F                <1> 	jz	short syschown1 ; 11/03/2022
 20140                              <1> 		; 11/03/2022
 20141                              <1> 		; bit $40,i.flgs / no, set userid on execution?
 20142                              <1> 		; bne 3f / yes error, could create Trojan Horses
 20143                              <1> syschown_err:
 20144                              <1> 	; 'permission denied !'
 20145 000042B7 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
 20146 000042BF 0000                <1>
 20147 000042C1 E99FEEFFFF          <1> 	jmp	error
 20148                              <1> syschown1: ; 2:
 20149                              <1> 	;; AL = owner (number/ID)
 20150                              <1> 	;mov	[i.uid], al ; 23/06/2015
 20151                              <1> 	;	; movb r2,i.uid / no, put the new owners id 
 20152                              <1> 	;		      ; / in the i-node
 20153                              <1> 	; 02/04/2021 (Retro UNIX 386 v2)
 20154                              <1> 	; AX = owner number
 20155 000042C6 66A3[28680000]      <1> 	mov	[i.uid], ax ; owner
 20156                              <1> 	; 13/03/2022
 20157                              <1> 	;; 14/02/2022 (Retro UNIX 386 v1.2)
 20158                              <1> 	;test	dl, 04h ; ISGID ; set grup id on execution
 20159                              <1> 	;jz	short syschown2
 20160                              <1> 	; 01/05/2021 (Retro UNIX 386 v2)
 20161 000042CC C1E810              <1> 	shr	eax, 16
 20162 000042CF A2[2A680000]        <1> 	mov	[i.gid], al ; group
 20163                              <1> syschown2:
 20164                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 20165                              <1> syschmod2:
 20166                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20167 000042D4 C605[956C0000]01    <1> 	mov	byte [imodx], 1	; (flag means file data is same
 20168                              <1> 			      ;  but inode's itself has been modified)
 20169 000042DB E8260A0000          <1> 	call	setimod ; 25/05/2020
 20170                              <1> 	
 20171 000042E0 E9A0EEFFFF          <1> 	jmp	sysret
 20172                              <1> 
 20173                              <1> 	; 1: 
 20174                              <1> 		; jmp sysret4
 20175                              <1> 	; 3:
 20176                              <1> 		; jmp	error
 20177                              <1> 
 20178                              <1> isown:
 20179                              <1> 	; 11/03/2022
 20180                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20181                              <1> 	; 06/11/2021
 20182                              <1> 	; 12/06/2021
 20183                              <1> 	; 01/05/2021
 20184                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 20185                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20186                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 20187                              <1> 	;
 20188                              <1> 	; 'isown' is given a file name (the 1st argument).
 20189                              <1> 	;  It find the i-number of that file via 'namei' 
 20190                              <1> 	;  then gets the i-node into core via 'iget'.
 20191                              <1> 	;  It then tests to see if the user is super user. 
 20192                              <1> 	;  If not, it checks to see if the user is owner of 
 20193                              <1> 	;  the file. If he is not an error occurs.
 20194                              <1> 	;  If user is the owner 'setimod' is called to indicate
 20195                              <1> 	;  the inode has been modified and the 2nd argument of
 20196                              <1> 	;  the call is put in r2.
 20197                              <1> 	;
 20198                              <1> 	; INPUTS ->
 20199                              <1> 	;    arguments of syschmod and syschown calls
 20200                              <1> 	; OUTPUTS ->
 20201                              <1> 	;    u.uid - id of user
 20202                              <1> 	;    imod - set to a 1
 20203                              <1> 	;    r2 - contains second argument of the system call
 20204                              <1> 	;
 20205                              <1> 	;   ((AX=R2) output as 2nd argument)
 20206                              <1> 	;
 20207                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))
 20208                              <1> 	;
 20209                              <1> 		; jsr r0,arg2 / u.namep points to file name
 20210                              <1> 	;; ! 2nd argument on top of stack !
 20211                              <1> 	;; 22/06/2015 - 32 bit modifications
 20212                              <1> 	;; 07/07/2013
 20213 000042E5 891D[C06C0000]      <1> 	mov	[u.namep], ebx ;; 1st argument
 20214 000042EB 51                  <1> 	push 	ecx ;* ; 2nd argument
 20215                              <1> 	;;
 20216 000042EC E88BFDFFFF          <1> 	call	namei
 20217                              <1> 		; jsr r0,namei / get its i-number
 20218                              <1>        ; Retro UNIX 8086 v1 modification !
 20219                              <1>        ; ax = 0 -> file not found 
 20220                              <1> 	;and	ax, ax
 20221                              <1> 	;jz	error
 20222                              <1> 	;jc	error ; 27/05/2013
 20223                              <1> 		; br error3
 20224 000042F1 730F                <1> 	jnc	short isown1  ; 25/05/2020 (isown0 -> isown1)
 20225                              <1> 	; 'file not found !' error
 20226 000042F3 C705[186D0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 20227 000042FB 0000                <1>
 20228 000042FD E963EEFFFF          <1> 	jmp	error
 20229                              <1> isown1:
 20230 00004302 E86E080000          <1> 	call	iget
 20231                              <1> 		; jsr r0,iget / get i-node into core
 20232                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 20233                              <1> 	;; 06/11/2021
 20234                              <1> 	;jnc	short isown3
 20235                              <1> 	;mov	[u.error], eax
 20236                              <1> 	;jmp	error
 20237                              <1> ;isown3:
 20238                              <1> 	; check if it is super user ID
 20239                              <1> 	; 09/01/2022 (Retro UNIX 386 v2 fs inode structure)
 20240 00004307 66A1[F66C0000]      <1> 	mov	ax, [u.uid]
 20241 0000430D 6609C0              <1> 	or	ax, ax
 20242                              <1> 	;mov	al, [u.uid] ; 02/08/2013
 20243                              <1> 	;or	al, al
 20244                              <1> 		; tstb u.uid / super user?
 20245                              <1> 	; 12/06/2021
 20246 00004310 7418                <1> 	jz	short isown2 ; 25/05/2020 (isown1 -> isown2)
 20247                              <1> 		; beq 1f / yes, branch
 20248                              <1> 	
 20249                              <1> 	; check user ID	(if same with file's owner)
 20250 00004312 663B05[28680000]    <1> 	cmp	ax, [i.uid] ; 09/01/2022
 20251                              <1> 	;cmp	al, [i.uid]
 20252                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
 20253                              <1> 				 ; / the file
 20254                              <1> 	;jne	error
 20255                              <1> 		; beq 1f / yes
 20256                              <1> 		; jmp error3 / no, error
 20257                              <1> 	; 11/03/2022
 20258 00004319 740F                <1> 	je	short isown2 ; 25/05/2020
 20259                              <1> 	;; 01/05/2021
 20260                              <1> 	;jne	short isown_err
 20261                              <1> 
 20262                              <1> 	; 11/03/2022 (*)
 20263                              <1> 	; Note: It is seen as original unix (v5-v7) kernel
 20264                              <1> 	;	source handles 'u.gid' for group permissions
 20265                              <1> 	;	but kernel uses 'u.uid' as primary and unic
 20266                              <1> 	;	(singular) user id/number; a user group
 20267                              <1> 	;	does/can not contain same user id/number
 20268                              <1> 	;	with anotner group. So, if active/current
 20269                              <1> 	;	user ID is same with file's owner id,
 20270                              <1> 	;	group id check is not needed.
 20271                              <1> 	;	([u.uid] = [i.uid] is enough to confirm)	
 20272                              <1> 
 20273                              <1> 	; 01/05/2021
 20274                              <1> 	;mov	ax, [u.uid]
 20275                              <1> 	;or	ax, ax
 20276                              <1> 	;jz	short isown2 
 20277                              <1> 	;cmp	ax, [i.uid]
 20278                              <1> 	;;je	short isown2
 20279                              <1> 	;jne	short isown_err
 20280                              <1> 
 20281                              <1> 	; 01/05/2021
 20282                              <1> 	; ((Note: UNIX v7 x86 'chown', 'chmod' procedures
 20283                              <1> 	;    and their sub procedures do not check group ID))
 20284                              <1> 	; (('sys4.c', 'fio.c'))
 20285                              <1> 
 20286                              <1> 	; 11/03/2022 (*)
 20287                              <1> 	; 01/05/2021
 20288                              <1> 	; check group ID (if same with group of file's owner)
 20289                              <1> 	;mov	al, [u.gid]
 20290                              <1> 	;cmp	al, [i.gid]
 20291                              <1> 	;je	short isown2
 20292                              <1> isown_err:
 20293 0000431B C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER ; 11
 20294 00004323 0000                <1>
 20295                              <1> 			; 'permission denied !' error
 20296 00004325 E93BEEFFFF          <1> 	jmp	error
 20297                              <1> 
 20298                              <1> 	; 25/05/2020
 20299                              <1> ;isown2: ; 1:
 20300                              <1> ;	call	setimod
 20301                              <1> ;		; jsr r0,setimod / indicates 
 20302                              <1> ;		;	       ; / i-node has been modified
 20303                              <1> isown2: 
 20304                              <1> 	; 25/05/2020
 20305 0000432A 58                  <1> 	pop	eax ;* ; 2nd argument
 20306                              <1> 		; mov (sp)+,r2 / mode is put in r2 
 20307                              <1> 		       ; / (u.off put on stack with 2nd arg)
 20308 0000432B C3                  <1> 	retn
 20309                              <1> 
 20310                              <1> ;;arg:  ; < get system call arguments >
 20311                              <1> 	; 'arg' extracts an argument for a routine whose call is 
 20312                              <1> 	; of form:
 20313                              <1> 	;	sys 'routine' ; arg1
 20314                              <1> 	;		or
 20315                              <1> 	;	sys 'routine' ; arg1 ; arg2
 20316                              <1> 	;		or
 20317                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
 20318                              <1> 	;	
 20319                              <1> 	; INPUTS ->
 20320                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
 20321                              <1> 	;	This pointers's value is actually the value of
 20322                              <1> 	;	update pc at the the trap to sysent (unkni) is
 20323                              <1> 	;	made to process the sys instruction
 20324                              <1> 	;    r0 - contains the return address for the routine
 20325                              <1> 	;	that called arg. The data in the word pointer 
 20326                              <1> 	;	to by the return address is used as address
 20327                              <1> 	;	in which the extracted argument is stored
 20328                              <1> 	;    	
 20329                              <1> 	; OUTPUTS ->
 20330                              <1> 	;    'address' - contains the extracted argument 
 20331                              <1> 	;    u.sp+18 - is incremented by 2 
 20332                              <1> 	;    r1 - contains the extracted argument
 20333                              <1> 	;    r0 - points to the next instruction to be
 20334                              <1> 	;	 executed in the calling routine.
 20335                              <1> 	;
 20336                              <1>   
 20337                              <1> 	; mov u.sp,r1
 20338                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
 20339                              <1> 			; / into argument of arg2
 20340                              <1> 	; add $2,18.(r1) / point pc on stack 
 20341                              <1> 			      ; / to next system argument
 20342                              <1> 	; rts r0
 20343                              <1> 
 20344                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
 20345                              <1> 	; 'arg2' takes first argument in system call
 20346                              <1> 	;  (pointer to name of the file) and puts it in location
 20347                              <1> 	;  u.namep; takes second argument and puts it in u.off
 20348                              <1> 	;  and on top of the stack
 20349                              <1> 	;	
 20350                              <1> 	; INPUTS ->
 20351                              <1> 	;    u.sp, r0
 20352                              <1> 	;    	
 20353                              <1> 	; OUTPUTS ->
 20354                              <1> 	;    u.namep
 20355                              <1> 	;    u.off 
 20356                              <1> 	;    u.off pushed on stack
 20357                              <1> 	;    r1
 20358                              <1> 	;
 20359                              <1> 
 20360                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
 20361                              <1> 				; / first arg in sys call
 20362                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
 20363                              <1> 				; / second arg in sys call
 20364                              <1> 	; mov r0,r1 / r0 points to calling routine
 20365                              <1> 	; mov (sp),r0 / put operation code back in r0
 20366                              <1> 	; mov u.off,(sp) / put pointer to second argument 
 20367                              <1> 			; / on stack
 20368                              <1> 	; jmp (r1) / return to calling routine
 20369                              <1> 
 20370                              <1> systime: ; / get time of year
 20371                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20372                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 20373                              <1> 	;
 20374                              <1> 	; 20/06/2013
 20375                              <1> 	; 'systime' gets the time of the year.
 20376                              <1> 	; The present time is put on the stack.
 20377                              <1> 	;
 20378                              <1> 	; Calling sequence:
 20379                              <1> 	;	systime
 20380                              <1> 	; Arguments: -
 20381                              <1> 	;	
 20382                              <1> 	; Inputs: -
 20383                              <1> 	; Outputs: sp+2, sp+4 - present time
 20384                              <1> 	; ...............................................................
 20385                              <1> 	;	
 20386                              <1> 	; Retro UNIX 8086 v1 modification: 
 20387                              <1> 	;       'systime' system call will return to the user
 20388                              <1> 	;	with unix time (epoch) in DX:AX register pair
 20389                              <1> 	;
 20390                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
 20391                              <1> 	;	system call for PC compatibility !!		 	
 20392                              <1> 
 20393 0000432C E809E9FFFF          <1> 	call 	epoch
 20394 00004331 A3[A46C0000]        <1> 	mov 	[u.r0], eax
 20395                              <1> 		; mov s.time,4(sp)
 20396                              <1> 		; mov s.time+2,2(sp) / put the present time 
 20397                              <1> 				   ; / on the stack
 20398                              <1> 		; br sysret4
 20399 00004336 E94AEEFFFF          <1> 	jmp	sysret 
 20400                              <1> 
 20401                              <1> sysstime: ; / set time
 20402                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20403                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20404                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 20405                              <1> 	;
 20406                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
 20407                              <1> 	;
 20408                              <1> 	; Calling sequence:
 20409                              <1> 	;	sysstime
 20410                              <1> 	; Arguments: -
 20411                              <1> 	;	
 20412                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
 20413                              <1> 	; Outputs: -
 20414                              <1> 	; ...............................................................
 20415                              <1> 	;	
 20416                              <1> 	; Retro UNIX 8086 v1 modification: 
 20417                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
 20418                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
 20419                              <1> 	; 
 20420                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 20421                              <1> 	;	to get sysstime system call arguments from the user;
 20422                              <1> 	;	* 1st argument, lowword of unix time is in BX register
 20423                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
 20424                              <1> 	;
 20425                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
 20426                              <1> 	;	system call for PC compatibility !!	
 20427                              <1> 
 20428                              <1> 	; 09/01/2022 (Retro UNIX 386 v2 fs inode structure)
 20429 0000433B 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0 ; 16 bit user ID
 20430                              <1> 	;cmp	byte [u.uid], 0
 20431                              <1> 		; tstb u.uid / is user the super user
 20432                              <1> 	;ja	error
 20433                              <1> 		; bne error4 / no, error
 20434 00004343 760F                <1> 	jna	short systime1
 20435                              <1> 	; 'permission denied !'
 20436 00004345 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
 20437 0000434D 0000                <1>
 20438 0000434F E911EEFFFF          <1> 	jmp	error
 20439                              <1> systime1:
 20440                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
 20441                              <1> 	; EBX = unix (epoch) time (from user)
 20442 00004354 89D8                <1> 	mov	eax, ebx
 20443 00004356 E85CEAFFFF          <1> 	call 	set_date_time
 20444                              <1> 		; mov 4(sp),s.time
 20445                              <1> 		; mov 2(sp),s.time+2 / set the system time
 20446 0000435B E925EEFFFF          <1> 	jmp	sysret
 20447                              <1> 		; br sysret4
 20448                              <1> 
 20449                              <1> sysbreak:
 20450                              <1> 	; 18/10/2015
 20451                              <1> 	; 07/10/2015
 20452                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20453                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
 20454                              <1> 	;
 20455                              <1> 	; 'sysbreak' sets the programs break points. 
 20456                              <1> 	; It checks the current break point (u.break) to see if it is
 20457                              <1> 	; between "core" and the stack (sp). If it is, it is made an
 20458                              <1> 	; even address (if it was odd) and the area between u.break
 20459                              <1> 	; and the stack is cleared. The new breakpoint is then put
 20460                              <1> 	; in u.break and control is passed to 'sysret'.
 20461                              <1> 	;
 20462                              <1> 	; Calling sequence:
 20463                              <1> 	;	sysbreak; addr
 20464                              <1> 	; Arguments: -
 20465                              <1> 	;	
 20466                              <1> 	; Inputs: u.break - current breakpoint
 20467                              <1> 	; Outputs: u.break - new breakpoint 
 20468                              <1> 	;	area between old u.break and the stack (sp) is cleared.
 20469                              <1> 	; ...............................................................
 20470                              <1> 	;	
 20471                              <1> 	; Retro UNIX 8086 v1 modification:
 20472                              <1> 	;	The user/application program puts breakpoint address
 20473                              <1> 	;       in BX register as 'sysbreak' system call argument.
 20474                              <1> 	; 	(argument transfer method 1)
 20475                              <1> 	;
 20476                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
 20477                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
 20478                              <1> 	;  NOTE:
 20479                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
 20480                              <1> 	;	'u.break' address) of user's memory for original unix's
 20481                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
 20482                              <1> 
 20483                              <1> 		; mov u.break,r1 / move users break point to r1
 20484                              <1> 		; cmp r1,$core / is it the same or lower than core?
 20485                              <1> 		; blos 1f / yes, 1f
 20486                              <1> 	; 23/06/2015
 20487 00004360 8B2D[D46C0000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
 20488                              <1> 	;and	ebp, ebp
 20489                              <1> 	;jz	short sysbreak_3 
 20490                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
 20491                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
 20492 00004366 8B15[9C6C0000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
 20493 0000436C 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
 20494                              <1> 	; 07/10/2015
 20495 0000436F 891D[D46C0000]      <1> 	mov	[u.break], ebx ; virtual address !!!
 20496                              <1> 	;
 20497 00004375 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
 20498                              <1> 			   ; with top of user's stack (virtual!)
 20499 00004377 7327                <1> 	jnb	short sysbreak_3
 20500                              <1> 		; cmp r1,sp / is it the same or higher 
 20501                              <1> 			  ; / than the stack?
 20502                              <1> 		; bhis 1f / yes, 1f
 20503 00004379 89DE                <1> 	mov	esi, ebx
 20504 0000437B 29EE                <1> 	sub	esi, ebp ; new break point - old break point
 20505 0000437D 7621                <1> 	jna	short sysbreak_3 
 20506                              <1> 	;push	ebx
 20507                              <1> sysbreak_1:
 20508 0000437F 89EB                <1> 	mov	ebx, ebp  
 20509 00004381 E841E4FFFF          <1> 	call	get_physical_addr ; get physical address
 20510 00004386 0F826DFEFFFF        <1> 	jc	tr_addr_nm_err
 20511                              <1> 	; 18/10/2015
 20512 0000438C 89C7                <1> 	mov	edi, eax 
 20513 0000438E 29C0                <1> 	sub	eax, eax ; 0
 20514                              <1> 		 ; ECX = remain byte count in page (1-4096)
 20515 00004390 39CE                <1> 	cmp	esi, ecx
 20516 00004392 7302                <1> 	jnb	short sysbreak_2
 20517 00004394 89F1                <1> 	mov	ecx, esi
 20518                              <1> sysbreak_2:
 20519 00004396 29CE                <1> 	sub	esi, ecx
 20520 00004398 01CD                <1> 	add	ebp, ecx
 20521 0000439A F3AA                <1> 	rep 	stosb
 20522 0000439C 09F6                <1> 	or	esi, esi
 20523 0000439E 75DF                <1> 	jnz	short sysbreak_1
 20524                              <1> 	;
 20525                              <1> 		; bit $1,r1 / is it an odd address
 20526                              <1> 		; beq 2f / no, its even
 20527                              <1> 		; clrb (r1)+ / yes, make it even
 20528                              <1> 	; 2: / clear area between the break point and the stack
 20529                              <1> 		; cmp r1,sp / is it higher or same than the stack
 20530                              <1> 		; bhis 1f / yes, quit
 20531                              <1> 		; clr (r1)+ / clear word
 20532                              <1> 		; br 2b / go back
 20533                              <1> 	;pop	ebx
 20534                              <1> sysbreak_3: ; 1:
 20535                              <1> 	;mov	[u.break], ebx ; virtual address !!!
 20536                              <1> 		; jsr r0,arg; u.break / put the "address" 
 20537                              <1> 			; / in u.break (set new break point)
 20538                              <1> 		; br sysret4 / br sysret
 20539 000043A0 E9E0EDFFFF          <1> 	jmp	sysret
 20540                              <1> 
 20541                              <1> maknod: 
 20542                              <1> 	; 18/07/2022
 20543                              <1> 	; 12/03/2022
 20544                              <1> 	; 11/03/2022
 20545                              <1> 	; 14/02/2022
 20546                              <1> 	; 10/01/2022
 20547                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20548                              <1> 	; 06/11/2021 (Retro UNIX 386 v2)
 20549                              <1> 	; 15/08/2021
 20550                              <1> 	; 06/05/2021
 20551                              <1> 	; 02/05/2021
 20552                              <1> 	; 01/04/2021
 20553                              <1> 	; 27/03/2021
 20554                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 20555                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20556                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 20557                              <1> 	;
 20558                              <1> 	; 'maknod' creates an i-node and makes a directory entry
 20559                              <1> 	; for this i-node in the current directory.
 20560                              <1> 	;
 20561                              <1> 	; INPUTS ->
 20562                              <1> 	;    r1 - contains mode
 20563                              <1> 	;    ii - current directory's i-number	
 20564                              <1> 	;    	
 20565                              <1> 	; OUTPUTS ->
 20566                              <1> 	;    u.dirbuf - contains i-number of free i-node 
 20567                              <1> 	;    i.flgs - flags in new i-node 
 20568                              <1> 	;    i.uid - filled with u.uid
 20569                              <1> 	;    i.nlks - 1 is put in the number of links
 20570                              <1> 	;    i.ctim - creation time
 20571                              <1> 	;    i.ctim+2 - modification time
 20572                              <1> 	;    imod - set via call to setimod
 20573                              <1> 	;	
 20574                              <1> 	; ((AX = R1)) input
 20575                              <1> 	;
 20576                              <1> 	; (Retro UNIX Prototype : 
 20577                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
 20578                              <1>         ; ((Modified registers: eax, edx, ebx, ecx, esi, edi, ebp))
 20579                              <1> 
 20580                              <1> 	; 27/03/2021
 20581                              <1> 	; INPUT:
 20582                              <1>  	;	AX = mode
 20583                              <1> 	;
 20584                              <1> 	; ('maknod' is called by 'syscreat' and 'sysmkdir')
 20585                              <1> 	; (('syscreat' and 'sysmkdir' will set AX input))
 20586                              <1> 
 20587                              <1> 	; 27/03/2021
 20588                              <1> 	; Retro UNIX 386 v2 inode mode flags (ref: 'ux.s')
 20589                              <1> 	; for File Inode: (high byte)
 20590                              <1> 	;   IFREG - 1 = regular file (8000h)
 20591                              <1> 	;   IFDIR - 1 = directory (4000h)
 20592                              <1> 	;   IRSVD - 0 = reserved bit (2000h) ; Mounted flag for dirs
 20593                              <1> 	;   ILARG - large file addressing bit (1000h)
 20594                              <1> 	;   ISUID - set user id on exec (800h)
 20595                              <1> 	;   ISGID - set group id on exec (400h)
 20596                              <1> 	;   IEXTT - 1 = use extents (200h)
 20597                              <1> 	;   IREAD - read, owner (100h)
 20598                              <1> 	; for Device Inode: (high byte)
 20599                              <1> 	;   IFREG - 0 = device file (8000h)
 20600                              <1> 	;   IFBLK - 1 = block device (4000h)
 20601                              <1> 	;   IFCHR - character special (2000h) -always 1-
 20602                              <1> 	;   IFIFO - fifo special (1000h)
 20603                              <1> 	;   IPIPE - pipe special (800h) ; 07/02/2020
 20604                              <1> 	;   IREDIR - redirected (400h)  ; 07/02/2020
 20605                              <1> 	;   IEXTR - 1 = external device driver (200h)
 20606                              <1> 	;   IREAD - read, owner (100h)
 20607                              <1> 
 20608                              <1> 	;; / r1 contains the mode
 20609                              <1> 	;or 	ah, 80h	; 10000000b
 20610                              <1> 	;	; bis $100000,r1 / allocate flag set
 20611                              <1> 
 20612                              <1> 	; 14/02/2022
 20613                              <1> 	; input ->
 20614                              <1> 	;   [u.namep] points to the file name address
 20615                              <1> 	;	     (in the user's memory space)
 20616                              <1> 	;   [u.dirp] points to empty slot in the directory
 20617                              <1> 
 20618                              <1> 	; high 3 bit will be checked here
 20619                              <1> 	; 	(ref: unix v7 x86 source, iget.c)
 20620                              <1> 
 20621                              <1> ;	; 27/03/2021
 20622                              <1> ;	test	ah, 0E0h ; 80h+40h+20h
 20623                              <1> ;	jnz	short maknod0	
 20624                              <1> ;
 20625                              <1> ;	; ('syscreat' clears ILARG & IEXTT bits)
 20626                              <1> ;	;and	ah, ~0Ch ; clear ILARG & IEXTT bits
 20627                              <1> ;	;	; user can set ISUID & ISGID bits
 20628                              <1> ;
 20629                              <1> ;	or	ah, 80h ; IFREG
 20630                              <1> ;maknod0:
 20631 000043A5 50                  <1> 	push	eax ; ***** ; 27/03/2021 (32 bit push, pop)
 20632                              <1> 		; mov r1,-(sp) / put mode on stack
 20633                              <1> 	; 31/07/2013
 20634                              <1> 	;mov	ax, [ii] ; move current i-number to AX/r1
 20635                              <1> 	;	; mov ii,r1 / move current i-number to r1
 20636                              <1> 	;mov	dl, 1 ; owner flag mask
 20637                              <1> 	; 15/08/2021
 20638                              <1> 	;movzx	eax, word [ii] ; move current i-number to EAX
 20639                              <1> 	; 09/01/2022
 20640 000043A6 A1[7C6C0000]        <1> 	mov	eax, [ii] ; move current i-number to EAX
 20641                              <1> 	; 25/03/2021
 20642 000043AB 66BA8000            <1> 	mov	dx, 80h	; IWRITE - write,owner
 20643 000043AF E8AB080000          <1> 	call	access	
 20644                              <1> 		; jsr r0,access; 1 / get its i-node into core
 20645                              <1> 	; 15/08/2021
 20646                              <1> 	; NOTE: cpu will not return here if there is a permission error
 20647                              <1> 	;	(it will jump to 'error' address from/in 'access')
 20648                              <1> 	
 20649 000043B4 50                  <1> 	push	eax ; **** (parent) ; 27/03/2021 (32 bit push, pop)
 20650                              <1> 		; mov r1,-(sp) / put i-number on stack
 20651                              <1> 	;mov	ax, 40
 20652                              <1> 	;	; mov $40.,r1 / r1 = 40
 20653                              <1> 	; 27/03/2021
 20654 000043B5 31C0                <1> 	xor	eax, eax
 20655                              <1> 	;;dec	ax ; 0FFFFh
 20656                              <1> 	; 15/08/2021
 20657                              <1> 	;dec	eax ; 0FFFFFFFFh
 20658                              <1> 	; 01/04/2021
 20659                              <1> ;maknod1: ; 1: / scan for a free i-node (next 4 instructions)
 20660                              <1> 	;;inc	ax
 20661                              <1> 	;	; inc r1 / r1 = r1 + 1
 20662                              <1> 	; 15/08/2021
 20663                              <1> 	;inc	eax
 20664                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 20665                              <1> 	; eax = 0 -> start from first free inode
 20666                              <1> 	; eax > 0 -> locate this inode on the inode map buffer
 20667                              <1> 	; NOTE:
 20668                              <1> 	; Retro UNIX 386 v2 'imap' is mostly different than v1 'imap'
 20669                              <1> 	; ('imap' will not check inode table)
 20670 000043B7 E8980A0000          <1> 	call	imap
 20671                              <1> 		; jsr r0,imap / get byte address and bit position in 
 20672                              <1> 			    ; /	inode map in r2 & m
 20673                              <1> 	; 09/01/2022
 20674                              <1> 	; (cpu will not return here if there would be an eror in imap)
 20675                              <1> 	; 15/08/2021
 20676                              <1> 	;jc	short maknod_err
 20677                              <1> 
 20678                              <1> 	; DX (MQ) has a 1 in the calculated bit position
 20679                              <1>         ; eBX (R2) has byte address of the byte with allocation bit
 20680                              <1> 
 20681                              <1> 	; 06/11/2021
 20682                              <1> 	; ebp = superblock buffer address
 20683                              <1> 	; eax = inode number
 20684                              <1> 	; 10/01/2022
 20685                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
 20686                              <1> 	;		of current IMAP sector	
 20687                              <1> 
 20688                              <1> 	; 27/03/2021
 20689                              <1> 	; If cpu is here, there is not an error
 20690                              <1> 	; and EBX points to inode map buffer
 20691                              <1> 	; DL has 1 at bit position which is for free inode
 20692                              <1> 	; (E)AX = inode number
 20693                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 20694                              <1> 	; ECX = byte offset from the (start of) inode map buffer
 20695                              <1> 
 20696                              <1> 	; 15/08/2021
 20697                              <1> maknod1:
 20698                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
 20699                              <1> 	;	       Inode count must be checked here
 20700                              <1> 	; (Original UNIX v1 did not check inode count here !?)
 20701 000043BC 8413                <1> 	test	[ebx], dl
 20702                              <1> 		; bitb mq,(r2) / is the i-node active
 20703                              <1> 	;jnz	short maknod1
 20704                              <1> 	;	; bne 1b / yes, try the next one
 20705                              <1> 	; 15/08/2021
 20706 000043BE 7408                <1> 	jz	short maknod3 ; free inode (inactive inode)
 20707                              <1> maknod2:
 20708 000043C0 40                  <1> 	inc	eax
 20709 000043C1 E8B20A0000          <1> 	call	imap_x ; next call to imap (bypass 1st call code)
 20710                              <1> 	; 10/01/2022
 20711                              <1> 	; (cpu will/would not return here 
 20712                              <1> 	;  if there is/was an error in 'imap_x')
 20713                              <1> 	;jnc	short maknod1
 20714 000043C6 EBF4                <1> 	jmp	short maknod1
 20715                              <1> 
 20716                              <1> 	; 14/02/2022
 20717                              <1> ;maknod_err:
 20718                              <1> ;	; 15/08/2021
 20719                              <1> ;	;pop	edx  ; two pops for stack alignment
 20720                              <1> ;	;pop	edx  ; (may not be needed while jumping to 'error')
 20721                              <1> ;	mov	[u.error], eax
 20722                              <1> ;	jmp	error
 20723                              <1> maknod3:
 20724                              <1> 	; 10/01/2022
 20725                              <1> 	; ebp = superblock buffer address
 20726                              <1> 	; eax = (free) inode number
 20727                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
 20728                              <1> 	;			of current IMAP sector
 20729                              <1> 	; EBX = buffer address/offset for relevant alloc byte
 20730                              <1> 	;  DL has 1 at bit position which is for free inode
 20731                              <1> 	;
 20732                              <1> 	; ECX = byte offset from the (start of) inode map buffer
 20733                              <1> 
 20734                              <1> 	;mov	[ebp+SB.LastInode], eax ; (free) inode number
 20735                              <1> 
 20736 000043C8 50                  <1> 	push	eax ; ***
 20737 000043C9 51                  <1> 	push	ecx ; **
 20738 000043CA 52                  <1> 	push	edx ; *
 20739                              <1> 	; 18/07/2022
 20740                              <1> 	;push	ebp ; @ ; 11/03/2022
 20741                              <1> 
 20742 000043CB 8B457C              <1> 	mov	eax, [ebp+SB.ImapBuffer]
 20743                              <1> 
 20744 000043CE E821160000          <1> 	call	wslot
 20745                              <1> 	; ebx = buffer data address (write operation bit is set)
 20746                              <1> 	; eax = physical sector number
 20747                              <1> 	; Note: ebx contains addr of the 1st buffer in the buf chain
 20748                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 20749                              <1> 
 20750                              <1> 	; 18/07/2022
 20751                              <1> 	;pop	ebp ; @ ; 11/03/2022
 20752                              <1> 
 20753                              <1> 	;mov	[ebp+SB.ImapBuffer], ebx
 20754                              <1> 			; save inode map buffer address
 20755 000043D3 5A                  <1> 	pop	edx ; *
 20756 000043D4 59                  <1> 	pop	ecx ; **
 20757 000043D5 01CB                <1> 	add	ebx, ecx ; + byte offset (for allocation bit pos)	
 20758                              <1> 
 20759                              <1> 	; set allocation bit (for this new inode) ; 10/01/2022 
 20760 000043D7 0813                <1> 	or	[ebx], dl
 20761                              <1> 		; bisb mq,(r2) / no, make it active 
 20762                              <1> 			     ; / (put a 1 in the bit map)
 20763                              <1> 	;push	ebp ; @
 20764 000043D9 E823160000          <1> 	call	dskwr ; writes the 1st buffer to sector
 20765                              <1> 		      ; (at the beginning/head of the buffer chain)
 20766                              <1> 	;pop	ebp ; @
 20767                              <1> 
 20768                              <1> 	; if we are here, buffer has been written to disk successfully 
 20769                              <1> 	; (otherwise cpu would jump to 'error' address)
 20770                              <1> 
 20771                              <1> 	; set superblock modified flag
 20772 000043DE BA[966C0000]        <1> 	mov	edx, smod
 20773 000043E3 F605[816C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 20774 000043EA 7401                <1> 	jz	short maknod4 ; no, root device
 20775                              <1> 	; yes, mounted device
 20776                              <1> 	;mov	edx, mmod
 20777 000043EC 42                  <1> 	inc	edx ; edx = offset mmod
 20778                              <1> maknod4: 
 20779 000043ED FE02                <1> 	inc	byte [edx] ; superblock modified !
 20780                              <1> 
 20781                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20782                              <1> 	;;
 20783                              <1> 	;; 27/03/2021
 20784                              <1> 	;; (ref: 'UNIXHDCP.ASM', 'mak_nod', 18/01/2020)
 20785                              <1> 	;or	byte [smod], 2 ; inode map modified
 20786                              <1> 	;; 01/04/2021
 20787                              <1> 	;;or	byte [imapbuf_hdr+bufhdr.status], 2
 20788                              <1> 	;or	byte [imapbuf_hdr], 2 ; set modified flag bit
 20789                              <1> 	; 02/05/2021
 20790                              <1> 	;or	byte [esi+ldrv.b_status], 2 ; inode map modified
 20791                              <1> 	; 15/08/2021
 20792                              <1> 	; 06/05/2021
 20793                              <1> 	;or	byte [esi+ldrv.status], 2 ; inode map modified
 20794                              <1> 	;;or	byte [sysbuf_hdr], 2 ; set modified flag bit
 20795                              <1> 	
 20796                              <1> 	;mov	eax, [ebp+SB.LastInode] ; (free) inode number
 20797                              <1> 	;push	eax ; ***
 20798                              <1> 
 20799                              <1> 	; 12/03/2022
 20800                              <1> 	; increase first free inode number
 20801 000043EF 8B0424              <1> 	mov	eax, [esp] ; ***
 20802 000043F2 40                  <1> 	inc	eax ; next inode number 
 20803                              <1> 		    ; (free inode search start value)
 20804 000043F3 894534              <1> 	mov	[ebp+SB.FirstFreeIno], eax
 20805                              <1> 
 20806                              <1> 	; 12/03/2022
 20807                              <1> 	; decrease free inode count
 20808 000043F6 8B5530              <1> 	mov	edx, [ebp+SB.FreeInodes]
 20809                              <1> 	;cmp	edx, 0FFFFFFFFh
 20810                              <1> 	;je	short maknod5 ; invalid
 20811 000043F9 42                  <1> 	inc	edx ; 0FFFFFFFFh -> 0
 20812 000043FA 7405                <1> 	jz	short maknod5 ; invalid
 20813 000043FC 4A                  <1> 	dec	edx
 20814 000043FD 4A                  <1> 	dec	edx
 20815 000043FE 895530              <1> 	mov	[ebp+SB.FreeInodes], edx ; -1
 20816                              <1> maknod5:
 20817 00004401 E851170000          <1> 	call	get_system_time
 20818                              <1> 		; eax = current time (as unix epoch time)
 20819 00004406 89455C              <1> 	mov	[ebp+SB.ModifTime], eax
 20820                              <1> 
 20821 00004409 58                  <1> 	pop	eax ; *** ; inode number
 20822                              <1> 	;;
 20823 0000440A E866070000          <1> 	call	iget
 20824                              <1> 		; jsr r0,iget / get i-node into core
 20825                              <1> 	; 09/01/2022
 20826                              <1> 	;  (If cpu is here, there was/is not an error!)
 20827                              <1> 	; 06/11/2021
 20828                              <1> 	;jc	short maknod_err
 20829                              <1> 	
 20830                              <1> 	;test	word [i.flgs], 8000h 
 20831                              <1> 	;	; tst i.flgs / is i-node already allocated
 20832                              <1> 	;jnz	short maknod1	
 20833                              <1> 	;	; blt 1b / yes, look for another one
 20834                              <1> 	; 27/03/2021
 20835                              <1> 	; (Retro UNIX 386 v2 inode flags) 
 20836 0000440F F605[25680000]E0    <1> 	test	byte [i.flgs+1], 0E0h ; 80h+40h+20h
 20837                              <1> 	;jnz	short maknod1 ; i-node already allocated
 20838                              <1> 	;		      ; (as it is in inode table)
 20839                              <1> 	; 15/08/2021
 20840 00004416 75A8                <1> 	jnz	short maknod2 ; defective inode map !?
 20841                              <1> 
 20842                              <1> 	; AX = free inode number
 20843 00004418 66A3[DC6C0000]      <1> 	mov	[u.dirbuf], ax
 20844                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
 20845 0000441E 58                  <1> 	pop	eax ; **** (parent) ; 27/03/2021 (32 bit push, pop)
 20846                              <1> 		; mov (sp)+,r1 / get current i-number back
 20847 0000441F E851070000          <1> 	call	iget
 20848                              <1> 		; jsr r0,iget / get i-node in core
 20849                              <1> 	; 09/01/2022
 20850                              <1> 	; 06/11/2021
 20851                              <1> 	;jc	short maknod_err
 20852                              <1> 
 20853                              <1> 	; 14/02/2022
 20854                              <1> 	; here..
 20855                              <1> 	;  [u.namep] points to the file name address
 20856                              <1> 	;	     (in the user's memory space)
 20857                              <1> 	;  [u.dirp] points to empty slot in the directory
 20858                              <1> 
 20859 00004424 E81CF7FFFF          <1> 	call	mkdir
 20860                              <1> 		; jsr r0,mkdir / make a directory entry 
 20861                              <1> 			     ; / in current directory
 20862                              <1> 	; 09/01/2022
 20863                              <1> 	;  (If cpu is here, there was/is not an error in 'mkdir'!)
 20864                              <1> 	; 06/11/2021
 20865                              <1> 	;jc	short maknod_err
 20866                              <1> 	
 20867                              <1> 	; (eax = 0)
 20868                              <1> 	;movzx	eax, [u.difbuf] ; 06/11/2021
 20869 00004429 66A1[DC6C0000]      <1> 	mov	ax, [u.dirbuf]
 20870                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
 20871 0000442F E841070000          <1> 	call	iget
 20872                              <1> 		; jsr r0,iget / get it into core
 20873                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
 20874                              <1> 	; 09/01/2022
 20875                              <1> 	; 06/11/2021
 20876                              <1> 	;jc	short maknod_err
 20877                              <1> 
 20878                              <1> 	;mov	ecx, 8
 20879                              <1> 	; 27/03/2021
 20880 00004434 31C9                <1> 	xor	ecx, ecx 
 20881 00004436 B110                <1> 	mov	cl, 16 ; 64 bit inodes
 20882 00004438 31C0                <1> 	xor	eax, eax ; 0
 20883 0000443A BF[24680000]        <1> 	mov	edi, inode 
 20884 0000443F F3AB                <1> 	rep	stosd
 20885                              <1> 	;
 20886                              <1> 	;pop	word [i.flgs]
 20887                              <1> 	;	; mov (sp)+,i.flgs / fill flags
 20888                              <1> 	; 27/03/2021 (32 bit push, pop)
 20889 00004441 58                  <1> 	pop	eax ; *****
 20890 00004442 66A3[24680000]      <1> 	mov	[i.flgs], ax
 20891                              <1> 
 20892                              <1> 	;mov 	cl, [u.uid] ; 02/08/2013
 20893                              <1> 	;mov 	[i.uid], cl
 20894                              <1> 	;	; movb u.uid,i.uid / user id
 20895                              <1> 	; 15/08/2021
 20896                              <1> 	; 27/03/2021
 20897 00004448 8A0D[FA6C0000]      <1> 	mov	cl, [u.gid] ; 8 bit group ID ; 15/08/2021
 20898 0000444E 880D[2A680000]      <1> 	mov	[i.gid], cl 	
 20899 00004454 668B0D[F66C0000]    <1> 	mov	cx, [u.uid] ; 16 bit user ID
 20900 0000445B 66890D[28680000]    <1> 	mov	[i.uid], cx	
 20901                              <1> 
 20902 00004462 C605[26680000]01    <1> 	mov     byte [i.nlks], 1
 20903                              <1> 		; movb $1,i.nlks / 1 link
 20904                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
 20905                              <1> 	;mov	eax, [s.time]
 20906                              <1> 	;mov 	[i.ctim], eax
 20907                              <1> 	 	; mov s.time,i.ctim / time created
 20908                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
 20909                              <1> 	; Retro UNIX 8086 v1 modification !
 20910                              <1> 	; i.ctime=0, i.ctime+2=0 and
 20911                              <1>         ; 'setimod' will set ctime of file via 'epoch'
 20912                              <1> 	;call	setimod
 20913                              <1> 	;	; jsr r0,setimod / set modified flag
 20914                              <1> 	;retn
 20915                              <1> 	;	; rts r0 / return
 20916                              <1> 	; 27/03/2021
 20917 00004469 E998080000          <1> 	jmp	setimod
 20918                              <1> 
 20919                              <1> sysseek: ; / moves read write pointer in an fsp entry
 20920                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20921                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 20922                              <1> 	;
 20923                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
 20924                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
 20925                              <1> 	; The file descriptor refers to a file open for reading or
 20926                              <1> 	; writing. The read (or write) pointer is set as follows:
 20927                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
 20928                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
 20929                              <1> 	;	  current location plus offset.
 20930                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
 20931                              <1> 	;	  size of file plus offset.
 20932                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
 20933                              <1> 	;
 20934                              <1> 	; Calling sequence:
 20935                              <1> 	;	sysseek; offset; ptrname
 20936                              <1> 	; Arguments:
 20937                              <1> 	;	offset - number of bytes desired to move 
 20938                              <1> 	;		 the r/w pointer
 20939                              <1> 	;	ptrname - a switch indicated above
 20940                              <1> 	;
 20941                              <1> 	; Inputs: r0 - file descriptor 
 20942                              <1> 	; Outputs: -
 20943                              <1> 	; ...............................................................
 20944                              <1> 	;	
 20945                              <1> 	; Retro UNIX 8086 v1 modification: 
 20946                              <1> 	;       'sysseek' system call has three arguments; so,
 20947                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
 20948                              <1> 	;	* 2nd argument, offset is in CX register
 20949                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
 20950                              <1> 	;	
 20951                              <1> 
 20952 0000446E E820000000          <1> 	call	seektell
 20953                              <1> 	; AX = u.count
 20954                              <1> 	; BX = *u.fofp
 20955                              <1> 		; jsr r0,seektell / get proper value in u.count
 20956                              <1> 		; add u.base,u.count / add u.base to it
 20957 00004473 0305[C86C0000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
 20958 00004479 8903                <1> 	mov	[ebx], eax
 20959                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
 20960 0000447B E905EDFFFF          <1> 	jmp	sysret
 20961                              <1> 		; br sysret4
 20962                              <1> 
 20963                              <1> systell: ; / get the r/w pointer
 20964                              <1> 	; 01/03/2022
 20965                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20966                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20967                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 20968                              <1> 	;
 20969                              <1> 	; Retro UNIX 8086 v1 modification:
 20970                              <1> 	; ! 'systell' does not work in original UNIX v1,
 20971                              <1> 	; 	    it returns with error !
 20972                              <1> 	; Inputs: r0 - file descriptor 
 20973                              <1> 	; Outputs: r0 - file r/w pointer
 20974                              <1> 
 20975                              <1> 	;xor	ecx, ecx ; 0
 20976                              <1> 	;mov	edx, 1 ; 05/08/2013
 20977                              <1> 	; 09/01/2022
 20978 00004480 29D2                <1> 	sub	edx, edx
 20979 00004482 FEC2                <1> 	inc	dl
 20980                              <1> 	; edx = 1
 20981                              <1> 	;call 	seektell
 20982 00004484 E810000000          <1> 	call 	seektell0 ; 05/08/2013
 20983                              <1> 	;mov	ebx, [u.fofp]
 20984                              <1> 	; 01/03/2022
 20985                              <1> 	;mov	eax, [ebx]
 20986 00004489 A3[A46C0000]        <1> 	mov	[u.r0], eax
 20987 0000448E E9F2ECFFFF          <1> 	jmp	sysret
 20988                              <1> 
 20989                              <1> ; Original unix v1 'systell' system call:
 20990                              <1> 		; jsr r0,seektell
 20991                              <1> 		; br error4
 20992                              <1> 
 20993                              <1> seektell:
 20994                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20995                              <1> 	; 06/11/2021
 20996                              <1> 	; 12/06/2021
 20997                              <1> 	; 06/05/2021 (Retro UNIX 386 v2)
 20998                              <1> 	; 03/01/2016
 20999                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21000                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 21001                              <1> 	;
 21002                              <1> 	; 'seektell' puts the arguments from sysseek and systell
 21003                              <1> 	; call in u.base and u.count. It then gets the i-number of
 21004                              <1> 	; the file from the file descriptor in u.r0 and by calling
 21005                              <1> 	; getf. The i-node is brought into core and then u.count
 21006                              <1> 	; is checked to see it is a 0, 1, or 2.
 21007                              <1> 	; If it is 0 - u.count stays the same
 21008                              <1> 	;          1 - u.count = offset (u.fofp)
 21009                              <1> 	;	   2 - u.count = i.size (size of file)
 21010                              <1> 	; 	 		
 21011                              <1> 	; !! Retro UNIX 8086 v1 modification:
 21012                              <1> 	;	Argument 1, file descriptor is in BX;
 21013                              <1> 	;	Argument 2, offset is in CX;
 21014                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
 21015                              <1> 	;
 21016                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
 21017                              <1> 	; call 	arg
 21018                              <1> 	;
 21019                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
 21020                              <1> 	;
 21021 00004493 890D[C86C0000]      <1> 	mov 	[u.base], ecx ; offset
 21022                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
 21023                              <1> 	; 09/01/2022
 21024                              <1> 	; ebx = file descriptor (0 to 9)
 21025                              <1> seektell0:
 21026 00004499 8915[CC6C0000]      <1> 	mov 	[u.count], edx
 21027                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
 21028                              <1> 	;mov	ax, bx
 21029                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
 21030                              <1> 			     ; / (index in u.fp list)
 21031                              <1> 	; 12/06/2021
 21032                              <1> 	; BX = file descriptor (file number)
 21033 0000449F E8A2FBFFFF          <1> 	call	getf
 21034                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
 21035                              <1> 	; 09/01/2022
 21036 000044A4 09C0                <1> 	or	eax, eax
 21037                              <1> 	;or	ax, ax ; i-number of the file
 21038                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
 21039                              <1> 		             ; / put it on the stack
 21040                              <1> 	;jz	error
 21041                              <1> 		; beq error4 / if i-number is 0, not active so error
 21042 000044A6 750F                <1> 	jnz	short seektell1
 21043 000044A8 C705[186D0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 21044 000044B0 0000                <1>
 21045 000044B2 E9AEECFFFF          <1> 	jmp	error
 21046                              <1> seektell1:
 21047                              <1> 	; 06/05/2021
 21048                              <1> 	;push	eax
 21049                              <1> 	;cmp	ah, 80h
 21050                              <1> 	;jb	short seektell2
 21051                              <1> 	;	; bgt .+4 / if its positive jump
 21052                              <1> 	;neg	ax
 21053                              <1> 	;	; neg r1 / if not make it positive
 21054                              <1> seektell2:
 21055 000044B7 E8B9060000          <1> 	call	iget
 21056                              <1> 		; jsr r0,iget / get its i-node into core
 21057                              <1> 	; 09/01/2022
 21058                              <1> 	; (if there is/was an error in 'iget', cpu will not come here)
 21059                              <1> 	;; 06/11/2021
 21060                              <1> 	;jnc	short seektell6
 21061                              <1> 	;mov	[u.error], eax
 21062                              <1> 	;jmp	error
 21063                              <1> seektell6:
 21064 000044BC 8B1D[B86C0000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
 21065 000044C2 803D[CC6C0000]01    <1> 	cmp	byte [u.count], 1
 21066                              <1> 		; cmp u.count,$1 / is ptr name =1
 21067 000044C9 7705                <1> 	ja	short seektell3
 21068                              <1> 		; blt 2f / no its zero
 21069 000044CB 7409                <1> 	je	short seektell4
 21070                              <1> 		; beq 1f / yes its 1
 21071 000044CD 31C0                <1> 	xor	eax, eax
 21072                              <1> 	;jmp	short seektell5
 21073 000044CF C3                  <1> 	retn
 21074                              <1> seektell3:
 21075                              <1> 	; 03/01/2016
 21076                              <1> 	;;movzx	eax, word [i.size]
 21077                              <1> 	;mov   	ax, [i.size]
 21078                              <1> 	;	; mov i.size,u.count /  put number of bytes 
 21079                              <1> 	;			; / in file in u.count
 21080                              <1> 	;;jmp	short seektell5
 21081                              <1> 	;	; br 2f
 21082                              <1> 	; 06/05/2021 - Retro UNIX 386 v2
 21083 000044D0 A1[2C680000]        <1> 	mov	eax, [i.size]
 21084 000044D5 C3                  <1> 	retn
 21085                              <1> seektell4: ; 1: / ptrname =1
 21086                              <1> 	;mov	ebx, [u.fofp]
 21087 000044D6 8B03                <1> 	mov	eax, [ebx]
 21088                              <1> 		; mov *u.fofp,u.count / put offset in u.count
 21089                              <1> ;seektell5: ; 2: / ptrname =0
 21090                              <1> 	;mov	[u.count], eax
 21091                              <1> 	;pop	eax 
 21092                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
 21093 000044D8 C3                  <1> 	retn
 21094                              <1> 		; rts r0
 21095                              <1> 
 21096                              <1> sysintr: ; / set interrupt handling
 21097                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21098                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21099                              <1> 	;
 21100                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
 21101                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
 21102                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
 21103                              <1> 	; If one does the interrupt character in the tty buffer is
 21104                              <1> 	; cleared and 'sysret'is called. If one does not exits
 21105                              <1> 	; 'sysret' is just called.	
 21106                              <1> 	;
 21107                              <1> 	; Calling sequence:
 21108                              <1> 	;	sysintr; arg
 21109                              <1> 	; Argument:
 21110                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
 21111                              <1> 	;	    - if 1, intterupts cause their normal result
 21112                              <1> 	;		 i.e force an exit.
 21113                              <1> 	;	    - if arg is a location within the program,
 21114                              <1> 	;		control is passed to that location when
 21115                              <1> 	;		an interrupt occurs.	
 21116                              <1> 	; Inputs: -
 21117                              <1> 	; Outputs: -
 21118                              <1> 	; ...............................................................
 21119                              <1> 	;	
 21120                              <1> 	; Retro UNIX 8086 v1 modification: 
 21121                              <1> 	;       'sysintr' system call sets u.intr to value of BX
 21122                              <1> 	;	then branches into sysquit.
 21123                              <1> 	;
 21124 000044D9 66891D[F06C0000]    <1> 	mov	[u.intr], bx
 21125                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
 21126                              <1> 		; br 1f / go into quit routine
 21127 000044E0 E9A0ECFFFF          <1> 	jmp	sysret
 21128                              <1> 
 21129                              <1> sysquit:
 21130                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21131                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21132                              <1> 	;
 21133                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
 21134                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
 21135                              <1> 	; tty exists. If one does the interrupt character in the tty
 21136                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
 21137                              <1> 	; 'sysret' is just called.	
 21138                              <1> 	;
 21139                              <1> 	; Calling sequence:
 21140                              <1> 	;	sysquit; arg
 21141                              <1> 	; Argument:
 21142                              <1> 	;	arg - if 0, this call disables quit signals from the
 21143                              <1> 	;		typewriter (ASCII FS)
 21144                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
 21145                              <1> 	;		cease and a core image to be produced.
 21146                              <1> 	;		 i.e force an exit.
 21147                              <1> 	;	    - if arg is an address in the program,
 21148                              <1> 	;		a quit causes control to sent to that
 21149                              <1> 	;		location.	
 21150                              <1> 	; Inputs: -
 21151                              <1> 	; Outputs: -
 21152                              <1> 	; ...............................................................
 21153                              <1> 	;	
 21154                              <1> 	; Retro UNIX 8086 v1 modification: 
 21155                              <1> 	;       'sysquit' system call sets u.quit to value of BX
 21156                              <1> 	;	then branches into 'sysret'.
 21157                              <1> 	;
 21158 000044E5 66891D[F26C0000]    <1> 	mov	[u.quit], bx
 21159 000044EC E994ECFFFF          <1> 	jmp	sysret
 21160                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
 21161                              <1> 	;1:
 21162                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
 21163                              <1> 			      ; / to r1
 21164                              <1> 		; beq sysret4 / return to user
 21165                              <1> 		; clrb 6(r1) / clear the interrupt character 
 21166                              <1> 			   ; / in the tty buffer
 21167                              <1> 		; br sysret4 / return to user
 21168                              <1> 
 21169                              <1> syssetuid: ; / set process id
 21170                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21171                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21172                              <1> 	;		(16 bit uid)
 21173                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21174                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 21175                              <1> 	;
 21176                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
 21177                              <1> 	; to the process id in (u.r0). Both the effective user u.uid
 21178                              <1> 	; and the real user u.ruid are set to this. 
 21179                              <1> 	; Only the super user can make this call.	
 21180                              <1> 	;
 21181                              <1> 	; Calling sequence:
 21182                              <1> 	;	syssetuid
 21183                              <1> 	; Arguments: -
 21184                              <1> 	;
 21185                              <1> 	; Inputs: (u.r0) - contains the process id.
 21186                              <1> 	; Outputs: -
 21187                              <1> 	; ...............................................................
 21188                              <1> 	;	
 21189                              <1> 	; Retro UNIX 8086 v1 modification: 
 21190                              <1> 	;       BL contains the (new) user ID of the current process
 21191                              <1> 
 21192                              <1> 	; 27/03/2021
 21193                              <1> 	; INPUT:
 21194                              <1> 	;    BX = (new) user ID
 21195                              <1> 
 21196                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
 21197                              <1> 	;cmp	bl, [u.ruid] 
 21198                              <1> 	;	; cmpb r1,u.ruid / is it equal to the real user 
 21199                              <1> 			       ; / id number
 21200                              <1> 	; 27/03/2021
 21201 000044F1 663B1D[F86C0000]    <1> 	cmp	bx, [u.ruid]
 21202 000044F8 7420                <1> 	je	short setuid1
 21203                              <1> 		; beq 1f / yes
 21204                              <1> 	;cmp	byte [u.uid], 0 ; 02/08/2013
 21205                              <1> 	;	; tstb u.uid / no, is current user the super user?
 21206                              <1> 	;;ja	error
 21207                              <1> 	;	; bne error4 / no, error
 21208                              <1> 	; 27/03/2021
 21209 000044FA 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0 
 21210 00004502 760F                <1> 	jna	short setuid0
 21211                              <1> setuid_err:
 21212                              <1> setgid_err:
 21213 00004504 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
 21214 0000450C 0000                <1>
 21215                              <1> 				; 'permission denied !' error
 21216 0000450E E952ECFFFF          <1> 	jmp	error
 21217                              <1> setuid0:
 21218                              <1> 	;mov	[u.ruid], bl
 21219                              <1> 	; 27/03/2021
 21220 00004513 66891D[F86C0000]    <1> 	mov	[u.ruid], bx
 21221                              <1> setuid1: ; 1:
 21222                              <1> 	;mov	[u.uid], bl ; 02/08/2013
 21223                              <1> 	;	; movb r1,u.uid / put process id in u.uid
 21224                              <1> 	;	; movb r1,u.ruid / put process id in u.ruid
 21225                              <1> 	; 27/03/2021
 21226 0000451A 66891D[F66C0000]    <1> 	mov	[u.uid], bx
 21227 00004521 E95FECFFFF          <1> 	jmp	sysret
 21228                              <1> 		; br sysret4 / system return
 21229                              <1> 
 21230                              <1> sysgetuid: ; < get user id >
 21231                              <1> 	; 11/03/2022
 21232                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21233                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21234                              <1> 	;		(16 bit uid)
 21235                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21236                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21237                              <1> 	;
 21238                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
 21239                              <1> 	; The real user ID identifies the person who is logged in,
 21240                              <1> 	; in contradistinction to the effective user ID, which
 21241                              <1> 	; determines his access permission at each moment. It is thus
 21242                              <1> 	; useful to programs which operate using the 'set user ID'
 21243                              <1> 	; mode, to find out who invoked them.	
 21244                              <1> 	;
 21245                              <1> 	; Calling sequence:
 21246                              <1> 	;	syssetuid
 21247                              <1> 	; Arguments: -
 21248                              <1> 	;
 21249                              <1> 	; Inputs: -
 21250                              <1> 	; Outputs: (u.r0) - contains the real user's id.
 21251                              <1> 	; ...............................................................
 21252                              <1> 	;	
 21253                              <1> 	; Retro UNIX 8086 v1 modification: 
 21254                              <1> 	;       AL contains the real user ID at return.
 21255                              <1> 	;
 21256                              <1> 	; 11/03/2022 - Retro UNIX 386 v1.2
 21257                              <1> 	; Input:
 21258                              <1> 	;	none
 21259                              <1> 	; Output/Return:
 21260                              <1> 	;	AX = real user ID
 21261                              <1> 	;	Hig Word of EAX = effective user ID
 21262                              <1> 
 21263                              <1> 	;;movzx eax, byte [u.ruid]
 21264                              <1> 	; 27/03/2021
 21265                              <1> 	;movzx	eax, word [u.ruid]
 21266                              <1> 	; 11/03/2022
 21267                              <1> 	; (return u.uid & u.ruid numbers as it is in unix v5-v7)
 21268 00004526 66A1[F66C0000]      <1> 	mov	ax, [u.uid]
 21269 0000452C C1E010              <1> 	shl	eax, 16	; efective user ID in high word of eax
 21270                              <1> 	; 09/01/2022
 21271 0000452F 66A1[F86C0000]      <1> 	mov	ax, [u.ruid] ; real user ID in low word of eax
 21272 00004535 A3[A46C0000]        <1> 	mov	[u.r0], eax 
 21273                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
 21274 0000453A E946ECFFFF          <1> 	jmp	sysret
 21275                              <1> 		; br sysret4 / systerm return, sysret
 21276                              <1> 
 21277                              <1> syssetgid: ; set group id
 21278                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21279                              <1> 	; 02/04/2021
 21280                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21281                              <1> 	;
 21282                              <1> 	; 'syssetgid' sets the user's group id (u.gid) 
 21283                              <1> 	;  of the current process to the process id in (u.r0).
 21284                              <1> 	;  Both the effective user u.gid and the real user
 21285                              <1> 	;  u.rgid are set to this. 
 21286                              <1> 	;  Only the super user can make this call.	
 21287                              <1> 	
 21288                              <1> 	; INPUT:
 21289                              <1> 	;	BL = (new) group ID
 21290                              <1> 	; OUTPUT:
 21291                              <1> 	;	-
 21292                              <1> 
 21293 0000453F 3A1D[FB6C0000]      <1> 	cmp	bl, [u.rgid] 
 21294 00004545 7410                <1> 	je	short setgid1
 21295                              <1> 
 21296                              <1> 	;cmp	byte [u.uid], 0
 21297                              <1> 	; 02/04/2021
 21298 00004547 66833D[F66C0000]00  <1> 	cmp	word [u.uid], 0
 21299 0000454F 77B3                <1> 	ja	short setgid_err
 21300                              <1> setgid0:
 21301 00004551 881D[FB6C0000]      <1> 	mov	[u.rgid], bl
 21302                              <1> setgid1: ; 1:
 21303 00004557 881D[FA6C0000]      <1> 	mov	[u.gid], bl
 21304 0000455D E923ECFFFF          <1> 	jmp	sysret
 21305                              <1> 
 21306                              <1> sysgetgid: ; < get group id >
 21307                              <1> 	; 11/03/2022
 21308                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21309                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21310                              <1> 	;
 21311                              <1> 	; 'sysgetgid' returns the real group ID of the current process.
 21312                              <1> 	; The real group ID identifies the group of the person
 21313                              <1> 	; who is logged in, in contradistinction to the effective
 21314                              <1> 	; group ID, which determines his access permission at each moment.
 21315                              <1> 	; It is thus useful to programs which operate using
 21316                              <1> 	; the 'set group ID' mode, to find out the group of the user
 21317                              <1> 	; who invoked them.
 21318                              <1> 
 21319                              <1> 	; 11/03/2022 - Retro UNIX 386 v1.2
 21320                              <1> 	; Input:
 21321                              <1> 	;	none
 21322                              <1> 	; Output/Return:
 21323                              <1> 	;	AL = real group ID
 21324                              <1> 	;	AH = effective group ID
 21325                              <1> 
 21326                              <1> 	;movzx	eax, word [u.ruid]
 21327                              <1> 	;; 09/01/2022
 21328                              <1> 	;mov	ax, [u.ruid]
 21329                              <1> 	; 11/03/2022
 21330                              <1> 	; (return u.gid & u.rgid numbers as it is in unix v5-v7)
 21331 00004562 8A25[FA6C0000]      <1> 	mov	ah, [u.gid] ; efective group ID in byte 1
 21332 00004568 A0[FB6C0000]        <1> 	mov	al, [u.rgid] ; real group ID in byte 0
 21333 0000456D A3[A46C0000]        <1> 	mov	[u.r0], eax
 21334 00004572 E90EECFFFF          <1> 	jmp	sysret
 21335                              <1> 
 21336                              <1> sysver: ; get operating system version
 21337                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21338                              <1> 	; 18/06/2021 - Retro UNIX 386 v2
 21339                              <1> 
 21340                              <1> 	;VMAJOR equ 2 ; Retro UNIX 386 v2
 21341                              <1> 	;VMINOR equ 0 ; Retro UNIX 386 v2.0 (v2.0.0)
 21342                              <1> 	;CURRENT_VERSION equ (VMAJOR*256)+VMINOR
 21343                              <1> 
 21344                              <1> 	; 09/01/2022
 21345                              <1> 	VMAJOR equ 1 ; Retro UNIX 386 v1
 21346                              <1> 	VMINOR equ 2 ; Retro UNIX 386 v1.2 (v1.2.0)
 21347                              <1> 	CURRENT_VERSION equ (VMAJOR*256)+VMINOR 		  
 21348                              <1> 
 21349                              <1> 	; 29/04/2016 - TRDOS 386 v2.0
 21350                              <1> 	;mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
 21351                              <1> 	; 18/06/2021
 21352 00004577 C705[A46C0000]0201- <1> 	mov	dword [u.r0], CURRENT_VERSION ;	(ah = 2, al = 0)
 21353 0000457F 0000                <1>
 21354 00004581 E9FFEBFFFF          <1> 	jmp	sysret
 21355                              <1> 
 21356                              <1> anyi: 
 21357                              <1> 	; 18/07/2022
 21358                              <1> 	; 26/03/2022
 21359                              <1> 	; 13/03/2022
 21360                              <1> 	; 12/03/2022
 21361                              <1> 	; 09/01/2022
 21362                              <1> 	; 02/01/2022
 21363                              <1> 	; 01/01/2022
 21364                              <1> 	; 27/12/2021 (Retro UNIX 386 v1.2)
 21365                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 21366                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21367                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
 21368                              <1> 	;
 21369                              <1> 	; 'anyi' is called if a file deleted while open.
 21370                              <1> 	; "anyi" checks to see if someone else has opened this file.
 21371                              <1> 	;
 21372                              <1> 	; INPUTS ->
 21373                              <1> 	;    r1 - contains an i-number
 21374                              <1> 	;    fsp - start of table containing open files
 21375                              <1> 	;
 21376                              <1> 	; OUTPUTS ->
 21377                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
 21378                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
 21379                              <1> 	;    if file not found - bit in i-node map is cleared
 21380                              <1> 	;    			 (i-node is freed)
 21381                              <1> 	;               all blocks related to i-node are freed
 21382                              <1> 	;	        all flags in i-node are cleared
 21383                              <1> 	; ((AX = R1)) input
 21384                              <1> 	;
 21385                              <1> 	;    (Retro UNIX Prototype: 02/12/2012, UNIXCOPY.ASM)
 21386                              <1> 	;	12/03/2022
 21387                              <1>         ;    ((Modified registers: eax, edx, ecx, ebx, esi, edi, ebp))  
 21388                              <1> 	;
 21389                              <1> 		; / r1 contains an i-number
 21390 00004586 BB[14690000]        <1> 	mov	ebx, fsp
 21391                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
 21392                              <1> anyi_1: ; 1:
 21393                              <1> 	;cmp	eax, [ebx] ; 09/01/2022 (32 bit inode number)
 21394 0000458B 663B03              <1> 	cmp	ax, [ebx]
 21395                              <1> 		; cmp r1,(r2) / do i-numbers match?
 21396                              <1> 	;je	short anyi_3
 21397                              <1> 		; beq 1f / yes, 1f
 21398                              <1> 	; 12/03/2022
 21399 0000458E 7505                <1> 	jne	short anyi_0		
 21400                              <1> 
 21401                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21402                              <1> 	;neg	ax
 21403                              <1> 	;	; neg r1 / no complement r1
 21404                              <1> 	;cmp	ax, [ebx]
 21405                              <1> 	;	; cmp r1,(r2) / do they match now?
 21406                              <1> 	;;je	short anyi_3
 21407                              <1> 		; beq 1f / yes, transfer
 21408                              <1> 		; / i-numbers do not match
 21409                              <1> 	; 12/03/2022
 21410                              <1> 	;jne	short ayni_0
 21411                              <1> 
 21412                              <1> anyi_3: ; 1: / i-numbers match
 21413                              <1> 	; 13/03/2022 (BugFix)
 21414                              <1> 	;; 09/01/2022
 21415                              <1> 	;test	byte [ebx+5], 1 ; open for writing flag
 21416                              <1> 	;jz	short anyi_0	
 21417                              <1> 
 21418                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21419 00004590 804B0580            <1> 	or	byte [ebx+5], 80h ; set deleted file flag (bit 7)
 21420                              <1> 	; 22/06/2015
 21421                              <1> 	;inc 	byte [ebx+9]
 21422                              <1> 		; incb 7(r2) / increment upper byte of the 4th word
 21423                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
 21424 00004594 C3                  <1> 	retn
 21425                              <1> 		; rts r0
 21426                              <1> anyi_0:
 21427                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21428                              <1> 	;add	ebx, fp.size ; runix v2 fsp table size is 16 bytes
 21429                              <1> 	; 01/01/2022
 21430 00004595 83C310              <1> 	add	ebx, 16 ; runix v2 fsp table size is 16 bytes
 21431                              <1> 	;;add	ebx, 10 ; fsp table size is 10 bytes
 21432                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
 21433                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
 21434                              <1> 	; 22/11/2021
 21435                              <1> 	;cmp	ebx, fsp + (NFILES*fp.size) ; fsp+(NFILES*16)
 21436                              <1> 	; 02/01/2022
 21437 00004598 81FB[346C0000]      <1> 	cmp	ebx, fsp + (nfiles*16)
 21438                              <1> 	; 01/01/2022
 21439                              <1> 	;cmp	ebx, fsp + (NFILES*16) ; fsp+(NFILES*fp.size)
 21440                              <1> 	;;cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
 21441                              <1> 		; cmp r2,$fsp+[nfiles*8] 
 21442                              <1> 			; / are we at last entry in the table
 21443 0000459E 72EB                <1> 	jb	short anyi_1
 21444                              <1> 		; blt 1b / no, check next entries i-number
 21445                              <1> 
 21446                              <1> 	; 27/12/2021
 21447                              <1> 	;;cmp	ax, 32768
 21448                              <1> 	;cmp	ah, 80h ; negative number check
 21449                              <1> 	;	; tst r1 / yes, no match
 21450                              <1> 	;	; bge .+4
 21451                              <1> 	;jb	short anyi_2
 21452                              <1> 	;neg	ax
 21453                              <1> 	;	; neg r1 / make i-number positive
 21454                              <1> ;anyi_2:	
 21455                              <1> 	; 12/03/2022
 21456                              <1> 	;push	eax ; **** ; inode number
 21457                              <1> 	;
 21458 000045A0 E8AF080000          <1> 	call	imap
 21459                              <1> 		; jsr r0,imap / get address of allocation bit 
 21460                              <1> 			    ; / in the i-map in r2
 21461                              <1> 
 21462                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
 21463                              <1>         ;; EBX (R2) has address of the byte with allocation bit
 21464                              <1> 
 21465                              <1> 	; 12/03/2022
 21466                              <1> 	; (at return of imap)
 21467                              <1> 	; ebp = superblock buffer address
 21468                              <1> 	; eax = inode number
 21469                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
 21470                              <1> 	;			of current IMAP sector
 21471                              <1> 	; EBX = buffer address/offset for relevant alloc byte
 21472                              <1> 	;  DL has 1 at bit position which is for free inode
 21473                              <1> 	;
 21474                              <1> 	; ECX = byte offset from the (start of) inode map buffer
 21475                              <1> 
 21476                              <1>  	;;not	dx
 21477                              <1> 	;not 	dl ; 0 at calculated bit position, other bits are 1
 21478                              <1>         ;;and	[ebx], dx
 21479                              <1> 	;and 	[ebx], dl 
 21480                              <1> 	;	; bicb mq,(r2) / clear bit for i-node in the imap
 21481                              <1> 
 21482                              <1> 	; 12/03/2022 ; (*)
 21483                              <1> 
 21484                              <1> 	;mov	[ebp+SB.LastInode], eax ; (free) inode number
 21485                              <1> 
 21486 000045A5 50                  <1> 	push	eax ; ***
 21487 000045A6 51                  <1> 	push	ecx ; **
 21488 000045A7 52                  <1> 	push	edx ; *
 21489                              <1> 
 21490                              <1> 	; 18/07/2022
 21491                              <1> 	;push	ebp ; @ ; 11/03/2022
 21492                              <1> 
 21493 000045A8 8B457C              <1> 	mov	eax, [ebp+SB.ImapBuffer]
 21494                              <1> 
 21495 000045AB E844140000          <1> 	call	wslot
 21496                              <1> 	; ebx = buffer data address (write operation bit is set)
 21497                              <1> 	; eax = physical sector number
 21498                              <1> 	; Note: ebx contains addr of the 1st buffer in the buf chain
 21499                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 21500                              <1> 
 21501                              <1> 	; 18/07/2022
 21502                              <1> 	;pop	ebp ; @ ; 11/03/2022
 21503                              <1> 
 21504                              <1> 	;mov	[ebp+SB.ImapBuffer], ebx
 21505                              <1> 			; save inode map buffer address
 21506 000045B0 5A                  <1> 	pop	edx ; *
 21507 000045B1 59                  <1> 	pop	ecx ; **
 21508 000045B2 01CB                <1> 	add	ebx, ecx ; + byte offset (for allocation bit pos)	
 21509                              <1> 
 21510                              <1> 	;not	dx
 21511 000045B4 F6D2                <1> 	not 	dl ; 0 at calculated bit position, other bits are 1
 21512                              <1>         ;and	[ebx], dx
 21513 000045B6 2013                <1> 	and 	[ebx], dl 
 21514                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
 21515                              <1> 
 21516                              <1> 	;push	ebp ; @
 21517 000045B8 E844140000          <1> 	call	dskwr ; writes the 1st buffer to sector
 21518                              <1> 		      ; (at the beginning/head of the buffer chain)
 21519                              <1> 	;pop	ebp ; @
 21520                              <1> 
 21521                              <1> 	; if we are here, buffer has been written to disk successfully 
 21522                              <1> 	; (otherwise cpu would jump to 'error' address)
 21523                              <1> 
 21524                              <1> 	; 12/03/2022 ; (*)
 21525                              <1> 	; set superblock modified flag
 21526 000045BD BA[966C0000]        <1> 	mov	edx, smod
 21527 000045C2 F605[816C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 21528 000045C9 7401                <1> 	jz	short anyi_2 ; no, root device
 21529                              <1> 	; yes, mounted device
 21530 000045CB 42                  <1> 	inc	edx ; edx = offset mmod
 21531                              <1> anyi_2:
 21532 000045CC FE02                <1> 	inc	byte [edx] ; superblock modified !
 21533                              <1> 
 21534                              <1> 	; 12/03/2022
 21535                              <1> 	; decrease first free inode number (if it is required)
 21536 000045CE 8B0424              <1> 	mov	eax, [esp] ; ***
 21537                              <1> 	; eax = released/freed inode number 
 21538 000045D1 394534              <1> 	cmp	[ebp+SB.FirstFreeIno], eax
 21539 000045D4 7603                <1> 	jna	short anyi_4
 21540 000045D6 894534              <1> 	mov	[ebp+SB.FirstFreeIno], eax
 21541                              <1> 		    ; (free inode search start value)
 21542                              <1> anyi_4:
 21543                              <1> 	; 12/03/2022
 21544                              <1> 	; increase free inode count
 21545 000045D9 8B5530              <1> 	mov	edx, [ebp+SB.FreeInodes]
 21546                              <1> 	;cmp	edx, 0FFFFFFFFh
 21547                              <1> 	;je	short anyi_5 ; invalid
 21548 000045DC 42                  <1> 	inc	edx ; 0FFFFFFFFh -> 0
 21549 000045DD 7403                <1> 	jz	short anyi_5 ; invalid
 21550 000045DF 895530              <1> 	mov	[ebp+SB.FreeInodes], edx ; +1
 21551                              <1> anyi_5:
 21552 000045E2 E870150000          <1> 	call	get_system_time
 21553                              <1> 		; eax = current time (as unix epoch time)
 21554 000045E7 89455C              <1> 	mov	[ebp+SB.ModifTime], eax
 21555                              <1> 
 21556 000045EA 58                  <1> 	pop	eax ; *** ; inode number
 21557                              <1> 
 21558 000045EB E860070000          <1> 	call	itrunc
 21559                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
 21560                              <1> 
 21561                              <1> 	; 26/03/2022
 21562                              <1> 	; eax = 0 ; (itrunc clears eax at return)
 21563                              <1> 
 21564                              <1> 	; 12/03/2022
 21565                              <1> 	;pop	eax ; **** ; inode number
 21566                              <1> 
 21567                              <1> 	; 26/03/2022
 21568 000045F0 66A3[24680000]      <1> 	mov	[i.flgs], ax ; (eax should be 0 here)
 21569                              <1> 	;mov 	word [i.flgs], 0
 21570                              <1> 		; clr i.flgs / clear all flags in the i-node
 21571 000045F6 C3                  <1> 	retn
 21572                              <1> 		; rts r0 / return
 21573                              <1> 
 21574                              <1> ;anyi_3: ; 1: / i-numbers match
 21575                              <1> ;	; 09/01/2022
 21576                              <1> ;	test	byte [ebx+5], 1 ; open for writing flag
 21577                              <1> ;	jz	short anyi_0	
 21578                              <1> ;
 21579                              <1> ;	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21580                              <1> ;	or	byte [ebx+5], 80h ; set deleted file flag (bit 7)
 21581                              <1> ;	; 22/06/2015
 21582                              <1> ;	;inc 	byte [ebx+9]
 21583                              <1> ;		; incb 7(r2) / increment upper byte of the 4th word
 21584                              <1> ;		   ; / in that fsp entry (deleted flag of fsp entry)
 21585                              <1> ;	retn
 21586                              <1> ;		; rts r0
 21587                                  %include 'u3.s'      ; 10/05/2015
 21588                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 21589                              <1> ; (re-write kernel for test by using previous version without a major defect)
 21590                              <1> ; ****************************************************************************
 21591                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS3.INC
 21592                              <1> ; Last Modification: 24/12/2021
 21593                              <1> ; ----------------------------------------------------------------------------
 21594                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 21595                              <1> ; (v0.1 - Beginning: 11/07/2012)
 21596                              <1> ;
 21597                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 21598                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 21599                              <1> ; <Bell Laboratories (17/3/1972)>
 21600                              <1> ; <Preliminary Release of UNIX Implementation Document>
 21601                              <1> ;
 21602                              <1> ; Retro UNIX 8086 v1 - U3.ASM (08/03/2014) //// UNIX v1 -> u3.s
 21603                              <1> ;
 21604                              <1> ; ****************************************************************************
 21605                              <1> 
 21606                              <1> tswitch: ; Retro UNIX 386 v1
 21607                              <1> tswap:
 21608                              <1> 	; 01/09/2015
 21609                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 21610                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 21611                              <1> 	; time out swap, called when a user times out.
 21612                              <1> 	; the user is put on the low priority queue.
 21613                              <1> 	; This is done by making a link from the last user
 21614                              <1> 	; on the low priority queue to him via a call to 'putlu'.
 21615                              <1> 	; then he is swapped out.
 21616                              <1> 	;
 21617                              <1> 	; Retro UNIX 386 v1 modification ->
 21618                              <1> 	;       swap (software task switch) is performed by changing
 21619                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 21620                              <1> 	;	as in Retro UNIX 8086 v1.
 21621                              <1> 	;
 21622                              <1> 	; RETRO UNIX 8086 v1 modification ->
 21623                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21624                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21625                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21626                              <1> 	;	compatibles was using 1MB segmented memory 
 21627                              <1> 	;	in 8086/8088 times.
 21628                              <1> 	;
 21629                              <1> 	; INPUTS ->
 21630                              <1> 	;    u.uno - users process number
 21631                              <1> 	;    runq+4 - lowest priority queue
 21632                              <1> 	; OUTPUTS ->
 21633                              <1> 	;    r0 - users process number
 21634                              <1> 	;    r2 - lowest priority queue address
 21635                              <1> 	;
 21636                              <1> 	; ((AX = R0, BX = R2)) output
 21637                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
 21638                              <1> 	;
 21639 000045F7 A0[F56C0000]        <1> 	mov 	al, [u.uno]
 21640                              <1> 	       	; movb u.uno,r1 / move users process number to r1
 21641                              <1> 		; mov  $runq+4,r2 
 21642                              <1> 			; / move lowest priority queue address to r2
 21643 000045FC E8CD000000          <1>         call 	putlu
 21644                              <1> 		; jsr r0,putlu / create link from last user on Q to 
 21645                              <1> 		             ; / u.uno's user
 21646                              <1> 
 21647                              <1> switch: ; Retro UNIX 386 v1
 21648                              <1> swap:
 21649                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 21650                              <1> 	; 02/09/2015
 21651                              <1> 	; 01/09/2015
 21652                              <1> 	; 31/08/2015
 21653                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 21654                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 21655                              <1> 	; 'swap' is routine that controls the swapping of processes
 21656                              <1> 	; in and out of core.
 21657                              <1> 	;
 21658                              <1> 	; Retro UNIX 386 v1 modification ->
 21659                              <1> 	;       swap (software task switch) is performed by changing
 21660                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 21661                              <1> 	;	as in Retro UNIX 8086 v1.
 21662                              <1> 	;
 21663                              <1> 	; RETRO UNIX 8086 v1 modification ->
 21664                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21665                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21666                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21667                              <1> 	;	compatibles was using 1MB segmented memory 
 21668                              <1> 	;	in 8086/8088 times.
 21669                              <1> 	;
 21670                              <1> 	; INPUTS ->
 21671                              <1> 	;    runq table - contains processes to run.
 21672                              <1> 	;    p.link - contains next process in line to be run.
 21673                              <1> 	;    u.uno - process number of process in core	
 21674                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
 21675                              <1> 	; OUTPUTS ->
 21676                              <1> 	;    (original unix v1 -> present process to its disk block)
 21677                              <1> 	;    (original unix v1 -> new process into core -> 
 21678                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
 21679                              <1> 	;	   for new process)
 21680                              <1> 	;    u.quant = 3 (Time quantum for a process)
 21681                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
 21682                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
 21683                              <1> 	;	 for now, it will swap the process if there is not
 21684                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
 21685                              <1> 	;	 or will count down from 3 to 0 even if there is a
 21686                              <1> 	;        keyboard event locking due to repetitive key strokes.
 21687                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
 21688                              <1> 	;
 21689                              <1> 	;    u.pri -points to highest priority run Q.
 21690                              <1> 	;    r2 - points to the run queue.
 21691                              <1> 	;    r1 - contains new process number
 21692                              <1> 	;    r0 - points to place in routine or process that called
 21693                              <1> 	;	  swap all user parameters
 21694                              <1> 	;				
 21695                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
 21696                              <1> 	;
 21697                              <1> swap_0:
 21698                              <1> 		;mov $300,*$ps / processor priority = 6
 21699 00004601 BE[926C0000]        <1> 	mov	esi, runq
 21700                              <1> 		; mov $runq,r2 / r2 points to runq table
 21701                              <1> swap_1: ; 1: / search runq table for highest priority process
 21702 00004606 668B06              <1> 	mov	ax, [esi]
 21703 00004609 6621C0              <1> 	and 	ax, ax
 21704                              <1>        		; tst (r2)+ / are there any processes to run 
 21705                              <1> 			  ; / in this Q entry
 21706 0000460C 7507                <1> 	jnz	short swap_2
 21707                              <1>        		; bne 1f / yes, process 1f
 21708                              <1> 		; cmp r2,$runq+6 / if zero compare address 
 21709                              <1> 			       ; / to end of table
 21710                              <1> 		; bne 1b / if not at end, go back
 21711 0000460E E8E0000000          <1> 	call	idle
 21712                              <1> 		; jsr r0,idle; s.idlet+2 / wait for interrupt; 
 21713                              <1> 				       ; / all queues are empty
 21714 00004613 EBF1                <1> 	jmp	short swap_1
 21715                              <1> 		; br swap
 21716                              <1> swap_2: ; 1:
 21717 00004615 0FB6D8              <1> 	movzx	ebx, al ; 02/09/2015
 21718                              <1> 		; tst -(r2) / restore pointer to right Q entry
 21719                              <1>  		; mov r2,u.pri / set present user to this run queue
 21720                              <1> 	        ; movb (r2)+,r1 / move 1st process in queue to r1
 21721 00004618 38E0                <1> 	cmp	al, ah
 21722                              <1> 		; cmpb r1,(r2)+ / is there only 1 process 
 21723                              <1> 			      ; / in this Q to be run
 21724 0000461A 740A                <1> 	je	short swap_3
 21725                              <1>        		; beq 1f / yes
 21726                              <1> 		; tst -(r2) / no, pt r2 back to this Q entry
 21727                              <1> 	;movzx	ebx, al
 21728 0000461C 8AA3[B3680000]      <1> 	mov	ah, [ebx+p.link-1] 
 21729 00004622 8826                <1>        	mov	[esi], ah
 21730                              <1> 		; movb p.link-1(r1),(r2) / move next process 
 21731                              <1> 				       ; / in line into run queue
 21732 00004624 EB05                <1> 	jmp	short swap_4
 21733                              <1>        		; br 2f
 21734                              <1> swap_3: ; 1:
 21735                              <1> 	;xor	dx, dx
 21736                              <1> 	; 24/12/2021
 21737 00004626 31D2                <1> 	xor	edx, edx
 21738 00004628 668916              <1> 	mov	[esi], dx
 21739                              <1> 		; clr -(r2) / zero the entry; no processes on the Q
 21740                              <1> swap_4: ; / write out core to appropriate disk area and read 
 21741                              <1>       ; / in new process if required
 21742                              <1>        		; clr *$ps / clear processor status
 21743 0000462B 8A25[F56C0000]      <1> 	mov 	ah, [u.uno]
 21744 00004631 38C4                <1> 	cmp	ah, al
 21745                              <1> 		; cmpb r1,u.uno / is this process the same as 
 21746                              <1> 			      ; / the process in core?
 21747 00004633 743B                <1>        	je	short swap_8
 21748                              <1>        		; beq 2f / yes, don't have to swap
 21749                              <1>        		; mov r0,-(sp) / no, write out core; save r0 
 21750                              <1> 			   ; / (address in routine that called swap)
 21751                              <1> 		; mov r1,-(sp) / put r1 (new process #) on the stack
 21752                              <1> 	; 01/09/2015
 21753                              <1> 	;mov	[u.usp], esp
 21754                              <1>        		; mov sp,u.usp / save stack pointer
 21755                              <1> 		; mov $sstack,sp / move swap stack pointer 
 21756                              <1> 			       ; / to the stack pointer
 21757 00004635 08E4                <1> 	or	ah, ah
 21758                              <1>        		; tstb u.uno / is the process # = 0
 21759 00004637 740D                <1>        	jz	short swap_6 ; 'sysexit'
 21760                              <1> 		; beq  1f / yes, kill process by overwriting
 21761                              <1> 	; 02/09/2015
 21762 00004639 8925[A06C0000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
 21763                              <1> 	;
 21764 0000463F E834000000          <1> 	call	wswap
 21765                              <1> 		;jsr r0,wswap / write out core to disk
 21766                              <1> 	 ; 31/08/2015
 21767                              <1> 	;movzx	ebx, al ; New (running) process number
 21768 00004644 EB1C                <1> 	jmp 	short swap_7
 21769                              <1> swap_6:
 21770                              <1> 	; 31/08/2015
 21771                              <1> 	; Deallocate memory pages belong to the process
 21772                              <1> 	; which is being terminated
 21773                              <1> 	; 14/05/2015 ('sysexit')
 21774                              <1>  	; Deallocate memory pages of the process
 21775                              <1> 	; (Retro UNIX 386 v1 modification !)
 21776                              <1> 	;
 21777                              <1> 	; movzx ebx, al
 21778 00004646 53                  <1> 	push	ebx
 21779 00004647 A1[046D0000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
 21780 0000464C 8B1D[086D0000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
 21781 00004652 E8B8DEFFFF          <1> 	call	deallocate_page_dir
 21782 00004657 A1[006D0000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
 21783 0000465C E844DFFFFF          <1> 	call	deallocate_page
 21784 00004661 5B                  <1> 	pop	ebx
 21785                              <1> swap_7: ;1: 
 21786                              <1> 	; 02/09/2015
 21787                              <1> 	; 31/08/2015
 21788                              <1> 	; 14/05/2015
 21789 00004662 C0E302              <1> 	shl	bl, 2 ; * 4 
 21790 00004665 8B83[D0680000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
 21791                              <1> 	;cli
 21792 0000466B E831000000          <1> 	call	rswap
 21793                              <1>  		; mov (sp)+,r1 / restore r1 to new process number
 21794                              <1> 		; jsr r0,rswap / read new process into core
 21795                              <1>        		; jsr r0,unpack / unpack the users stack from next
 21796                              <1> 			      ; / to his program to its normal
 21797                              <1> 	; 01/09/2015
 21798                              <1> 	;mov	esp, [u.usp]	
 21799                              <1> 		; mov u.usp,sp / location; restore stack pointer to
 21800                              <1> 			     ; / new process stack
 21801                              <1> 		; mov (sp)+,r0 / put address of where the process 
 21802                              <1> 			     ; / that just got swapped in, left off.,
 21803                              <1> 			     ; / i.e., transfer control to new process
 21804                              <1> 	;sti
 21805                              <1> swap_8: ;2:
 21806                              <1> 	; RETRO UNIX 8086 v1 modification !
 21807 00004670 C605[EC6C0000]04    <1> 	mov	byte [u.quant], time_count 
 21808                              <1> 		; movb $30.,uquant / initialize process time quantum
 21809 00004677 C3                  <1> 	retn
 21810                              <1> 		; rts r0 / return
 21811                              <1> 
 21812                              <1> wswap:  ; < swap out, swap to disk >
 21813                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 21814                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 21815                              <1> 	; 'wswap' writes out the process that is in core onto its 
 21816                              <1> 	; appropriate disk area.
 21817                              <1> 	;
 21818                              <1> 	; Retro UNIX 386 v1 modification ->
 21819                              <1> 	;       User (u) structure content and the user's register content
 21820                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
 21821                              <1> 	;	saving 'u' structure and user registers for task switching).
 21822                              <1> 	;	u.usp - points to kernel stack address which contains
 21823                              <1> 	;		user's registers while entering system call.  
 21824                              <1> 	;	u.sp  - points to kernel stack address 
 21825                              <1> 	;		to return from system call -for IRET-.
 21826                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 21827                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 21828                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 21829                              <1> 	;
 21830                              <1> 	; Retro UNIX 8086 v1 modification ->
 21831                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21832                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21833                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21834                              <1> 	;	compatibles was using 1MB segmented memory 
 21835                              <1> 	;	in 8086/8088 times.
 21836                              <1> 	;
 21837                              <1> 	; INPUTS ->
 21838                              <1> 	;    u.break - points to end of program
 21839                              <1> 	;    u.usp - stack pointer at the moment of swap
 21840                              <1> 	;    core - beginning of process program		
 21841                              <1> 	;    ecore - end of core 	
 21842                              <1> 	;    user - start of user parameter area		
 21843                              <1> 	;    u.uno - user process number	
 21844                              <1> 	;    p.dska - holds block number of process	
 21845                              <1> 	; OUTPUTS ->
 21846                              <1> 	;    swp I/O queue
 21847                              <1> 	;    p.break - negative word count of process 
 21848                              <1> 	;    r1 - process disk address	
 21849                              <1> 	;    r2 - negative word count
 21850                              <1> 	;
 21851                              <1> 	; RETRO UNIX 8086 v1 input/output:
 21852                              <1> 	;
 21853                              <1> 	; INPUTS ->
 21854                              <1> 	;    u.uno - process number (to be swapped out)
 21855                              <1> 	; OUTPUTS ->
 21856                              <1> 	;    none
 21857                              <1> 	;
 21858                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
 21859                              <1> 	;
 21860 00004678 8B3D[006D0000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
 21861 0000467E B921000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 21862 00004683 BE[9C6C0000]        <1> 	mov	esi, user ; active user (u) structure	
 21863 00004688 F3A5                <1> 	rep	movsd
 21864                              <1> 	;
 21865 0000468A 8B35[A06C0000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
 21866                              <1> 			     ;      points to user registers)
 21867 00004690 8B0D[9C6C0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 21868                              <1> 			     ; (for IRET)
 21869                              <1> 			     ; [u.sp] -> EIP (user)
 21870                              <1> 			     ; [u.sp+4]-> CS (user)
 21871                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 21872                              <1> 			     ; [u.sp+12] -> ESP (user)
 21873                              <1> 			     ; [u.sp+16] -> SS (user)	
 21874 00004696 29F1                <1> 	sub	ecx, esi     ; required space for user registers
 21875 00004698 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 21876                              <1> 			     ; (for IRET) 	
 21877 0000469B C1E902              <1> 	shr	ecx, 2	     		
 21878 0000469E F3A5                <1> 	rep	movsd
 21879 000046A0 C3                  <1> 	retn
 21880                              <1> 
 21881                              <1> 	; Original UNIX v1 'wswap' routine:
 21882                              <1> 	; wswap:
 21883                              <1> 		; mov *$30,u.emt / determines handling of emts
 21884                              <1>         	; mov *$10,u.ilgins / determines handling of 
 21885                              <1> 				; / illegal instructions
 21886                              <1> 		; mov u.break,r2 / put process program break address in r2
 21887                              <1> 		; inc r2 / add 1 to it 
 21888                              <1> 		; bic $1,r2 / make it even
 21889                              <1> 		; mov r2,u.break / set break to an even location
 21890                              <1> 		; mov u.usp,r3 / put users stack pointer 
 21891                              <1> 			     ; / at moment of swap in r3
 21892                              <1> 		; cmp r2,$core / is u.break less than $core
 21893                              <1> 		; blos 2f / yes
 21894                              <1> 		; cmp r2,r3 / no, is (u.break) greater than stack ptr.
 21895                              <1>        		; bhis 2f / yes
 21896                              <1> 	; 1:
 21897                              <1>        		; mov (r3)+,(r2)+ / no, pack stack next to users program
 21898                              <1> 		; cmp r3,$ecore / has stack reached end of core
 21899                              <1> 		; bne 1b / no, keep packing
 21900                              <1> 	 	; br 1f / yes
 21901                              <1> 	; 2:
 21902                              <1>        		; mov $ecore,r2 / put end of core in r2 
 21903                              <1> 	; 1:
 21904                              <1>        		; sub  $user,r2 / get number of bytes to write out 
 21905                              <1> 			   ; / (user up to end of stack gets written out)
 21906                              <1> 		; neg r2 / make it negative
 21907                              <1> 		; asr r2 / change bytes to words (divide by 2)
 21908                              <1> 		; mov r2,swp+4 / word count
 21909                              <1> 		; movb u.uno,r1 / move user process number to r1
 21910                              <1> 		; asl r1 / x2 for index
 21911                              <1>       		; mov r2,p.break-2(r1) / put negative of word count 
 21912                              <1> 				     ; / into the p.break table
 21913                              <1>        		; mov p.dska-2(r1),r1 / move disk address of swap area 
 21914                              <1> 				    ; /	for process to r1
 21915                              <1>        		; mov r1,swp+2 / put processes dska address in swp+2 
 21916                              <1> 			     ; / (block number)
 21917                              <1> 		; bis $1000,swp / set it up to write (set bit 9)
 21918                              <1>        		; jsr r0,ppoke / write process out on swap area of disk
 21919                              <1> 	; 1:
 21920                              <1>        		; tstb swp+1 / is lt done writing?
 21921                              <1>        		; bne 1b / no, wait
 21922                              <1> 		; rts r0 / yes, return to swap
 21923                              <1> 
 21924                              <1> rswap:  ; < swap in, swap from disk >
 21925                              <1> 	; 15/09/2015
 21926                              <1> 	; 28/08/2015
 21927                              <1> 	; 14/05/2015
 21928                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 21929                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 21930                              <1> 	; 'rswap' reads a process whose number is in r1, 
 21931                              <1> 	; from disk into core.
 21932                              <1> 	;
 21933                              <1> 	; Retro UNIX 386 v1 modification ->
 21934                              <1> 	;       User (u) structure content and the user's register content
 21935                              <1> 	;	will be restored from process's/user's UPAGE (a page for
 21936                              <1> 	;	saving 'u' structure and user registers for task switching).
 21937                              <1> 	;	u.usp - points to kernel stack address which contains
 21938                              <1> 	;		user's registers while entering system call.  
 21939                              <1> 	;	u.sp  - points to kernel stack address 
 21940                              <1> 	;		to return from system call -for IRET-.
 21941                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 21942                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 21943                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 21944                              <1> 	;
 21945                              <1> 	; RETRO UNIX 8086 v1 modification ->
 21946                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21947                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21948                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21949                              <1> 	;	compatibles was using 1MB segmented memory 
 21950                              <1> 	;	in 8086/8088 times.
 21951                              <1> 	;
 21952                              <1> 	; INPUTS ->
 21953                              <1> 	;    r1 - process number of process to be read in
 21954                              <1> 	;    p.break - negative of word count of process 
 21955                              <1> 	;    p.dska - disk address of the process		
 21956                              <1> 	;    u.emt - determines handling of emt's 	
 21957                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 21958                              <1> 	; OUTPUTS ->
 21959                              <1> 	;    8 = (u.ilgins)
 21960                              <1> 	;    24 = (u.emt)
 21961                              <1> 	;    swp - bit 10 is set to indicate read 
 21962                              <1> 	;		(bit 15=0 when reading is done)	
 21963                              <1> 	;    swp+2 - disk block address
 21964                              <1> 	;    swp+4 - negative word count 	
 21965                              <1> 	;      ((swp+6 - address of user structure)) 
 21966                              <1> 	;
 21967                              <1> 	; RETRO UNIX 8086 v1 input/output:
 21968                              <1> 	;
 21969                              <1> 	; INPUTS ->
 21970                              <1> 	;    AL	- new process number (to be swapped in)	 
 21971                              <1> 	; OUTPUTS ->
 21972                              <1> 	;    none
 21973                              <1> 	;
 21974                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
 21975                              <1> 	;
 21976                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
 21977 000046A1 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
 21978 000046A3 B921000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 21979 000046A8 BF[9C6C0000]        <1> 	mov	edi, user ; active user (u) structure	
 21980 000046AD F3A5                <1> 	rep	movsd
 21981 000046AF 58                  <1> 	pop	eax ; 15/09/2015, 'rswap' return address 
 21982 000046B0 8B3D[A06C0000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
 21983                              <1> 			     ;      points to user registers)
 21984 000046B6 8B0D[9C6C0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 21985                              <1> 			     ; (for IRET)
 21986                              <1> 			     ; [u.sp] -> EIP (user)
 21987                              <1> 			     ; [u.sp+4]-> CS (user)
 21988                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 21989                              <1> 			     ; [u.sp+12] -> ESP (user)
 21990                              <1> 			     ; [u.sp+16] -> SS (user)		
 21991                              <1> 	; 28/08/2015
 21992 000046BC 29F9                <1> 	sub	ecx, edi     ; required space for user registers
 21993 000046BE 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 21994                              <1> 			     ; (for IRET) 	
 21995 000046C1 C1E902              <1> 	shr	ecx, 2	       		
 21996 000046C4 F3A5                <1> 	rep	movsd
 21997 000046C6 8B25[A06C0000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
 21998 000046CC 50                  <1> 	push	eax ; 15/09/2015 'rswap' return address
 21999 000046CD C3                  <1> 	retn
 22000                              <1> 
 22001                              <1> 	; Original UNIX v1 'rswap'  and 'unpack' routines:
 22002                              <1> 	;rswap:
 22003                              <1>        		; asl r1 / process number x2 for index
 22004                              <1>        		; mov p.break-2(r1), swp+4 / word count
 22005                              <1>        		; mov p.dska-2(r1),swp+2 / disk address
 22006                              <1>        		; bis $2000,swp / read
 22007                              <1>        		; jsr r0,ppoke / read it in 
 22008                              <1> 	; 1:
 22009                              <1>        		; tstb swp+1 / done
 22010                              <1>        		; bne 1b / no, wait for bit 15 to clear (inhibit bit)
 22011                              <1>        		; mov u.emt,*$30 / yes move these
 22012                              <1>        		; mov u.ilgins,*$10 / back
 22013                              <1>        		; rts r0 / return
 22014                              <1> 
 22015                              <1> 	;unpack: ; / move stack back to its normal place
 22016                              <1> 		; mov u.break,r2 / r2 points to end of user program
 22017                              <1>        		; cmp r2,$core / at beginning of user program yet?
 22018                              <1> 		; blos 2f / yes, return
 22019                              <1> 		; cmp r2,u.usp / is break_above the stack pointer 
 22020                              <1> 			     ; / before swapping
 22021                              <1> 		; bhis 2f / yes, return
 22022                              <1> 		; mov $ecore,r3 / r3 points to end of core
 22023                              <1> 		; add r3,r2
 22024                              <1> 		; sub u.usp,r2 / end of users stack is in r2
 22025                              <1> 	; 1:
 22026                              <1> 		; mov -(r2),-(r3) / move stack back to its normal place
 22027                              <1> 		; cmp r2,u.break / in core
 22028                              <1> 		; bne 1b
 22029                              <1> 	; 2:
 22030                              <1>        		; rts r0
 22031                              <1> 
 22032                              <1> putlu: 
 22033                              <1> 	; 12/09/2015
 22034                              <1> 	; 02/09/2015
 22035                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 22036                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 22037                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
 22038                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
 22039                              <1> 	; the last process on the queue to process in r1 by putting
 22040                              <1> 	; the process number in r1 into the last process's link.
 22041                              <1> 	;
 22042                              <1> 	; INPUTS ->
 22043                              <1> 	;    r1 - user process number
 22044                              <1> 	;    r2 - points to lowest priority queue 
 22045                              <1> 	;    p.dska - disk address of the process		
 22046                              <1> 	;    u.emt - determines handling of emt's 	
 22047                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 22048                              <1> 	; OUTPUTS ->
 22049                              <1> 	;    r3 - process number of last process on the queue upon
 22050                              <1> 	;	  entering putlu
 22051                              <1> 	;    p.link-1 + r3 - process number in r1
 22052                              <1> 	;    r2 - points to lowest priority queue
 22053                              <1> 	;
 22054                              <1> 	; ((Modified registers: EDX, EBX)) 
 22055                              <1> 	;
 22056                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
 22057                              <1> 
 22058                              <1> 	; eBX = r2
 22059                              <1> 	; eAX = r1 (AL=r1b)
 22060                              <1> 
 22061 000046CE BB[926C0000]        <1> 	mov	ebx, runq
 22062 000046D3 0FB613              <1> 	movzx  	edx, byte [ebx]
 22063 000046D6 43                  <1> 	inc	ebx
 22064 000046D7 20D2                <1> 	and	dl, dl
 22065                              <1> 		; tstb (r2)+ / is queue empty?
 22066 000046D9 740A                <1>        	jz	short putlu_1
 22067                              <1> 		; beq 1f / yes, branch
 22068 000046DB 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
 22069                              <1> 		; movb (r2),r3 / no, save the "last user" process number
 22070                              <1> 			     ; / in r3
 22071 000046DD 8882[B3680000]      <1>        	mov	[edx+p.link-1], al
 22072                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
 22073                              <1> 			     ; / "last users" link
 22074 000046E3 EB03                <1> 	jmp	short putlu_2
 22075                              <1> 		; br 2f /
 22076                              <1> putlu_1: ; 1:
 22077 000046E5 8843FF              <1> 	mov	[ebx-1], al
 22078                              <1>        		; movb r1,-1(r2) / user is only user; 
 22079                              <1> 			    ; / put process no. at beginning and at end
 22080                              <1> putlu_2: ; 2: 
 22081 000046E8 8803                <1> 	mov	[ebx], al
 22082                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
 22083                              <1> 			     ; / on the queue
 22084 000046EA 88C2                <1> 	mov	dl, al
 22085 000046EC 88B2[B3680000]      <1>         mov     [edx+p.link-1], dh ; 0
 22086                              <1> 		; dec r2 / restore r2
 22087 000046F2 C3                  <1>         retn
 22088                              <1> 		; rts r0
 22089                              <1> 
 22090                              <1> ;copyz:
 22091                              <1> ;       mov     r1,-(sp) / put r1 on stack
 22092                              <1> ;       mov     r2,-(sp) / put r2 on stack
 22093                              <1> ;       mov     (r0)+,r1
 22094                              <1> ;       mov     (r0)+,r2
 22095                              <1> ;1:
 22096                              <1> ;       clr     (r1)+ / clear all locations between r1 and r2
 22097                              <1> ;       cmp     r1,r2 
 22098                              <1> ;       blo     1b
 22099                              <1> ;       mov     (sp)+,r2 / restore r2
 22100                              <1> ;       mov     (sp)+,r1 / restore r1
 22101                              <1> ;       rts     r0 
 22102                              <1> 
 22103                              <1> idle:
 22104                              <1> 	; 01/09/2015
 22105                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 22106                              <1> 	; 10/04/2013 - 23/10/2013 (Retro UNIX 8086 v1)
 22107                              <1> 	; (idle & wait loop)
 22108                              <1> 	; Retro Unix 8086 v1 modification on original UNIX v1
 22109                              <1> 	; idle procedure!
 22110                              <1>       	;
 22111                              <1>   	; 01/09/2015
 22112 000046F3 FB                  <1> 	sti
 22113                              <1>       	; 29/07/2013
 22114 000046F4 F4                  <1>       	hlt
 22115 000046F5 90                  <1>       	nop ; 10/10/2013
 22116 000046F6 90                  <1>       	nop
 22117 000046F7 90                  <1>       	nop
 22118                              <1>       	; 23/10/2013
 22119 000046F8 90                  <1>       	nop
 22120 000046F9 90                  <1>       	nop
 22121 000046FA 90                  <1>       	nop
 22122 000046FB 90                  <1>       	nop
 22123 000046FC C3                  <1>       	retn      
 22124                              <1> 
 22125                              <1> 	;mov *$ps,-(sp) / save ps on stack
 22126                              <1> 	;clr *$ps / clear ps
 22127                              <1> 	;mov clockp,-(sp) / save clockp on stack
 22128                              <1> 	;mov (r0)+,clockp / arg to idle in clockp
 22129                              <1> 	;1 / wait for interrupt
 22130                              <1> 	;mov (sp)+,clockp / restore clockp, ps
 22131                              <1> 	;mov (sp)+,*$ps
 22132                              <1> 	;rts r0
 22133                              <1> 
 22134                              <1> clear:
 22135                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
 22136                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 22137                              <1> 	; 09/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 22138                              <1> 	; 'clear' zero's out of a block (whose block number is in r1)
 22139                              <1> 	; on the current device (cdev)
 22140                              <1> 	;	
 22141                              <1> 	; INPUTS ->
 22142                              <1> 	;    r1 - block number of block to be zeroed
 22143                              <1> 	;    cdev - current device number 
 22144                              <1> 	; OUTPUTS ->
 22145                              <1> 	;    a zeroed I/O buffer onto the current device
 22146                              <1> 	;    r1 - points to last entry in the I/O buffer
 22147                              <1> 	;
 22148                              <1> 	; ((AX = R1)) input/output
 22149                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 14/11/2012, UNIXCOPY.ASM)
 22150                              <1>         ;    ((Modified registers: EDX, ECX, EBX, ESI, EDI, EBP))  
 22151                              <1> 
 22152 000046FD E8F2120000          <1> 	call 	wslot
 22153                              <1> 		; jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
 22154                              <1>                    ; / word of I/O queue r5 points to first data word in buffer
 22155 00004702 89DF                <1> 	mov	edi, ebx ; r5
 22156 00004704 89C2                <1> 	mov	edx, eax
 22157 00004706 B980000000          <1> 	mov	ecx, 128
 22158                              <1> 		; mov $256.,r3
 22159 0000470B 31C0                <1> 	xor	eax, eax
 22160 0000470D F3AB                <1> 	rep	stosd
 22161 0000470F 89D0                <1> 	mov	eax, edx
 22162                              <1> ; 1: 
 22163                              <1>        		; clr (r5)+ / zero data word in buffer
 22164                              <1>        		; dec r3
 22165                              <1>        		; bgt 1b / branch until all data words in buffer are zero
 22166                              <1> 	;call	dskwr
 22167                              <1> 		; jsr r0,dskwr / write zeroed buffer area out onto physical
 22168                              <1>                              ; / block specified in r1
 22169                              <1> 	; eAX (r1) = block number
 22170                              <1> 	;retn
 22171                              <1> 		; rts r0
 22172                              <1> 	; 24/12/2021
 22173 00004711 E9EB120000          <1> 	jmp	dskwr
 22174                                  %include 'u4.s'      ; 15/04/2015
 22175                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 22176                              <1> ; (re-write kernel for test by using previous version without a major defect)
 22177                              <1> ; ****************************************************************************
 22178                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS4.INC
 22179                              <1> ; Last Modification: 27/02/2022 (Retro UNIX 386 v1.2)
 22180                              <1> ; ----------------------------------------------------------------------------
 22181                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22182                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22183                              <1> ;
 22184                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22185                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22186                              <1> ; <Bell Laboratories (17/3/1972)>
 22187                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22188                              <1> ;
 22189                              <1> ; Retro UNIX 8086 v1 - U4.ASM (04/07/2014) //// UNIX v1 -> u4.s
 22190                              <1> ;
 22191                              <1> ; ****************************************************************************
 22192                              <1> 
 22193                              <1> ;setisp:
 22194                              <1>        ;mov     r1,-(sp)
 22195                              <1>        ;mov     r2,-(sp)
 22196                              <1>        ;mov     r3,-(sp)
 22197                              <1>        ;mov     clockp,-(sp)
 22198                              <1>        ;mov     $s.syst+2,clockp
 22199                              <1>        ;jmp     (r0)
 22200                              <1> 
 22201                              <1> clock: ; / interrupt from 60 cycle clock
 22202                              <1> 	
 22203                              <1> 	; 14/10/2015
 22204                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 22205                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
 22206                              <1> 
 22207                              <1>        ;mov     r0,-(sp) / save r0
 22208                              <1>        ;tst     *$lks / restart clock?
 22209                              <1>        ;mov     $s.time+2,r0 / increment the time of day
 22210                              <1>        ;inc     (r0)
 22211                              <1>        ;bne     1f
 22212                              <1>        ;inc     -(r0)
 22213                              <1> ;1:
 22214                              <1>        ;mov     clockp,r0 / increment appropriate time category
 22215                              <1>        ;inc     (r0)
 22216                              <1>        ;bne     1f
 22217                              <1>        ;inc     -(r0)
 22218                              <1> ;1:
 22219                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 22220                              <1> 
 22221 00004716 803D[EC6C0000]00    <1> 	cmp	byte [u.quant], 0
 22222 0000471D 772C                <1> 	ja	short clk_1
 22223                              <1> 	;
 22224 0000471F 803D[986C0000]FF    <1>         cmp     byte [sysflg], 0FFh ; user or system space ?
 22225 00004726 7529                <1> 	jne	short clk_2 ; system space (sysflg <> 0FFh)
 22226 00004728 803D[F56C0000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ?
 22227 0000472F 761A                <1> 	jna	short clk_1 ; yes, do not swap out
 22228 00004731 66833D[F06C0000]00  <1> 	cmp	word [u.intr], 0
 22229 00004739 7616                <1> 	jna	short clk_2
 22230                              <1> clk_0:
 22231                              <1> 	; 14/10/2015
 22232 0000473B FE05[986C0000]      <1> 	inc	byte [sysflg] ; Now, we are in system space
 22233 00004741 58                  <1> 	pop	eax ; return address to the timer interrupt
 22234                              <1> 	;
 22235 00004742 B020                <1> 	MOV	AL,EOI			; GET END OF INTERRUPT MASK
 22236                              <1> 	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
 22237 00004744 E620                <1> 	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
 22238                              <1> 	;
 22239 00004746 E99FEAFFFF          <1> 	jmp     sysrelease ; 'sys release' by clock/timer
 22240                              <1> clk_1:
 22241 0000474B FE0D[EC6C0000]      <1> 	dec	byte [u.quant]
 22242                              <1> clk_2:
 22243 00004751 C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
 22244                              <1> 
 22245                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 22246                              <1> 
 22247                              <1>        ;mov     $uquant,r0 / decrement user time quantum
 22248                              <1>        ;decb    (r0)
 22249                              <1>        ;bge     1f / if less than 0
 22250                              <1>        ;clrb    (r0) / make it 0
 22251                              <1> ;1: / decrement time out counts return now if priority was not 0
 22252                              <1>        ;cmp     4(sp),$200 / ps greater than or equal to 200
 22253                              <1>        ;bge     2f / yes, check time outs
 22254                              <1>        ;tstb    (r0) / no, user timed out?
 22255                              <1>        ;bne     1f / no
 22256                              <1>        ;cmpb    sysflg,$-1 / yes, are we outside the system?
 22257                              <1>        ;bne     1f / no, 1f
 22258                              <1>        ;mov     (sp)+,r0 / yes, put users r0 in r0
 22259                              <1>        ;sys     0 / sysrele
 22260                              <1>        ;rti
 22261                              <1> ;2: / priority is high so just decrement time out counts
 22262                              <1>        ;mov     $toutt,r0 / r0 points to beginning of time out table
 22263                              <1> ;2:
 22264                              <1>        ;tstb    (r0) / is the time out?
 22265                              <1>        ;beq     3f / yes, 3f (get next entry)
 22266                              <1>        ;decb    (r0) / no, decrement the time
 22267                              <1>        ;bne     3f / isit zero now?
 22268                              <1>        ;incb    (r0) / yes, increment the time
 22269                              <1> ;3:
 22270                              <1>        ;inc     r0 / next entry
 22271                              <1>        ;cmp     r0,$touts / end of toutt table?
 22272                              <1>        ;blo     2b / no, check this entry
 22273                              <1>        ;mov     (sp)+,r0 / yes, restore r0
 22274                              <1>        ;rti / return from interrupt
 22275                              <1> ;1: / decrement time out counts; if 0 call subroutine
 22276                              <1>        ;mov     (sp)+,r0 / restore r0
 22277                              <1>        ;mov     $240,*$ps / set processor priority to 5
 22278                              <1>        ;jsr     r0,setisp / save registers
 22279                              <1>        ;mov     $touts-toutt-1,r0 / set up r0 as index to decrement thru
 22280                              <1>                                ;  / the table
 22281                              <1> ;1:
 22282                              <1>        ;tstb    toutt(r0) / is the time out for this entry
 22283                              <1>        ;beq     2f / yes
 22284                              <1>        ;decb    toutt(r0) / no, decrement the time
 22285                              <1>        ;bne     2f / is the time 0, now
 22286                              <1>        ;asl     r0 / yes, 2 x r0 to get word index for tout entry
 22287                              <1>        ;jsr     r0,*touts(r0) / go to appropriate routine specified in this
 22288                              <1>        ;asr     r0 / touts entry; set r0 back to toutt index
 22289                              <1> ;2:
 22290                              <1>        ;dec     r0 / set up r0 for next entry
 22291                              <1>        ;bge     1b / finished? , no, go back
 22292                              <1>        ;br      retisp / yes, restore registers and do a rti
 22293                              <1> 
 22294                              <1> ;retisp:
 22295                              <1>        ;mov     (sp)+,clockp / pop values before interrupt off the stack
 22296                              <1>        ;mov     (sp)+,r3
 22297                              <1>        ;mov     (sp)+,r2
 22298                              <1>        ;mov     (sp)+,r1
 22299                              <1>        ;mov     (sp)+,r0
 22300                              <1>        ;rti     / return from interrupt
 22301                              <1> 
 22302                              <1> 
 22303                              <1> wakeup: ; / wakeup processes waiting for an event 
 22304                              <1> 	; / by linking them to the queue
 22305                              <1> 	;
 22306                              <1> 	; 27/02/2022
 22307                              <1> 	; 15/09/2015
 22308                              <1> 	; 29/06/2015
 22309                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 22310                              <1> 	;
 22311                              <1> 	; 15/05/2013 - 02/06/2014
 22312                              <1> 	; Retro UNIX 8086 v1 modification !
 22313                              <1> 	; (Process/task switching routine by using
 22314                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.)
 22315                              <1> 	;
 22316                              <1> 	; In original UNIX v1, 'wakeup' is called to wake the process
 22317                              <1> 	; sleeping in the specified wait channel by creating a link 
 22318                              <1> 	; to it from the last user process on the run queue.
 22319                              <1> 	; If there is no process to wake up, nothing happens.
 22320                              <1> 	;
 22321                              <1> 	; In Retro UNIX 8086 v1, Int 09h keyboard interrupt will set
 22322                              <1> 	; 'switching' status of the current process (owns current tty)
 22323                              <1> 	; (via alt + function keys) to a process which has highest
 22324                              <1> 	; priority (on run queue) on the requested tty (0 to 7, except
 22325                              <1> 	; 8 and 9 which are tty identifiers of COM1, COM2 serial ports)
 22326                              <1> 	; as it's console tty. (NOTE: 'p.ttyc' is used to set console
 22327                              <1> 	; tty for tty switching by keyboard.)	 
 22328                              <1> 	; 
 22329                              <1> 	; INPUT -> 
 22330                              <1> 	;	   AL = wait channel (r3) ('tty number' for now)
 22331                              <1> 	;	   ;;EBX = Run queue (r2) offset
 22332                              <1> 	;
 22333                              <1> 	; ((modified registers: EAX, EBX))
 22334                              <1> 	;
 22335 00004752 0FB6D8              <1> 	movzx	ebx, al ; 29/06/2015
 22336 00004755 81C3[C8670000]      <1> 	add	ebx, wlist
 22337 0000475B 8A03                <1> 	mov	al, [ebx] ; waiting list (waiting process number)
 22338 0000475D 20C0                <1> 	and	al, al
 22339 0000475F 741E                <1> 	jz	short wa0 ; nothing to wakeup
 22340                              <1> 	;
 22341 00004761 30E4                <1> 	xor	ah, ah
 22342 00004763 8825[EC6C0000]      <1> 	mov 	[u.quant], ah ; 0 ; time quantum = 0	
 22343 00004769 8823                <1> 	mov	[ebx], ah ; 0 ; zero wait channel entry
 22344                              <1> 	; 15/09/2015
 22345 0000476B 0FB6D8              <1> 	movzx	ebx, al
 22346                              <1> 	; 27/02/2022 (p.waitc is not used)
 22347                              <1> 	;mov	[ebx+p.waitc-1], ah ; 0
 22348 0000476E FEC4                <1> 	inc	ah
 22349 00004770 88A3[C3680000]      <1> 	mov	byte [ebx+p.stat-1], ah ; 1 ; SRUN
 22350                              <1> 	;
 22351 00004776 57                  <1> 	push	edi
 22352 00004777 52                  <1> 	push	edx
 22353 00004778 E851FFFFFF          <1> 	call	putlu
 22354 0000477D 5A                  <1> 	pop	edx
 22355 0000477E 5F                  <1> 	pop	edi
 22356                              <1> wa0:
 22357 0000477F C3                  <1> 	retn
 22358                              <1> 
 22359                              <1> 	; 27/02/2022
 22360                              <1> 	; 05/12/2021
 22361                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
 22362                              <1> sleep: 
 22363                              <1> 	; 15/09/2015
 22364                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 22365                              <1> 	;
 22366                              <1> 	; 09/05/2013 - 20/03/2014
 22367                              <1> 	;
 22368                              <1> 	; Retro UNIX 8086 v1 modification !
 22369                              <1> 	; (Process/task switching and quit routine by using
 22370                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 22371                              <1> 	;
 22372                              <1> 	; In original UNIX v1, 'sleep' is called to wait for
 22373                              <1> 	; tty and tape output or input becomes available
 22374                              <1> 	; and process is put on waiting channel and swapped out,
 22375                              <1> 	; then -when the tty or tape is ready to write or read-
 22376                              <1> 	; 'wakeup' gets process back to active swapped-in status.)
 22377                              <1> 	;
 22378                              <1> 	; In Retro UNIX 8086 v1, Int 1Bh ctrl+brk interrupt and
 22379                              <1> 	; Int 09h keyboard interrupt will set 'quit' or 'switching'		
 22380                              <1> 	; status of the current process also INT 1Ch will count down
 22381                              <1> 	; 'uquant' value and INT 09h will redirect scancode of keystroke
 22382                              <1> 	; to tty buffer of the current process and kernel will get
 22383                              <1> 	; user input by using tty buffer of the current process
 22384                              <1> 	; (instead of standard INT 16h interrupt).
 22385                              <1> 	; TTY output will be redirected to related video page of text mode
 22386                              <1> 	; (INT 10h will be called with different video page depending
 22387                              <1> 	; on tty assignment of the active process: 0 to 7 for
 22388                              <1> 	; pseudo screens.)
 22389                              <1> 	;
 22390                              <1> 	; In Retro UNIX 8086 v1, 'sleep' will be called to wait for
 22391                              <1> 	; a keystroke from keyboard or wait for reading or writing
 22392                              <1> 	; characters/data on serial port(s).
 22393                              <1> 	;
 22394                              <1> 	; Character/Terminal input/output through COM1 and COM2 will be
 22395                              <1> 	; performed by related routines in addition to pseudo TTY routines.
 22396                              <1> 	; 
 22397                              <1> 	; R1 = AH = wait channel (0-9 for TTYs) ; 05/10/2013 (22/09/2013)
 22398                              <1> 	;
 22399                              <1> 	;; 05/10/2013
 22400                              <1>         ;10/12/2013
 22401                              <1> 	;cmp   byte [u.uno], 1
 22402                              <1>         ;ja    short sleep0
 22403                              <1> 	;retn
 22404                              <1> 
 22405                              <1> 	; 20/03/2014
 22406                              <1> 	;mov	bx, [runq]
 22407                              <1> 	;cmp	bl, bh
 22408                              <1> 	;jne	short sleep0	
 22409                              <1> 	; 25/02/2014
 22410                              <1> 	;cmp	word ptr [runq], 0
 22411                              <1> 	;ja	short sleep0	
 22412                              <1> 	;retn
 22413                              <1> sleep0:
 22414                              <1> 	;
 22415 00004780 E849000000          <1> 	call	isintr
 22416                              <1> 	;jnz	sysret
 22417                              <1> 		; / wait for event
 22418                              <1>        		; jsr r0,isintr / check to see if interrupt 
 22419                              <1> 			      ; / or quit from user
 22420                              <1>                		; br 2f / something happened
 22421                              <1> 			      ; / yes, his interrupt so return
 22422                              <1>                      	      ;	/ to user
 22423                              <1> 	; 05/12/2021
 22424 00004785 7405                <1> 	jz	short sleep_2
 22425                              <1> sleep_3:
 22426 00004787 E9F9E9FFFF          <1> 	jmp	sysret
 22427                              <1> sleep_2:
 22428                              <1> 	; 30/06/2015
 22429 0000478C 0FB6DC              <1>     	movzx	ebx, ah ; 30/06/2015
 22430 0000478F 81C3[C8670000]      <1> 	add	ebx, wlist
 22431 00004795 8A03                <1> 	mov	al, [ebx]
 22432 00004797 20C0                <1> 	and	al, al
 22433 00004799 7407                <1> 	jz	short sleep1
 22434 0000479B 53                  <1> 	push	ebx
 22435 0000479C E82DFFFFFF          <1> 	call	putlu
 22436 000047A1 5B                  <1> 	pop	ebx
 22437                              <1> sleep1:
 22438 000047A2 A0[F56C0000]        <1> 	mov	al, [u.uno]    
 22439 000047A7 8803                <1>   	mov	[ebx], al 	; put the process number
 22440                              <1> 				; in the wait channel
 22441                              <1> 		; mov (r0)+,r1 / put number of wait channel in r1
 22442                              <1> 		; movb wlist(r1),-(sp) / put old process number in there,
 22443                              <1> 				     ; / on the stack
 22444                              <1>        		; movb u.uno,wlist(r1) / put process number of process
 22445                              <1> 				     ; / to put to sleep in there
 22446                              <1> 	; 30/11/2021
 22447 000047A9 31DB                <1> 	xor	ebx, ebx
 22448 000047AB 8A1D[816C0000]      <1> 	mov	bl, [cdev]
 22449 000047B1 53                  <1> 	push	ebx
 22450                              <1>         ; 15/09/2015
 22451                              <1> 	;movzx	ebx, al
 22452 000047B2 88C3                <1> 	mov	bl, al
 22453 000047B4 C683[C3680000]04    <1>         mov     byte [ebx+p.stat-1], 4 ; SSLEEP
 22454                              <1> 	; 27/02/2022 (p.waitc is not used)
 22455                              <1> 	;inc	ah
 22456                              <1> 	;mov	[ebx+p.waitc-1], ah ; wait channel + 1
 22457                              <1> 	;
 22458                              <1> 	;
 22459                              <1> 	;push	word [cdev]
 22460                              <1> 	;	; mov cdev,-(sp) / nothing happened in isintr so
 22461 000047BB E841FEFFFF          <1> 	call	swap
 22462                              <1>        		; jsr r0,swap / swap out process that needs to sleep
 22463                              <1>         ;pop	word [cdev]
 22464                              <1> 	;	; mov (sp)+,cdev / restore device
 22465                              <1> 	; 30/11/2021
 22466 000047C0 58                  <1> 	pop	eax
 22467 000047C1 A2[816C0000]        <1> 	mov	[cdev], al
 22468 000047C6 E803000000          <1> 	call	isintr
 22469                              <1> 	; 22/09/2013
 22470                              <1> 	;jnz	sysret         
 22471                              <1> 		; jsr r0,isintr / check for interrupt of new process
 22472                              <1>                		; br 2f / yes, return to new user
 22473                              <1> 		; movb (sp)+,r1 / no, r1 = old process number that was 
 22474                              <1> 				; / originally on the wait channel
 22475                              <1>        		; beq 1f / if 0 branch
 22476                              <1>   		; mov $runq+4,r2 / r2 points to lowest priority queue
 22477                              <1>        		; mov $300,*$ps / processor priority = 6
 22478                              <1> 		; jsr r0,putlu / create link to old process number
 22479                              <1>        		; clr *$ps / clear the status; process priority = 0
 22480                              <1> 	; 05/12/2021
 22481 000047CB 75BA                <1> 	jnz	short sleep_3 ; jump to sysret
 22482                              <1>      ;1:
 22483 000047CD C3                  <1> 	retn
 22484                              <1> 		; rts r0 / return
 22485                              <1>      ;2:
 22486                              <1>         ;;jmp	sysret
 22487                              <1> 		; jmp sysret / return to user
 22488                              <1> 
 22489                              <1> isintr:
 22490                              <1> 	; 30/11/2021	
 22491                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 22492                              <1> 	;
 22493                              <1> 	; 09/05/2013 - 30/05/2014
 22494                              <1> 	;
 22495                              <1> 	; Retro UNIX 8086 v1 modification !
 22496                              <1> 	; (Process/task switching and quit routine by using
 22497                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 22498                              <1> 	;
 22499                              <1> 	; Retro UNIX 8086 v1 modification:
 22500                              <1> 	; 'isintr' checks if user interrupt request is enabled
 22501                              <1> 	;  and there is a 'quit' request by user;
 22502                              <1> 	;  otherwise, 'isintr' will return with zf=1 that means
 22503                              <1> 	;  "nothing to do". (20/10/2013)
 22504                              <1> 	;
 22505                              <1> 	; 20/10/2013
 22506 000047CE 66833D[DA6C0000]00  <1> 	cmp 	word [u.ttyp], 0 ; has process got a tty ?
 22507 000047D6 761F                <1> 	jna	short isintr2 ; retn
 22508                              <1> 	; 03/09/2013
 22509                              <1> 	; (nothing to do)
 22510                              <1> 	;retn
 22511                              <1> 	; 22/09/2013
 22512 000047D8 66833D[F06C0000]00  <1> 	cmp	word [u.intr], 0
 22513 000047E0 7615                <1> 	jna	short isintr2 ; retn
 22514                              <1> 	; 30/05/2014
 22515                              <1> 	;push	ax
 22516 000047E2 50                  <1> 	push	eax ; 30/11/2021 
 22517 000047E3 66A1[F26C0000]      <1> 	mov	ax, [u.quit]
 22518 000047E9 6609C0              <1> 	or	ax, ax ; 0 ?
 22519 000047EC 7408                <1> 	jz	short isintr1 ; zf = 1
 22520 000047EE 6683F8FE            <1> 	cmp	ax, 0FFFEh  ; 'ctrl + brk' check
 22521 000047F2 7702                <1> 	ja	short isintr1 ; 0FFFFh, zf = 0
 22522                              <1> 	;xor	ax, ax ; zf = 1
 22523                              <1> 	; 30/11/2021
 22524 000047F4 31C0                <1> 	xor	eax, eax
 22525                              <1> isintr1:
 22526                              <1> 	;pop	ax
 22527                              <1> 	; 30/11/2021
 22528 000047F6 58                  <1> 	pop	eax
 22529                              <1> isintr2: ; 22/09/2013
 22530                              <1> 	; zf=1 -> nothing to do
 22531 000047F7 C3                  <1> 	retn
 22532                              <1> 
 22533                              <1> 	; UNIX v1 original 'isintr' routine... 
 22534                              <1>        	;mov     r1,-(sp) / put number of wait channel on the stack
 22535                              <1>        	;mov     r2,-(sp) / save r2
 22536                              <1>        	;mov     u.ttyp,r1 / r1 = pointer to buffer of process control
 22537                              <1>         ;                 / typewriter
 22538                              <1>        	;beq     1f / if 0, do nothing except skip return
 22539                              <1>        	;movb    6(r1),r1 / put interrupt char in the tty buffer in r1
 22540                              <1>        	;beq     1f / if its 0 do nothing except skip return
 22541                              <1>        	;cmp     r1,$177 / is interrupt char = delete?
 22542                              <1>        	;bne     3f / no, so it must be a quit (fs)
 22543                              <1>        	;tst     u.intr / yes, value of u.intr determines handling
 22544                              <1>         ;              / of interrupts
 22545                              <1>        	;bne     2f / if not 0, 2f. If zero do nothing.
 22546                              <1>      ;1:
 22547                              <1>        	;tst     (r0)+ / bump r0 past system return (skip)
 22548                              <1>      ;4:
 22549                              <1>        	;mov     (sp)+,r2 / restore r1 and r2
 22550                              <1>        	;mov     (sp)+,r1
 22551                              <1>        	;rts     r0
 22552                              <1>      ;3: / interrupt char = quit (fs)
 22553                              <1>        	;tst     u.quit / value of u.quit determines handling of quits
 22554                              <1>        	;beq     1b / u.quit = 0 means do nothing
 22555                              <1>      ;2: / get here because either u.intr <> 0 or u.qult <> O
 22556                              <1>        	;mov     $tty+6,r1 / move pointer to tty block into r1
 22557                              <1>      ;1: / find process control tty entry in tty block
 22558                              <1>        	;cmp     (r1),u.ttyp / is this the process control tty buffer?
 22559                              <1>        	;beq     1f / block found go to 1f
 22560                              <1>        	;add     $8,r1 / look at next tty block
 22561                              <1>        	;cmp     r1,$tty+[ntty*8]+6 / are we at end of tty blocks
 22562                              <1>        	;blo     1b / no
 22563                              <1>        	;br      4b / no process control tty found so go to 4b
 22564                              <1>      ;1:
 22565                              <1>        	;mov     $240,*$ps / set processor priority to 5
 22566                              <1>        	;movb    -3(r1),0f / load getc call argument; character llst
 22567                              <1>         ;                  / identifier
 22568                              <1>        	;inc     0f / increment
 22569                              <1>      ;1:
 22570                              <1>        	;jsr     r0,getc; 0:.. / erase output char list for control
 22571                              <1>         ;        br 4b / process tty. This prevents a line of stuff
 22572                              <1>         ;             / being typed out after you hit the interrupt
 22573                              <1>         ;             / key
 22574                              <1>        	;br      1b
 22575                                  %include 'u5.s'      ; 03/06/2015
 22576                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 22577                              <1> ; (re-write kernel for test by using previous version without a major defect)
 22578                              <1> ; ****************************************************************************
 22579                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS5.INC
 22580                              <1> ; Last Modification: 17/07/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.3)
 22581                              <1> ; ----------------------------------------------------------------------------
 22582                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22583                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22584                              <1> ;
 22585                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22586                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22587                              <1> ; <Bell Laboratories (17/3/1972)>
 22588                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22589                              <1> ;
 22590                              <1> ; Retro UNIX 8086 v1 - U5.AS M (07/08/2013) //// UNIX v1 -> u5.s
 22591                              <1> ;
 22592                              <1> ; ****************************************************************************
 22593                              <1> 
 22594                              <1> 	; 09/03/2022
 22595                              <1> 	; 09/01/2022
 22596                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22597                              <1> mget_w:
 22598                              <1> 	; 28/10/2021
 22599                              <1> 	; 22/08/2021
 22600                              <1> 	; 20/08/2021
 22601                              <1> 	; 25/05/2020
 22602                              <1> 	; 24/05/2020 - Retro UNIX 386 v2	
 22603 000047F8 C605[3A6D0000]01    <1> 	mov	byte [mget_rw], 1 ; write access
 22604 000047FF EB07                <1> 	jmp	short mget
 22605                              <1> mget_r:
 22606                              <1> 	; 28/10/2021
 22607                              <1> 	; 22/08/2021
 22608                              <1> 	; 25/05/2020
 22609                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 22610 00004801 C605[3A6D0000]00    <1> 	mov	byte [mget_rw], 0 ; read access	
 22611                              <1> mget:
 22612                              <1> 	; 17/07/2022
 22613                              <1> 	; 09/03/2022
 22614                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 22615                              <1> 	; 28/11/2021
 22616                              <1> 	; 22/11/2021
 22617                              <1> 	; 28/10/2021 - temporary (simplified code)
 22618                              <1> 	; 22/08/2021
 22619                              <1> 	; 20/08/2021
 22620                              <1> 	; 25/05/2020
 22621                              <1> 	; 24/05/2020
 22622                              <1> 	; 05/05/2020
 22623                              <1> 	; 02/05/2020, 03/05/2020
 22624                              <1> 	; 29/04/2020 - Retro UNIX 386 v2
 22625                              <1> 	; New inode model/format (Modified UNIX v7 inode model)
 22626                              <1> 	;	
 22627                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22628                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 22629                              <1> 	;
 22630                              <1> 	; Get existing or (allocate) a new disk block for file
 22631                              <1> 	; 
 22632                              <1> 	; INPUTS ->
 22633                              <1> 	;    u.fofp (file offset pointer)
 22634                              <1> 	;    inode 
 22635                              <1> 	;    u.off (file offset)
 22636                              <1> 	; OUTPUTS ->
 22637                              <1> 	;    r1 (physical block number)
 22638                              <1> 	;    r2, r3, r5 (internal)
 22639                              <1> 	;
 22640                              <1> 	; ((AX = R1)) output
 22641                              <1> 	;    (Retro UNIX Prototype : 05/03/2013 - 14/11/2012, UNIXCOPY.ASM)
 22642                              <1> 	;
 22643                              <1> 	; Modified registers: eax, edx, ebx, ecx, esi, edi, ebp
 22644                              <1> 
 22645                              <1> 	; Retro UNIX 386 v2 'mget' procedure
 22646                              <1> 	; source code reference:
 22647                              <1> 	; 'mget' procedure in UNIXHDCP.ASM (25/01/2020) by Erdogan Tan
 22648                              <1> 
 22649                              <1> 	; Get sector/block address for current file pointer
 22650                              <1> 	; (If file pointer points to a number greater than current file
 22651                              <1> 	; size, a new -empty- sector/block will be created/written.)
 22652                              <1> 
 22653                              <1> 	; Note: 'mget' procedure will be used for only RUNIX v2 FS.
 22654                              <1> 	;	(installable file system drivers will not use 'mget')
 22655                              <1> 	;	 !!! 512 bytes per sector !!!  ; 02/05/2020
 22656                              <1> 
 22657                              <1> 	; ! 64 bit fofp ! but Retro UNIX 386 v2 kernel will use 32 bit
 22658                              <1> 	; file offset for regular files and directories.
 22659                              <1> 	; ('mget' procedure will be called for regular files & directories)
 22660                              <1> 
 22661                              <1> 	; 28/10/2021
 22662                              <1> 	; Note: 'mget' uses only current inode ([ii], 'inode:')
 22663                              <1> 	; (inode must be loaded at 'inode:' addr by 'iget' before 'mget')  
 22664                              <1> 
 22665                              <1> 		; mov *u.fofp,mq / file offset in mq
 22666                              <1> 		; clr ac / later to be high sig
 22667                              <1> 		; mov $-8,lsh   / divide ac/mq by 256.
 22668                              <1> 		; mov mq,r2
 22669                              <1> 		; bit $10000,i.flgs / lg/sm is this a large or small file
 22670                              <1> 		; bne 4f / branch for large file
 22671                              <1> 
 22672                              <1> 	; 09/01/2022
 22673                              <1> 	; Return: eax = physical block/sector number
 22674                              <1> mget_0:	
 22675 00004808 8B35[B86C0000]      <1>         mov     esi, [u.fofp]
 22676 0000480E 8B1E                <1> 	mov	ebx, [esi]
 22677                              <1>         ; ebx = file offset
 22678                              <1> 
 22679                              <1> 	; 20/08/2021
 22680 00004810 C1EB09              <1> 	shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 22681                              <1> 
 22682 00004813 F605[25680000]10    <1> 	test	byte [i.flgs+1], 10h ; is this a large or small file addr?
 22683 0000481A 7405                <1> 	jz	short mget_1 ; small file addressing
 22684 0000481C E984000000          <1> 	jmp	mget_5	; large file addressing
 22685                              <1> mget_1:
 22686                              <1> 	; If large file flag is clear -not set- RUNIX v2 FS inode
 22687                              <1> 	; will contain 10 direct disk block/sector dword pointers.
 22688                              <1> 
 22689                              <1> 	; 05/05/2020
 22690                              <1> 	;shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 22691                              <1> 
 22692 00004821 83FB0A              <1> 	cmp	ebx, 10	; block 10
 22693 00004824 7338                <1> 	jnb	short mget_3 ; file offset >= 5120
 22694                              <1> 
 22695                              <1> 	; 05/05/2020
 22696                              <1> 	;cmp	ebx, 5120
 22697                              <1> 	;jnb	short mget_3 ; file offset >= 5120
 22698                              <1> 
 22699                              <1> 	;mov	bl, bh
 22700                              <1> 	;and	bl, 1Eh ; clear all bits but bits 1,2,3,4 ; 0,2,..,18
 22701                              <1> 	;	; max. value = 12h = 10010b = 18 (because ebx <= 5119) 
 22702                              <1> 	;shl	bl, 1	; * 2 ; max. value = 24h = 100100b = 36
 22703                              <1> 	;xor	bh, bh  ; clear bh
 22704                              <1> 		; RUNIX v2 (RUFS 2) file system bytes per sector value
 22705                              <1> 		; is always 512.
 22706                              <1> 		; ebx = 4*(ebx/512)  = 0 to 36
 22707                              <1> 
 22708                              <1> 	; 05/05/2020
 22709 00004826 C0E302              <1> 	shl	bl, 2 ; * 4
 22710                              <1> 		 ; ebx = 0 to 36
 22711                              <1> 
 22712 00004829 8B83[30680000]      <1> 	mov	eax, [ebx+i.dskp] ; disk sector addr ptr 0 to 9 for file
 22713                              <1> 	; 22/08/2021
 22714 0000482F 89DE                <1> 	mov	esi, ebx
 22715                              <1> 	;xor	ebx, ebx ; 0
 22716                              <1> 	; 09/03/2022
 22717                              <1> 	;; 09/01/2022
 22718                              <1> 	;xor	bl, bl
 22719                              <1> 
 22720 00004831 09C0                <1> 	or	eax, eax
 22721 00004833 7512                <1> 	jnz	short mget_2 ; existing block/sector (logical)
 22722                              <1> 
 22723 00004835 56                  <1> 	push	esi ; * ; 22/08/2021
 22724 00004836 E872010000          <1> 	call	alloc_m ; 24/05/2020	
 22725                              <1> 	;call	alloc	; allocate a new sector/block for this file	
 22726                              <1> 			; eax = sector/block number
 22727                              <1> 			; ebx = buffer header address
 22728 0000483B 5E                  <1> 	pop	esi ; * ; 22/08/2021
 22729                              <1> 	; 28/11/2021
 22730                              <1> 	;jc	short mget_2 
 22731                              <1> 			; cf = 1 -> eax = 'no free block' error
 22732                              <1> 	; 22/08/2021
 22733 0000483C 8986[30680000]      <1> 	mov	[esi+i.dskp], eax  ; logical sector/block address
 22734                              <1> 
 22735                              <1> 	; 09/01/2022
 22736 00004842 E8BF040000          <1> 	call	setimod	; set inode modification flag
 22737                              <1> 			; and set modification time
 22738                              <1> 
 22739                              <1> 	; eax = logical sector/block number
 22740                              <1> 	; ([idev] = logical drive number)
 22741                              <1> 	; 28/10/2021
 22742                              <1> 	; [cdev] = logical drive number (0 or 1)
 22743                              <1> 	;	(0 = root fs, 1 = mounted fs)
 22744                              <1> mget_2:
 22745                              <1> 	; 09/01/2022
 22746                              <1> 	; eax = logical sector/block number
 22747 00004847 F605[816C0000]01    <1> 	test	byte [cdev], 1
 22748 0000484E 7507                <1> 	jnz	short mget_14
 22749                              <1> 	; convert to physical sector/block number
 22750 00004850 0305[586D0000]      <1> 	add	eax, [systm+SB.BootSectAddr]
 22751 00004856 C3                  <1> 	retn
 22752                              <1> 	; 09/01/2022
 22753                              <1> mget_14:
 22754                              <1> 	; convert to physical sector/block number
 22755 00004857 0305[606F0000]      <1> 	add	eax, [mount+SB.BootSectAddr]
 22756 0000485D C3                  <1> 	retn
 22757                              <1> 	
 22758                              <1> 		; rts r0
 22759                              <1> mget_3: ; 3: / adding on block which changes small file to a large file
 22760                              <1> 	; 22/11/2021
 22761 0000485E E84A010000          <1> 	call	alloc_m ; 24/05/2020
 22762                              <1> 	;call	alloc	; allocate a new sector/block for this file
 22763                              <1> 			; eax = sector/block number
 22764                              <1> 			; ebx = buffer header  ; 24/05/2020
 22765                              <1> 	; 28/11/2021
 22766                              <1> 	;jc	short mget_2 ; error code in eax
 22767                              <1> 
 22768                              <1> 	; 09/01/2022
 22769                              <1> 	; convert to physical block/sector number
 22770 00004863 50                  <1> 	push	eax ; *!* ; logical sector/block number 
 22771 00004864 E8DEFFFFFF          <1> 	call	mget_2
 22772                              <1> 
 22773                              <1>         ; EAX (r1) = Physical block (sector) number
 22774 00004869 E886110000          <1> 	call 	wslot
 22775                              <1> 		; jsr r0,wslot / set up I/O buffer for write, r5 points to 
 22776                              <1> 			     ; / first data word in buffer
 22777                              <1>         ; EAX (r1) = Physical block number
 22778                              <1> 	; 28/11/2021
 22779                              <1> 	; ebx = buffer (data) address
 22780                              <1> 	; 22/11/2021
 22781 0000486E 31C9                <1> 	xor	ecx, ecx
 22782 00004870 B10A                <1> 	mov 	cl, 10	; r3, transfer old physical block pointers
 22783                              <1> 			; into new indirect block area for the new
 22784                              <1> 			; large file		
 22785 00004872 89DF                <1> 	mov 	edi, ebx ; r5
 22786 00004874 BE[30680000]        <1> 	mov	esi, i.dskp  ; current inode's direct disk addr ptrs
 22787 00004879 89C2                <1> 	mov	edx, eax
 22788 0000487B 31C0                <1> 	xor	eax, eax
 22789                              <1> mget_4:
 22790 0000487D A5                  <1> 	movsd 	
 22791 0000487E 8946FC              <1> 	mov	[esi-4], eax ; 0
 22792 00004881 E2FA                <1> 	loop	mget_4
 22793                              <1> 
 22794                              <1> 	; 22/11/2021
 22795 00004883 B176                <1> 	mov 	cl, 128-10 ; clear rest of data buffer
 22796                              <1> ;mget_4: ; 1
 22797 00004885 F3AB                <1> 	rep 	stosd
 22798                              <1> 		; clr (r5)+
 22799                              <1> 		; dec r3
 22800                              <1> 		; bgt 1b
 22801 00004887 89D0                <1> 	mov	eax, edx
 22802                              <1>         ; EAX (r1) = Physical block number
 22803 00004889 E873110000          <1> 	call	dskwr
 22804                              <1> 		; jsr r0,dskwr / write new indirect block on disk
 22805                              <1> 
 22806                              <1> 	;; EAX (r1) = Physical block number
 22807                              <1> 
 22808                              <1> 	; 09/01/2022        
 22809 0000488E 8F05[30680000]      <1> 	pop	dword [i.dskp] ; *!* ; logical sector/block number
 22810                              <1>  
 22811                              <1> 	; eax = logical disk sector/block number/addr ; 09/01/2022
 22812                              <1> 	;mov 	[i.dskp], eax ; 22/11/2021 
 22813                              <1> 		; mov r1,i.dskp / put pointer to indirect block in i-node
 22814                              <1> 
 22815 00004894 800D[25680000]10    <1> 	or	byte [i.flgs+1], 10000b ; 10h ; 16  ; large file flag
 22816                              <1> 		; bis $10000,i.flgs / set large file bit 
 22817                              <1> 				  ; / in i.flgs word of i-node
 22818 0000489B E866040000          <1> 	call	setimod
 22819                              <1> 		; jsr r0,setimod / set i-node modified flag
 22820                              <1> 
 22821 000048A0 E963FFFFFF          <1> 	jmp	mget_0 ; 09/01/2022
 22822                              <1> 		; br mget
 22823                              <1> 
 22824                              <1> mget_5:  ; 4 ; large file
 22825                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 22826                              <1> 	;
 22827                              <1> 	; Retro UNIX 386 v2 disk inode contains..
 22828                              <1> 	; (if large file flag is set)
 22829                              <1> 	; 8 indirect disk block/sector dword pointers
 22830                              <1> 	; +1 double indirect disk block/sector dword pointers
 22831                              <1> 	; +1 triple indirect disk block/sector dword pointers
 22832                              <1> 
 22833                              <1> 	; check indirect pointers limit (as file offset)
 22834                              <1> 	; 8*128 = 1024 blocks (or sectors) or 512 KB
 22835                              <1> 	; check dx (file offset hw) value
 22836                              <1> 	
 22837                              <1> 	; 03/05/2020
 22838                              <1> 	;cmp	ebx, 524288  ; is file offset >= 524288 ?
 22839                              <1> 	;jnb	short mget_6 ; yes, check double indirect limit
 22840                              <1> 
 22841                              <1> 	; 05/05/2020
 22842 000048A5 81FB00040000        <1> 	cmp	ebx, 1024    ; block 1024 (byte 524288)	
 22843 000048AB 7320                <1> 	jnb	short mget_6 ; check double indirect limit
 22844                              <1> 
 22845 000048AD C605[3C6D0000]01    <1> 	mov	byte [level], 1 ; levels, 1 = indirect blocks
 22846                              <1> 
 22847                              <1> 	; 05/05/2020
 22848                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 22849                              <1> 
 22850 000048B4 88D9                <1> 	mov	cl, bl
 22851 000048B6 80E17F              <1> 	and	cl, 127
 22852 000048B9 880D[3D6D0000]      <1> 	mov	[level+1], cl ; level 1, direct block ptr index (0 to 127)
 22853                              <1> 	;shr	bx, 7 ; bl = level 0, indirect block pointer index (0 to 7)
 22854                              <1> 	; 17/07/2022
 22855 000048BF C1EB07              <1> 	shr	ebx, 7
 22856                              <1> 	;mov	[level+2], bl
 22857                              <1> 
 22858 000048C2 C0E302              <1> 	shl	bl, 2 ; * 4 to convert index number to offset
 22859                              <1> 
 22860                              <1> 	;mov	esi, i.dskp
 22861                              <1> 	;add	esi, ebx
 22862                              <1> 
 22863 000048C5 8DB3[30680000]      <1> 	lea	esi, [ebx+i.dskp]
 22864                              <1> 
 22865 000048CB EB64                <1> 	jmp	short mget_8
 22866                              <1> 
 22867                              <1> mget_6:
 22868                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22869                              <1> 	; 03/05/2020
 22870                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 22871                              <1> 	; check double indirect pointer limit (as file offset)
 22872                              <1> 	; (128*128)+1024 = 16384+1024 blocks or 8 MB + 512 KB
 22873                              <1> 	; check dx (file offset hw) value
 22874                              <1> 	
 22875                              <1> 	;cmp	ebx, 8912896 ; >= 17408 sectors (16384+1024) ?	
 22876                              <1> 	;jnb	short mget_7 ; yes, use triple indirect pointer (block)
 22877                              <1> 
 22878                              <1> 	; 05/05/2020
 22879 000048CD 81FB00440000        <1> 	cmp	ebx, 17408   ; block 17408 (byte 8912896)	
 22880 000048D3 7328                <1> 	jnb	short mget_7 ; use triple indirect pointer (block)
 22881                              <1> 
 22882 000048D5 C605[3C6D0000]02    <1> 	mov	byte [level], 2  ; levels, 2 = double indirect blocks
 22883                              <1> 	
 22884                              <1> 	;sub	ebx, 524288 ; 1024 sectors
 22885                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 22886                              <1> 			; (from sector 1024)
 22887                              <1> 	; 05/05/2020
 22888 000048DC 81EB00040000        <1> 	sub	ebx, 1024 ; offset from sector 1024
 22889                              <1> 	
 22890 000048E2 88D9                <1> 	mov	cl, bl
 22891 000048E4 80E17F              <1> 	and	cl, 127
 22892 000048E7 880D[3D6D0000]      <1> 	mov	[level+1], cl
 22893                              <1> 			; level 2, direct block ptr index (0 to 127)	
 22894                              <1> 	;shr	bx, 7
 22895                              <1> 	; 17/07/2022
 22896 000048ED C1EB07              <1> 	shr	ebx, 7
 22897 000048F0 881D[3E6D0000]      <1> 	mov	[level+2], bl
 22898                              <1> 			; level 1, indirect block ptr index (0 to 127)
 22899                              <1> 
 22900 000048F6 BE[50680000]        <1> 	mov	esi, i.dskp + 32 ; 8*4
 22901                              <1> 			; level 0, double indirect block pointer
 22902 000048FB EB34                <1> 	jmp	short mget_8
 22903                              <1> 
 22904                              <1> mget_7:
 22905                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22906                              <1> 	; 03/05/2020
 22907                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 22908                              <1> 	; triple indirect pointer ; 8912896 to 1082654720 bytes
 22909                              <1> 	;mov	esi, i.dskp + 36 ; 9*4
 22910                              <1> 
 22911 000048FD C605[3C6D0000]03    <1> 	mov	byte [level], 3  ; levels, 3 = triple indirect blocks
 22912                              <1> 
 22913                              <1> 	;sub	ebx, 8912896 ; 17408 sectors (16384+1024)
 22914                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 22915                              <1> 			; (from sector 17408)
 22916                              <1> 	; 05/05/2020
 22917 00004904 81EB00440000        <1> 	sub	ebx, 17408 ; offset from sector 17408	
 22918                              <1> 
 22919 0000490A 88D9                <1> 	mov	cl, bl
 22920 0000490C 80E17F              <1> 	and	cl, 127
 22921 0000490F 880D[3D6D0000]      <1> 	mov	[level+1], cl  
 22922                              <1> 			; level 3, direct block ptr index (0 to 127)	
 22923 00004915 C1EB07              <1> 	shr	ebx, 7	
 22924 00004918 88D9                <1> 	mov	cl, bl
 22925 0000491A 80E17F              <1> 	and	cl, 127
 22926 0000491D 880D[3E6D0000]      <1> 	mov	[level+2], cl
 22927                              <1> 			; level 2, indirect block ptr index (0 to 127)
 22928                              <1> 	;shr	bx, 7
 22929                              <1> 	; 17/07/2022
 22930 00004923 C1EB07              <1> 	shr	ebx, 7
 22931 00004926 881D[3F6D0000]      <1> 	mov	[level+3], bl
 22932                              <1> 			; level 1, double indir blk ptr index (0 to 127)
 22933                              <1> 
 22934 0000492C BE[54680000]        <1> 	mov	esi, i.dskp + 36 ; 9*4
 22935                              <1> 			; level 0, triple indirect block pointer
 22936                              <1> mget_8:
 22937                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22938 00004931 8B06                <1> 	mov	eax, [esi]
 22939 00004933 09C0                <1> 	or 	eax, eax ; R1
 22940 00004935 751A                <1> 	jnz 	short mget_10 ; 2f
 22941                              <1> 		; bne 2f / if no indirect block exists
 22942 00004937 56                  <1> 	push	esi	; * ; 24/05/2020
 22943                              <1> 
 22944 00004938 E870000000          <1> 	call	alloc_m ; 24/05/2020
 22945                              <1> 	;call	alloc	; allocate a new block for this file	
 22946                              <1> 			; eax = block number
 22947                              <1> 			; ebx = buffer header address
 22948                              <1> 			; [pdn] = physical drive number ; 25/05/2020
 22949                              <1> 	;jc	mget_2	; cf -> 1 & eax = 0 -> no free block
 22950                              <1> 
 22951 0000493D 5E                  <1> 	pop	esi	; * ; 24/05/2020
 22952                              <1> 	;jc	short mget_9
 22953                              <1> 
 22954                              <1> 	; 09/01/2022
 22955                              <1> 	; eax = logical sector/block number
 22956                              <1> 
 22957 0000493E 8906                <1> 	mov	[esi], eax ; record sector/block address on i.dskp area
 22958                              <1> 
 22959 00004940 E8C1030000          <1> 	call 	setimod
 22960                              <1> 		; jsr r0,setimod / set i-node modified byte
 22961                              <1> 	; EAX = new block number (logical)
 22962                              <1> 
 22963                              <1> 	; 09/01/2022
 22964                              <1> 	; convert to physical block/sector number
 22965 00004945 E8FDFEFFFF          <1> 	call	mget_2
 22966                              <1> 	;
 22967 0000494A E8AEFDFFFF          <1> 	call 	clear
 22968                              <1> 		; jsr r0,clear / clear new block
 22969                              <1> 	; 09/03/2022
 22970                              <1> 	;add	ebx, 8
 22971                              <1> 	; ebx = buffer data address
 22972                              <1> 	; 22/11/2021
 22973 0000494F EB0A                <1> 	jmp	short mget_11
 22974                              <1> ;mget_9:
 22975                              <1> ;	pop	edx ; *  ; 09/01/2022
 22976                              <1> ;	retn
 22977                              <1> mget_10: ;2
 22978                              <1> 	; 09/01/2022
 22979                              <1> 	; eax = logical sector/block number/address
 22980                              <1> 	; convert to physical sector/block number/address
 22981 00004951 E8F1FEFFFF          <1> 	call	mget_2	
 22982                              <1> 	; 05/03/2013
 22983                              <1> 	; EAX = r1, physical block number (of indirect block)
 22984 00004956 E835100000          <1> 	call 	dskrd ; read indirect block
 22985                              <1> 		; jsr r0,dskrd / read in indirect block
 22986                              <1> 	;jc	short mget_9
 22987                              <1> mget_11:
 22988                              <1> 	; 22/11/2021
 22989                              <1> 	; eax = physical block/sector address
 22990                              <1> 	; ebx = buffer (data) address ; 09/03/2022
 22991                              <1> 
 22992 0000495B 89C2                <1> 	mov	edx, eax ; *  ; save physical sector number in edx
 22993                              <1> 
 22994 0000495D 0FB605[3C6D0000]    <1> 	movzx	eax, byte [level]
 22995 00004964 8A80[3C6D0000]      <1> 	mov	al, [eax+level] ; get sector pointer offset
 22996 0000496A C1E002              <1> 	shl	eax, 2 ; * 4 ; 09/01/2022
 22997                              <1> 	;shl	ax, 2 ; * 4
 22998                              <1> 
 22999 0000496D 01C3                <1> 	add	ebx, eax
 23000                              <1> 
 23001 0000496F 8B03                <1> 	mov 	eax, [ebx] ; put logical block no of block
 23002                              <1> 			   ; in file sought in R1 (EAX)
 23003                              <1> 		; mov (r2),r1 / put physical block no of block in file
 23004                              <1> 	               	    ; / sought in r1
 23005                              <1> 
 23006 00004971 21C0                <1> 	and	eax, eax  ; if logical sector/block number is zero
 23007                              <1> 			  ; then we need a new block for file
 23008 00004973 740D                <1> 	jz	short mget_12
 23009                              <1> 
 23010 00004975 FE0D[3C6D0000]      <1> 	dec	byte [level]
 23011 0000497B 75D4                <1> 	jnz	short mget_10
 23012                              <1> 
 23013                              <1> 	; 09/03/2022
 23014                              <1> 	;sub	ebx, ebx ; ebx = 0 ; existing sector
 23015                              <1> 
 23016                              <1> 	;retn
 23017                              <1> 	; 09/01/2022
 23018                              <1> 	; eax = logical block/sector number
 23019 0000497D E9C5FEFFFF          <1> 	jmp	mget_2
 23020                              <1> 
 23021                              <1> mget_12:
 23022                              <1> 	; 22/11/2021
 23023 00004982 52                  <1> 	push	edx ; *
 23024 00004983 53                  <1> 	push	ebx ; ** ; buffer data position
 23025 00004984 E824000000          <1> 	call	alloc_m
 23026                              <1> 	;call	alloc	 ; allocate a new block for this file	
 23027                              <1> 			 ; eax = block number (logical)
 23028                              <1> 			 ; ebx = buffer header address
 23029 00004989 5E                  <1> 	pop	esi ; **
 23030                              <1> 	; 09/01/2022
 23031                              <1> 	;pop	edx ; *
 23032                              <1> 	;jc	short mget_9 ; cf -> 1 & eax = 0 -> no free block
 23033                              <1> 
 23034 0000498A 8906                <1> 	mov	[esi], eax ; record/save block number (logical)
 23035                              <1> 
 23036                              <1> 	; 22/11/2021
 23037 0000498C 870424              <1> 	xchg	eax, [esp] ; *
 23038                              <1> 
 23039                              <1> 	; eax (r1) = physical block number (of indirect block)
 23040 0000498F E860100000          <1> 	call 	wslot
 23041                              <1> 		; jsr r0,wslot
 23042                              <1>         ; eax (r1) = physical block number
 23043                              <1> 	; ebx (r5) = pointer to buffer (indirect block)
 23044 00004994 E868100000          <1> 	call 	dskwr
 23045                              <1> 	; eax = r1 = physical block number (of indirect block)
 23046                              <1> 		; jsr r0,dskwr / write newly modified indirect block 
 23047                              <1> 			     ; / back out on disk
 23048 00004999 58                  <1> 	pop	eax ; *  ; 31/07/2013
 23049                              <1> 		; mov (sp),r1 / restore block number of new block	
 23050                              <1> 
 23051                              <1> 	; 09/01/2022
 23052                              <1> 	; eax = logical sector/block number/address of new block
 23053                              <1> 	; convert to physical sector/block number/address
 23054 0000499A E8A8FEFFFF          <1> 	call	mget_2	
 23055                              <1> 
 23056 0000499F E859FDFFFF          <1> 	call 	clear
 23057                              <1> 		; jsr r0,clear / clear new block
 23058                              <1> 
 23059 000049A4 FE0D[3C6D0000]      <1> 	dec	byte [level]
 23060 000049AA 75AF                <1> 	jnz	short mget_11 
 23061                              <1> 		; ebx = buffer (data) address ; 09/03/2022
 23062                              <1> 
 23063                              <1> 	; 09/01/2022
 23064                              <1> 	; eax = physical sector/block number/address of new block
 23065                              <1> 	
 23066                              <1> 	; 22/11/2021
 23067                              <1> 	; ebx = buffer address
 23068                              <1> mget_13: ; 2
 23069                              <1> 	; eax (r1) = Block number of new block
 23070 000049AC C3                  <1> 	retn
 23071                              <1> 		; rts r0
 23072                              <1> 
 23073                              <1> 	; 09/01/2022
 23074                              <1> 	; 26/11/2021
 23075                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23076                              <1> alloc_m:
 23077                              <1> 	; 27/11/2021
 23078                              <1> 	; 28/10/2021
 23079                              <1> 	; 07/05/2021
 23080                              <1> 	; 26/05/2020
 23081                              <1> 	; 25/05/2020
 23082                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 23083                              <1> 	; 'alloc' call in 'mget'
 23084                              <1> 	;
 23085                              <1> 	; (('mget_r' will be returned with error))
 23086                              <1> 	; (('mget_w' will continue to 'alloc'))
 23087                              <1> 
 23088                              <1> 	; Note: 'sysread' will return with cf = 0, eax = 0
 23089                              <1> 	; if [fofp] >= file size (eax = 0 --> EOF)
 23090                              <1> 	; So, if we are here, that means [fofp] < file size
 23091                              <1> 	;     but disk address is 0. 
 23092                              <1> 	
 23093 000049AD 803D[3A6D0000]01    <1> 	cmp	byte [mget_rw], 1 ; write access ? (mget_w) 
 23094 000049B4 730F                <1> 	jnb	short alloc ; yes (this is a call from 'mget_w')
 23095                              <1> 	; ((cf = 1))	
 23096                              <1> 	; no (this is a call from 'mget_r') !
 23097                              <1> 	;mov	eax, ERR_FILE_SIZE ; file size error (inode error!)
 23098                              <1> 		; [User may change this empty/invalid inode (disk) sector
 23099                              <1> 		; pointer with a new valid inode (disk) sector pointer 
 23100                              <1> 		; by writing new clear (zero) sector to same file position
 23101                              <1> 		; in order to correct file size -inode parm/content- error.
 23102                              <1> 		; It may be useful for recovering lost data if other sector
 23103                              <1> 		; pointers are not empty.]	
 23104                              <1> 	;retn
 23105                              <1> 	; 27/11/2021
 23106 000049B6 C705[186D0000]1400- <1> 	mov	dword [u.error], ERR_FILE_SIZE 
 23107 000049BE 0000                <1>
 23108                              <1> 			; file size error (inode error!)
 23109 000049C0 E9A0E7FFFF          <1> 	jmp	error
 23110                              <1> alloc:
 23111                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23112                              <1> 	; 27/11/2021
 23113                              <1> 	; 26/11/2021 - Major modification for Runix v2 file system
 23114                              <1> 	;	(I have called this kernel version as v1.2, it is a
 23115                              <1> 	;	 debug/test version just before Retro UNIX 386 v2 kernel)
 23116                              <1> 	;	((there were running problems on new version, 
 23117                              <1> 	;	  so i am developing an intermediate version with minimum
 23118                              <1> 	;	  modification on v1.1 code which is successfuly running))
 23119                              <1> 	;	 ; /// Erdogan Tan - Istanbul, 26/11/2021 /// 
 23120                              <1> 	;	 
 23121                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23122                              <1> 	; 01/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 23123                              <1> 	;
 23124                              <1> 	; get a free block and 
 23125                              <1> 	; set the corresponding bit in the free storage map
 23126                              <1> 	; 
 23127                              <1> 	; INPUTS ->
 23128                              <1> 	;    cdev (current device)
 23129                              <1> 	;    r2 
 23130                              <1> 	;    r3
 23131                              <1> 	; OUTPUTS ->
 23132                              <1> 	;    r1 (physical block number of block assigned)
 23133                              <1> 	;    smod, mmod, systm (super block), mount (mountable super block)	
 23134                              <1> 	;
 23135                              <1> 	; ((AX = R1)) output
 23136                              <1> 	;    (Retro UNIX Prototype : 14/11/2012 - 21/07/2012, UNIXCOPY.ASM)
 23137                              <1>         ;    ((Modified registers: edx, ecx)) 
 23138                              <1> 
 23139                              <1> 	; 26/11/2021
 23140                              <1> 	; INPUT:
 23141                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 23142                              <1> 	; OUTPUT:
 23143                              <1> 	;	eax = disk block/sector number/address (physical)
 23144                              <1> 	;	(ebx = disk buffer address for sector/block in eax)
 23145                              <1> 	;
 23146                              <1> 	;    Note:	
 23147                              <1> 	;	Free blocks map will be modified and written to it's disk.
 23148                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 23149                              <1> 	;	modification flag will be set; but the superblock 
 23150                              <1> 	;	will not be written to it's disk in this 'alloc' procedure)
 23151                              <1> 	;
 23152                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi, ebp
 23153                              <1> 
 23154                              <1> 	; 09/01/2022
 23155                              <1> 	; Return: eax = logical block/sector number 
 23156                              <1> 
 23157                              <1> 	; 26/11/2021
 23158 000049C5 BB[546D0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 23159                              <1> 		; mov $systm,r2 / start of inode and free storage map for drum
 23160 000049CA F605[816C0000]01    <1> 	test	byte [cdev], 1
 23161                              <1> 		; tst cdev
 23162 000049D1 7405                <1> 	jz	short alloc_1
 23163                              <1> 		; beq 1f / drum is device
 23164 000049D3 BB[5C6F0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 23165                              <1> 		; mov $mount,r2 / disk or tape is device, start of inode and
 23166                              <1> 			      ; / free storage map
 23167                              <1> alloc_1: ; 1
 23168                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23169 000049D8 F6436A01            <1> 	test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 23170 000049DC 7507                <1> 	jnz	short alloc_2  ; 'read only file system' error
 23171                              <1> 	;
 23172 000049DE 8B4B38              <1> 	mov	ecx, [ebx+SB.FreeBlocks] ; count of free blocks/sectors
 23173 000049E1 21C9                <1> 	and	ecx, ecx
 23174 000049E3 750F                <1> 	jnz	short alloc_3
 23175                              <1> alloc_2:
 23176                              <1> 	; 'no free blocks on disk !' error
 23177 000049E5 C705[186D0000]2100- <1> 	mov	dword [u.error], ERR_ALLOC
 23178 000049ED 0000                <1>
 23179 000049EF E971E7FFFF          <1> 	jmp	error
 23180                              <1> alloc_3:
 23181                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23182 000049F4 31C0                <1> 	xor	eax, eax
 23183                              <1> 	; 23/07/2021
 23184 000049F6 8B4B3C              <1> 	mov	ecx, [ebx+SB.FirstFreeBlk] ; 1st free sector number
 23185                              <1> 					 ; (as logical sector number)
 23186 000049F9 09C9                <1> 	or	ecx, ecx
 23187 000049FB 7415                <1> 	jz	short alloc_5 ; 0 = initial/reset value or 'not valid'
 23188 000049FD 41                  <1> 	inc	ecx ; 0FFFFFFFFh -> 0
 23189 000049FE 7412                <1> 	jz	short alloc_5 ; 'not valid' or 'not calculated'
 23190 00004A00 49                  <1> 	dec	ecx ; restore first free block value
 23191 00004A01 89C8                <1> 	mov	eax, ecx
 23192                              <1> 	; 1 allocation byte (in fbm) is for 8 sectors
 23193 00004A03 C1E903              <1> 	shr	ecx, 3	; first free block number / 8
 23194 00004A06 80E1FC              <1> 	and	cl, ~3	; dword alignment (to backward)
 23195                              <1> 	; 27/11/2021
 23196 00004A09 890D[406D0000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm
 23197                              <1> alloc_4:
 23198 00004A0F C1E80C              <1> 	shr	eax, 12 ; 1 fbm sector for 4096 sectors
 23199                              <1> alloc_5:
 23200                              <1> 	; 26/11/2021
 23201 00004A12 53                  <1> 	push	ebx ; ** ; superblock buffer address 
 23202                              <1> 	; eax = fbm sector index
 23203 00004A13 A3[446D0000]        <1> 	mov	[free_map_index], eax
 23204 00004A18 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 23205                              <1> 			; free blocks map start sector addr
 23206                              <1> 	; 09/01/2022
 23207 00004A1B 034304              <1> 	add	eax, [ebx+SB.BootSectAddr] 
 23208                              <1> 			; + Hidden Sectors
 23209                              <1> 	;
 23210                              <1> 	; eax = physical sector number
 23211 00004A1E E86D0F0000          <1> 	call	dskrd
 23212                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 23213                              <1> 	; eax = physical sector number
 23214                              <1> 	; ebx = buffer data address
 23215                              <1> 	; 27/11/2021
 23216 00004A23 8B15[406D0000]      <1> 	mov	edx, [free_map_offset] ; byte position on fbm
 23217 00004A29 A3[486D0000]        <1> 	mov	[free_map_sector], eax ; physical sector number
 23218 00004A2E B9FF010000          <1> 	mov	ecx, 511
 23219                              <1> 	;and	edx, 511
 23220 00004A33 21CA                <1> 	and 	edx, ecx ; fbm byte offset in fbm buffer
 23221 00004A35 41                  <1> 	inc	ecx ; 512
 23222 00004A36 01D9                <1> 	add	ecx, ebx
 23223 00004A38 01DA                <1> 	add	edx, ebx ; + buffer address
 23224 00004A3A 5B                  <1> 	pop	ebx ; ** ; superblock buffer address 
 23225                              <1> 	;
 23226                              <1> 	; ebx = superblock buffer address
 23227                              <1> 	; edx = fbm buffer address + byte offset (dword aligned)
 23228                              <1> 	; ecx = fbm buffer address + 512
 23229                              <1> alloc_6:
 23230                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23231                              <1> 	;		for Retro UNIX 386 v1.2
 23232                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 code
 23233                              <1> 	; (dword scan) ((1 dword = 32 sectors, 1 byte = 8 sectors))
 23234                              <1> 	; ((Note: Logical drive size must be multiplies of 32 sectors))
 23235                              <1> 	; 19/05/2020
 23236                              <1> 	; edx = free blocks map byte address 
 23237 00004A3B 0FBC02              <1> 	bsf	eax, [edx] ; Scans source operand for first bit set (1).
 23238                              <1> 			  ; Clear ZF if a bit is found set (1) and 
 23239                              <1> 			  ; loads the destination with an index to
 23240                              <1> 			  ; first set bit. (0 -> 31) 
 23241                              <1> 			  ; Sets ZF to 1 if no bits are found set.
 23242 00004A3E 752A                <1> 	jnz	short alloc_8 ; ZF = 0 -> a free block has been found
 23243                              <1> 
 23244 00004A40 A1[406D0000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 23245 00004A45 83C004              <1> 	add	eax, 4 ; next dword
 23246 00004A48 3B431C              <1> 	cmp	eax, [ebx+SB.FreeMapSize] ; fbm size in bytes
 23247 00004A4B 7209                <1> 	jb	short alloc_7
 23248                              <1> 	; invalidate superblock's first free block field
 23249 00004A4D C7433CFFFFFFFF      <1> 	mov	dword [ebx+SB.FirstFreeBlk], 0FFFFFFFFh
 23250                              <1> 	; 'no free blocks on disk !' error
 23251 00004A54 EB8F                <1> 	jmp	alloc_2
 23252                              <1> alloc_7:
 23253                              <1> 		; 26/05/2020
 23254                              <1> 		; NOTE: If ldrv size is not multiplies of 32 sectors,
 23255                              <1> 		; mod (ldrv size / 32) sectors (at the end of ldrv)
 23256                              <1> 		; can not be allocated (for regular files or dirs)! 
 23257                              <1> 		; (Kernel or runix fs installation program can use
 23258                              <1> 		;  this fact to save/duplicate critical sectors/data 
 23259                              <1> 		;  onto end sectors of that logical drive's runix fs.)
 23260                              <1> 
 23261                              <1> 	; 26/11/2021
 23262 00004A56 A3[406D0000]        <1> 	mov	[free_map_offset], eax
 23263                              <1> 	; 28/07/2021
 23264                              <1> 	; set next first free block value for search
 23265 00004A5B C1E003              <1> 	shl	eax, 3 ; * 8 ; first free block
 23266                              <1>  	; 26/11/2021
 23267 00004A5E 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 23268                              <1> 	; search (scan) for next free block map dword (in buffer)
 23269 00004A61 83C204              <1> 	add	edx, 4 ; next dword
 23270 00004A64 39CA                <1> 	cmp	edx, ecx
 23271 00004A66 72D3                <1> 	jb	short alloc_6
 23272                              <1> 	; 27/11/2021
 23273 00004A68 EBA5                <1> 	jmp	short alloc_4
 23274                              <1> 
 23275                              <1> alloc_8:
 23276                              <1> 	; 26/11/2021
 23277                              <1> 	; convert bit index to xor value
 23278                              <1> 	; and then set allocated flag for corresponding fbm bit 
 23279 00004A6A 89C1                <1> 	mov	ecx, eax
 23280                              <1> 	;mov	cl, al 
 23281                              <1> 	;sub	eax, eax
 23282                              <1> 	;inc	al ; eax = 1
 23283 00004A6C B001                <1> 	mov	al, 1
 23284 00004A6E D3E0                <1> 	shl	eax, cl
 23285 00004A70 3102                <1> 	xor	[edx], eax  ; clear allocated block's bit in the fbm
 23286                              <1> 	; zero bit means allocated disk block (1 means free disk block) 
 23287                              <1> 
 23288 00004A72 A1[406D0000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 23289                              <1> 		; note: eax is dword aligned (0,4,8,12..) !
 23290 00004A77 C1E003              <1> 	shl	eax, 3 ; * 8 ; free block number base
 23291 00004A7A 01C8                <1> 	add	eax, ecx ; add allocation bit index (0 to 31)	
 23292 00004A7C 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax ; current free block
 23293                              <1> 				; (which is being allocated here)
 23294                              <1> 
 23295                              <1> 	;mov	eax, [ebx+SB.FreeMapAddr] 
 23296                              <1> 	;		; free blocks map start sector addr
 23297                              <1> 	;add	eax, [free_map_index]
 23298                              <1> 	
 23299                              <1> 	;;add	eax, [ebx+SB.BootSectAddr] 
 23300                              <1> 	;		; + Hidden Sectors
 23301                              <1> 	; eax = physical sector number
 23302                              <1> 	
 23303                              <1> 	; 27/11/2021
 23304 00004A7F A1[486D0000]        <1> 	mov	eax, [free_map_sector] ; physical sector number
 23305                              <1> 	
 23306 00004A84 E86B0F0000          <1> 	call	wslot
 23307                              <1> 	; ebx = buffer data address (write operation bit is set)
 23308                              <1> 	; eax = physical sector number
 23309                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 23310                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 23311                              <1> 
 23312                              <1> 	; 27/11/2021
 23313                              <1> 	;mov	[free_map_buffer], ebx ; save free map buffer address
 23314                              <1> 
 23315 00004A89 E8730F0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 23316                              <1> 		      ; (at the beginning/head of the buffer chain)
 23317                              <1> 
 23318                              <1> 	; if we are here, buffer has been written to disk successfully 
 23319                              <1> 	; (otherwise cpu would jump to 'error' address)
 23320                              <1> 
 23321                              <1> 	; set superblock modified flag
 23322 00004A8E BA[966C0000]        <1> 	mov	edx, smod
 23323 00004A93 BB[546D0000]        <1> 	mov	ebx, systm
 23324 00004A98 F605[816C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 23325 00004A9F 7406                <1> 	jz	short alloc_9  ; no, root device
 23326                              <1> 	; yes, mounted device
 23327 00004AA1 BB[5C6F0000]        <1> 	mov	ebx, mount
 23328                              <1> 	;mov	edx, mmod
 23329 00004AA6 42                  <1> 	inc	edx ; edx = offset mmod
 23330                              <1> alloc_9: 
 23331 00004AA7 FE02                <1> 	inc	byte [edx] ; superblock modified !
 23332                              <1> 	
 23333                              <1> 	; Allocating a new sector/block (for file) has been completed here.
 23334 00004AA9 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 23335 00004AAC 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0 
 23336 00004AAD 7405                <1> 	jz	short alloc_10 ; not valid (not set)
 23337 00004AAF 48                  <1> 	dec	eax ; Free Blocks
 23338 00004AB0 48                  <1> 	dec	eax ; Free Blocks = Free Blocks - 1
 23339 00004AB1 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax
 23340                              <1> alloc_10:
 23341 00004AB4 E89E100000          <1> 	call	get_system_time
 23342                              <1> 		; eax = current time (as unix epoch time)
 23343                              <1> 	; 30/07/2021
 23344 00004AB9 89435C              <1> 	mov	[ebx+SB.ModifTime], eax
 23345                              <1> 
 23346 00004ABC 8B433C              <1> 	mov	eax, [ebx+SB.FirstFreeBlk] ; allocated block address
 23347 00004ABF FF433C              <1> 	inc	dword [ebx+SB.FirstFreeBlk] 
 23348                              <1> 				; +1, new value of first free block
 23349                              <1> 				; (new search will be started from here)
 23350                              <1> 				; ((it may not be free, no problem))
 23351                              <1> 
 23352                              <1> 	; put free map buffer address in ebx
 23353                              <1> 	; 27/11/2021
 23354                              <1> 	;mov	ebx, [free_map_buffer]
 23355                              <1> 
 23356 00004AC2 C3                  <1> 	retn	
 23357                              <1> 
 23358                              <1> 	; 11/02/2022
 23359                              <1> 	; 09/01/2022
 23360                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23361                              <1> free:
 23362                              <1> 	; 12/04/2022 (BugFix)
 23363                              <1> 	; 09/03/2022
 23364                              <1> 	; 11/02/2022
 23365                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23366                              <1> 	; 05/11/2021
 23367                              <1> 	; 29/10/2021 - temporary (simplified code)
 23368                              <1> 	; 14/08/2021
 23369                              <1> 	; 12/06/2021
 23370                              <1> 	; 07/06/2020
 23371                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 23372                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23373                              <1> 	; 07/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 23374                              <1> 	;
 23375                              <1> 	; calculates byte address and bit position for given block number
 23376                              <1> 	; then sets the corresponding bit in the free storage map
 23377                              <1> 	; 
 23378                              <1> 	; INPUTS ->
 23379                              <1> 	;    r1 - block number for a block structured device
 23380                              <1> 	;    cdev - current device 
 23381                              <1> 	; OUTPUTS ->
 23382                              <1> 	;    free storage map is updated
 23383                              <1> 	;    smod is incremented if cdev is root device (fixed disk)
 23384                              <1> 	;    mmod is incremented if cdev is a removable disk 	
 23385                              <1> 	;
 23386                              <1> 	;  (Retro UNIX Prototype : 01/12/2012, UNIXCOPY.ASM)
 23387                              <1>         ;  ((Modified registers: DX, CX))  
 23388                              <1> 
 23389                              <1> 	; 27/11/2021
 23390                              <1> 	; INPUT:
 23391                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 23392                              <1> 	;	eax = disk block/sector number/address (logical)
 23393                              <1> 	; OUTPUT:
 23394                              <1> 	;	ebx = superblock buffer address
 23395                              <1> 	;
 23396                              <1> 	;    Note:	
 23397                              <1> 	;	Free blocks map will be modified and written to it's disk.
 23398                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 23399                              <1> 	;	modification flag will be set; but the superblock 
 23400                              <1> 	;	will not be written to it's disk in this 'free' procedure)
 23401                              <1> 	;
 23402                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp 
 23403                              <1> 
 23404                              <1> 	; 27/11/2021
 23405 00004AC3 BB[546D0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 23406 00004AC8 F605[816C0000]01    <1> 	test	byte [cdev], 1
 23407 00004ACF 7405                <1> 	jz	short free_1
 23408 00004AD1 BB[5C6F0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 23409                              <1> free_1: ; 1
 23410                              <1> 	; 11/02/2022
 23411                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23412 00004AD6 F6436A01            <1> 	test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 23413 00004ADA 740F                <1> 	jz	short free_2 
 23414                              <1> 	; 'read only file system' error
 23415 00004ADC C705[186D0000]1E00- <1> 	mov	dword [u.error], ERR_READ_ONLY_FS
 23416 00004AE4 0000                <1>
 23417 00004AE6 E97AE6FFFF          <1> 	jmp	error
 23418                              <1> free_2:
 23419 00004AEB 89C1                <1> 	mov	ecx, eax ; logical sector/block number
 23420 00004AED A3[486D0000]        <1> 	mov	[free_map_sector], eax
 23421 00004AF2 C1E903              <1> 	shr	ecx, 3	; convert to fbmap byte offset
 23422 00004AF5 C1E80C              <1> 	shr	eax, 12 ; convert to fbmap sector index 
 23423                              <1> 			; (1 fb sector for 4096 sectors)
 23424                              <1> 	;and	cl, ~3	; dword alignment (to backward)
 23425                              <1> 	; 11/02/2022
 23426                              <1> 	;and	ecx, 511 ; convert to offset within fbm buffer
 23427 00004AF8 81E1FC010000        <1> 	and	ecx, 1FCh ; 508, dword aligned offset (32 bit scan)
 23428                              <1> 	;
 23429 00004AFE 890D[406D0000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm buffer
 23430                              <1> 	; 27/11/2021
 23431                              <1> 	; eax = fbm sector index
 23432 00004B04 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 23433                              <1> 			; free blocks map start sector address
 23434                              <1> 	; 09/01/2022
 23435 00004B07 034304              <1> 	add	eax, [ebx+SB.BootSectAddr]
 23436                              <1> 			; + Hidden Sectors
 23437                              <1> 	; 12/04/2022
 23438 00004B0A 53                  <1> 	push	ebx ; (*)
 23439                              <1> 	; ebx = superblock address
 23440                              <1> 	; eax = physical sector number
 23441 00004B0B E8800E0000          <1> 	call	dskrd
 23442                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 23443                              <1> 	; eax = physical sector number
 23444                              <1> 	; ebx = (fbm sector) buffer data address
 23445                              <1> 	; 27/11/2021
 23446 00004B10 A3[446D0000]        <1> 	mov	[free_map_index], eax  ; save physical sector address
 23447                              <1> 	; 12/04/2022
 23448 00004B15 8B15[406D0000]      <1> 	mov	edx, [free_map_offset] ; byte position in fbm buffer
 23449                              <1> 	; 11/02/2022
 23450                              <1> 	;(EDX contains -rounded down- dword aligned offset value)
 23451 00004B1B 01DA                <1> 	add	edx, ebx ; + (fbm sector) buffer start address
 23452                              <1> 	; 12/04/2022
 23453 00004B1D 5B                  <1> 	pop	ebx ; (*) superblock buffer address 	
 23454                              <1> 	;
 23455 00004B1E 29C0                <1> 	sub	eax, eax
 23456 00004B20 A0[486D0000]        <1> 	mov	al, [free_map_sector] ; logical sector number
 23457                              <1> 	;and	al, 7
 23458                              <1> 	; 11/02/2022
 23459 00004B25 241F                <1> 	and	al, 31 ; 32 bit fbm scan (with dword aligned offset)
 23460                              <1> 
 23461                              <1> 	; al = bit offset in fbm allocation byte
 23462                              <1> 	; edx = buffer address (start+offset)
 23463                              <1> 	; [free_map_offset] = byte position on fbm
 23464                              <1> 	; 27/11/2021
 23465 00004B27 0FAB02              <1> 	bts	[edx], eax  ; copy value of bit position in eax to cf
 23466                              <1> 			    ; then set same bit position at [edx]
 23467 00004B2A 7305                <1> 	jnc	short free_3 ; it was allocated sector
 23468                              <1> 
 23469                              <1> 	; already free sector !? 
 23470                              <1> 	; (nonsence or defective fs)
 23471                              <1> 
 23472 00004B2C 30C0                <1> 	xor	al, al ; 0  ; eax = 0
 23473 00004B2E 48                  <1> 	dec	eax ; 0FFFFFFFFh
 23474                              <1> 	;mov	[ebx+SB.FreeBlocks], eax 
 23475                              <1> 		; invalidate free blocks count
 23476 00004B2F EB18                <1> 	jmp	short free_5
 23477                              <1> free_3:
 23478                              <1> 	; 27/11/2021
 23479 00004B31 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 23480 00004B34 40                  <1> 	inc	eax
 23481                              <1> 	;jz	short free_4 ; 0FFFFFFFFh -> 0 (invalid!)
 23482                              <1> 	; 09/03/2022
 23483 00004B35 7501                <1> 	jnz	short free_4
 23484 00004B37 48                  <1> 	dec	eax  ; 0 -> 0FFFFFFFFh (invalid!)
 23485                              <1> free_4: 
 23486 00004B38 50                  <1> 	push	eax ; * ; number of free blocks 
 23487                              <1> 	;mov	eax, [free_map_index] ; fbm sector index
 23488                              <1> 	;add	eax, [ebx+SB.FreeMapAddr] 
 23489                              <1> 			; free blocks map start sector address
 23490                              <1> 	;add	eax, [ebx+SB.BootSectAddr]
 23491                              <1> 	;		; + Hidden Sectors
 23492 00004B39 A1[446D0000]        <1> 	mov	eax, [free_map_index] ; restore physical sector address
 23493                              <1> 	; eax = physical sector number
 23494 00004B3E E8B10E0000          <1> 	call	wslot
 23495                              <1> 	; ebx = buffer data address (write operation bit is set)
 23496                              <1> 	; eax = physical sector number
 23497                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 23498                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 23499                              <1> 
 23500 00004B43 E8B90E0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 23501                              <1> 		      ; (at the beginning/head of the buffer chain)
 23502                              <1> 
 23503                              <1> 	; if we are here, buffer has been written to disk successfully 
 23504                              <1> 	; (otherwise cpu would jump to 'error' address)
 23505 00004B48 58                  <1> 	pop	eax ; *  ; number of free blocks 
 23506                              <1> free_5:
 23507                              <1> 	; eax = number of free blocks 
 23508                              <1> 	;
 23509                              <1> 	; set superblock modified flag
 23510 00004B49 BA[966C0000]        <1> 	mov	edx, smod
 23511 00004B4E BB[546D0000]        <1> 	mov	ebx, systm
 23512 00004B53 F605[816C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 23513 00004B5A 7406                <1> 	jz	short free_6 ; no, root device
 23514                              <1> 	; yes, mounted device
 23515 00004B5C BB[5C6F0000]        <1> 	mov	ebx, mount
 23516                              <1> 	;mov	edx, mmod
 23517 00004B61 42                  <1> 	inc	edx ; edx = offset mmod
 23518                              <1> free_6: 
 23519 00004B62 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax 
 23520                              <1> 
 23521 00004B65 A1[486D0000]        <1> 	mov	eax, [free_map_sector] ; logical sector number
 23522 00004B6A 3B433C              <1> 	cmp	eax, [ebx+SB.FirstFreeBlk]
 23523 00004B6D 7303                <1> 	jnb	short free_7
 23524 00004B6F 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 23525                              <1> free_7:
 23526 00004B72 FE02                <1> 	inc	byte [edx] ; superblock modified !
 23527 00004B74 C3                  <1> 	retn
 23528                              <1> 	
 23529                              <1> iget:
 23530                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23531                              <1> 	; 30/11/2021
 23532                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 23533                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23534                              <1> 	; 07/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 23535                              <1> 	;
 23536                              <1> 	; get a new i-node whose i-number in r1 and whose device is in cdev
 23537                              <1> 	;
 23538                              <1> 	; ('iget' returns current i-number in r1, if input value of r1 is 0)
 23539                              <1> 	; 
 23540                              <1> 	; INPUTS ->
 23541                              <1> 	;    ii - current i-number, rootdir
 23542                              <1> 	;    cdev - new i-node device
 23543                              <1> 	;    idev - current i-node device
 23544                              <1> 	;    imod - current i-node modified flag
 23545                              <1> 	;    mnti - cross device file i-number
 23546                              <1> 	;    r1 - i-numbe rof new i-node
 23547                              <1> 	;    mntd - mountable device number		
 23548                              <1> 	; 	 
 23549                              <1> 	; OUTPUTS ->
 23550                              <1> 	;    cdev, idev, imod, ii, r1
 23551                              <1> 	;
 23552                              <1> 	; ((AX = R1)) input/output
 23553                              <1> 	;
 23554                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 23555                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 23556                              <1> 
 23557                              <1> 	; 22/11/2021
 23558                              <1> 	;;mov	dl, [cdev] ; 18/07/2013
 23559                              <1> 	;;mov	dh, [idev] ; 07/08/2013
 23560                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 23561                              <1> 	;mov	dh, [cdev]
 23562                              <1> 	;mov	dl, [idev]
 23563 00004B75 668B15[806C0000]    <1> 	mov	dx, [idev] ; [idev] in dl, [cdev] in dh
 23564                              <1> 	;
 23565                              <1> 	; 22/11/2021
 23566 00004B7C 25FFFF0000          <1> 	and	eax, 0FFFFh
 23567 00004B81 3B05[7C6C0000]      <1> 	cmp 	eax, [ii]
 23568                              <1> 		; cmp r1,ii / r1 = i-number of current file
 23569 00004B87 7504                <1> 	jne 	short iget_1
 23570                              <1> 		; bne 1f
 23571 00004B89 38F2                <1> 	cmp	dl, dh
 23572                              <1> 		; cmp idev,cdev
 23573                              <1> 			  ; / is device number of i-node = current device
 23574 00004B8B 746C                <1>         je	short iget_5
 23575                              <1> 	;	; beq 2f
 23576                              <1> 	; 14/08/2021
 23577                              <1> iget_1: ; 1:
 23578 00004B8D 30DB                <1> 	xor	bl, bl
 23579 00004B8F 381D[946C0000]      <1> 	cmp	[imod], bl ; 0	
 23580                              <1> 		; tstb imod / has i-node of current file
 23581                              <1> 			  ; / been modified i.e., imod set
 23582 00004B95 7628                <1> 	jna	short iget_2
 23583                              <1> 		; beq 1f
 23584 00004B97 881D[946C0000]      <1> 	mov	[imod], bl ; 0
 23585                              <1> 		; clrb imod / if it has, 
 23586                              <1> 			   ; / we must write the new i-node out on disk
 23587                              <1> 	; 22/11/2021 (32 bit push-pop)
 23588 00004B9D 50                  <1> 	push	eax ; *
 23589                              <1> 		; mov r1,-(sp)
 23590 00004B9E 52                  <1> 	push	edx ; **
 23591                              <1> 		; mov cdev,-(sp)
 23592 00004B9F A1[7C6C0000]        <1> 	mov	eax, [ii]
 23593                              <1> 		; mov ii,r1
 23594                              <1> 	;mov	dh, [idev]
 23595                              <1> 	;mov	[cdev], dh
 23596                              <1> 	; 09/01/2022
 23597 00004BA4 8815[816C0000]      <1> 	mov	[cdev], dl  ; dl = [idev]
 23598                              <1> 		; mov idev,cdev
 23599 00004BAA FEC3                <1> 	inc	bl ; 1
 23600                              <1> 	; 31/07/2013
 23601 00004BAC 881D[386D0000]      <1> 	mov     [rw], bl ; 1 == write 
 23602                              <1> 	;;28/07/2013 rw -> u.rw
 23603                              <1>         ;;mov   [u.rw], bl ; 1 == write
 23604 00004BB2 E843000000          <1> 	call	icalc
 23605                              <1> 		; jsr r0,icalc; 1
 23606 00004BB7 5A                  <1> 	pop	edx ; **
 23607 00004BB8 8835[816C0000]      <1> 	mov	[cdev], dh ; 22/11/2021
 23608                              <1> 		; mov (sp)+,cdev
 23609 00004BBE 58                  <1> 	pop	eax ; *
 23610                              <1> 		; mov (sp)+,r1
 23611                              <1> iget_2: ; 1:
 23612                              <1> 	;and	ax, ax
 23613 00004BBF 21C0                <1> 	and	eax, eax ; 22/11/2021 (32 bit inode number)
 23614                              <1> 		; tst r1 / is new i-number non zero
 23615 00004BC1 7431                <1> 	jz	short iget_4 ; 2f
 23616                              <1> 		; beq 2f / branch if r1=0
 23617                              <1> 
 23618                              <1> 	;mov 	dh, [cdev]
 23619 00004BC3 08F6                <1> 	or	dh, dh ; 22/11/2021
 23620                              <1> 		; tst cdev / is the current device number non zero
 23621                              <1> 			 ; / (i.e., device =/ drum)
 23622 00004BC5 7515                <1> 	jnz	short iget_3 ;  1f
 23623                              <1> 		; bne 1f / branch 1f cdev =/ 0  ;; (cdev != 0)
 23624                              <1> 	; 22/11/2021
 23625 00004BC7 3B05[8A6C0000]      <1> 	cmp	eax, [mnti]
 23626                              <1> 	;cmp	ax, [mnti]			
 23627                              <1> 		; cmp r1,mnti / mnti is the i-number of the cross device
 23628                              <1> 			    ; / file (root directory of mounted device)
 23629 00004BCD 750D                <1> 	jne	short iget_3 ; 1f
 23630                              <1> 		; bne 1f
 23631                              <1>         ;mov    bl, [mntd]
 23632 00004BCF FEC6                <1> 	inc	dh ; mov dh, 1 ; 22/11/2021
 23633 00004BD1 8835[816C0000]      <1>         mov	[cdev], dh ; 22/11/2021
 23634                              <1> 		; mov mntd,cdev / make mounted device the current device
 23635                              <1> 	; 22/11/2021
 23636 00004BD7 A1[866C0000]        <1> 	mov	eax, [rootdir] ; rootdir = 1 (for runix v2 file system)
 23637                              <1> 	;mov	ax, [rootdir]
 23638                              <1> 		; mov rootdir,r1
 23639                              <1> iget_3: ; 1:
 23640                              <1> 	; 22/11/2021
 23641 00004BDC A3[7C6C0000]        <1> 	mov	[ii], eax ; 32 bit inode number
 23642                              <1> 	;mov	[ii], ax
 23643                              <1> 		; mov r1,ii
 23644                              <1> 	; 30/11/2021
 23645 00004BE1 8835[806C0000]      <1> 	mov	[idev], dh ; cdev 
 23646                              <1> 	;mov	[idev], dl ; cdev
 23647                              <1> 		; mov cdev,idev
 23648 00004BE7 30DB                <1> 	xor	bl, bl
 23649                              <1>         ; 31/07/2013
 23650 00004BE9 881D[386D0000]      <1> 	mov     [rw], bl ; 0 == read 
 23651                              <1> 	;;28/07/2013 rw -> u.rw       
 23652                              <1>         ;;mov   [u.rw], bl ; 0 = read
 23653 00004BEF E806000000          <1> 	call	icalc
 23654                              <1> 		; jsr r0,icalc; 0 / read in i-node ii
 23655                              <1> iget_4: ; 2:
 23656                              <1> 	; 22/11/2021
 23657 00004BF4 A1[7C6C0000]        <1> 	mov	eax, [ii]
 23658                              <1> 	;mov	ax, [ii]
 23659                              <1> 		; mov ii,r1
 23660                              <1> iget_5:
 23661 00004BF9 C3                  <1> 	retn
 23662                              <1> 		; rts r0
 23663                              <1> 
 23664                              <1> icalc:
 23665                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23666                              <1> 	; 28/11/2021
 23667                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification 
 23668                              <1> 	; 02/07/2015
 23669                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23670                              <1> 	; 07/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 23671                              <1> 	;
 23672                              <1> 	; calculate physical block number from i-number then
 23673                              <1> 	; read or write that block
 23674                              <1> 	;
 23675                              <1> 	; 'icalc' is called from 'iget'
 23676                              <1> 	;
 23677                              <1> 	; for original unix v1:
 23678                              <1> 	; / i-node i is located in block (i+31.)/16. and begins 32.*
 23679                              <1>        	; / (i+31.) mod 16. bytes from its start
 23680                              <1> 	;
 23681                              <1> 	; for retro unix 8086 v1:
 23682                              <1> 	;  i-node is located in block (i+47)/16 and
 23683                              <1> 	;  begins 32*(i+47) mod 16 bytes from its start
 23684                              <1> 	;
 23685                              <1> 	; INPUTS ->
 23686                              <1> 	;    r1 - i-number of i-node
 23687                              <1> 	; 	 
 23688                              <1> 	; OUTPUTS ->
 23689                              <1> 	;    inode r/w
 23690                              <1> 	;
 23691                              <1> 	; ((AX = R1)) input
 23692                              <1> 	;
 23693                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 23694                              <1>         ;  ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))  
 23695                              <1> 	;
 23696                              <1> 
 23697                              <1> 	; 28/11/2021
 23698                              <1> 	;cmp	byte [idev], 0 ; [cdev] = [idev]
 23699 00004BFA 803D[816C0000]00    <1> 	cmp	byte [cdev], 0
 23700 00004C01 7607                <1> 	jna	short icalc_0r
 23701 00004C03 BD[5C6F0000]        <1> 	mov	ebp, mount  ; mounted file system's superblock 
 23702 00004C08 EB05                <1> 	jmp	short icalc_0m
 23703                              <1> icalc_0r:
 23704                              <1> 	; 28/11/2021
 23705 00004C0A BD[546D0000]        <1> 	mov	ebp, systm  ; root file system's superblock 
 23706                              <1> icalc_0m:
 23707                              <1> 	; 22/11/2021
 23708                              <1> 	;mov	edx, eax
 23709 00004C0F 8B15[7C6C0000]      <1> 	mov	edx, [ii] ; 32 bit inode number
 23710 00004C15 8B4528              <1> 	mov	eax, [ebp+SB.InodeTblAddr] ; inode table base address
 23711                              <1> 	;
 23712 00004C18 4A                  <1> 	dec	edx ; 0 based inode number 
 23713                              <1> 		    ; (inode index in inode table)
 23714 00004C19 52                  <1> 	push	edx ; *
 23715 00004C1A C1EA03              <1> 	shr	edx, 3
 23716 00004C1D 7402                <1> 	jz	short icalc_0t ; 0 for inodes 1 to 8
 23717 00004C1F 01D0                <1> 	add	eax, edx
 23718                              <1> icalc_0t:
 23719                              <1> 	; 09/01/2022
 23720                              <1> 	; eax = locical block/sector number 
 23721 00004C21 034504              <1> 	add	eax, [ebp+SB.BootSectAddr]
 23722                              <1> 	; eax = physical block/sector number 
 23723 00004C24 E8670D0000          <1> 	call	dskrd
 23724                              <1> 		; jsr r0,dskrd / read in block containing i-node i.
 23725                              <1> 	; 31/07/2013
 23726 00004C29 803D[386D0000]00    <1>         cmp     byte [rw], 0 ; Retro Unix 8086 v1 feature !
 23727                              <1> 	;; 28/07/2013 rw -> u.rw
 23728                              <1>         ;;cmp	byte [u.rw], 0 ; Retro Unix 8086 v1 feature !
 23729                              <1> 		; tst (r0)
 23730 00004C30 7605                <1> 	jna	short icalc_1
 23731                              <1> 		; beq 1f / branch to wslot when argument
 23732                              <1> 		       ; / in icalc call = 1
 23733                              <1> 	; eAX = r1 = block number
 23734 00004C32 E8BD0D0000          <1> 	call	wslot
 23735                              <1> 		; jsr r0,wslot / set up data buffer for write
 23736                              <1> 			     ; / (will be same buffer as dskrd got)
 23737                              <1> 	; EBX = r5 points to first word in data area for this block
 23738                              <1> icalc_1: ; 1:
 23739 00004C37 5A                  <1> 	pop	edx ; *
 23740                              <1> 	; 22/11/2021
 23741 00004C38 83E207              <1> 	and 	edx, 07h ; 8 inodes per inode table sector
 23742 00004C3B C1E206              <1> 	shl 	edx, 6 ; * 64 (inode size)
 23743                              <1> 	; edx = 64 * (mod(inodenumber-1)/8)
 23744 00004C3E 89DE                <1> 	mov	esi, ebx  ; ebx points to 1st word of the buffer
 23745 00004C40 01D6                <1> 	add	esi, edx  ; edx is inode offset in the buffer
 23746                              <1>           	; eSI (r5) points to first word in i-node i.	
 23747                              <1> 		; mov (sp)+,mq / calculate offset in data buffer; 
 23748                              <1> 			     ; / 32.*(i+31.)mod16
 23749                              <1> 		; mov $5,lsh / for i-node i.
 23750                              <1> 		; add mq,r5 / r5 points to first word in i-node i.
 23751 00004C42 BF[24680000]        <1> 	mov	edi, inode
 23752                              <1> 		; mov $inode,r1 / inode is address of first word 
 23753                              <1> 			      ; / of current i-node
 23754                              <1> 	;mov 	ecx, 8 ; 02/07/2015 (32 bit modification)
 23755                              <1> 	;	; mov $16.,r3
 23756                              <1> 	; 28/11/2021
 23757 00004C47 29C9                <1> 	sub	ecx, ecx
 23758 00004C49 B110                <1> 	mov	cl, 16 ; Retro UNIX 386 v2 inode size = 64 bytes
 23759                              <1> 	; 31/07/2013
 23760 00004C4B 382D[386D0000]      <1>   	cmp     [rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 23761                              <1>        ;;28/07/2013 rw -> u.rw                 
 23762                              <1>        ;;cmp    [u.rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 23763                              <1> 		; tst (r0)+ / branch to 2f when argument in icalc call = 0
 23764 00004C51 7609                <1> 	jna	short icalc_3
 23765                              <1> 		; beq 2f / r0 now contains proper return address 
 23766                              <1> 		       ; / for rts r0
 23767                              <1> icalc_2: ; 1:
 23768 00004C53 87F7                <1> 	xchg 	esi, edi
 23769                              <1> 	; overwrite old i-node (in buffer to be written)
 23770 00004C55 F3A5                <1> 	rep 	movsd
 23771                              <1> 		; mov (r1)+,(r5)+ / over write old i-node
 23772                              <1> 		; dec r3
 23773                              <1> 		; bgt 1b
 23774                              <1> 	;call	dskwr
 23775                              <1> 	;	; jsr r0,dskwr / write inode out on device
 23776                              <1> 	;retn
 23777                              <1> 	;	; rts r0
 23778                              <1> 	; 28/11/2021
 23779 00004C57 E9A50D0000          <1> 	jmp	dskwr
 23780                              <1> icalc_3: ; 2:
 23781                              <1> 	; copy new i-node into inode area of (core) memory
 23782 00004C5C F3A5                <1> 	rep 	movsd
 23783                              <1> 		; mov (r5)+,(r1)+ / read new i-node into 
 23784                              <1> 		                ; / "inode" area of core
 23785                              <1> 		; dec r3
 23786                              <1> 		; bgt 2b
 23787 00004C5E C3                  <1> 	retn
 23788                              <1> 		; rts r0
 23789                              <1> 
 23790                              <1> access:
 23791                              <1> 	; 13/03/2022
 23792                              <1> 	; 25/12/2021
 23793                              <1> 	; 19/12/2021
 23794                              <1> 	; 28/11/2021
 23795                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 23796                              <1> 	; 31/10/2021 - temporary (simplified code)
 23797                              <1> 	; 14/06/2021
 23798                              <1> 	; 02/05/2021
 23799                              <1> 	; 27/03/2021
 23800                              <1> 	; 26/03/2021
 23801                              <1> 	; 25/03/2021
 23802                              <1> 	; 23/03/2021 (Retro UNIX 386 v2 - Beginning)
 23803                              <1> 	;	((ref: unix v7 source - fio.c))
 23804                              <1> 	; ref: INODE STRUCTURE of Retro UNIX v2 file system
 23805                              <1> 	;	07/02/2020, 'RETRO UNIX v2 Inodes.pdf'
 23806                              <1> 	;	 
 23807                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23808                              <1> 	; 24/04/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 23809                              <1> 	;
 23810                              <1> 	; check whether user is owner of file or user has read or write
 23811                              <1> 	; permission (based on i.flgs).
 23812                              <1> 	;
 23813                              <1> 	; INPUTS ->
 23814                              <1> 	;    r1 - i-number of file
 23815                              <1> 	;    u.uid
 23816                              <1> 	; arg0 -> (owner flag mask)	 		
 23817                              <1> 	;     Retro UNIX 8086 v1 feature -> owner flag mask in DL (DX) 	 
 23818                              <1> 	; OUTPUTS ->
 23819                              <1> 	;    inode (or jump to error)
 23820                              <1> 	;
 23821                              <1> 	; ((AX = R1)) input/output
 23822                              <1> 	;
 23823                              <1> 	;  ((Modified registers: eCX, eBX, eDX, eSI, eDI, eBP))
 23824                              <1> 
 23825                              <1> 	; 26/03/2021
 23826                              <1> 	; INPUT:
 23827                              <1> 	;	eax = inode number (ax)
 23828                              <1> 	;	 dx = mode (IEXEC, IREAD or IWRITE) 
 23829                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 23830                              <1> 	;	
 23831                              <1> 	; OUTPUT:
 23832                              <1> 	;	inode (or jump to error)
 23833                              <1> 	;	eax (ax) = [ii] = inode number
 23834                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 23835                              <1> 	;
 23836                              <1> 	; Modified registers: (eax), ebx, ecx, edx, esi, edi, ebp
 23837                              <1> 	;
 23838                              <1> 	; IREAD	 equ 100h ; read permission flag, owner
 23839                              <1> 	; IWRITE equ 80h  ; write permission flag, owner
 23840                              <1> 	; IEXEC	 equ 40h  ; execute permission flag, owner	 
 23841                              <1> 		
 23842                              <1> 	; 23/03/2021
 23843 00004C5F 52                  <1> 	push	edx ; save flag (DX)
 23844                              <1> 	;push	dx  ; save flag (DL)
 23845 00004C60 E810FFFFFF          <1> 	call	iget
 23846                              <1> 		; jsr r0,iget / read in i-node for current directory
 23847                              <1> 			    ; / (i-number passed in r1)
 23848                              <1> 	;;mov	cl, [i.flgs]
 23849                              <1> 	;;	; mov i.flgs,r2
 23850                              <1> 	; 23/03/2021
 23851                              <1> 	;mov	cx, [i.iflgs]	
 23852                              <1> 
 23853                              <1> 	;;pop	dx  ; restore flag (DL)
 23854                              <1> 	; 23/03/2021
 23855 00004C65 5A                  <1> 	pop	edx ; restore flag (DX)
 23856                              <1> 
 23857                              <1> 	; 28/11/2021 (iget will not return here if there is an error)
 23858                              <1> 	; 31/10/2021
 23859                              <1> 	;jc	short access_5
 23860                              <1> 
 23861                              <1> 	; 31/10/2021
 23862                              <1> 	; Note: If eax input is same with [mnti], 'iget' will change
 23863                              <1> 	; [cdev] to 1 and eax will be 1 (root dir of mounted fs) 
 23864                              <1> 
 23865                              <1> 	; 27/03/2021
 23866                              <1> 	; 23/03/2021
 23867                              <1> 	; (check if it is write permission flag)
 23868 00004C66 6681FA8000          <1> 	cmp	dx, 80h ; IWRITE
 23869 00004C6B 775E                <1> 	ja	short access_r	; IREAD = 100h (owner)
 23870 00004C6D 722B                <1> 	jb	short access_x	; IEXEC = 40h (owner)
 23871                              <1> 	; IWRITE (80h)
 23872                              <1> access_w:
 23873                              <1> 	; 23/03/2021
 23874                              <1> 	; ((ref: Retro UNIX 386 v2, 'ux.s', 'ldrv' structure))
 23875                              <1> 	;mov	bl, [idev]
 23876                              <1> 	;call	getfs
 23877                              <1>  	;movzx	ebx, byte [idev]  ; logical drive number
 23878                              <1> 	;shl	bx, 6 ; * 64	  ; of current inode	
 23879                              <1> 	;add	ebx, ldrvtable	
 23880                              <1> 	;;test	byte [ebx+ldrv.pflags], 01h ; read only fs flag
 23881                              <1> 	;;jz	short access_0
 23882                              <1> 	;; 14/06/2021
 23883                              <1> 	; 14/06/2021
 23884                              <1> 	; check block device (fs) if it is read only fs or not ? 
 23885                              <1> 	;mov	edi, [ebx+ldrv.superblk]
 23886                              <1> 	;test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 23887                              <1> 	;jz	short access_0
 23888                              <1> 	; 31/10/2021
 23889 00004C6F 803D[816C0000]01    <1> 	cmp	byte [cdev], 1
 23890 00004C76 7207                <1> 	jb	short access_7 ; [cdev] = 0
 23891                              <1> 	; [cdev] = 1
 23892                              <1> 	; 28/11/2021
 23893 00004C78 BF[5C6F0000]        <1> 	mov	edi, mount ; mounted file system's superblock buffer
 23894 00004C7D EB05                <1> 	jmp	short access_8
 23895                              <1> access_7:
 23896                              <1> 	; 28/11/2021
 23897 00004C7F BF[546D0000]        <1> 	mov	edi, systm ; root file system's superblock buffer
 23898                              <1> access_8:
 23899 00004C84 F6476A01            <1> 	test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 23900 00004C88 7441                <1> 	jz	short access_0
 23901                              <1> 
 23902                              <1> 	; 23/03/2021
 23903                              <1> 	;mov	dword [u.error], ERR_READ_ONLY_FS
 23904                              <1> 	;		; 'read only file system !' error
 23905                              <1> 	;jmp	error
 23906                              <1> 
 23907                              <1> 	; 19/12/2021
 23908 00004C8A F605[25680000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file ?
 23909 00004C91 7438                <1> 	jz	short access_0  ; no, device file
 23910                              <1> 
 23911                              <1> 	; 31/10/2021
 23912 00004C93 B81E000000          <1> 	mov	eax, ERR_READ_ONLY_FS
 23913                              <1> 			; 'read only file system !' error
 23914                              <1> 	; 27/03/2021
 23915 00004C98 EB27                <1> 	jmp	short access_5
 23916                              <1> 
 23917                              <1> 	; check block device (fs) if it is read only fs or not ? 
 23918                              <1> 
 23919                              <1> 	;mov	dh, [u.uid]
 23920                              <1> 	;cmp	dh, [i.uid]
 23921                              <1> 	;	; cmpb i.uid,u.uid / is user same as owner of file
 23922                              <1> 	;jne	short access_1
 23923                              <1> 		; bne 1f / no, then branch
 23924                              <1> access_x:
 23925                              <1> 	; IEXEC (40h)
 23926                              <1> 	; 27/03/2021
 23927 00004C9A 668B1D[24680000]    <1> 	mov	bx, [i.flgs]
 23928 00004CA1 F6C780              <1> 	test	bh, 80h ; regular file ?
 23929 00004CA4 7416                <1> 	jz	short access_4 ; not executable file !
 23930 00004CA6 F6C740              <1> 	test	bh, 40h	; directory ?
 23931 00004CA9 7511                <1> 	jnz	short access_4 ; not executable file !
 23932 00004CAB 668B0D[F66C0000]    <1> 	mov	cx, [u.uid]
 23933 00004CB2 6609C9              <1> 	or	cx, cx
 23934 00004CB5 7520                <1> 	jnz	short access_3 ; (restricted user)
 23935                              <1> 	; (super user)
 23936                              <1> 	;test	[i.flgs], dl ; execute permission for owner
 23937                              <1> 	;test	byte [i.flgs], 49h ; for owner, group, others
 23938 00004CB7 F6C349              <1> 	test	bl, 49h ; exec perm for owner, group, others
 23939 00004CBA 7549                <1> 	jnz	short access_2
 23940                              <1> access_4:
 23941                              <1> 	; 31/10/2021
 23942 00004CBC B816000000          <1> 	mov	eax, ERR_NOT_EXECUTABLE
 23943                              <1> 			; 'not executable file !' error
 23944                              <1> 	; 26/03/2021
 23945                              <1> ;;sysexec_not_exf:
 23946                              <1> ;	mov	dword [u.error], ERR_NOT_EXECUTABLE
 23947                              <1> ;			; 'not executable file !' error
 23948                              <1> ;access_5:
 23949                              <1> ;	jmp	error
 23950                              <1> 	
 23951                              <1> 	; 31/10/2021
 23952                              <1> access_5:
 23953 00004CC1 A3[186D0000]        <1> 	mov	[u.error], eax
 23954 00004CC6 E99AE4FFFF          <1> 	jmp	error
 23955                              <1> 
 23956                              <1> access_r:
 23957                              <1> 	; 27/03/2021
 23958                              <1> access_0:
 23959                              <1> 	; 23/03/2021
 23960 00004CCB 668B0D[F66C0000]    <1> 	mov	cx, [u.uid]
 23961 00004CD2 6609C9              <1> 	or	cx, cx ; 0 ; root ?
 23962                              <1> 	;jz	short access_2 ; yes
 23963                              <1> 	; 25/12/2021
 23964 00004CD5 741E                <1> 	jz	short access_1 ; yes
 23965                              <1> access_3:
 23966                              <1> 	; 13/03/2022
 23967 00004CD7 663B0D[28680000]    <1> 	cmp	cx, [i.uid] ; owner ?
 23968 00004CDE 7415                <1> 	je	short access_1 ; yes
 23969                              <1> 	;; owner ?
 23970 00004CE0 8A1D[2A680000]      <1> 	mov	bl, [i.gid]
 23971                              <1> 	;cmp	cx, [i.uid]
 23972                              <1> 	;;je	short access_1
 23973                              <1> 	;; 02/05/2021
 23974                              <1> 	;jne	short access_6
 23975                              <1> 	; 13/03/2022
 23976                              <1> 	; same group ?
 23977 00004CE6 66C1EA03            <1> 	shr	dx, 3
 23978                              <1> 	; check owner's group number/ID
 23979 00004CEA 3A1D[FA6C0000]      <1> 	cmp	bl, [u.gid] ; same group number/ID ?
 23980 00004CF0 7403                <1> 	je	short access_1 ; yes
 23981                              <1> 	; one of others
 23982                              <1> 	;shr	dx, 6
 23983                              <1> 	;jmp	short access_1 ; others
 23984                              <1> 	; 13/03/2022
 23985                              <1> 	; one of others
 23986 00004CF2 C0EA03              <1> 	shr	dl, 3
 23987                              <1> ;	; 13/03/2022
 23988                              <1> ;	jmp	short access_1 ; others
 23989                              <1> ;access_6:
 23990                              <1> ;	;shr	cl, 2
 23991                              <1> ;	;	; asrb r2 / shift owner read write bits into non owner
 23992                              <1> ;	;	;       ; / read/write bits
 23993                              <1> ;	;	; asrb r2
 23994                              <1> ;
 23995                              <1> ;	; 23/03/2021
 23996                              <1> ;	; same group ?
 23997                              <1> ;	shr	dx, 3
 23998                              <1> ;	;mov	cl, [u.gid]
 23999                              <1> ;	;cmp	cl, [i.gid]
 24000                              <1> ;	;je	short access_1
 24001                              <1> ;	; 02/05/2021
 24002                              <1> ;	cmp	bl, [u.gid]
 24003                              <1> ;	je	short access_1 ; same group, different owner
 24004                              <1> ;
 24005                              <1> ;	; others
 24006                              <1> ;	;shr	dx, 3
 24007                              <1> ;	shr	dl, 3
 24008                              <1> ;	;jmp	short access_1	
 24009                              <1> ;
 24010                              <1> ;;access_1: ; 1:
 24011                              <1> ;	;and	cl, dl
 24012                              <1> ;	;	; bit r2,(r0)+ / test read-write flags against argument
 24013                              <1> ;	;		     ; / in access call
 24014                              <1> ;	;jnz	short access_2
 24015                              <1> ;	;	; bne 1f
 24016                              <1> ;	
 24017                              <1> ;	;or	dh, dh	; super user (root) ?
 24018                              <1> ;	;	; tstb u.uid
 24019                              <1> ;	;jz	short access_2 ; yes, super user
 24020                              <1> ;	;;jnz	error
 24021                              <1> ;	;	; beq 1f
 24022                              <1> ;	;	; jmp error
 24023                              <1> ;	
 24024                              <1> ;	;mov	dword [u.error], ERR_FILE_ACCESS 
 24025                              <1> ;	;		; 'permission denied !' error
 24026                              <1> ;	;jmp	error
 24027                              <1> 
 24028                              <1> access_1:
 24029                              <1> 	; 23/03/2021
 24030 00004CF5 668515[24680000]    <1> 	test	dx, [i.flgs]
 24031 00004CFC 7507                <1> 	jnz	short access_2
 24032                              <1> 
 24033                              <1> 	;; r/w permission error
 24034                              <1> 	;mov	dword [u.error], ERR_FILE_ACCESS 
 24035                              <1> 	;		; 'permission denied !' error
 24036                              <1> 	;;jmp	error
 24037                              <1> 
 24038                              <1> 	; 31/10/2021
 24039 00004CFE B80B000000          <1> 	mov	eax, ERR_FILE_ACCESS 
 24040                              <1> 			; 'permission denied !' error
 24041                              <1> 	; 27/03/2021
 24042 00004D03 EBBC                <1> 	jmp	short access_5
 24043                              <1> 
 24044                              <1> access_2: ; 1:
 24045                              <1> 	;; DL = flags
 24046                              <1> 	;retn
 24047                              <1> 	;	; rts r0
 24048                              <1> 	; 27/03/2021
 24049                              <1> 	; DX = flag (100h-20h-04h or 80h-10h-02h or 40h-08h-01h)
 24050 00004D05 C3                  <1> 	retn
 24051                              <1> 
 24052                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 24053                              <1> %if 0
 24054                              <1> 
 24055                              <1> setimod:
 24056                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24057                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 24058                              <1> 	;
 24059                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 24060                              <1> 	; the inode has been modified. Also puts the time of modification
 24061                              <1> 	; into the inode.
 24062                              <1> 	;
 24063                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 24064                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 24065                              <1> 	;
 24066                              <1> 	
 24067                              <1> 	;push 	edx
 24068                              <1> 	push	eax
 24069                              <1> 
 24070                              <1> 	mov 	byte [imod], 1
 24071                              <1> 		; movb $1,imod / set current i-node modified bytes
 24072                              <1> 	; Erdogan Tan 14-7-2012
 24073                              <1> 	call 	epoch
 24074                              <1> 		 ; mov s.time,i.mtim 
 24075                              <1> 			    ; / put present time into file modified time
 24076                              <1> 		 ; mov s.time+2,i.mtim+2
 24077                              <1> 
 24078                              <1> 	mov 	[i.mtim], eax
 24079                              <1> 	
 24080                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 24081                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 24082                              <1> 	cmp	dword [i.ctim], 0
 24083                              <1> 	jnz	short setimod_ok
 24084                              <1> 
 24085                              <1> 	mov 	[i.ctim], eax
 24086                              <1> 
 24087                              <1> setimod_ok: ; 31/07/2013
 24088                              <1> 	pop	eax
 24089                              <1> 	;pop	edx
 24090                              <1> 	
 24091                              <1> 	retn
 24092                              <1> 		; rts r0
 24093                              <1> %endif
 24094                              <1> 
 24095                              <1> setimod:
 24096                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 24097                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 24098                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24099                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 24100                              <1> 	;
 24101                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 24102                              <1> 	; the inode has been modified. Also puts the time of modification
 24103                              <1> 	; into the inode.
 24104                              <1> 	;
 24105                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 24106                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 24107                              <1> 	;
 24108                              <1> 
 24109                              <1> 	; Reference:
 24110                              <1> 	; 25/01/2020 - 'UNIXHDCP.ASM', 'setimod' procedure
 24111                              <1> 	;	(Retro UNIX 386 v2 file system installation utility)
 24112                              <1> 
 24113                              <1> 	; 25/05/2020
 24114                              <1> 	;
 24115                              <1> 	; INPUT:
 24116                              <1> 	;	none
 24117                              <1> 	; OUTPUT:
 24118                              <1> 	;	inode times and [imod] will be set
 24119                              <1> 	;	      ([imodx] will be reset)
 24120                              <1> 	;	cf = 0 	
 24121                              <1> 
 24122                              <1> 	; Modified registers: ecx, (edx)?
 24123                              <1> 	
 24124                              <1> 	;push 	edx
 24125 00004D06 50                  <1> 	push	eax
 24126                              <1> 
 24127 00004D07 C605[946C0000]01    <1> 	mov 	byte [imod], 1
 24128                              <1> 		; movb $1,imod / set current i-node modified bytes
 24129                              <1> 
 24130                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 24131 00004D0E A1[60680000]        <1> 	mov	eax, [i.ctim] ; inode (file) creation time
 24132 00004D13 21C0                <1> 	and	eax, eax
 24133 00004D15 7518                <1> 	jnz	short setimod_4
 24134                              <1> 
 24135                              <1> 	; New file
 24136                              <1> setimod_1:
 24137                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 by Erdogan Tan
 24138                              <1> 	;	 (Modified UNIX v7 inode and new FS construction) 	
 24139                              <1> 	;
 24140 00004D17 E83B0E0000          <1> 	call	get_system_time ; get current (unix epoch) time
 24141                              <1> 
 24142                              <1> 	;; Erdogan Tan 14-7-2012
 24143                              <1> 	;call 	epoch
 24144                              <1> 	;	 ; mov s.time,i.mtim 
 24145                              <1> 	;		    ; / put present time into file modified time
 24146                              <1> 	;	 ; mov s.time+2,i.mtim+2
 24147                              <1> 	;
 24148                              <1> 	;mov 	[i.mtim], eax
 24149                              <1> 
 24150                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 24151                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 24152                              <1> 	;cmp	dword [i.ctim], 0
 24153                              <1> 	;jnz	short setimod_ok
 24154                              <1> 		
 24155 00004D1C A3[60680000]        <1> 	mov 	[i.ctim], eax
 24156                              <1> 	
 24157                              <1> 	; 25/05/2020
 24158 00004D21 EB05                <1> 	jmp	short setimod_3
 24159                              <1> 
 24160                              <1> setimod_2:
 24161                              <1> 	; File/Directory data (file size or content) is changed
 24162                              <1> 	; This is last modification date&time
 24163 00004D23 A3[5C680000]        <1> 	mov	[i.mtim], eax
 24164                              <1> setimod_3:
 24165                              <1> 	; 19/09/2019 ('UNIXHDCP.ASM', 'setimod' by Erdogan Tan)
 24166                              <1> 	; This is last access or last changing date&time
 24167                              <1> 	; of inode (chmod,chown,chgrp,link)
 24168                              <1> 	; parameters (without file/dir data changing)
 24169 00004D28 A3[58680000]        <1> 	mov	[i.atim], eax
 24170                              <1> 
 24171                              <1> setimod_ok: ; 31/07/2013
 24172 00004D2D 58                  <1> 	pop	eax
 24173                              <1> 	;pop	edx
 24174                              <1> 	
 24175 00004D2E C3                  <1> 	retn
 24176                              <1> 		; rts r0
 24177                              <1> setimod_4:
 24178                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 24179 00004D2F 31C9                <1> 	xor	ecx, ecx
 24180 00004D31 390D[5C680000]      <1> 	cmp	[i.mtim], ecx ; 0
 24181 00004D37 76EA                <1> 	jna	short setimod_2
 24182                              <1> 
 24183 00004D39 E8190E0000          <1> 	call	get_system_time ; get current (unix epoch) time
 24184                              <1> 	; ((system time will be updated directly by timer interrupt))
 24185                              <1> 
 24186 00004D3E 803D[956C0000]00    <1> 	cmp	byte [imodx], 0 ; flag means "file/dir data is same but
 24187 00004D45 76DC                <1> 	jna	short setimod_2 ; inode has been changed"
 24188                              <1> 
 24189                              <1> 	; File/Dir data (File size or content) is same but
 24190                              <1> 	; inode's mode, link count, owner or group id has been changed
 24191                              <1> 	; (so, we do not change last modification date&time)
 24192 00004D47 C605[956C0000]00    <1> 	mov	byte [imodx], 0 ; reset inode modified (extended) flag
 24193 00004D4E EBD8                <1> 	jmp	short setimod_3
 24194                              <1> 
 24195                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 24196                              <1> %if 0
 24197                              <1> 	; Retro UNIX 386 v1.1 'itrunc' code
 24198                              <1> itrunc:
 24199                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24200                              <1> 	; 23/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 24201                              <1> 	;
 24202                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 24203                              <1> 	;  to zero length.
 24204                              <1> 	;
 24205                              <1> 	; INPUTS ->
 24206                              <1> 	;    r1 - i-number of i-node
 24207                              <1> 	;    i.dskp - pointer to contents or indirect block in an i-node
 24208                              <1> 	;    i.flgs - large file flag		
 24209                              <1> 	;    i.size - size of file	
 24210                              <1> 	; 	 
 24211                              <1> 	; OUTPUTS ->
 24212                              <1> 	;    i.flgs - large file flag is cleared
 24213                              <1> 	;    i.size - set to 0	
 24214                              <1> 	;    i.dskp .. i.dskp+16 - entire list is cleared
 24215                              <1> 	;    setimod - set to indicate i-node has been modified
 24216                              <1> 	;    r1 - i-number of i-node  					
 24217                              <1> 	;
 24218                              <1> 	; ((AX = R1)) input/output
 24219                              <1> 	;
 24220                              <1> 	;  (Retro UNIX Prototype : 01/12/2012 - 10/03/2013, UNIXCOPY.ASM)
 24221                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 24222                              <1> 
 24223                              <1> 	call	iget
 24224                              <1> 		; jsr r0,iget
 24225                              <1> 	mov	esi, i.dskp
 24226                              <1> 		; mov $i.dskp,r2 / address of block pointers in r2
 24227                              <1> 	xor	eax, eax
 24228                              <1> itrunc_1: ; 1:
 24229                              <1> 	lodsw
 24230                              <1> 		; mov (r2)+,r1 / move physical block number into r1
 24231                              <1> 	or 	ax, ax
 24232                              <1> 	jz	short itrunc_5
 24233                              <1> 		; beq 5f
 24234                              <1> 	push	esi
 24235                              <1> 		; mov r2,-(sp)
 24236                              <1> 	test    word [i.flgs], 1000h    
 24237                              <1> 		; bit $10000,i.flgs / test large file bit?
 24238                              <1> 	jz	short itrunc_4
 24239                              <1> 		; beq 4f / if clear, branch
 24240                              <1> 	push	eax
 24241                              <1> 		; mov r1,-(sp) / save block number of indirect block
 24242                              <1> 	call	dskrd
 24243                              <1> 		; jsr r0,dskrd / read in block, 1st data word 
 24244                              <1> 			     ; / pointed to by r5
 24245                              <1> 	; eBX = r5 = Buffer data address (the 1st word)
 24246                              <1> 	mov	ecx, 256
 24247                              <1> 		; mov $256.,r3 / move word count into r3
 24248                              <1> 	mov	esi, ebx
 24249                              <1> itrunc_2: ; 2:
 24250                              <1> 	lodsw
 24251                              <1> 		; mov (r5)+,r1 / put 1st data word in r1; 
 24252                              <1> 			     ; / physical block number
 24253                              <1> 	and	ax, ax
 24254                              <1> 	jz	short itrunc_3
 24255                              <1> 		; beq 3f / branch if zero
 24256                              <1> 	;push	ecx
 24257                              <1> 	push	cx
 24258                              <1> 		; mov r3,-(sp) / save r3, r5 on stack
 24259                              <1> 	;push	esi
 24260                              <1> 		; mov r5,-(sp)
 24261                              <1> 	call	free
 24262                              <1> 		; jsr r0,free / free block in free storage map
 24263                              <1> 	;pop	esi
 24264                              <1> 		; mov(sp)+,r5
 24265                              <1> 	pop	cx
 24266                              <1> 	;pop	ecx
 24267                              <1> 		; mov (sp)+,r3
 24268                              <1> itrunc_3: ; 3:
 24269                              <1> 	loop	itrunc_2
 24270                              <1> 		; dec r3 / decrement word count
 24271                              <1> 		; bgt 2b / branch if positive
 24272                              <1> 	pop	eax
 24273                              <1> 		; mov (sp)+,r1 / put physical block number of 
 24274                              <1> 			     ; / indirect block
 24275                              <1> 	; 01/08/2013
 24276                              <1>         and     word [i.flgs], 0EFFFh ; 1110111111111111b
 24277                              <1> itrunc_4: ; 4:
 24278                              <1> 	call	free
 24279                              <1> 		; jsr r0,free / free indirect block
 24280                              <1> 	pop	esi
 24281                              <1> 		; mov (sp)+,r2
 24282                              <1> itrunc_5: ; 5:
 24283                              <1> 	cmp	esi, i.dskp+16
 24284                              <1> 		; cmp r2,$i.dskp+16.
 24285                              <1> 	jb	short itrunc_1	
 24286                              <1> 		; bne 1b / branch until all i.dskp entries check
 24287                              <1> 	; 01/08/2013
 24288                              <1> 	;and     word [i.flgs], 0EFFFh ; 1110111111111111b
 24289                              <1> 		; bic $10000,i.flgs / clear large file bit
 24290                              <1> 	mov	edi, i.dskp
 24291                              <1> 	mov	cx, 8
 24292                              <1> 	xor 	ax, ax
 24293                              <1> 	mov	[i.size], ax ; 0
 24294                              <1> 		; clr i.size / zero file size
 24295                              <1> 	rep	stosw
 24296                              <1> 		; jsr r0,copyz; i.dskp; i.dskp+16. 
 24297                              <1> 			   ; / zero block pointers
 24298                              <1> 	call	setimod
 24299                              <1> 		; jsr r0,setimod / set i-node modified flag
 24300                              <1> 	mov	ax, [ii]
 24301                              <1> 		; mov ii,r1
 24302                              <1> 	retn
 24303                              <1> 		; rts r0
 24304                              <1> 
 24305                              <1> 	; Retro UNIX 386 v1.1 'imap' code
 24306                              <1> imap:
 24307                              <1> 	; 17/07/2022 (Retro UNIX 386 v1.2)
 24308                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24309                              <1> 	; 26/04/2013 (Retro UNIX 8086 v1)
 24310                              <1> 	;
 24311                              <1> 	; 'imap' finds the byte in core (superblock) containing
 24312                              <1> 	; allocation bit for an i-node whose number in r1.
 24313                              <1> 	;
 24314                              <1> 	; INPUTS ->
 24315                              <1> 	;    r1 - contains an i-number
 24316                              <1> 	;    fsp - start of table containing open files
 24317                              <1> 	;
 24318                              <1> 	; OUTPUTS ->
 24319                              <1> 	;    r2 - byte address of byte with the allocation bit
 24320                              <1> 	;    mq - a mask to locate the bit position.	
 24321                              <1> 	;	  (a 1 is in calculated bit posisiton)
 24322                              <1> 	;
 24323                              <1> 	; ((AX = R1)) input/output
 24324                              <1> 	; ((DL/DX = MQ)) output
 24325                              <1> 	; ((BX = R2)) output
 24326                              <1> 	;
 24327                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 24328                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI))  
 24329                              <1> 	;
 24330                              <1> 		; / get the byte that has the allocation bit for 
 24331                              <1> 		; / the i-number contained in r1
 24332                              <1> 	;mov	dx, 1
 24333                              <1> 	mov	dl, 1
 24334                              <1> 		; mov $1,mq / put 1 in the mq
 24335                              <1> 	movzx	ebx, ax
 24336                              <1> 		; mov r1,r2 / r2 now has i-number whose byte
 24337                              <1>  		          ; / in the map we must find
 24338                              <1> 	sub	bx, 41
 24339                              <1> 		; sub $41.,r2 / r2 has i-41
 24340                              <1> 	mov	cl, bl
 24341                              <1> 		; mov r2,r3 / r3 has i-41
 24342                              <1> 	and	cl, 7
 24343                              <1> 		; bic $!7,r3 / r3 has (i-41) mod 8 to get 
 24344                              <1> 			   ; / the bit position
 24345                              <1> 	jz	short imap1
 24346                              <1> 	;shl	dx, cl
 24347                              <1> 	shl	dl, cl
 24348                              <1> 		; mov r3,lsh / move the 1 over (i-41) mod 8 positions
 24349                              <1> imap1:			   ; / to the left to mask the correct bit
 24350                              <1> 	;shr	bx, 3
 24351                              <1> 	; 17/07/2022
 24352                              <1> 	shr	ebx, 3
 24353                              <1> 		; asr r2
 24354                              <1> 		; asr r2
 24355                              <1> 		; asr r2 / r2 has (i-41) base 8 of the byte number
 24356                              <1> 		       ; / from the start of the map
 24357                              <1> 		; mov r2,-(sp) / put (i-41) base 8 on the stack
 24358                              <1> 	mov	esi, systm
 24359                              <1> 		; mov $systm,r2 / r2 points to the in-core image of
 24360                              <1> 				; / the super block for drum
 24361                              <1> 	;cmp	word [cdev], 0
 24362                              <1> 	cmp	byte [cdev], 0
 24363                              <1> 		; tst cdev / is the device the disk
 24364                              <1> 	jna	short imap2
 24365                              <1> 		; beq 1f / yes
 24366                              <1> 	add	esi, mount - systm
 24367                              <1> 		; add $mount-systm,r2 / for mounted device,
 24368                              <1> 			; / r2 points to 1st word of its super block
 24369                              <1> imap2: ; 1:
 24370                              <1> 	add	bx, [esi] ;; add free map size to si
 24371                              <1> 		; add (r2)+,(sp) / get byte address of allocation bit
 24372                              <1> 	add	bx, 4
 24373                              <1> 	add	ebx, esi
 24374                              <1>         	; add (sp)+,r2 / ?
 24375                              <1> 	;add	ebx, 4 ;; inode map offset in superblock
 24376                              <1> 		      ;; (2 + free map size + 2)
 24377                              <1> 		; add $2,r2 / ?
 24378                              <1>  	; DL/DX (MQ) has a 1 in the calculated bit position
 24379                              <1>         ; BX (R2) has byte address of the byte with allocation bit
 24380                              <1> 	retn
 24381                              <1> 		; rts r0
 24382                              <1> %endif
 24383                              <1> 
 24384                              <1> 	; Retro UNIX 386 v2.0 'itrunc' code
 24385                              <1> itrunc:
 24386                              <1> 	; 26/03/2022
 24387                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
 24388                              <1> 	; 07/06/2020
 24389                              <1> 	; 02/06/2020
 24390                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 24391                              <1> 	;
 24392                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 24393                              <1> 	;  to zero length.
 24394                              <1> 	; 07/06/2020
 24395                              <1> 	; 02/06/2020
 24396                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 24397                              <1> 	;
 24398                              <1> 	; 'itrunc' truncates a file whose i-number is given
 24399                              <1> 	; in ax to zero length.
 24400                              <1> 	;
 24401                              <1> 
 24402                              <1> 	; Reference: 
 24403                              <1> 	;	Retro UNIX 386 v2 FS installation utility
 24404                              <1> 	; 17/01/2020 - 'UNIXHDCP.ASM', 'itrunc' procedure
 24405                              <1> 
 24406                              <1> 	; * Free all the disk blocks associated
 24407                              <1> 	; * with the specified inode structure.
 24408                              <1> 	
 24409                              <1> 	; INPUT: 
 24410                              <1> 	;	(e)ax = inode number
 24411                              <1> 	; OUTPUT: 
 24412                              <1> 	;	inode will be modified (file size = 0)
 24413                              <1> 	;	; 26/03/20221
 24414                              <1> 	;	eax = 0 (if cf=0)
 24415                              <1> 
 24416                              <1> 	; (Modified registers: eax, edx, ecx, ebx, esi, edi, ebp) 
 24417                              <1> 
 24418                              <1> 	; 07/06/2020
 24419                              <1> 
 24420                              <1> 	; [cdev] = current logical drive number
 24421                              <1> 	;    eax = inode number (for [cdev])
 24422                              <1> 
 24423 00004D50 E820FEFFFF          <1> 	call 	iget
 24424                              <1> 	; 10/01/2022
 24425                              <1> 	;jc	short itrunc_0 ; error code in eax (al)
 24426                              <1> 
 24427                              <1> 	;    eax = inode number, [ii]
 24428                              <1> 	; [cdev] = current logical drive number (same with input)
 24429                              <1> 	; [idev] = logical drive number of current inode, [ii]
 24430                              <1> 	;   [ii] = current inode ([ii] = ax input, if ax was not zero)
 24431                              <1> 	; [imod] = 0		
 24432                              <1> 	; ([imodx] = 0)
 24433                              <1> 
 24434 00004D55 F605[25680000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file or directory	
 24435 00004D5C 750F                <1> 	jnz	short itrunc_1
 24436                              <1> 
 24437                              <1> 	; 10/01/2022
 24438 00004D5E C705[186D0000]FF00- <1> 	mov	dword [u.error], ERR_NOT_REGULAR ; 255 
 24439 00004D66 0000                <1>
 24440                              <1> 			; 'not a regular file (or directory) !' error
 24441                              <1> itrunc_0:
 24442 00004D68 E9F8E3FFFF          <1> 	jmp	error
 24443                              <1> itrunc_1:
 24444 00004D6D F605[25680000]10    <1> 	test	byte [i.flgs+1], 10h ; large file (indirect blocks)
 24445 00004D74 7528                <1> 	jnz	short itrunc_5 ; large file
 24446 00004D76 BE[30680000]        <1> 	mov	esi, i.dskp ; disk address pointer 0
 24447                              <1> itrunc_2:
 24448 00004D7B AD                  <1> 	lodsd
 24449 00004D7C 21C0                <1> 	and	eax, eax
 24450 00004D7E 740C                <1> 	jz	short itrunc_3 ; empty ! (no more sectors/blocks)
 24451                              <1> 	; eax = block address to be released
 24452 00004D80 56                  <1> 	push	esi ; * ; 10/01/2022
 24453 00004D81 E83DFDFFFF          <1> 	call	free
 24454                              <1> 	; modified registers: ebx, ecx, edx, esi, edi, ebp 
 24455                              <1> 	; 10/01/2022
 24456                              <1> 	;jc	short itrunc_0 ; error code in eax
 24457 00004D86 5E                  <1> 	pop	esi ; * ; 10/01/2022
 24458 00004D87 31C0                <1> 	xor	eax, eax ; 0
 24459 00004D89 8946FC              <1> 	mov	[esi-4], eax ; 0
 24460                              <1> itrunc_3:
 24461 00004D8C 81FE[58680000]      <1> 	cmp	esi, i.dskp+40
 24462 00004D92 72E7                <1> 	jb	short itrunc_2 ; next disk address ptr
 24463                              <1> itrunc_4:
 24464 00004D94 A3[2C680000]        <1> 	mov	[i.size], eax ; 0
 24465                              <1> 	;mov	[i.size_h], al ; 0
 24466                              <1> 	
 24467                              <1> 	; clear large file flag
 24468                              <1> 	;and     byte [i.flgs+1], 0EFh ; 11101111b ; not 10h
 24469                              <1> 		
 24470                              <1> 	;call	setimod
 24471                              <1> 	;retn
 24472 00004D99 E968FFFFFF          <1> 	jmp	setimod
 24473                              <1> 
 24474                              <1> itrunc_5:
 24475                              <1> 	; free disk blocks by using triple indirect blocks at first
 24476 00004D9E BE[54680000]        <1> 	mov	esi, i.dskp+36
 24477 00004DA3 8B06                <1> 	mov	eax, [esi]
 24478 00004DA5 09C0                <1> 	or	eax, eax
 24479 00004DA7 740C                <1> 	jz	short itrunc_6
 24480                              <1> 
 24481 00004DA9 BA02000000          <1> 	mov	edx, 2 ; Triple indirect sign (level = 2)
 24482 00004DAE E835000000          <1> 	call	tloop
 24483                              <1> 	; 10/01/2022
 24484                              <1> 	;jc	short itrunc_0
 24485                              <1> 		; eax = 0	
 24486 00004DB3 8906                <1> 	mov	[esi], eax ; 0
 24487                              <1> itrunc_6:
 24488                              <1> 	; free disk blocks by using double indirect blocks at second
 24489 00004DB5 BE[50680000]        <1> 	mov	esi, i.dskp+32
 24490 00004DBA 8B06                <1> 	mov	eax, [esi]
 24491 00004DBC 21C0                <1> 	and	eax, eax 
 24492 00004DBE 740C                <1> 	jz	short itrunc_7
 24493                              <1> 
 24494 00004DC0 BA01000000          <1> 	mov	edx, 1 ; Double indirect sign (level = 1)
 24495 00004DC5 E81E000000          <1> 	call	tloop
 24496                              <1> 	; 10/01/2022
 24497                              <1> 	;jc	short itrunc_0
 24498                              <1> 		; eax = 0	
 24499 00004DCA 8906                <1> 	mov	[esi], eax ; 0
 24500                              <1> 	;esi = i.dskp+32
 24501                              <1> itrunc_7:
 24502                              <1> 	; free disk blocks by using single indirect blocks at third
 24503 00004DCC 83EE04              <1> 	sub	esi, 4
 24504 00004DCF 8B06                <1> 	mov	eax, [esi]
 24505 00004DD1 09C0                <1> 	or	eax, eax
 24506 00004DD3 7409                <1> 	jz	short itrunc_8
 24507                              <1> 
 24508 00004DD5 29D2                <1> 	sub	edx, edx ; 0  ; Single indirect sign (level = 0)
 24509 00004DD7 E80C000000          <1> 	call	tloop
 24510                              <1> 	; 10/01/2022
 24511                              <1> 	;jc	short itrunc_0
 24512                              <1> 		; eax = 0
 24513 00004DDC 8906                <1> 	mov	[esi], eax ; 0
 24514                              <1> itrunc_8:
 24515 00004DDE 81FE[30680000]      <1> 	cmp	esi, i.dskp
 24516 00004DE4 77E6                <1> 	ja	short itrunc_7
 24517 00004DE6 EBAC                <1> 	jmp	short itrunc_4
 24518                              <1> 
 24519                              <1> tloop:
 24520                              <1> 	; 26/03/2022
 24521                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
 24522                              <1> 	; 07/06/2020
 24523                              <1> 	; 03/06/2020
 24524                              <1> 	; 02/06/2020
 24525                              <1> 	; 26/05/2020 - Retro UNIX 386 v2 by Erdogan Tan
 24526                              <1> 	; 
 24527                              <1> 	; * Free all the disk blocks associated
 24528                              <1> 	; * with the specified inode structure.
 24529                              <1> 
 24530                              <1> 	; Reference: 
 24531                              <1> 	;	Retro UNIX 386 v2 FS installation utility
 24532                              <1> 	; 17/01/2020 - 'UNIXHDCP.ASM', 'tloop' procedure
 24533                              <1> 
 24534                              <1> 	; INPUT: 
 24535                              <1> 	;	03/06/2020
 24536                              <1> 	;	eax = indirect block number/address (logical)
 24537                              <1> 	;	edx = level (in dl) 
 24538                              <1> 	;	(0 = indirect, 1 = double indr. 2 = triple indr.) 	
 24539                              <1> 	;
 24540                              <1> 	; OUTPUT: 
 24541                              <1> 	;	indirect blocks will be released
 24542                              <1> 	;
 24543                              <1> 	; Modified registers: eax, ebx, ecx, edx
 24544                              <1> 
 24545                              <1> 	; 03/06/2020
 24546                              <1> 
 24547 00004DE8 57                  <1> 	push	edi ; *
 24548 00004DE9 56                  <1> 	push	esi ; **
 24549                              <1> 
 24550 00004DEA 50                  <1> 	push	eax ; ***
 24551                              <1> 
 24552 00004DEB 52                  <1> 	push	edx ; **** level
 24553                              <1> 
 24554                              <1> 	; [ii] = current inode number
 24555                              <1> 	;;[idev] = logical drive number of current inode, [ii]
 24556                              <1> 	; eax = logical sector/block number
 24557                              <1> 
 24558                              <1> 	; 26/03/2022
 24559                              <1> 	; [cdev] = logical drive number (0 or 1)
 24560                              <1> 
 24561                              <1> 	; 10/01/2022
 24562                              <1> 	; convert to physical sector/block number/address
 24563 00004DEC E856FAFFFF          <1> 	call	mget_2	
 24564                              <1> 
 24565 00004DF1 E89A0B0000          <1> 	call	dskrd ; read disk sector
 24566                              <1> 
 24567                              <1> 		;; ebx = buffer header address
 24568                              <1> 		;; eax = physical sector/block number 
 24569                              <1> 		;; [pdn] = phsysical drive (index) number
 24570                              <1> 		
 24571                              <1> 		;; Modified registers: eax, edx, ecx, esi, edi
 24572                              <1> 		;; If cf = 1 --> eax = error code (al)
 24573                              <1> 
 24574                              <1> 	; 10/01/2022
 24575                              <1> 	; Return from 'dskrd': (Retro UNIX 386 v1.2)
 24576                              <1> 	; 	eax = physical block/sector number
 24577                              <1> 	; 	ebx = buffer data address
 24578                              <1>  	; Modified registers: edx, ecx, ebx, esi, edi, ebp
 24579                              <1>  
 24580 00004DF6 5A                  <1> 	pop	edx ; **** ; level in dl
 24581                              <1> 	; 10/01/2022
 24582                              <1> 	;jc	short tloop_5
 24583                              <1> 
 24584                              <1> 	;mov	esi, [ebx+bufhdr.address] ; buffer address
 24585                              <1> 	; 10/01/2022
 24586 00004DF7 89DE                <1> 	mov	esi, ebx ; buffer data address	
 24587                              <1> 
 24588                              <1> 	; 07/06/2020
 24589 00004DF9 B980000000          <1> 	mov	ecx, 512/4 ; 128 dwords	
 24590                              <1> 
 24591 00004DFE 80FA01              <1> 	cmp	dl, 1 ; -
 24592 00004E01 722C                <1> 	jb	short tloop_7
 24593 00004E03 7407                <1> 	je	short tloop_1
 24594 00004E05 BF[64750000]        <1> 	mov	edi, trpi_buf ; triple indirect buffer address
 24595 00004E0A EB05                <1> 	jmp	short tloop_2
 24596                              <1> tloop_1:
 24597 00004E0C BF[64730000]        <1> 	mov	edi, dbli_buf ; double indirect buffer address
 24598                              <1> tloop_2:
 24599                              <1> 	; copy disk r/w buffer content to indirect block buffer
 24600                              <1> 	;mov	ecx, 512/4 ; 128 dwords	
 24601 00004E11 F3A5                <1> 	rep	movsd
 24602                              <1> 
 24603 00004E13 FECA                <1> 	dec	dl ; -
 24604                              <1> 		   ; next indirect block level, 2 -> 1, 1 -> 0
 24605 00004E15 89FE                <1> 	mov	esi, edi  ; (dbli, trpi) indirect buffer + 512
 24606 00004E17 B180                <1> 	mov	cl, 128 ; 128 dwords
 24607                              <1> tloop_3:
 24608 00004E19 83EE04              <1> 	sub	esi, 4  ; previous pointer
 24609                              <1> 
 24610 00004E1C 8B06                <1> 	mov	eax, [esi]
 24611                              <1> 
 24612 00004E1E 09C0                <1> 	or	eax, eax ; 0
 24613 00004E20 7409                <1> 	jz	short tloop_4
 24614                              <1> 
 24615                              <1> 	; 26/03/2022
 24616 00004E22 52                  <1> 	push	edx ; @@
 24617                              <1> 	; 03/06/2020
 24618 00004E23 51                  <1> 	push	ecx ; @
 24619 00004E24 E8BFFFFFFF          <1> 	call	tloop
 24620 00004E29 59                  <1> 	pop	ecx ; @
 24621                              <1> 	; 26/03/2022
 24622 00004E2A 5A                  <1> 	pop	edx ; @@
 24623                              <1> 	; 10/01/2022
 24624                              <1> 	;jc	short tloop_5
 24625                              <1> tloop_4:
 24626 00004E2B E2EC                <1> 	loop	tloop_3
 24627                              <1> 
 24628 00004E2D EB1A                <1> 	jmp	short tloop_10
 24629                              <1> 
 24630                              <1> 	; 10/01/2022
 24631                              <1> ;tloop_5:
 24632                              <1> ;	pop	edx ; ***  ; discard eax
 24633                              <1> ;	; error code in eax
 24634                              <1> ;tloop_6:
 24635                              <1> ;	pop	esi ; **
 24636                              <1> ;	pop	edi ; *
 24637                              <1> ;	retn
 24638                              <1> 	
 24639                              <1> 	; free blocks in current indirect block
 24640                              <1> tloop_7:
 24641                              <1> 	;mov	ecx, 512/4  ; 128 dwords
 24642 00004E2F 81C6FC010000        <1> 	add	esi, 508
 24643                              <1> tloop_8:
 24644 00004E35 8B06                <1> 	mov	eax, [esi]
 24645 00004E37 21C0                <1> 	and	eax, eax ; 0 ?
 24646 00004E39 7409                <1> 	jz	short tloop_9
 24647                              <1> 	
 24648 00004E3B 56                  <1> 	push	esi ; **** ; 10/01/2022
 24649 00004E3C 51                  <1> 	push	ecx ; *****
 24650 00004E3D E881FCFFFF          <1> 	call	free
 24651                              <1> 		; if cf = 0 -> eax = 0
 24652                              <1> 		; if cf = 1 -> eax = error code (in al)
 24653 00004E42 59                  <1> 	pop	ecx ; *****
 24654 00004E43 5E                  <1> 	pop	esi ; **** ; 10/01/2022
 24655                              <1> 	; 10/01/2022
 24656                              <1> 	;; 07/06/2020
 24657                              <1> 	;jc	short tloop_6
 24658                              <1> tloop_9:
 24659 00004E44 83EE04              <1> 	sub	esi, 4
 24660 00004E47 E2EC                <1> 	loop	tloop_8
 24661                              <1> tloop_10:
 24662 00004E49 58                  <1> 	pop	eax ; *** ; free indirect block's itself
 24663 00004E4A E874FCFFFF          <1> 	call	free
 24664                              <1> 		;; if cf = 0 -> eax = 0
 24665                              <1> 		;; if cf = 1 -> eax = error code (in al)
 24666                              <1> 	; 10/01/2022
 24667                              <1> 	; (if we are here, there is not an error, cf=0) 
 24668                              <1> 	;jmp	short tloop_6
 24669                              <1> 
 24670                              <1> 	; 10/02/2022
 24671 00004E4F 31C0                <1> 	xor	eax, eax ; 0
 24672 00004E51 5E                  <1> 	pop	esi ; **
 24673 00004E52 5F                  <1> 	pop	edi ; *
 24674 00004E53 C3                  <1> 	retn
 24675                              <1> 
 24676                              <1> 	; Retro UNIX 386 v2.0 'imap' code
 24677                              <1> 	;	(runix v2 fs inode map)
 24678                              <1> imap:
 24679                              <1> 	; 18/04/2022
 24680                              <1> 	; 26/03/2022
 24681                              <1> 	; 12/03/2022
 24682                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
 24683                              <1> 	;	(major modification)
 24684                              <1> 	; 05/11/2021 - temporary (simplified code)
 24685                              <1> 	; 21/08/2021
 24686                              <1> 	; 15/08/2021
 24687                              <1> 	; 14/06/2021
 24688                              <1> 	; 02/05/2021
 24689                              <1> 	; 01/04/2021, 08/04/2021, 24/04/2021
 24690                              <1> 	; 29/03/2021
 24691                              <1> 	; 28/03/2021 - Retro UNIX 386 v2 (beginning)
 24692                              <1> 	;
 24693                              <1> 	; 'imap' finds the byte in inode map containing
 24694                              <1> 	; allocation bit for an i-node whose number in (E)AX
 24695                              <1> 	;
 24696                              <1> 	; (ref: 'UNIXHDCP.ASM', imap', 22/01/2020) 
 24697                              <1> 	;
 24698                              <1> 	; ((Retro UNIX 386 v2 'imap' code is mostly different
 24699                              <1> 	; than Retro UNIX 386 v1.1 'imap' code.))
 24700                              <1> 	;
 24701                              <1> 	; INPUTS ->
 24702                              <1> 	;   EAX = inode number
 24703                              <1> 	;        0 = first free inode
 24704                              <1> 	;       >0 = requested inode
 24705                              <1> 	;   [cdev] = current (logical) drive/device
 24706                              <1> 	;	
 24707                              <1> 	; OUTPUTS ->
 24708                              <1> 	;    EBX = address of the byte contains allocation bit
 24709                              <1> 	;     DX has 1 at calculated bit position
 24710                              <1> 	;   ; 05/11/2021	
 24711                              <1> 	;    EBP = superblock buffer address  
 24712                              <1> 	;    (EAX = inode number)
 24713                              <1> 	;   12/03/2022
 24714                              <1> 	;    (if EAX input is 0, EAX = first free inode > 1)
 24715                              <1> 	;	 		  	
 24716                              <1> 	;   ; 08/04/2021
 24717                              <1> 	;     If cf=1 -> error code in eax (al) 	
 24718                              <1> 	;
 24719                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp
 24720                              <1> 
 24721                              <1> 	; 05/11/2021
 24722 00004E54 803D[816C0000]00    <1> 	cmp	byte [cdev], 0
 24723 00004E5B 7616                <1> 	jna	short imap_0
 24724                              <1> 	; 10/01/2022
 24725 00004E5D BD[5C6F0000]        <1> 	mov	ebp, mount ; mounted fs superblock buffer
 24726 00004E62 EB14                <1> 	jmp	short imap_1
 24727                              <1> 
 24728                              <1> imap_ialloc_err:
 24729                              <1> 	; 10/01/2022
 24730 00004E64 C705[186D0000]2100- <1> 	mov	dword [u.error], ERR_INO_ALLOC ; 33
 24731 00004E6C 0000                <1>
 24732                              <1> 			; 'inode allocation error !'
 24733 00004E6E E9F2E2FFFF          <1> 	jmp	error
 24734                              <1>  
 24735                              <1> imap_0:
 24736                              <1> 	; 10/01/2022
 24737 00004E73 BD[546D0000]        <1> 	mov	ebp, systm ; root fs superblock buffer
 24738                              <1> imap_1:
 24739                              <1> 	; 26/03/2022
 24740                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 24741                              <1> imap_x:
 24742                              <1> 	; 05/11/2021
 24743                              <1> 	; 21/08/2021
 24744                              <1> 	; 15/08/2021 (Retro UNIX 386 v2)
 24745                              <1> 	; call from 'maknod2' ; 10/01/2022
 24746                              <1> 	;
 24747                              <1> 	; eax = inode number
 24748                              <1> 	; [cdev] = device number for inode in eax
 24749                              <1> 	; ebp = superblock buffer address
 24750                              <1> 
 24751                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 24752                              <1> 	; 'imap' and 'imap_x' will return with..
 24753                              <1> 	;    ECX = byte offset from inode map buff (imap_x)
 24754                              <1> 	;    EBX = byte addr of the byte with allocation bit
 24755                              <1> 	;    EDX (DL) has a 1 in the calculated bit position
 24756                              <1> 
 24757                              <1> 	; 02/05/2021
 24758                              <1> 	; convert inode number to first free inode if it is 0
 24759 00004E78 E83B000000          <1> 	call	imap_3 ; 10/01/2022
 24760 00004E7D 72E5                <1> 	jc	short imap_ialloc_err
 24761                              <1> 	; eax = inode number > 1 (1 = root directory inode)
 24762                              <1> 
 24763 00004E7F 898584000000        <1> 	mov	[ebp+SB.LastInode], eax
 24764                              <1> 	
 24765 00004E85 50                  <1> 	push	eax ; * ; save inode number
 24766                              <1> 
 24767                              <1> 	; convert inode number to inode map sector index
 24768 00004E86 E845000000          <1> 	call	imap_8 ; 10/01/2022
 24769 00004E8B 50                  <1> 	push	eax ; ** ; byte offset in inode map buffer
 24770                              <1> 
 24771                              <1> 	; edx = inode map buffer sector index number (< 16)
 24772                              <1> 	; eax = byte offset in inode map buffer (< 512)
 24773                              <1> 
 24774                              <1> 	; 15/08/2021
 24775 00004E8C 89958C000000        <1> 	mov	[ebp+SB.ImapIndex], edx
 24776 00004E92 8B4520              <1> 	mov	eax, [ebp+SB.InodeMapAddr]
 24777 00004E95 01D0                <1> 	add	eax, edx
 24778 00004E97 034504              <1> 	add	eax, [ebp+SB.BootSectAddr]
 24779                              <1> 	; eax = physical sector number
 24780                              <1> 	; [cdev] = current device/disk number
 24781                              <1> 	
 24782                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 24783 00004E9A 55                  <1> 	push	ebp ; ***
 24784 00004E9B E8F00A0000          <1> 	call	dskrd
 24785 00004EA0 5D                  <1> 	pop	ebp ; ***
 24786                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 24787                              <1> 	; eax = physical sector number
 24788                              <1> 	; ebx = buffer data address
 24789                              <1> 
 24790                              <1> 	; 26/03/2022
 24791                              <1> 	; (ecx may be > 255 at return from dskrd)
 24792                              <1> 	;sub	ecx, ecx ; 0
 24793                              <1> 	; 10/01/2022
 24794                              <1> 	;mov	cl, [esp+4] ; * ; inode number
 24795                              <1> 	; 18/04/2022
 24796 00004EA1 8B4C2404            <1> 	mov	ecx, [esp+4] ; * ; inode number
 24797 00004EA5 FEC9                <1> 	dec	cl
 24798                              <1> 	; 26/03/2022
 24799 00004EA7 31D2                <1> 	xor	edx, edx
 24800                              <1> 	;mov	dl, 1
 24801 00004EA9 FEC2                <1> 	inc	dl ; dl = 1
 24802                              <1> 	;and	ecx, 7
 24803                              <1> 	; 26/03/2022
 24804                              <1> 	; 02/05/2021
 24805                              <1> 	;dec	cl
 24806                              <1> 	;jz	short imap_2 ; 15/08/2021
 24807 00004EAB 80E107              <1> 	and	cl, 7	; 1 imap byte is for 8 inodes 
 24808                              <1> 	;jz	short imap_2
 24809 00004EAE D2E2                <1> 	shl	dl, cl
 24810                              <1> imap_2:
 24811                              <1> 	; 10/01/2022
 24812                              <1> 	; save physical sector number of imap sector in the SB
 24813 00004EB0 89457C              <1> 	mov	[ebp+SB.ImapBuffer], eax ; ! sector addr !
 24814                              <1> 	; 
 24815 00004EB3 59                  <1> 	pop	ecx ; ** ; byte offset in inode map buffer
 24816 00004EB4 01CB                <1> 	add	ebx, ecx ; + byte position
 24817 00004EB6 58                  <1> 	pop	eax ; * ; inode number
 24818                              <1> 
 24819                              <1> 	; 10/01/2022
 24820                              <1> 	; ECX contains byte offset from inode map buff (imap_x)
 24821                              <1> 	; EDX (DL) has a 1 in the calculated bit position
 24822                              <1> 	; EBX has byte address of the byte with allocation bit
 24823                              <1> 
 24824 00004EB7 C3                  <1> 	retn
 24825                              <1> 
 24826                              <1> imap_3:
 24827                              <1> 	; 10/01/2022
 24828                              <1> 	; 15/08/2021
 24829                              <1> 	; 02/05/2021
 24830                              <1> 	; 28/03/2021
 24831                              <1> 	; get first free inode number (from superblock)
 24832                              <1> 	; and check inode number against inode count
 24833                              <1> 	;
 24834                              <1> 	; INPUT:
 24835                              <1> 	;    eax = 0 -> get first free inode number
 24836                              <1> 	;    (eax > 0 -> check inode number)
 24837                              <1> 	;    ebp = superblock address ; 15/08/2021
 24838                              <1> 	; OUTPUT:
 24839                              <1> 	;    eax = inode number 
 24840                              <1> 	;    (eax will be 2 when SB.FirstFreeIno is invalid)
 24841                              <1> 	;    cf = 1 -> inode allocation error/problem
 24842                              <1> 	
 24843 00004EB8 21C0                <1> 	and	eax, eax	
 24844 00004EBA 750E                <1> 	jnz	short imap_5
 24845                              <1> 
 24846                              <1> 	; get first free inode
 24847                              <1> 	;mov	eax, [ebp+SB.FreeInodes]
 24848                              <1> 	;and	eax, eax
 24849                              <1> 	;jz	short imap_6
 24850                              <1> 	; 10/01/2022
 24851 00004EBC 394530              <1> 	cmp	[ebp+SB.FreeInodes], eax ; 0
 24852 00004EBF 760D                <1> 	jna	short imap_6	
 24853 00004EC1 8B4534              <1> 	mov	eax, [ebp+SB.FirstFreeIno] ; 1 based inode num
 24854 00004EC4 40                  <1> 	inc	eax
 24855 00004EC5 7502                <1> 	jnz	short imap_4 ; 0FFFFFFFFh -> 0
 24856                              <1> 	; invalid first free inode value (not initialized)
 24857 00004EC7 B003                <1> 	mov	al, 3 ; first free inode to be searched + 1
 24858                              <1> imap_4:
 24859 00004EC9 48                  <1> 	dec	eax
 24860                              <1> imap_5:
 24861                              <1> 	; 15/08/2021
 24862                              <1> 	; check inode number against inode count of the fs
 24863 00004ECA 394514              <1> 	cmp	[ebp+SB.InodeCount], eax
 24864 00004ECD C3                  <1> 	retn	; if cf = 1 --> inode number > inode count
 24865                              <1> imap_6:
 24866                              <1> 	; 'imap' inode allocation error !
 24867 00004ECE F9                  <1> 	stc
 24868                              <1> imap_7:
 24869 00004ECF C3                  <1> 	retn
 24870                              <1> 
 24871                              <1> imap_8:
 24872                              <1> 	; 10/01/2022
 24873                              <1> 	; 15/08/2021
 24874                              <1> 	; 02/05/2021
 24875                              <1> 	; 28/03/2021
 24876                              <1> 	; convert inode count to inode map sector index
 24877                              <1> 	;
 24878                              <1> 	; INPUT: 
 24879                              <1> 	;    eax = inode number
 24880                              <1> 	; OUTPUT:
 24881                              <1> 	;    edx = inode map sector offset/index number
 24882                              <1> 	;    eax = byte offset from start of imapbuf	 
 24883                              <1> 
 24884 00004ED0 31D2                <1> 	xor	edx, edx
 24885 00004ED2 48                  <1> 	dec	eax ; zero based inode number
 24886 00004ED3 74FA                <1> 	jz	short imap_7
 24887                              <1> 
 24888 00004ED5 C1E803              <1> 	shr	eax, 3 ; 8 inodes per inode map byte
 24889                              <1> 		; eax = byte offset from start of inode map
 24890 00004ED8 88E2                <1> 	mov	dl, ah ; ah <= 31 (1Fh) for Retro UNIX 386 v2
 24891 00004EDA D0EA                <1> 	shr	dl, 1
 24892                              <1> 		; edx = inode map sector offset/index number
 24893                              <1> 	;and	eax, 511
 24894 00004EDC 6625FF01            <1> 	and	ax, 511
 24895                              <1> 		; eax = byte offset from start of imapbuf
 24896 00004EE0 C3                  <1> 	retn
 24897                                  %include 'u6.s'      ; 31/05/2015
 24898                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 24899                              <1> ; (re-write kernel for test by using previous version without a major defect)
 24900                              <1> ; ****************************************************************************
 24901                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS6.INC
 24902                              <1> ; Last Modification: 19/07/2022
 24903                              <1> ; ----------------------------------------------------------------------------
 24904                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 24905                              <1> ; (v0.1 - Beginning: 11/07/2012)
 24906                              <1> ;
 24907                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 24908                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 24909                              <1> ; <Bell Laboratories (17/3/1972)>
 24910                              <1> ; <Preliminary Release of UNIX Implementation Document>
 24911                              <1> ;
 24912                              <1> ; Retro UNIX 8086 v1 - U6.ASM (23/07/2014) //// UNIX v1 -> u6.s
 24913                              <1> ;
 24914                              <1> ; ****************************************************************************
 24915                              <1> 
 24916                              <1> 	; 09/03/2022
 24917                              <1> 	; 25/12/2021
 24918                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 24919                              <1> readi:
 24920                              <1> 	; 20/05/2015
 24921                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 24922                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 24923                              <1> 	;
 24924                              <1> 	; Reads from an inode whose number in R1
 24925                              <1> 	; 
 24926                              <1> 	; INPUTS ->
 24927                              <1> 	;    r1 - inode number
 24928                              <1> 	;    u.count - byte count user desires
 24929                              <1> 	;    u.base - points to user buffer
 24930                              <1> 	;    u.fofp - points to word with current file offset
 24931                              <1> 	; OUTPUTS ->
 24932                              <1> 	;    u.count - cleared
 24933                              <1> 	;    u.nread - accumulates total bytes passed back
 24934                              <1> 	;
 24935                              <1> 	; ((AX = R1)) input/output
 24936                              <1> 	;    (Retro UNIX Prototype: 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
 24937                              <1>         ;    ((Modified registers: edx, ebx, ecx, esi, edi)) -15/07/2022- 
 24938                              <1> 
 24939 00004EE1 31D2                <1> 	xor	edx, edx ; 0
 24940 00004EE3 8915[D06C0000]      <1> 	mov 	[u.nread], edx ; 0
 24941                              <1> 		; clr u.nread / accumulates number of bytes transmitted
 24942 00004EE9 668915[106D0000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
 24943 00004EF0 3915[CC6C0000]      <1> 	cmp 	[u.count], edx ; 0
 24944                              <1> 		; tst u.count / is number of bytes to be read greater than 0
 24945 00004EF6 7701                <1> 	ja 	short readi_1 ; 1f
 24946                              <1> 		; bgt 1f / yes, branch
 24947 00004EF8 C3                  <1> 	retn
 24948                              <1> 		; rts r0 / no, nothing to read; return to caller
 24949                              <1> readi_1: ; 1:
 24950                              <1> 	;	; mov r1,-(sp) / save i-number on stack
 24951                              <1> 	;cmp	ax, 40
 24952                              <1> 	;	; cmp r1,$40. / want to read a special file 
 24953                              <1> 	;	;             / (i-nodes 1,...,40 are for special files)
 24954                              <1>         ;ja	dskr 
 24955                              <1> 	;	; ble 1f / yes, branch
 24956                              <1> 	;	; jmp dskr / no, jmp to dskr; 
 24957                              <1> 	;	;         / read file with i-node number (r1)
 24958                              <1> 	;	;    / starting at byte ((u.fofp)), read in u.count bytes
 24959                              <1> 	
 24960                              <1> 	; 28/11/2021
 24961 00004EF9 F605[166D0000]FF    <1> 	test	byte [u.kcall], 0FFh
 24962                              <1> 	;jnz	short readi_2  ; 'readi' called by 'namei'
 24963                              <1> 	; 09/03/2022
 24964                              <1> 	;jz	short _readi_2
 24965                              <1> 	;jmp	dskr
 24966 00004F00 750C                <1> 	jnz	short readi_2 ; 'readi' called by 'namei'
 24967                              <1> ;_readi_2:	; 09/03/2022
 24968                              <1> 	; eax = inode number
 24969                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 24970 00004F02 E86EFCFFFF          <1> 	call	iget
 24971                              <1> ;readi_2:
 24972                              <1> 	; 28/11/2021
 24973                              <1> 	; eax = inode number
 24974                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 24975 00004F07 E800050000          <1> 	call	is_regular_file
 24976                              <1> 	;jz	dskr ; regular file 
 24977                              <1> 	; 25/12/2021
 24978 00004F0C 7505                <1> 	jnz	short readi_5 ; device file 
 24979                              <1> readi_2:	 ; 09/03/2022
 24980                              <1> 	; regular file
 24981 00004F0E E9E3000000          <1> 	jmp	dskr
 24982                              <1> readi_5:
 24983                              <1> 	; (20/05/2015)
 24984 00004F13 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 24985                              <1> 
 24986                              <1> 	; 28/11/2021	
 24987                              <1> 	; device file
 24988 00004F14 BB[2E4F0000]        <1> 	mov	ebx, readi_4
 24989 00004F19 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 24990 00004F1C 720E                <1> 	jb	short readi_3
 24991 00004F1E 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 24992 00004F21 7709                <1> 	ja	short readi_3	
 24993                              <1> 	
 24994                              <1> 	; convert v2 inode number to v1 device inode number
 24995 00004F23 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 24996 00004F25 89C1                <1> 	mov	ecx, eax
 24997 00004F27 C0E102              <1> 	shl	cl, 2 ; * 4
 24998 00004F2A 01CB                <1> 	add	ebx, ecx
 24999                              <1> readi_3:
 25000 00004F2C FF23                <1> 	jmp	dword [ebx]	
 25001                              <1> 		 ; jmp *1f-2(r1)
 25002                              <1> readi_4: ; 1:
 25003 00004F2E [7E4F0000]          <1> 	dd	null ; 28/11/2021
 25004 00004F32 [824F0000]          <1> 	dd	rtty ; tty, AX = 1 (runix)
 25005                              <1> 		 ;rtty / tty; r1=2
 25006                              <1> 		 ;rppt / ppt; r1=4
 25007 00004F36 [D24F0000]          <1> 	dd	rmem ; mem, AX = 2 (runix)
 25008                              <1> 		 ;rmem / mem; r1=6
 25009                              <1> 		 ;rrf0 / rf0
 25010                              <1> 		 ;rrk0 / rk0
 25011                              <1> 		 ;rtap / tap0
 25012                              <1> 		 ;rtap / tap1
 25013                              <1> 		 ;rtap / tap2
 25014                              <1> 		 ;rtap / tap3
 25015                              <1> 		 ;rtap / tap4
 25016                              <1> 		 ;rtap / tap5
 25017                              <1> 		 ;rtap / tap6
 25018                              <1> 		 ;rtap / tap7
 25019 00004F3A [51580000]          <1> 	dd	rfd ; fd0, AX = 3 (runix only)
 25020 00004F3E [51580000]          <1> 	dd	rfd ; fd1, AX = 4 (runix only)
 25021 00004F42 [51580000]          <1> 	dd	rhd ; hd0, AX = 5 (runix only)
 25022 00004F46 [51580000]          <1> 	dd	rhd ; hd1, AX = 6 (runix only)	
 25023 00004F4A [51580000]          <1> 	dd	rhd ; hd2, AX = 7 (runix only)
 25024 00004F4E [51580000]          <1> 	dd	rhd ; hd3, AX = 8 (runix only)	
 25025 00004F52 [E74F0000]          <1> 	dd	rlpr ; lpr, AX = 9 (invalid, write only device !?)
 25026 00004F56 [CE4F0000]          <1> 	dd	rcvt ; tty0, AX = 10 (runix)	  
 25027                              <1> 		 ;rcvt / tty0
 25028 00004F5A [CE4F0000]          <1> 	dd	rcvt ; tty1, AX = 11 (runix)	  
 25029                              <1> 		 ;rcvt / tty1
 25030 00004F5E [CE4F0000]          <1> 	dd	rcvt ; tty2, AX = 12 (runix)	  
 25031                              <1> 		 ;rcvt / tty2
 25032 00004F62 [CE4F0000]          <1> 	dd	rcvt ; tty3, AX = 13 (runix)	  
 25033                              <1> 		 ;rcvt / tty3
 25034 00004F66 [CE4F0000]          <1> 	dd	rcvt ; tty4, AX = 14 (runix)	  
 25035                              <1> 		 ;rcvt / tty4
 25036 00004F6A [CE4F0000]          <1> 	dd	rcvt ; tty5, AX = 15 (runix)	  
 25037                              <1> 		 ;rcvt / tty5
 25038 00004F6E [CE4F0000]          <1> 	dd	rcvt ; tty6, AX = 16 (runix)	  
 25039                              <1> 		 ;rcvt / tty6
 25040 00004F72 [CE4F0000]          <1> 	dd	rcvt ; tty7, AX = 17 (runix)	  
 25041                              <1> 		 ;rcvt / tty7
 25042 00004F76 [CE4F0000]          <1> 	dd	rcvt ; COM1, AX = 18 (runix only)	  
 25043                              <1> 		 ;rcrd / crd
 25044 00004F7A [CE4F0000]          <1> 	dd	rcvt ; COM2, AX = 19 (runix only)
 25045                              <1> 
 25046                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25047                              <1> null:
 25048 00004F7E 31C0                <1> 	xor	eax, eax
 25049 00004F80 58                  <1> 	pop	eax
 25050 00004F81 C3                  <1> 	retn
 25051                              <1> 
 25052                              <1> 	; 11/01/2022
 25053                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 25054                              <1> rtty: ; / read from console tty
 25055                              <1> 	; 17/10/2015 - 16/07/2015 (Retro UNIX 8086 v1)
 25056                              <1> 	; 	     (Only 1 byte is read, by ignoring byte count!)
 25057                              <1> 	;  	     WHAT FOR: Every character from Keyboard input 
 25058                              <1> 	;	     must be written immediate on video page (screen)
 25059                              <1> 	;	     when it is required.	
 25060                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25061                              <1> 	; 11/03/2013 - 19/06/2014 (Retro UNIX 8086 v1)
 25062                              <1> 	;
 25063                              <1> 	; Console tty buffer is PC keyboard buffer
 25064                              <1> 	; and keyboard-keystroke handling is different than original
 25065                              <1> 	; unix (PDP-11) here. TTY/Keyboard procedures here are changed
 25066                              <1> 	; according to IBM PC compatible ROM BIOS keyboard functions. 
 25067                              <1> 	;
 25068                              <1> 	; 06/12/2013
 25069 00004F82 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 25070 00004F89 8A83[A3680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 25071                              <1> rttys:
 25072                              <1> 		; mov tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
 25073                              <1> 	               ; / of the control and status block
 25074                              <1> 		; tst 2(r5) / for the console tty; this word points to the console
 25075                              <1> 		       ; / tty buffer
 25076                              <1> 	; 28/07/2013
 25077 00004F8F A2[D96C0000]        <1> 	mov 	[u.ttyn], al
 25078                              <1> 	; 13/01/2014
 25079 00004F94 FEC0                <1> 	inc	al
 25080 00004F96 A2[DA6C0000]        <1> 	mov	[u.ttyp], al ; tty number + 1
 25081                              <1> rtty_nc: ; 01/02/2014
 25082                              <1> 	; 29/09/2013
 25083                              <1> 	;mov	ecx, 10
 25084                              <1> 	; 11/01/2022
 25085 00004F9B 29C9                <1> 	sub	ecx, ecx
 25086 00004F9D B10A                <1> 	mov	cl, 10
 25087                              <1> rtty_1: 	; 01/02/2014
 25088                              <1> 	;push 	cx ; 29/09/2013
 25089                              <1> 	; 11/12/2021
 25090 00004F9F 51                  <1> 	push	ecx
 25091                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 25092 00004FA0 B001                <1> 	mov 	al, 1
 25093 00004FA2 E8C20B0000          <1> 	call 	getc
 25094                              <1> 	;pop 	cx ; 29/09/2013	
 25095                              <1> 	; 11/12/2021
 25096 00004FA7 59                  <1> 	pop	ecx
 25097 00004FA8 7516                <1> 	jnz	short rtty_2
 25098                              <1> 		; bne 1f / 2nd word of console tty buffer contains number
 25099                              <1> 	               ; / of chars. Is this number non-zero?
 25100 00004FAA E20D                <1> 	loop	rtty_idle ; 01/02/2014
 25101                              <1> 	; 05/10/2013
 25102 00004FAC 8A25[D96C0000]      <1> 	mov	ah, [u.ttyn]
 25103                              <1> 	; 29/09/2013
 25104 00004FB2 E8C9F7FFFF          <1> 	call	sleep
 25105                              <1> 		; jsr r0,canon; ttych / if 0, call 'canon' to get a line
 25106                              <1>                 ;           / (120 chars.)
 25107                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 25108 00004FB7 EBE2                <1> 	jmp	short rtty_nc ; 01/02/2014
 25109                              <1> 
 25110                              <1> rtty_idle:
 25111                              <1> 	; 29/07/2013
 25112 00004FB9 E835F7FFFF          <1> 	call 	idle
 25113 00004FBE EBDF                <1> 	jmp	short rtty_1 ; 01/02/2014
 25114                              <1> 	;1:
 25115                              <1> 		; tst 2(r5) / is the number of characters zero
 25116                              <1> 		; beq ret1 / yes, return to caller via 'ret1'
 25117                              <1> 		; movb *4(r5),r1 / no, put character in r1
 25118                              <1> 		; inc 4(r5) / 3rd word of console tty buffer points to byte which
 25119                              <1> 		          ; / contains the next char.
 25120                              <1> 		; dec 2(r5) / decrement the character count
 25121                              <1> rtty_2:
 25122 00004FC0 30C0                <1> 	xor 	al, al
 25123 00004FC2 E8A20B0000          <1> 	call 	getc
 25124 00004FC7 E895000000          <1> 	call	passc
 25125                              <1> 		; jsr r0,passc / move the character to core (user)
 25126                              <1> 	;; 17/10/2015 - 16/07/2015
 25127                              <1> 	; 19/06/2014
 25128                              <1> 	;;jnz	short rtty_nc
 25129 00004FCC 58                  <1> 	pop	eax  ; (20/05/2015)
 25130 00004FCD C3                  <1> 	retn 
 25131                              <1> ;ret1:
 25132                              <1> 		; jmp ret / return to caller via 'ret'
 25133                              <1> 
 25134                              <1> rcvt:   ; < receive/read character from tty >
 25135                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25136                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 25137                              <1> 	;
 25138                              <1> 	; Retro UNIX 8086 v1 modification !
 25139                              <1> 	; 
 25140                              <1> 	; In original UNIX v1, 'rcvt' routine 
 25141                              <1> 	;		(exactly different than this one)
 25142                              <1> 	;	was in 'u9.s' file.
 25143                              <1> 	;
 25144 00004FCE 2C0A                <1> 	sub 	al, 10
 25145                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 25146                              <1> 	; 16/07/2013
 25147                              <1> 	; 21/05/2013
 25148 00004FD0 EBBD                <1>         jmp     short rttys
 25149                              <1>       
 25150                              <1> ;rppt: / read paper tape
 25151                              <1> ;	jsr	r0,pptic / gets next character in clist for ppt input and
 25152                              <1> ;			 / places
 25153                              <1> ;		br ret / it in r1; if there 1s no problem with reader, it
 25154                              <1> ;		       / also enables read bit in prs
 25155                              <1> ;	jsr	r0,passc / place character in users buffer area
 25156                              <1> ;	br	rppt
 25157                              <1> 
 25158                              <1> rmem: ; / transfer characters from memory to a user area of core
 25159                              <1> 	; 17/10/2015
 25160                              <1> 	; 11/06/2015
 25161                              <1> 	; 24/05/2015
 25162                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25163                              <1> 	;
 25164 00004FD2 8B35[B86C0000]      <1> 	mov     esi, [u.fofp]
 25165                              <1> rmem_1:
 25166 00004FD8 8B1E                <1>         mov     ebx, [esi]        
 25167                              <1> 	        ; mov *u.fofp,r1 / save file offset which points to the char
 25168                              <1> 		               ; / to be transferred to user
 25169 00004FDA FF06                <1>         inc     dword [esi] ; 17/10/2015
 25170                              <1> 		; inc *u.fofp / increment file offset to point to 'next' 
 25171                              <1> 			    ; / char in memory file
 25172 00004FDC 8A03                <1> 	mov	al, [ebx]
 25173                              <1> 		; movb (r1),r1 / get character from memory file, 
 25174                              <1> 		             ; / put it in r1
 25175 00004FDE E87E000000          <1> 	call	passc        ; jsr r0,passc / move this character to 
 25176                              <1> 			     ;  / the next byte of the users core area
 25177                              <1> 		; br rmem / continue
 25178 00004FE3 75F3                <1> 	jnz	short rmem_1
 25179                              <1> ret_:
 25180 00004FE5 58                  <1> 	pop	eax ; 09/06/2015
 25181 00004FE6 C3                  <1> 	retn
 25182                              <1> 
 25183                              <1> rlpr:
 25184                              <1> ;1:
 25185                              <1> ;rcrd:
 25186 00004FE7 C705[186D0000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 25187 00004FEF 0000                <1>
 25188 00004FF1 E96FE1FFFF          <1> 	jmp	error
 25189                              <1> 		;jmp	error / see 'error' routine
 25190                              <1> 
 25191                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25192                              <1> dskr:
 25193                              <1> 	; 19/07/2022
 25194                              <1> 	; 12/10/2015
 25195                              <1> 	; 21/08/2015
 25196                              <1> 	; 25/07/2015
 25197                              <1> 	; 10/07/2015
 25198                              <1> 	; 16/06/2015
 25199                              <1> 	; 31/05/2015
 25200                              <1> 	; 24/05/2015 (Retro UNIX 386 v1 - Beginning)
 25201                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 25202                              <1> dskr_0:
 25203 00004FF6 50                  <1> 	push	eax
 25204                              <1> 		; mov (sp),r1 / i-number in r1
 25205                              <1> 	; AX = i-number
 25206 00004FF7 E879FBFFFF          <1> 	call	iget
 25207                              <1> 		; jsr r0,iget / get i-node (r1) into i-node section of core
 25208                              <1>         ;movzx	edx, word [i.size] ; 16/06/2015
 25209                              <1> 	;	; mov i.size,r2 / file size in bytes in r2
 25210                              <1> 	; 28/11/2021
 25211 00004FFC 8B15[2C680000]      <1> 	mov	edx, [i.size] ; 32 bit file size (runix v2 inode)
 25212                              <1> 	;
 25213 00005002 8B1D[B86C0000]      <1> 	mov	ebx, [u.fofp]
 25214 00005008 2B13                <1> 	sub	edx, [ebx]
 25215                              <1> 		; sub *u.fofp,r2 / subtract file offset
 25216                              <1>         ; 12/10/2015
 25217                              <1> 	; jna	short ret_ 
 25218                              <1> 		; blos ret
 25219 0000500A 7709                <1> 	ja	short dskr_1
 25220                              <1> 	;
 25221                              <1> dskr_retn: ; 12/10/2015
 25222 0000500C 58                  <1> 	pop	eax
 25223 0000500D C605[166D0000]00    <1> 	mov	byte [u.kcall], 0
 25224 00005014 C3                  <1> 	retn	
 25225                              <1> dskr_1: 
 25226 00005015 3B15[CC6C0000]      <1> 	cmp     edx, [u.count] 
 25227                              <1> 		; cmp r2,u.count / are enough bytes left in file 
 25228                              <1> 			       ; / to carry out read
 25229 0000501B 7306                <1> 	jnb	short dskr_2
 25230                              <1> 		; bhis 1f
 25231 0000501D 8915[CC6C0000]      <1> 	mov	[u.count], edx
 25232                              <1> 		; mov r2,u.count / no, just read to end of file
 25233                              <1> dskr_2: ; 1:
 25234                              <1> 	; (E)AX = i-number ; 28/11/2021 (32 bit inode number)
 25235                              <1> 	;call	mget
 25236                              <1> 		; jsr r0,mget / returns physical block number of block 
 25237                              <1> 		    ; / in file where offset points
 25238                              <1> 	; 28/11/2021
 25239 00005023 E8D9F7FFFF          <1> 	call	mget_r
 25240                              <1> 
 25241                              <1> 	; eax = physical block number
 25242                              <1> 	; [cdev] = current device number 
 25243 00005028 E863090000          <1> 	call	dskrd
 25244                              <1> 		; jsr r0,dskrd / read in block, r5 points to 
 25245                              <1> 			     ; / 1st word of data in buffer
 25246                              <1> 	; 09/06/2015
 25247 0000502D 803D[166D0000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
 25248 00005034 770F                <1> 	ja	short dskr_4	  ; zf=0 -> the caller is 'namei'
 25249 00005036 66833D[106D0000]00  <1> 	cmp	word [u.pcount], 0
 25250 0000503E 7705                <1> 	ja	short dskr_4
 25251                              <1> dskr_3:
 25252                              <1> 	; [u.base] = virtual address to transfer (as destination address)
 25253 00005040 E857000000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 25254                              <1> dskr_4:
 25255                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
 25256 00005045 E843030000          <1> 	call	sioreg
 25257                              <1> 		; jsr r0,sioreg
 25258                              <1> 	
 25259                              <1> 	; 19/07/2022
 25260                              <1> 	;xchg	esi, edi
 25261                              <1> 	
 25262                              <1> 	; 19/07/2022
 25263                              <1> 	;  EDX = user data offset (previous value of [u.pbase])
 25264                              <1> 	;  ESI = pointer to file offset 
 25265                              <1> 	;  EDI = system (I/O) buffer offset
 25266                              <1> 	;  ECX = byte count
 25267                              <1> 	;  EBX = system buffer (data) address	
 25268                              <1> 	;  EAX = remain bytes after byte count within page frame 
 25269                              <1> 
 25270 0000504A 010E                <1> 	add	[esi], ecx 
 25271                              <1> 			; new file offset (old offset + byte count)
 25272                              <1> 	;
 25273 0000504C 89FE                <1> 	mov	esi, edi ; sector (I/O) buffer offset
 25274 0000504E 89D7                <1> 	mov	edi, edx
 25275                              <1> 
 25276                              <1> 	; EDI = file (user data) offset
 25277                              <1> 	; ESI = sector (I/O) buffer offset
 25278                              <1> 	; ECX = byte count
 25279 00005050 F3A4                <1> 	rep	movsb
 25280                              <1> 		; movb (r2)+,(r1)+ / move data from buffer into working core
 25281                              <1> 		                 ; / starting at u.base
 25282                              <1> 		; dec r3
 25283                              <1> 		; bne 2b / branch until proper number of bytes are transferred
 25284                              <1> 	; 25/07/2015
 25285                              <1> 	; eax = remain bytes in buffer
 25286                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 25287 00005052 09C0                <1> 	or	eax, eax
 25288 00005054 75EA                <1> 	jnz	short dskr_3 ; (page end before system buffer end!)		
 25289                              <1> 	; 03/08/2013
 25290                              <1> 	;pop	eax
 25291 00005056 390D[CC6C0000]      <1> 	cmp	[u.count], ecx ; 0
 25292                              <1> 		; tst u.count / all bytes read off disk
 25293                              <1> 		; bne dskr
 25294                              <1> 		; br ret
 25295                              <1>         ;ja	short dskr_0
 25296                              <1> 	;mov	[u.kcall], cl ; 0 ; 09/06/2015
 25297                              <1> 	;retn
 25298                              <1> 	; 12/10/2015
 25299 0000505C 76AE                <1> 	jna	short dskr_retn
 25300 0000505E 58                  <1> 	pop	eax  ; (i-node number)
 25301 0000505F EB95                <1> 	jmp	short dskr_0
 25302                              <1> 	
 25303                              <1> passc:
 25304                              <1> 	; 18/10/2015
 25305                              <1> 	; 10/07/2015
 25306                              <1> 	; 01/07/2015
 25307                              <1> 	; 08/06/2015
 25308                              <1> 	; 04/06/2015
 25309                              <1> 	; 20/05/2015
 25310                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25311                              <1> 	;
 25312                              <1>    	;(Retro UNIX 386 v1 - translation from user's virtual address
 25313                              <1> 	;		      to physical address
 25314 00005061 66833D[106D0000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 25315                              <1> 			     ; 1-4095 --> use previous physical base address
 25316                              <1> 			     ; in [u.pbase]
 25317 00005069 7705                <1> 	ja	short passc_3
 25318                              <1> 	; 08/06/2015 - 10/07/2015
 25319 0000506B E82C000000          <1> 	call	trans_addr_w
 25320                              <1> passc_3:
 25321                              <1> 	; 19/05/2015
 25322 00005070 66FF0D[106D0000]    <1> 	dec	word [u.pcount]
 25323                              <1> 	;
 25324 00005077 8B1D[0C6D0000]      <1> 	mov	ebx, [u.pbase]
 25325 0000507D 8803                <1> 	mov	[ebx], al
 25326                              <1> 		; movb r1,*u.base / move a character to the next byte of the
 25327                              <1> 		               ; / users buffer
 25328 0000507F FF05[C86C0000]      <1> 	inc	dword [u.base]
 25329                              <1> 		; inc u.base / increment the pointer to point to 
 25330                              <1> 			  ; / the next byte in users buffer
 25331 00005085 FF05[0C6D0000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 25332 0000508B FF05[D06C0000]      <1> 	inc	dword [u.nread]
 25333                              <1> 		; inc u.nread / increment the number of bytes read
 25334 00005091 FF0D[CC6C0000]      <1> 	dec	dword [u.count]
 25335                              <1> 		; dec u.count / decrement the number of bytes to be read
 25336                              <1> 		; bne 1f / any more bytes to read? ; yes, branch
 25337 00005097 C3                  <1> 	retn
 25338                              <1> 		; mov (sp)+,r0 / no, do a non-local return to the caller of
 25339                              <1> 		             ; / 'readi' by:
 25340                              <1> 		;/ (1) pop the return address off the stack into r0
 25341                              <1> 		; mov (sp)+,r1 / (2) pop the i-number off the stack into r1
 25342                              <1> 	;1:
 25343                              <1> 		; clr	*$ps / clear processor status
 25344                              <1> 		; rts r0 / return to address currently on top of stack
 25345                              <1> 
 25346                              <1> trans_addr_r:
 25347                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 25348                              <1> 	;	-'add_to_swap_queue' call is disabled as temporary-
 25349                              <1> 	; Translate virtual address to physical address 
 25350                              <1> 	; for reading from user's memory space
 25351                              <1> 	; (Retro UNIX 386 v1 feature only !)
 25352                              <1> 	; 18/10/2015
 25353                              <1> 	; 10/07/2015
 25354                              <1> 	; 09/06/2015
 25355                              <1> 	; 08/06/2015 
 25356                              <1> 	; 04/06/2015
 25357                              <1> 	;
 25358                              <1> 	; 18/10/2015
 25359 00005098 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
 25360 0000509A EB04                <1> 	jmp 	short trans_addr_rw
 25361                              <1> 
 25362                              <1> 	;push	eax
 25363                              <1> 	;push	ebx
 25364                              <1> 	;mov	ebx, [u.base]
 25365                              <1> 	;call	get_physical_addr ; get physical address
 25366                              <1> 	;;jnc	short cpass_0
 25367                              <1> 	;jnc	short passc_1
 25368                              <1> 	;mov	[u.error], eax
 25369                              <1> 	;;pop	ebx
 25370                              <1> 	;;pop	eax
 25371                              <1> 	;jmp	error
 25372                              <1> ;cpass_0:
 25373                              <1> 	; 18/10/2015
 25374                              <1> 	; 20/05/2015
 25375                              <1> 	;mov 	[u.pbase], eax ; physical address	
 25376                              <1> 	;mov	[u.pcount], cx ; remain byte count in page (1-4096)
 25377                              <1> 	;pop	ebx
 25378                              <1> 	;pop	eax
 25379                              <1> 	;retn	; 08/06/2015
 25380                              <1> 
 25381                              <1> trans_addr_w:
 25382                              <1> 	; 31/12/2021
 25383                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 25384                              <1> 	;	-'add_to_swap_queue' call is disabled as temporary-
 25385                              <1> 	; Translate virtual address to physical address
 25386                              <1> 	; for writing to user's memory space
 25387                              <1> 	; (Retro UNIX 386 v1 feature only !)
 25388                              <1> 	; 18/10/2015
 25389                              <1> 	; 29/07/2015
 25390                              <1> 	; 10/07/2015
 25391                              <1> 	; 09/06/2015
 25392                              <1> 	; 08/06/2015
 25393                              <1> 	; 04/06/2015 (passc)
 25394                              <1> 	;
 25395                              <1> 	; 18/10/2015
 25396 0000509C 29D2                <1> 	sub	edx, edx
 25397 0000509E FEC2                <1> 	inc	dl ; 1 (write access sign)
 25398                              <1> trans_addr_rw:
 25399 000050A0 50                  <1> 	push	eax
 25400 000050A1 53                  <1> 	push	ebx
 25401                              <1> 	; 18/10/2015
 25402 000050A2 52                  <1> 	push 	edx ; r/w sign (in DL)
 25403                              <1> 	;
 25404 000050A3 8B1D[C86C0000]      <1> 	mov	ebx, [u.base]
 25405 000050A9 E819D7FFFF          <1> 	call	get_physical_addr ; get physical address
 25406 000050AE 730A                <1> 	jnc	short passc_0
 25407 000050B0 A3[186D0000]        <1> 	mov	[u.error], eax
 25408                              <1> 	;pop	edx
 25409                              <1> 	;pop 	ebx
 25410                              <1> 	;pop	eax
 25411 000050B5 E9ABE0FFFF          <1> 	jmp	error
 25412                              <1> passc_0:
 25413 000050BA F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page ; 18/10/2015
 25414 000050BD 5A                  <1> 	pop	edx ; 18/10/2015
 25415 000050BE 7517                <1> 	jnz	short passc_1
 25416                              <1> 	; 18/10/2015
 25417 000050C0 20D2                <1> 	and 	dl, dl
 25418 000050C2 7413                <1> 	jz	short passc_1
 25419                              <1> 	; 20/05/2015
 25420                              <1> 	; read only (duplicated) page -must be copied to a new page-
 25421                              <1> 	; EBX = linear address
 25422 000050C4 51                  <1> 	push 	ecx
 25423                              <1> 	; 31/12/2021 - Retro UNIX 386 v1.2 (BugFix)
 25424 000050C5 53                  <1> 	push	ebx ;* ; BugFix  ; 31/12/2021
 25425 000050C6 E86DD6FFFF          <1> 	call 	copy_page
 25426 000050CB 5B                  <1> 	pop	ebx ;* ; BugFix  ; 31/12/2021
 25427 000050CC 59                  <1> 	pop	ecx
 25428 000050CD 7217                <1> 	jc	short passc_2
 25429                              <1> 	; 30/11/2021
 25430                              <1> 	;push	eax ; physical address of the new/allocated page
 25431                              <1> 	;call	add_to_swap_queue
 25432                              <1> 	;pop	eax
 25433                              <1> 	; 18/10/2015
 25434 000050CF 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
 25435                              <1> 	;mov 	ecx, PAGE_SIZE
 25436                              <1> 	;sub	ecx, ebx 
 25437 000050D5 01D8                <1> 	add	eax, ebx  
 25438                              <1> passc_1: 
 25439                              <1> 	; 18/10/2015
 25440                              <1> 	; 20/05/2015
 25441 000050D7 A3[0C6D0000]        <1> 	mov 	[u.pbase], eax ; physical address	
 25442 000050DC 66890D[106D0000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
 25443 000050E3 5B                  <1> 	pop	ebx
 25444 000050E4 58                  <1> 	pop	eax
 25445 000050E5 C3                  <1> 	retn	; 08/06/2015
 25446                              <1> passc_2:
 25447 000050E6 C705[186D0000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
 25448 000050EE 0000                <1>
 25449                              <1> 	;pop 	ebx
 25450                              <1> 	;pop	eax
 25451 000050F0 E970E0FFFF          <1> 	jmp	error
 25452                              <1> 
 25453                              <1> 	; 09/03/2022
 25454                              <1> 	; 25/12/2021
 25455                              <1> 	; 11/12/2021
 25456                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25457                              <1> writei:
 25458                              <1> 	; 20/05/2015
 25459                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25460                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 25461                              <1> 	;
 25462                              <1> 	; Write data to file with inode number in R1
 25463                              <1> 	; 
 25464                              <1> 	; INPUTS ->
 25465                              <1> 	;    r1 - inode number
 25466                              <1> 	;    u.count - byte count to be written
 25467                              <1> 	;    u.base - points to user buffer
 25468                              <1> 	;    u.fofp - points to word with current file offset
 25469                              <1> 	; OUTPUTS ->
 25470                              <1> 	;    u.count - cleared
 25471                              <1> 	;    u.nread - accumulates total bytes passed back	
 25472                              <1> 	; ((AX = R1))
 25473                              <1> 	;    (Retro UNIX Prototype: 18/11/2012 - 11/11/2012, UNIXCOPY.ASM)
 25474                              <1> 	;    ((Modified registers: edx, ebx, ecx, esi, edi)) -15/07/2022-	
 25475                              <1> 
 25476 000050F5 31C9                <1> 	xor	ecx, ecx
 25477 000050F7 890D[D06C0000]      <1> 	mov 	[u.nread], ecx  ; 0
 25478                              <1> 		; clr u.nread / clear the number of bytes transmitted during
 25479                              <1> 		            ; / read or write calls
 25480 000050FD 66890D[106D0000]    <1> 	mov	[u.pcount], cx	; 19/05/2015
 25481 00005104 390D[CC6C0000]      <1> 	cmp 	[u.count], ecx
 25482                              <1> 	;	; tst u.count / test the byte count specified by the user
 25483 0000510A 770B                <1> 	ja 	short writei_1	; 1f
 25484                              <1> 		; bgt 1f / any bytes to output; yes, branch
 25485                              <1> 
 25486                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 25487 0000510C 83F810              <1> 	cmp	eax, 16  ; LPR_INODE ; lpt (parallel port printer) ?
 25488 0000510F 7505                <1> 	jne	short writei_0
 25489 00005111 E943010000          <1> 	jmp	lpr_stat	; get/read line status
 25490                              <1> writei_0:
 25491 00005116 C3                  <1> 	retn
 25492                              <1> 	;	; rts r0 / no, return - no writing to do
 25493                              <1> writei_1: ;1:
 25494                              <1> 	;	; mov r1 ,-(sp) / save the i-node number on the stack
 25495                              <1> 	;cmp 	ax, 40
 25496                              <1> 	;	; cmp r1,$40.
 25497                              <1> 	;	; / does the i-node number indicate a special file?
 25498                              <1>         ;ja	dskw 
 25499                              <1> 	;	; bgt dskw / no, branch to standard file output
 25500                              <1> 
 25501                              <1> 	; 28/11/2021
 25502 00005117 F605[166D0000]FF    <1> 	test	byte [u.kcall], 0FFh
 25503 0000511E 750C                <1> 	jnz	short writei_2  ; 'writei' called by 'mkdir'
 25504                              <1> 
 25505                              <1> 	; eax = inode number
 25506                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 25507 00005120 E850FAFFFF          <1> 	call	iget
 25508                              <1> ;writei_2:
 25509                              <1> 	; 28/11/2021
 25510                              <1> 	; eax = inode number
 25511                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 25512 00005125 E8E2020000          <1> 	call	is_regular_file
 25513                              <1> 	;jz	dskw ; regular file 
 25514                              <1> 	; 25/12/2021
 25515 0000512A 7505                <1> 	jnz	short writei_5 ; device file
 25516                              <1> writei_2:	 ; 09/03/2022 
 25517                              <1> 	; regular file
 25518 0000512C E968010000          <1> 	jmp	dskw
 25519                              <1> writei_5:
 25520                              <1> 	; (20/05/2015)
 25521 00005131 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 25522                              <1> 	
 25523                              <1> 	; 28/11/2021	
 25524                              <1> 	; device file
 25525 00005132 BB[4C510000]        <1> 	mov	ebx, writei_4
 25526 00005137 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 25527 0000513A 720E                <1> 	jb	short writei_3
 25528 0000513C 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 25529 0000513F 7709                <1> 	ja	short writei_3 ; 11/12/2021	
 25530                              <1> 	
 25531                              <1> 	; convert v2 inode number to v1 device inode number
 25532 00005141 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 25533 00005143 89C1                <1> 	mov	ecx, eax
 25534 00005145 C0E102              <1> 	shl	cl, 2 ; * 4
 25535 00005148 01CB                <1> 	add	ebx, ecx
 25536                              <1> writei_3:
 25537 0000514A FF23                <1> 	jmp	dword [ebx]	
 25538                              <1> 		; jmp *1f-2(r1)
 25539                              <1> 		; / jump table and jump to the appropriate routine
 25540                              <1> writei_4: ;1:
 25541 0000514C [7E4F0000]          <1> 	dd	null ; 28/11/2021
 25542 00005150 [9C510000]          <1> 	dd	wtty ; tty, AX = 1 (runix)
 25543                              <1> 		 ;wtty / tty; r1=2
 25544                              <1> 		 ;wppt / ppt; r1=4
 25545 00005154 [EF510000]          <1> 	dd	wmem ; mem, AX = 2 (runix)
 25546                              <1> 		 ;wmem / mem; r1=6
 25547                              <1> 		 ;wrf0 / rf0
 25548                              <1> 		 ;wrk0 / rk0
 25549                              <1> 		 ;wtap / tap0
 25550                              <1> 		 ;wtap / tap1
 25551                              <1> 		 ;wtap / tap2
 25552                              <1> 		 ;wtap / tap3
 25553                              <1> 		 ;wtap / tap4
 25554                              <1> 		 ;wtap / tap5
 25555                              <1> 		 ;wtap / tap6
 25556                              <1> 		 ;wtap / tap7
 25557 00005158 [C6580000]          <1> 	dd	wfd ; fd0, AX = 3 (runix only)
 25558 0000515C [C6580000]          <1> 	dd	wfd ; fd1, AX = 4 (runix only)
 25559 00005160 [C6580000]          <1> 	dd	whd ; hd0, AX = 5 (runix only)
 25560 00005164 [C6580000]          <1> 	dd	whd ; hd1, AX = 6 (runix only)	
 25561 00005168 [C6580000]          <1> 	dd	whd ; hd2, AX = 7 (runix only)
 25562 0000516C [C6580000]          <1> 	dd	whd ; hd3, AX = 8 (runix only)	
 25563 00005170 [1F520000]          <1> 	dd	wlpr ; lpr, AX = 9   (runix)
 25564 00005174 [E9510000]          <1> 	dd	xmtt ; tty0, AX = 10 (runix)	  
 25565                              <1> 		 ;xmtt / tty0
 25566 00005178 [E9510000]          <1> 	dd	xmtt ; tty1, AX = 11 (runix)	  
 25567                              <1> 		 ;xmtt / tty1
 25568 0000517C [E9510000]          <1> 	dd	xmtt ; tty2, AX = 12 (runix)	  
 25569                              <1> 		 ;xmtt / tty2
 25570 00005180 [E9510000]          <1> 	dd	xmtt ; tty3, AX = 13 (runix)	  
 25571                              <1> 		 ;xmtt / tty3
 25572 00005184 [E9510000]          <1> 	dd	xmtt ; tty4, AX = 14 (runix)	  
 25573                              <1> 		 ;xmtt / tty4
 25574 00005188 [E9510000]          <1> 	dd	xmtt ; tty5, AX = 15 (runix)	  
 25575                              <1> 		 ;xmtt / tty5
 25576 0000518C [E9510000]          <1> 	dd	xmtt ; tty6, AX = 16 (runix)	  
 25577                              <1> 		 ;xmtt / tty6
 25578 00005190 [E9510000]          <1> 	dd	xmtt ; tty7, AX = 17 (runix)	  
 25579                              <1> 		 ;xmtt / tty7
 25580 00005194 [E9510000]          <1> 	dd	xmtt ; COM1, AX = 18 (runix only)	  
 25581                              <1> 		; / wlpr / lpr
 25582 00005198 [E9510000]          <1> 	dd	xmtt ; COM2, AX = 19 (runix only)
 25583                              <1> 
 25584                              <1> ;	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25585                              <1> ;null:
 25586                              <1> ;	xor	eax, eax
 25587                              <1> ;	pop	eax
 25588                              <1> ;	retn	
 25589                              <1> 
 25590                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 25591                              <1> wtty: ; write to console tty (write to screen)
 25592                              <1> 	; 18/11/2015
 25593                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25594                              <1> 	; 12/03/2013 - 07/07/2014 (Retro UNIX 8086 v1)
 25595                              <1> 	;
 25596                              <1> 	; Console tty output is on current video page
 25597                              <1> 	; Console tty character output procedure is changed here
 25598                              <1> 	; acconding to IBM PC compatible ROM BIOS video (text mode) functions.
 25599                              <1> 	;
 25600 0000519C 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 25601 000051A3 8AA3[A3680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 25602 000051A9 88E0                <1> 	mov	al, ah ; 07/07/2014
 25603                              <1> wttys:	
 25604                              <1> 	; 10/10/2013
 25605 000051AB 8825[D96C0000]      <1> 	mov 	[u.ttyn], ah
 25606                              <1> 	; 13/01/2014
 25607 000051B1 FEC0                <1> 	inc	al
 25608 000051B3 A2[DB6C0000]        <1> 	mov	[u.ttyp+1], al ; tty number + 1
 25609                              <1> wtty_nc: ; 15/05/2013
 25610                              <1> 	; AH = [u.ttyn] = tty number ; 28/07/2013
 25611 000051B8 E870010000          <1> 	call	cpass
 25612                              <1> 		; jsr r0,cpass / get next character from user buffer area; if
 25613                              <1> 		             ; / none go to return address in syswrite
 25614                              <1> 		; tst r1 / is character = null
 25615                              <1> 		; beq wtty / yes, get next character
 25616                              <1> 	; 10/10/2013
 25617 000051BD 7428                <1> 	jz	short wret
 25618                              <1> 	;1 :
 25619                              <1> 		;mov 	$240,*$ps / no, set processor priority to five
 25620                              <1> 		;cmpb	cc+1,$20. / is character count for console tty greater
 25621                              <1> 		;	          / than 20
 25622                              <1> 		;bhis	2f / yes; branch to put process to sleep
 25623                              <1> 	; 27/06/2014
 25624                              <1> wtty_1:
 25625                              <1> 	; AH = tty number
 25626                              <1> 	; AL = ASCII code of the character
 25627                              <1> 	; 15/04/2014
 25628                              <1> 	;push	ax
 25629                              <1> 	; 11/12/2021
 25630 000051BF 50                  <1> 	push	eax
 25631 000051C0 E8120A0000          <1> 	call	putc ; 14/05/2013
 25632 000051C5 731D                <1> 	jnc	short wtty_2
 25633                              <1> 	; 18/11/2015
 25634 000051C7 E827F5FFFF          <1> 	call	idle
 25635                              <1> 	;mov	ax, [esp]
 25636                              <1> 	; 11/12/2021
 25637 000051CC 8B0424              <1> 	mov	eax, [esp]
 25638 000051CF E8030A0000          <1> 	call	putc
 25639 000051D4 730E                <1> 	jnc	short wtty_2 
 25640                              <1> 	; 02/06/2014
 25641 000051D6 8A25[D96C0000]      <1> 	mov	ah, [u.ttyn]
 25642 000051DC E89FF5FFFF          <1> 	call	sleep
 25643                              <1> 	;pop	ax
 25644                              <1> 	; 11/12/2021
 25645 000051E1 58                  <1> 	pop	eax
 25646 000051E2 EBDB                <1> 	jmp 	short wtty_1
 25647                              <1> 		; jc 	error ; 15/05/2013 (COM1 or COM2 serial port error)
 25648                              <1> 		; jsr 	r0,putc; 1 / find place in freelist to assign to 
 25649                              <1> 			      ; / console tty and
 25650                              <1> 		; br 	2f / place character in list; if none available
 25651                              <1> 		   	  ; / branch to put process to sleep
 25652                              <1> 		; jsr	r0,startty / attempt to output character on tty
 25653                              <1> wtty_2:
 25654                              <1> 	; 15/04/2014
 25655                              <1> 	;pop	ax
 25656                              <1> 	; 11/12/2021
 25657 000051E4 58                  <1> 	pop	eax
 25658 000051E5 EBD1                <1> 	jmp	short wtty_nc
 25659                              <1> 		; br wtty
 25660                              <1> wret:	; 10/10/2013 (20/05/2015)
 25661 000051E7 58                  <1> 	pop	eax
 25662 000051E8 C3                  <1> 	retn
 25663                              <1> 	;2:
 25664                              <1> 		;mov	r1,-(sp) / place character on stack
 25665                              <1> 		;jsr	r0,sleep; 1 / put process to sleep
 25666                              <1> 		;mov	(sp)+,r1 / remove character from stack
 25667                              <1> 		;br	1b / try again to place character in clist and output
 25668                              <1> 
 25669                              <1> xmtt:   ; < send/write character to tty >
 25670                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25671                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 25672                              <1> 	;
 25673                              <1> 	; Retro UNIX 8086 v1 modification !
 25674                              <1> 	; 
 25675                              <1> 	; In original UNIX v1, 'xmtt' routine 
 25676                              <1> 	;		(exactly different than this one)
 25677                              <1> 	;	was in 'u9.s' file.
 25678                              <1> 	;
 25679 000051E9 2C0A                <1> 	sub 	al, 10
 25680                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 25681                              <1> 	; 10/10/2013
 25682 000051EB 88C4                <1> 	mov	ah, al
 25683                              <1> 	; 28/07/2013
 25684 000051ED EBBC                <1> 	jmp	short wttys
 25685                              <1> 
 25686                              <1> ;wppt:
 25687                              <1> ;	jsr	r0,cpass / get next character from user buffer area,
 25688                              <1> ;		         / if none return to writei's calling routine
 25689                              <1> ;	jsr	r0,pptoc / output character on ppt
 25690                              <1> ;	br	wppt
 25691                              <1> 
 25692                              <1> wmem: ; / transfer characters from a user area of core to memory file
 25693                              <1> 	; 17/10/2015
 25694                              <1> 	; 11/06/2015
 25695                              <1> 	; 24/05/2015
 25696                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25697                              <1> 	;
 25698 000051EF 813D[09070000]-     <1> 	cmp	dword [x_timer], clock ; multi tasking clock/timer
 25699 000051F5 [16470000]          <1>
 25700 000051F9 7415                <1>         je      short wmem_acc_err
 25701                              <1> 	;
 25702 000051FB 8B35[B86C0000]      <1>         mov     esi, [u.fofp] 
 25703                              <1> wmem_1:
 25704 00005201 E827010000          <1> 	call	cpass
 25705                              <1> 		; jsr r0,cpass / get next character from users area of
 25706                              <1> 			     ; / core and put it in r1
 25707                              <1>         	; mov r1,-(sp) / put character on the stack
 25708                              <1> 	; 20/09/2013
 25709 00005206 74DF                <1> 	jz	short wret ; wmem_2  
 25710 00005208 8B1E                <1>         mov     ebx, [esi]
 25711                              <1> 		; mov *u.fofp,r1 / save file offset in r1
 25712 0000520A FF06                <1>         inc     dword [esi] ; 17/10/2015
 25713                              <1> 		; inc *u.fofp / increment file offset to point to next
 25714                              <1> 			    ; / available location in file
 25715 0000520C 8803                <1> 	mov	[ebx], al	
 25716                              <1> 		; movb (sp)+,(r1) / pop char off stack, put in memory loc 
 25717                              <1> 			        ; / assigned to it
 25718 0000520E EBF1                <1> 	jmp	short wmem_1
 25719                              <1> 		; br wmem / continue
 25720                              <1> 	;1:
 25721                              <1> 	;jmp	error / ?
 25722                              <1> ;wmem_2:	
 25723                              <1> ;	; 20/09/2013
 25724                              <1> ;	pop	ax
 25725                              <1> ;	retn
 25726                              <1> 
 25727                              <1> wmem_acc_err:
 25728 00005210 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 25729 00005218 0000                <1>
 25730 0000521A E946DFFFFF          <1> 	jmp	error
 25731                              <1> 
 25732                              <1> ;wlpr:
 25733                              <1> 	; 12/06/2022
 25734                              <1> 	;mov	dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 25735                              <1> 	;jmp 	error   ; ... Printing procedure will be located here ...
 25736                              <1> 		;/	jsr	r0,cpass
 25737                              <1> 		;/	cmp	r0,$'a
 25738                              <1> 		;/	blo	1f
 25739                              <1> 		;/	cmp	r1,$'z
 25740                              <1> 		;/	bhi	1f
 25741                              <1> 		;/	sub	$40,r1
 25742                              <1> 		;/1:
 25743                              <1> 		;/	jsr	r0,lptoc
 25744                              <1> 		;/	br	wlpr
 25745                              <1> 		; br rmem / continue
 25746                              <1> 
 25747                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - PRINTER BIOS (Functions)
 25748                              <1> 
 25749                              <1> ;; Ref: MSDOS 3.3 (Retro DOS 3.2) Printer driver code (MSLPT.ASM)
 25750                              <1> ;; MSLPT.ASM - MSDOS 3.3 - 24/07/1987
 25751                              <1> ;; 23/03/2018 - Retro DOS v2.0
 25752                              <1> ;; RETRODOS32.ASM - 03/08/2019 (Retro DOS v3.2)
 25753                              <1> 
 25754                              <1> ; IBM ROMBIOS (INT 17h) STATUS BITS
 25755                              <1> 
 25756                              <1> NOTBUSYSTATUS	equ 10000000b	; NOT BUSY
 25757                              <1> ACKSTATUS	equ 01000000b	; ACKNOWLEDGE (FOR WHAT?)
 25758                              <1> NOPAPERSTATUS	equ 00100000b	; NO MORE PAPER
 25759                              <1> SELECTEDSTATUS	equ 00010000b	; THE PRINTER SAID IT WAS SELECTED
 25760                              <1> IOERRSTATUS	equ 00001000b	; SOME KIND ERROR
 25761                              <1> RESERVED	equ 00000110b	; NOPS
 25762                              <1> TIMEOUTSTATUS	equ 00000001b	; TIME OUT.
 25763                              <1> 
 25764                              <1> ;----------------------------------------------------------------
 25765                              <1> ;								:
 25766                              <1> ;		WRITE TO PRINTER DEVICE 			:
 25767                              <1> ;								:
 25768                              <1> ;   CX has count of bytes to be printed 			:
 25769                              <1> ;   ES:DI point to source buffer contains characters		:
 25770                              <1> ;   AuxNum (in msbio.asm) has printer number			:
 25771                              <1> ;								:
 25772                              <1> ;----------------------------------------------------------------
 25773                              <1> 
 25774                              <1> wlpr:
 25775                              <1> 	; 15/07/2022
 25776                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 25777                              <1> PRN$WRIT:
 25778                              <1> 	; INPUT:
 25779                              <1> 	;	[u.count] = count of characters to be printed
 25780                              <1> 	;	[u.base] = buffer address in user's memory space
 25781                              <1> 	;
 25782                              <1> 	;	(if ECX = 0, printer status will be returned)
 25783                              <1> 	
 25784                              <1> 	;xor	ebx, ebx
 25785                              <1> PRN$LOOP:
 25786 0000521F E809010000          <1> 	call	cpass		  ; Get a character into AL
 25787 00005224 7431                <1> 	jz	short pr_exit
 25788                              <1> 	;
 25789 00005226 B302                <1> 	mov	bl, 2  ; retry count
 25790                              <1> PRN$OUT:
 25791                              <1> 	; al = character which will be printed
 25792 00005228 30E4                <1> 	xor	ah, ah ; 0	  ; PRINT THE CHARACTER IN (AL)
 25793 0000522A E850000000          <1> 	call	PRNOP
 25794 0000522F 74EE                <1> 	jz	short PRN$LOOP 	  ; if error, try to print again
 25795                              <1> PrRetry:
 25796                              <1> 	; al = character
 25797 00005231 FECB                <1> 	dec	bl
 25798 00005233 75F3                <1> 	jnz	short PRN$OUT
 25799                              <1> pr_err_exit:
 25800 00005235 0FB6C0              <1> 	movzx	eax, al
 25801 00005238 A3[186D0000]        <1> 	mov	[u.error], eax
 25802 0000523D A3[A46C0000]        <1> 	mov	[u.r0], eax ; error code in AL
 25803                              <1> 	;mov 	ebp, [u.sp]
 25804 00005242 8B1D[9C6C0000]      <1> 	mov	ebx, [u.sp] ; 15/07/2022
 25805                              <1> 			; Kernel stack at the beginning of sys call
 25806 00005248 8B15[D06C0000]      <1> 	mov	edx, [u.nread]
 25807 0000524E 4A                  <1> 	dec	edx ; last char failed
 25808                              <1> 	;mov	[ebp+20], edx ; count of printed characters in edx
 25809 0000524F 895314              <1> 	mov	[ebx+20], edx ; 15/07/2022
 25810 00005252 E90EDFFFFF          <1> 	jmp	error
 25811                              <1> pr_exit:
 25812 00005257 58                  <1> 	pop	eax ; inode number
 25813                              <1> 
 25814                              <1> 	;mov	eax, [u.nread]
 25815                              <1> 	;mov	[u.r0], eax ; count of printed chacters
 25816                              <1> 	;jmp	sysret
 25817 00005258 C3                  <1> 	retn	; return from writei to syswrite (rw0)
 25818                              <1> 
 25819                              <1> ; 12/06/2022
 25820                              <1> 
 25821                              <1> ;----------------------------------------------------------------
 25822                              <1> ;								:
 25823                              <1> ;		PRINTER STATUS ROUTINE				:
 25824                              <1> ;								:
 25825                              <1> ;----------------------------------------------------------------
 25826                              <1> ;
 25827                              <1> 	
 25828                              <1> lpr_stat:
 25829                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2					   
 25830                              <1> PRN$STAT:
 25831 00005259 E81F000000          <1> 	call	PRNSTAT		  ; get the status
 25832 0000525E 750E                <1> 	jnz	short prn_stat_retn
 25833                              <1> 				  ; if error jump to error routine
 25834                              <1> 	;mov	al, 9		  ; AGAIN, ASSUME OUT OF PAPER...    
 25835 00005260 B01F                <1> 	mov	al, ERR_PRN_PAPER
 25836 00005262 F6C420              <1> 	test	ah, NOPAPERSTATUS					   
 25837 00005265 7507                <1> 	jnz	short prn_stat_retn
 25838 00005267 F6C480              <1> 	test	ah, NOTBUSYSTATUS					   
 25839 0000526A 750D                <1> 	jnz	short prn_stat_ok ; if not busy return (with cf=0)
 25840 0000526C B022                <1> 	mov	al, ERR_PRN_BUSY  ; else busy, return to busy exit
 25841                              <1> prn_stat_retn:
 25842                              <1> 	; al = error code
 25843                              <1> 	; ah = status flags
 25844 0000526E A3[A46C0000]        <1> 	mov	[u.r0], eax
 25845                              <1> 	;movzx	eax, al
 25846                              <1> 	;mov 	[u.error], eax
 25847 00005273 58                  <1> 	pop	eax ; discard return address to syswrite
 25848 00005274 E90CDFFFFF          <1> 	jmp	sysret
 25849                              <1> prn_stat_ok:
 25850 00005279 30C0                <1> 	xor	al, al ; 0
 25851 0000527B EBF1                <1> 	jmp	short prn_stat_retn
 25852                              <1> 
 25853                              <1> ;
 25854                              <1> ;   PRNSTAT	get printer status
 25855                              <1> ;   PRNOP	print a character
 25856                              <1> ;
 25857                              <1> ; PRNSTAT and PRNOP are two routines which call on the ROM-BIOS
 25858                              <1> ; printer routines.  The routines share code which calls on the bios and
 25859                              <1> ; then determines which, if any, error occured. PRNSTAT and PRNOP differ
 25860                              <1> ; only by the value put into AH before the ROM-BIOS call.
 25861                              <1> ;
 25862                              <1> ;   INPUT	if PRNOP then character in AL
 25863                              <1> ;
 25864                              <1> ;   OUTPUT	- AL holds error code
 25865                              <1> ;		- AH status byte from printer
 25866                              <1> ;		- flag NZ if error
 25867                              <1> 
 25868                              <1> PRNSTAT:						   
 25869 0000527D B402                <1> 	mov	ah, 2		  ; set command for get status 
 25870                              <1> 
 25871                              <1> PRNOP:
 25872                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 25873                              <1> 	;
 25874                              <1> 	; Print character (on paper)
 25875                              <1> 
 25876                              <1> 	; INPUT:
 25877                              <1> 	;	al = character to be printed
 25878                              <1> 	; OUTPUT:
 25879                              <1> 	;	zf = 1 -> ok
 25880                              <1> 	;	zf = 0 -> error code in AL
 25881                              <1> 
 25882 0000527F E8DC0B0000          <1> 	call	int17h	 ; call lpt bios
 25883                              <1> 	
 25884 00005284 F6C408              <1> 	test	ah, IOERRSTATUS	  ; I/O ERROR?			   
 25885 00005287 740A                <1> 	jz	short short prnop_chk_nrdy ; NO, TRY NOT READY
 25886                              <1> 
 25887                              <1> 	; AT THIS POINT, WE KNOW WE HAVE AN ERROR.
 25888                              <1> 	; THE CONVERSE IS NOT TRUE.	   
 25889                              <1> 									   
 25890                              <1> 	;mov	al, 9		  ; FIRST, ASSUME OUT OF PAPER	   
 25891 00005289 B01F                <1> 	mov	al, ERR_PRN_PAPER
 25892 0000528B F6C420              <1> 	test	ah, NOPAPERSTATUS ; OUT OF PAPER SET?		   
 25893 0000528E 7502                <1> 	jnz	short PRNOP1	  ; YES, ERROR IS SET
 25894                              <1> 	;mov	al, ERR_PRN_IO
 25895 00005290 FEC0                <1> 	inc	al		  ; INDICATE I/O ERROR		   
 25896                              <1> PRNOP1:									   
 25897                              <1> 									   
 25898                              <1> ; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT)	   
 25899                              <1> 									   
 25900 00005292 C3                  <1> 	retn			  ; RETURN WITH ERROR		   
 25901                              <1> 									   
 25902                              <1> ; THE BITS SAID NO ERROR.
 25903                              <1> ; UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WORK HERE. 								   
 25904                              <1> 									   
 25905                              <1> prnop_chk_nrdy:								   
 25906                              <1> 	;mov	al, 2		  ; ASSUME NOT-READY		   
 25907 00005293 B019                <1> 	mov	al, ERR_PRN_TIMEOUT ; ''time out !' error
 25908                              <1> 	
 25909 00005295 F6C401              <1> 	test	ah, TIMEOUTSTATUS ; IS TIME-OUT SET?		   
 25910                              <1> 				  ; IF NZ THEN ERROR, ELSE OK???
 25911                              <1> PRNOP2: 
 25912 00005298 C3                  <1> 	retn
 25913                              <1> 
 25914                              <1> 
 25915                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25916                              <1> 
 25917                              <1> dskw: ; / write routine for non-special files
 25918                              <1> 	;
 25919                              <1> 	; 19/07/2022
 25920                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 25921                              <1> 	; 28/11/2021
 25922                              <1> 	; 25/07/2015
 25923                              <1> 	; 16/06/2015
 25924                              <1> 	; 09/06/2015
 25925                              <1> 	; 31/05/2015 (Retro UNIX 386 v1 - Beginning)
 25926                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
 25927                              <1> 
 25928                              <1> 	; 01/08/2013 (mkdir_w check)
 25929                              <1> 	;push	ax ; 26/04/2013
 25930                              <1> 	;	; mov (sp),r1 / get an i-node number from the stack into r1
 25931                              <1> 	; 28/11/2021
 25932 00005299 50                  <1> 	push	eax
 25933                              <1> 	; AX = inode number
 25934 0000529A E8D6F8FFFF          <1> 	call	iget
 25935                              <1> 		; jsr r0,iget / write i-node out (if modified), 
 25936                              <1> 		            ; / read i-node 'r1' into i-node area of core
 25937 0000529F 8B1D[B86C0000]      <1>         mov     ebx, [u.fofp] 
 25938 000052A5 8B13                <1> 	mov 	edx, [ebx]
 25939                              <1> 		; mov *u.fofp,r2 / put the file offset [(u.off) or the offset
 25940                              <1> 			       ; / in the fsp entry for this file] in r2
 25941 000052A7 0315[CC6C0000]      <1> 	add 	edx, [u.count]	
 25942                              <1> 		; add u.count,r2 / no. of bytes to be written
 25943                              <1> 			       ; / + file offset is put in r2
 25944                              <1> 	;; 16/06/2015        
 25945                              <1> 	;cmp	edx, 65535 ; file size limit (for UNIX v1 file system)
 25946                              <1> 	;jna	short dskw_0
 25947                              <1> 	;mov	dword [u.error], ERR_FILE_SIZE ; 'file size error !'
 25948                              <1> 	;jmp	error
 25949                              <1> dskw_0:	
 25950                              <1> 	; 28/11/2021
 25951 000052AD 3B15[2C680000]      <1> 	cmp	edx, [i.size] ; 32 bit file size (runix v2 inode)
 25952                              <1> 	;cmp	dx, [i.size]
 25953                              <1> 	;	; cmp r2,i.size / is this greater than the present size of
 25954                              <1> 		              ; / the file?
 25955 000052B3 760B                <1> 	jna	short dskw_1
 25956                              <1> 		; blos 1f / no, branch
 25957 000052B5 8915[2C680000]      <1> 	mov	[i.size], edx ; 32 bit file size (runix v2 inode)
 25958                              <1> 	;mov	[i.size], dx
 25959                              <1> 	 	; mov r2,i.size / yes, increase the file size to 
 25960                              <1> 			      ; / file offset + no. of data bytes
 25961 000052BB E846FAFFFF          <1> 	call	setimod
 25962                              <1> 	 	; jsr r0,setimod / set imod=1 (i.e., core inode has been
 25963                              <1> 		          ; / modified), stuff time of modification into
 25964                              <1> 	          	  ; / core image of i-node
 25965                              <1> dskw_1: ; 1:
 25966                              <1> 	; 28/11/2021
 25967                              <1> 	;call	mget
 25968 000052C0 E833F5FFFF          <1> 	call	mget_w
 25969                              <1> 		; jsr r0,mget / get the block no. in which to write 
 25970                              <1> 			    ; /	the next data byte
 25971                              <1> 	; eax = physical block/sector number
 25972 000052C5 8B1D[B86C0000]      <1> 	mov     ebx, [u.fofp]
 25973 000052CB 8B13                <1> 	mov	edx, [ebx]
 25974 000052CD 81E2FF010000        <1> 	and	edx, 1FFh  
 25975                              <1> 		; bit *u.fofp,$777 / test the lower 9 bits of the file offset
 25976 000052D3 750C                <1> 	jnz	short dskw_2
 25977                              <1> 		; bne 2f / if its non-zero, branch; if zero, file offset = 0,
 25978                              <1> 		       ; / 512, 1024,...(i.e., start of new block)
 25979 000052D5 813D[CC6C0000]0002- <1> 	cmp	dword [u.count], 512
 25980 000052DD 0000                <1>
 25981                              <1> 		; cmp u.count,$512. / if zero, is there enough data to fill
 25982                              <1> 				  ; / an entire block? (i.e., no. of
 25983 000052DF 7305                <1> 	jnb	short dskw_3
 25984                              <1> 		; bhis 3f / bytes to be written greater than 512.? 
 25985                              <1> 			; / Yes, branch. Don't have to read block
 25986                              <1> dskw_2: ; 2: / in as no past info. is to be saved (the entire block will be
 25987                              <1>    		; / overwritten).
 25988 000052E1 E8AA060000          <1> 	call	dskrd
 25989                              <1> 		; jsr r0,dskrd / no, must retain old info.. 
 25990                              <1> 			     ; / Hence, read block 'r1' into an I/O buffer
 25991                              <1> dskw_3: ; 3:
 25992                              <1> 	; EAX (r1) = block/sector number
 25993 000052E6 E809070000          <1> 	call	wslot
 25994                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
 25995                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
 25996 000052EB 803D[166D0000]00    <1> 	cmp	byte [u.kcall], 0
 25997 000052F2 770F                <1> 	ja	short dskw_5 ; zf=0 -> the caller is 'mkdir'
 25998                              <1> 	;
 25999 000052F4 66833D[106D0000]00  <1> 	cmp	word [u.pcount], 0
 26000 000052FC 7705                <1> 	ja	short dskw_5
 26001                              <1> dskw_4:
 26002                              <1> 	; [u.base] = virtual address to transfer (as source address)
 26003 000052FE E895FDFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 26004                              <1> dskw_5:
 26005                              <1> 	; eBX (r5) = system (I/O) buffer address
 26006 00005303 E885000000          <1> 	call	sioreg
 26007                              <1> 		; jsr r0,sioreg / r3 = no. of bytes of data, 
 26008                              <1> 			     ; / r1 = address of data, r2 points to location
 26009                              <1> 			     ; / in buffer in which to start writing data
 26010                              <1> 	; 19/07/2022
 26011                              <1> 	;  EDX = user data offset (previous value of [u.pbase])
 26012                              <1> 	;  ESI = pointer to file offset 
 26013                              <1> 	;  EDI = system (I/O) buffer offset
 26014                              <1> 	;  ECX = byte count
 26015                              <1> 	;  EBX = system buffer (data) address	
 26016                              <1> 	;  EAX = remain bytes after byte count within page frame 
 26017                              <1> 
 26018                              <1> 	; 19/07/2022 - Erdogan Tan
 26019                              <1> 	; BugFix (Also original unix v1 kernel code has this bug!)
 26020                              <1> 	; ((Against a possible disk write failure/error, 
 26021                              <1> 	;   file offset must not be updated/increased before 'dskwr'
 26022                              <1> 	;   but it was updated in 'sioreg'. I have modified 'sioreg'
 26023                              <1> 	;   and 'dskw' procedures for that.))
 26024                              <1> 
 26025                              <1> 	; 19/07/2022
 26026 00005308 56                  <1> 	push	esi ; *	 ; save file offset (pointer)
 26027 00005309 51                  <1> 	push	ecx ; ** ; save byte count
 26028 0000530A 89D6                <1> 	mov	esi, edx
 26029                              <1> 
 26030                              <1> 	; ESI = file (user data) offset
 26031                              <1> 	; EDI = sector (I/O) buffer offset
 26032                              <1> 	; ECX = byte count
 26033                              <1> 	;
 26034 0000530C F3A4                <1>   	rep	movsb
 26035                              <1> 		; movb (r1 )+,(r2)+ 
 26036                              <1> 		         ; / transfer a byte of data to the I/O buffer
 26037                              <1> 		; dec r3 / decrement no. of bytes to be written
 26038                              <1> 		; bne 2b / have all bytes been transferred? No, branch
 26039                              <1> 	; 25/07/2015
 26040                              <1> 	; eax = remain bytes in buffer
 26041                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 26042 0000530E 09C0                <1> 	or	eax, eax
 26043 00005310 75EC                <1> 	jnz	short dskw_4 ; (page end before system buffer end!)	
 26044                              <1> dskw_6:
 26045 00005312 E8EA060000          <1> 	call	dskwr
 26046                              <1> 		; jsr r0,dskwr / yes, write the block and the i-node
 26047                              <1> 
 26048                              <1> 	; 19/07/2022
 26049                              <1> 	; (there is not a disk write error, we can increase file offset)
 26050 00005317 58                  <1> 	pop	eax ; ** ; byte count
 26051 00005318 5F                  <1> 	pop	edi ; *  ; file offset (pointer)
 26052                              <1> 	;
 26053 00005319 0107                <1> 	add	[edi], eax
 26054                              <1> 			; new file offset (old offset + byte count)
 26055                              <1> 
 26056 0000531B 833D[CC6C0000]00    <1>         cmp     dword [u.count], 0
 26057                              <1> 		; tst u.count / any more data to write?
 26058 00005322 779C                <1> 	ja	short dskw_1
 26059                              <1> 		; bne 1b / yes, branch
 26060                              <1> 	; 03/08/2013
 26061 00005324 C605[166D0000]00    <1> 	mov	byte [u.kcall], 0
 26062                              <1> 	; 20/09/2013 (;;)
 26063                              <1> 	;pop	ax
 26064                              <1> 	; 28/11/2021
 26065 0000532B 58                  <1> 	pop	eax  
 26066 0000532C C3                  <1> 	retn
 26067                              <1> 	;;jmp 	short dskw_ret 
 26068                              <1> 	        ; jmp ret / no, return to the caller via 'ret'
 26069                              <1> 
 26070                              <1> 	; 24/12/2021
 26071                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 26072                              <1> cpass: ; / get next character from user area of core and put it in r1
 26073                              <1> 	; 18/10/2015
 26074                              <1> 	; 10/10/2015
 26075                              <1> 	; 10/07/2015
 26076                              <1> 	; 02/07/2015
 26077                              <1> 	; 01/07/2015
 26078                              <1> 	; 24/06/2015
 26079                              <1> 	; 08/06/2015
 26080                              <1> 	; 04/06/2015
 26081                              <1> 	; 20/05/2015
 26082                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 26083                              <1> 	;
 26084                              <1> 	; INPUTS -> 
 26085                              <1> 	;     [u.base] = virtual address in user area
 26086                              <1> 	;     [u.count] = byte count (max.)
 26087                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
 26088                              <1> 	; OUTPUTS -> 
 26089                              <1> 	;     AL = the character which is pointed by [u.base]
 26090                              <1> 	;     zf = 1 -> transfer count has been completed	
 26091                              <1>         ;
 26092                              <1> 	; ((Modified registers: EAX, EDX, ECX))
 26093                              <1> 	;
 26094                              <1> 	;
 26095 0000532D 833D[CC6C0000]00    <1> 	cmp 	dword [u.count], 0  ; 14/08/2013
 26096                              <1> 		; tst u.count / have all the characters been transferred
 26097                              <1> 			    ; / (i.e., u.count, # of chars. left
 26098 00005334 763F                <1> 	jna	short cpass_3
 26099                              <1> 		; beq 1f / to be transferred = 0?) yes, branch
 26100 00005336 FF0D[CC6C0000]      <1> 	dec	dword [u.count]
 26101                              <1> 		; dec u.count / no, decrement u.count
 26102                              <1>         ; 19/05/2015 
 26103                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
 26104                              <1> 	;		      to physical address
 26105 0000533C 66833D[106D0000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 26106                              <1> 			     ; 1-4095 --> use previous physical base address
 26107                              <1> 			     ; in [u.pbase]
 26108 00005344 770E                <1> 	ja	short cpass_1
 26109                              <1> 	; 02/07/2015
 26110 00005346 833D[086D0000]00    <1> 	cmp	dword [u.ppgdir], 0  ; is the caller os kernel
 26111 0000534D 7427                <1> 	je	short cpass_k 	; (sysexec, '/etc/init') ? 
 26112                              <1> 	; 08/06/2015 - 10/07/2015
 26113 0000534F E844FDFFFF          <1> 	call	trans_addr_r
 26114                              <1> cpass_1:
 26115                              <1> 	; 02/07/2015
 26116                              <1> 	; 24/06/2015
 26117 00005354 66FF0D[106D0000]    <1> 	dec	word [u.pcount]
 26118                              <1> cpass_2: 
 26119                              <1> 	; 10/10/2015
 26120                              <1> 	; 02/07/2015
 26121 0000535B 8B15[0C6D0000]      <1> 	mov	edx, [u.pbase]
 26122 00005361 8A02                <1> 	mov	al, [edx] ; 10/10/2015
 26123                              <1> 		; movb *u.base,r1 / take the character pointed to 
 26124                              <1> 				; / by u.base and put it in r1
 26125 00005363 FF05[D06C0000]      <1> 	inc	dword [u.nread]
 26126                              <1> 		; inc u.nread / increment no. of bytes transferred
 26127 00005369 FF05[C86C0000]      <1> 	inc	dword [u.base]
 26128                              <1> 		; inc u.base / increment the buffer address to point to the
 26129                              <1> 			   ; / next byte
 26130 0000536F FF05[0C6D0000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 26131                              <1> cpass_3:
 26132 00005375 C3                  <1> 	retn
 26133                              <1> 		; rts	r0 / next byte
 26134                              <1> 	; 1: 
 26135                              <1> 		; mov (sp)+,r0 
 26136                              <1> 		         ; / put return address of calling routine into r0
 26137                              <1> 		; mov (sp)+,r1 / i-number in r1
 26138                              <1> 		; rts r0 / non-local return
 26139                              <1> cpass_k:
 26140                              <1> 	; 02/07/2015
 26141                              <1> 	; The caller is os kernel 
 26142                              <1> 	; (get sysexec arguments from kernel's memory space)
 26143                              <1> 	;
 26144 00005376 8B1D[C86C0000]      <1> 	mov	ebx, [u.base]
 26145 0000537C 66C705[106D0000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
 26146 00005384 10                  <1>
 26147 00005385 891D[0C6D0000]      <1> 	mov	[u.pbase], ebx
 26148 0000538B EBCE                <1> 	jmp	short cpass_2
 26149                              <1> 	
 26150                              <1> sioreg: 
 26151                              <1> 	; 19/07/2022
 26152                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 26153                              <1> 	; 25/07/2015
 26154                              <1> 	; 18/07/2015
 26155                              <1> 	; 02/07/2015
 26156                              <1> 	; 17/06/2015
 26157                              <1> 	; 09/06/2015
 26158                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 26159                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
 26160                              <1> 	;
 26161                              <1> 	; INPUTS -> 
 26162                              <1> 	;     EBX = system buffer (data) address (r5)
 26163                              <1> 	;     [u.fofp] = pointer to file offset pointer
 26164                              <1> 	;     [u.base] = virtual address of the user buffer
 26165                              <1> 	;     [u.pbase] = physical address of the user buffer
 26166                              <1> 	;     [u.count] = byte count
 26167                              <1> 	;     [u.pcount] = byte count within page frame 			
 26168                              <1> 	; OUTPUTS -> 
 26169                              <1> 	;     ESI = user data offset (r1)
 26170                              <1> 	;     EDI = system (I/O) buffer offset (r2)
 26171                              <1> 	;     ECX = byte count (r3)
 26172                              <1> 	;     EAX = remain bytes after byte count within page frame
 26173                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
 26174                              <1>         ;
 26175                              <1> 	; ((Modified registers:  EDX))
 26176                              <1> 
 26177                              <1> 	; 19/07/2022
 26178                              <1> 	; OUTPUTS -> 
 26179                              <1> 	;	EDX = user data offset (previous value of [u.pbase])
 26180                              <1> 	;	ESI = pointer to file offset 
 26181                              <1> 	; 	EDI = system (I/O) buffer offset
 26182                              <1> 	;	ECX = byte count
 26183                              <1> 	;	EBX = system buffer (data) address	
 26184                              <1> 	;	EAX = remain bytes after byte count within page frame
 26185                              <1>  
 26186 0000538D 8B35[B86C0000]      <1>         mov     esi, [u.fofp]
 26187 00005393 8B3E                <1>         mov     edi, [esi]
 26188                              <1> 		; mov *u.fofp,r2 / file offset (in bytes) is moved to r2
 26189 00005395 89F9                <1> 	mov	ecx, edi
 26190                              <1> 		; mov r2,r3 / and also to r3
 26191 00005397 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
 26192                              <1> 		; bis $177000,r3 / set bits 9,...,15 of file offset in r3
 26193 0000539D 81E7FF010000        <1> 	and	edi, 1FFh
 26194                              <1> 		; bic $!777,r2 / calculate file offset mod 512.
 26195 000053A3 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
 26196                              <1> 		; add r5,r2 / r2 now points to 1st byte in system buffer
 26197                              <1> 			  ; / where data is to be placed
 26198                              <1>                 ; mov u.base,r1 / address of data is in r1
 26199 000053A5 F7D9                <1> 	neg	ecx
 26200                              <1> 		; neg r3 / 512 - file offset (mod512.) in r3 
 26201                              <1> 		       ; / (i.e., the no. of free bytes in the file block)
 26202 000053A7 3B0D[CC6C0000]      <1> 	cmp	ecx, [u.count]
 26203                              <1> 		; cmp r3,u.count / compare this with the no. of data bytes
 26204                              <1> 			       ; / to be written to the file
 26205 000053AD 7606                <1> 	jna	short sioreg_0
 26206                              <1> 		; blos	2f / if less than branch. Use the no. of free bytes
 26207                              <1> 			 ; / in the file block as the number to be written
 26208 000053AF 8B0D[CC6C0000]      <1> 	mov	ecx, [u.count]
 26209                              <1> 		; mov u.count,r3 / if greater than, use the no. of data 
 26210                              <1> 			       ; / bytes as the number to be written
 26211                              <1> sioreg_0:
 26212                              <1> 	; 17/06/2015
 26213 000053B5 803D[166D0000]00    <1> 	cmp	byte [u.kcall], 0 
 26214 000053BC 7613                <1> 	jna	short sioreg_1
 26215                              <1> 	; 25/07/2015
 26216                              <1> 	 ; the caller is 'mkdir' or 'namei'
 26217 000053BE A1[C86C0000]        <1> 	mov	eax, [u.base] ; 25/07/2015
 26218 000053C3 A3[0C6D0000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
 26219 000053C8 66890D[106D0000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
 26220 000053CF EB0B                <1> 	jmp	short sioreg_2
 26221                              <1> sioreg_1:
 26222                              <1> 	; 25/07/2015
 26223                              <1> 	; 18/07/2015
 26224                              <1> 	; 09/06/2015 
 26225 000053D1 0FB715[106D0000]    <1> 	movzx	edx, word [u.pcount]
 26226                              <1> 		; ecx and [u.pcount] are always > 0, here
 26227 000053D8 39D1                <1> 	cmp	ecx, edx	
 26228 000053DA 7728                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
 26229                              <1> sioreg_2: ; 2:
 26230 000053DC 31C0                <1> 	xor 	eax, eax ; 25/07/2015
 26231                              <1> sioreg_3:
 26232 000053DE 010D[D06C0000]      <1> 	add 	[u.nread], ecx
 26233                              <1> 		; add r3,u.nread / r3 + number of bytes xmitted 
 26234                              <1> 			         ; / during write is put into u.nread
 26235 000053E4 290D[CC6C0000]      <1> 	sub 	[u.count], ecx
 26236                              <1> 		; sub r3,u.count / u.count = no. of bytes that still 
 26237                              <1> 			       ; / must be written or read
 26238 000053EA 010D[C86C0000]      <1> 	add 	[u.base], ecx
 26239                              <1> 		; add r3,u.base / u.base points to the 1st of the remaining
 26240                              <1> 			      ; / data bytes
 26241                              <1>         ; 19/07/2022
 26242                              <1> 	;add 	[esi], ecx 
 26243                              <1> 	;	; add r3,*u.fofp / new file offset = number of bytes done
 26244                              <1> 			       ; / + old file offset
 26245                              <1> 	; 25/07/2015
 26246                              <1> 	;mov	esi, [u.pbase]
 26247                              <1> 	; 19/07/2022
 26248 000053F0 8B15[0C6D0000]      <1> 	mov	edx, [u.pbase]
 26249                              <1> 
 26250 000053F6 66290D[106D0000]    <1> 	sub	[u.pcount], cx
 26251 000053FD 010D[0C6D0000]      <1> 	add	[u.pbase], ecx
 26252 00005403 C3                  <1>         retn
 26253                              <1> 		; rts r0
 26254                              <1> 		; transfer count > [u.pcount]
 26255                              <1> sioreg_4:
 26256                              <1> 	; 25/07/2015
 26257                              <1> 	; transfer count > [u.pcount] 
 26258                              <1> 	; (ecx > edx)
 26259 00005404 89C8                <1> 	mov	eax, ecx
 26260 00005406 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
 26261 00005408 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
 26262 0000540A EBD2                <1> 	jmp	short sioreg_3
 26263                              <1> 
 26264                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 26265                              <1> is_regular_file:
 26266                              <1> 	; check if it is a regular file or device file inode
 26267                              <1> 	;
 26268                              <1> 	; INPUT:
 26269                              <1> 	;	current inode
 26270                              <1> 	; OUTPUT:
 26271                              <1> 	;	cf = 0 and zf = 1 -> regular file
 26272                              <1> 	;	cf = 0 and zf = 0 -> device file
 26273                              <1> 	;	cf = 1 -> invalid file (jump to 'error')
 26274                              <1> 	;
 26275                              <1> 	; Modified registers: ecx (cl)
 26276                              <1> 
 26277                              <1> 	; 28/11/2021
 26278 0000540C 8A0D[25680000]      <1> 	mov	cl, [i.flgs+1]
 26279 00005412 F6C180              <1> 	test	cl, 80h		; regular file ?
 26280 00005415 7514                <1> 	jnz	short isregf_1  ; yes 
 26281 00005417 80E120              <1> 	and	cl, 20h 	; device file ?
 26282 0000541A 7511                <1> 	jnz	short isregf_2  ; yes 
 26283                              <1> 
 26284                              <1> 	; 28/11/2021
 26285                              <1> 	; invalid inode/file type !
 26286 0000541C C705[186D0000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
 26287 00005424 0000                <1>
 26288                              <1> 	;stc
 26289                              <1> 	;retn
 26290 00005426 E93ADDFFFF          <1> 	jmp	error
 26291                              <1> isregf_1:
 26292 0000542B 30C9                <1> 	xor	cl, cl  ; cl = 0
 26293                              <1> 	; zf = 1
 26294                              <1> 	;retn
 26295                              <1> isregf_2:
 26296                              <1> 	; zf = 0
 26297                              <1> 	; cl = 20h
 26298 0000542D C3                  <1> 	retn	
 26299                                  %include 'u7.s'      ; 18/04/2015
 26300                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 26301                              <1> ; (re-write kernel for test by using previous version without a major defect)
 26302                              <1> ; ****************************************************************************
 26303                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - SYS7.INC
 26304                              <1> ; Last Modification: 12/06/2022
 26305                              <1> ; ----------------------------------------------------------------------------
 26306                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 26307                              <1> ; (v0.1 - Beginning: 11/07/2012)
 26308                              <1> ;
 26309                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 26310                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 26311                              <1> ; <Bell Laboratories (17/3/1972)>
 26312                              <1> ; <Preliminary Release of UNIX Implementation Document>
 26313                              <1> ;
 26314                              <1> ; Retro UNIX 8086 v1 - U7.ASM (13/07/2014) //// UNIX v1 -> u7.s
 26315                              <1> ;
 26316                              <1> ; ****************************************************************************
 26317                              <1> 
 26318                              <1> sysmount: ; / mount file system; args special; name
 26319                              <1> 	; 15/05/2022
 26320                              <1> 	; 09/05/2022
 26321                              <1> 	;	 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 26322                              <1> 	; 08/02/2022
 26323                              <1> 	; 07/02/2022
 26324                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
 26325                              <1> 	; 14/11/2015
 26326                              <1> 	; 24/10/2015
 26327                              <1> 	; 13/10/2015
 26328                              <1> 	; 10/07/2015
 26329                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 26330                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 26331                              <1> 	;
 26332                              <1> 	; 'sysmount' anounces to the system that a removable 
 26333                              <1> 	; file system has been mounted on a special file.
 26334                              <1> 	; The device number of the special file is obtained via
 26335                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
 26336                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
 26337                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
 26338                              <1> 	; to read file system into core, i.e. the first block on the
 26339                              <1> 	; mountable file system is read in. This block is super block
 26340                              <1> 	; for the file system. This call is super user restricted.	
 26341                              <1> 	;
 26342                              <1> 	; Calling sequence:
 26343                              <1> 	;	sysmount; special; name
 26344                              <1> 	; Arguments:
 26345                              <1> 	;	special - pointer to name of special file (device)
 26346                              <1> 	;	name -  pointer to name of the root directory of the
 26347                              <1> 	;		newly mounted file system. 'name' should 
 26348                              <1> 	;		always be a directory.
 26349                              <1> 	; Inputs: - 
 26350                              <1> 	; Outputs: -
 26351                              <1> 	; ...............................................................
 26352                              <1> 	;				
 26353                              <1> 	; Retro UNIX 8086 v1 modification: 
 26354                              <1> 	;       'sysmount' system call has two arguments; so,
 26355                              <1> 	;	* 1st argument, special is pointed to by BX register
 26356                              <1> 	;	* 2nd argument, name is in CX register
 26357                              <1> 	;
 26358                              <1> 	;	NOTE: Device numbers, names and related procedures are 
 26359                              <1> 	;	       already modified for IBM PC compatibility and 
 26360                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
 26361                              <1> 	
 26362                              <1> 	;call	arg2
 26363                              <1> 		; jsr r0,arg2 / get arguments special and name
 26364 0000542E 891D[C06C0000]      <1> 	mov	[u.namep], ebx
 26365                              <1> 	; 07/02/2022
 26366                              <1> 	;push	ecx ; directory name
 26367                              <1> 	;cmp	dword [mnti], 0 ; 11/01/2022 (32 bit inode number)
 26368 00005434 66833D[8A6C0000]00  <1> 	cmp	word [mnti], 0
 26369                              <1> 		; tst mnti / is the i-number of the cross device file
 26370                              <1> 			 ; / zero?
 26371                              <1> 	;;ja	error
 26372                              <1>         	; bne errora / no, error
 26373                              <1> 	;ja	sysmnt_err0
 26374                              <1> 	; 11/01/2022
 26375 0000543C 7605                <1> 	jna	short sysmnt_0 ; 12/01/2022
 26376                              <1> sysmnt_0_err:
 26377 0000543E E993010000          <1> 	jmp	sysmnt_err0
 26378                              <1> sysmnt_0:
 26379                              <1> 	; 07/02/2022
 26380 00005443 51                  <1> 	push	ecx ; directory name
 26381 00005444 E875010000          <1> 	call	getspl
 26382                              <1> 		; jsr r0,getspl / get special files device number in r1
 26383                              <1> 	; 07/02/2022
 26384 00005449 8F05[C06C0000]      <1> 	pop	dword [u.namep] ; directory name
 26385                              <1> 
 26386                              <1> 	; 09/05/2022 - Retro UNIX v1.2 (Kernel v0.2.2.1)
 26387                              <1> 	; (root fs/device must not be mounted again)
 26388 0000544F 3A05[826C0000]      <1> 	cmp	al, [rdev]
 26389                              <1> 	;je	sysmnt_err0
 26390 00005455 74E7                <1> 	je	short sysmnt_0_err ; permission denied error
 26391                              <1> 
 26392                              <1> 	; 13/10/2015
 26393                              <1> 	;movzx	ebx, ax ; Retro UNIX 8086 v1 device number (0 to 5)
 26394                              <1>         ; 11/01/2022
 26395 00005457 29DB                <1> 	sub	ebx, ebx
 26396 00005459 88C3                <1> 	mov	bl, al
 26397 0000545B F683[AE620000]80    <1> 	test    byte [ebx+drv.status], 80h ; 24/10/2015 
 26398 00005462 750F                <1> 	jnz	short sysmnt_1
 26399                              <1> sysmnt_err1:
 26400 00005464 C705[186D0000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
 26401 0000546C 0000                <1>
 26402 0000546E E9F2DCFFFF          <1> 	jmp	error
 26403                              <1> sysmnt_1:
 26404                              <1> 	; 07/02/2022
 26405                              <1> 	;pop	dword [u.namep]
 26406                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
 26407                              <1> 				  ; / on the device
 26408                              <1> 	; 14/11/2015
 26409 00005473 53                  <1> 	push	ebx ; 13/10/2015
 26410                              <1> 		; mov r1,-(sp) / save the device number
 26411                              <1>         ;
 26412 00005474 E803ECFFFF          <1> 	call	namei
 26413                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 26414                              <1> 		       ; ax = 0 -> file not found 	
 26415                              <1> 	;jz	error
 26416                              <1> 	;jc	error
 26417                              <1> 		; jsr r0,namei / get the i-number of the file
 26418                              <1>                	; br errora
 26419 00005479 730F                <1> 	jnc	short sysmnt_2
 26420                              <1> sysmnt_err2:
 26421 0000547B C705[186D0000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
 26422 00005483 0000                <1>
 26423 00005485 E9DBDCFFFF          <1> 	jmp	error
 26424                              <1> sysmnt_2:
 26425                              <1> 	; 11/01/2022
 26426 0000548A A3[8A6C0000]        <1> 	mov	[mnti], eax ; 32 bit inode number (<= 65535)	
 26427                              <1> 	;mov	[mnti], ax
 26428                              <1>         	; mov r1,mnti / put it in mnti
 26429                              <1> 
 26430                              <1> 	; 15/05/2022
 26431                              <1> 	; -Retro UNIX 8086/386 v1 feaure only-
 26432 0000548F A1[7C6C0000]        <1> 	mov	eax, [ii]
 26433 00005494 A3[8E6C0000]        <1> 	mov	[mntp], eax ; parent dir inumber of [mnti]
 26434                              <1> 
 26435                              <1> 	; 11/01/2022
 26436 00005499 BB[546F0000]        <1> 	mov	ebx, sb1 ; super block buffer header (of mounted disk)
 26437                              <1> sysmnt_3: ;1:
 26438                              <1>         ;cmp	byte [ebx+1], 0
 26439                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
 26440                              <1> 			   ; / dismountable device set?
 26441                              <1>         ;jna	short sysmnt_4		
 26442                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
 26443                              <1> 	;call	idle 	; (wait for hardware interrupt)
 26444                              <1> 	;jmp	short sysmnt_3
 26445                              <1> sysmnt_4:   
 26446 0000549E 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
 26447 0000549F A2[836C0000]        <1> 	mov	[mdev], al
 26448                              <1> 		; mov (sp),mntd / no, put the device number in mntd
 26449 000054A4 8803                <1> 	mov	[ebx], al
 26450                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
 26451                              <1> 			      ; / of the I/O queue entry
 26452                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
 26453                              <1>         	; mov (sp)+,cdev / put device number in cdev
 26454 000054A6 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
 26455                              <1> 		; bis $2000,sb1 / set the read bit
 26456                              <1> 
 26457                              <1> 	; 09/05/2022
 26458 000054AB 31FF                <1> 	xor	edi, edi
 26459 000054AD 897B04              <1> 	mov	dword [ebx+4], edi ; 0 ; physical block number = 0
 26460                              <1> 
 26461                              <1> 	; 09/05/2022
 26462                              <1> 	; Retro UNIX v2 Hard Disk FS recognition.
 26463                              <1> 	;
 26464 000054B0 3C02                <1> 	cmp	al, 2 ; fd0 = 0, fd1 = 1, hd0 = 2, hd1 = 3
 26465 000054B2 7217                <1> 	jb	short sysmnt_8
 26466                              <1> 
 26467                              <1> 	; hard disk, read masterboot sector/block at first 
 26468 000054B4 E817060000          <1> 	call 	diskio
 26469 000054B9 721A                <1> 	jc	short sysmnt_9 ; disk read error !
 26470                              <1> sysmnt_6:
 26471                              <1>   	; return start sector address of
 26472                              <1> 	; retro unix v2 partition in esi
 26473 000054BB 8D7308              <1> 	lea	esi, [ebx+8] ; (mbr buffer data address)
 26474 000054BE E869DBFFFF          <1> 	call	runix_p_bs
 26475 000054C3 7206                <1> 	jc	short sysmnt_8 ; runix partition not found
 26476                              <1> 			       ; try to read superblock on
 26477                              <1> 			       ; physical sector 1	 
 26478                              <1> 	; eax = start sector/block
 26479 000054C5 894304              <1> 	mov	dword [ebx+4], eax ; (boot sector address)
 26480                              <1> 	; esi = partition table entry + 4
 26481 000054C8 8B7E08              <1> 	mov	edi, [esi+ptSectors-ptFileSystemID]
 26482                              <1> 	; edi = partition size in sectors
 26483                              <1> sysmnt_8:
 26484                              <1> 	; Retro UNIX 386 v1 modification : 
 26485                              <1> 	;	32 bit block number at buffer header offset 4
 26486                              <1> 	; 09/05/2022
 26487                              <1> 	;mov	dword [ebx+4], 1 ; physical block number = 1
 26488 000054CB FF4304              <1> 	inc	dword [ebx+4] ; +1 ; superblock address
 26489 000054CE E8FD050000          <1> 	call 	diskio
 26490 000054D3 7345                <1> 	jnc	short sysmnt_5
 26491                              <1> sysmnt_9:
 26492 000054D5 31C0                <1> 	xor 	eax, eax
 26493 000054D7 66A3[8A6C0000]      <1> 	mov	[mnti], ax ; 0
 26494 000054DD A2[836C0000]        <1> 	mov	[mdev], al ; 0
 26495                              <1> 	;mov	[cdev], al ; 0
 26496                              <1> 	; 08/02/2022
 26497 000054E2 803D[176D0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
 26498 000054E9 7508                <1> 	jne	short sysmnt_err3
 26499                              <1> 	; yes, clear [u.brwdev] for next check
 26500                              <1> 	; ([u.error] = DRV_NOT_RDY or OUT_OF_VOLUME error) 
 26501 000054EB FE05[176D0000]      <1> 	inc	byte [u.brwdev] ; 0, reset
 26502 000054F1 EB0A                <1> 	jmp	short sysmnt_err4
 26503                              <1> sysmnt_err3:	; 08/02/2022
 26504                              <1> 	; no, set [u.error] to disk read error
 26505 000054F3 C705[186D0000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; 'disk read error !'
 26506 000054FB 0000                <1>
 26507                              <1> sysmnt_err4:
 26508                              <1> 	; 08/02/2022
 26509                              <1> 	; 14/11/2015
 26510 000054FD FEC8                <1> 	dec 	al
 26511 000054FF 8903                <1> 	mov	[ebx], eax ; 000000FFh
 26512 00005501 FEC0                <1> 	inc	al
 26513 00005503 48                  <1> 	dec	eax
 26514 00005504 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
 26515 00005507 E959DCFFFF          <1> 	jmp	error
 26516                              <1> sysmnt_invd:
 26517                              <1> 	; 08/02/2022
 26518 0000550C C705[186D0000]1C00- <1> 	mov	dword [u.error], ERR_INV_FS ; 28
 26519 00005514 0000                <1>
 26520                              <1> 				 ;'invalid fs/superblock !' error
 26521 00005516 30C0                <1> 	xor	al, al ; 0
 26522 00005518 EBE3                <1> 	jmp	short sysmnt_err4
 26523                              <1> 
 26524                              <1> sysmnt_5:
 26525                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 26526                              <1> 	; Retro UNIX v2 Hard Disk FS recognition.
 26527                              <1> 	; edi = 0 -> diskette or 'not a runix v2 hdfs partition'
 26528                              <1> 	; edi > 0 -> retro unix v2 hdfs partition (volume) size
 26529                              <1> 	;	     in sectors
 26530                              <1> 
 26531 0000551A 21FF                <1> 	and	edi, edi
 26532 0000551C 740D                <1> 	jz	short sysmnt_10
 26533                              <1> 
 26534 0000551E 8B530C              <1> 	mov	edx, [ebx+12] ; SB.BootSectAddr (Hidden Sectors)
 26535 00005521 42                  <1> 	inc	edx ; +1 
 26536 00005522 3B5304              <1> 	cmp	edx, [ebx+4]  ; superblock (disk) address
 26537 00005525 75E5                <1> 	jne	short sysmnt_invd  ; invalid file system !
 26538                              <1> 
 26539 00005527 89F9                <1> 	mov	ecx, edi ; volume size (from partition table entry)
 26540 00005529 EB0C                <1> 	jmp	short sysmnt_11 ; bypass disk size comparison
 26541                              <1> 
 26542                              <1> sysmnt_10:
 26543                              <1> 	; 08/02/2022
 26544                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.1 BugFix)
 26545                              <1> 	;  v1.2 Note: This code will be changed for hard disk partitions
 26546                              <1> 	;	    ! (for now, rufs v2 floppy disks can be mounted) !		
 26547                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
 26548                              <1> 	; (Following check is needed to prevent mounting an
 26549                              <1> 	; invalid file system (invalid super block).
 26550                              <1> 	; 
 26551 0000552B 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
 26552 0000552E C0E002              <1> 	shl	al, 2 ; 4*index
 26553 00005531 8B88[92620000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
 26554                              <1> 	;shr 	ecx, 3 ; 11/01/2021 (8 sectors per 1 fbm byte)
 26555                              <1> 	; ecx = number of free map bytes (required)
 26556                              <1> 	;;movzx	edx, word [sb1+8] ; the 1st data word ('mount:')
 26557                              <1> 	;movzx	edx, word [ebx+8] ; the 1st data word (of the buffer)	
 26558                              <1> 	; edx = number of free blocks map bytes
 26559                              <1> 	;;shl	edx, 3 ; convert free map bytes to free map bits
 26560                              <1> 	;cmp	ecx, edx ; compare free map bits and volume size
 26561                              <1> 	;		 ; (in sectors), if they are not equal
 26562                              <1> 	;		 ; the disk to be mounted is an...
 26563                              <1> 	;jne	short sysmnt_invd ; invalid disk !
 26564                              <1> 	;		 ; (which has not got a valid super block)
 26565                              <1> sysmnt_11:	
 26566                              <1> 	; 07/02/2022
 26567                              <1> 	;xor	al, al ; 08/02/2022
 26568                              <1> 	; 11/01/2022
 26569                              <1> 	; Retro UNIX 386 v2 superblock (offset 8, volume size)
 26570 00005537 8B5310              <1> 	mov	edx, [ebx+16] ; SB.VolumeSize (in sectors)
 26571 0000553A 39D1                <1> 	cmp	ecx, edx ; compare SB.VolumeSize and Disk volume size
 26572                              <1> 			 ; (in sectors), if they are not equal
 26573                              <1> 			 ; the disk to be mounted is an...	
 26574 0000553C 75CE                <1> 	jne	short sysmnt_invd ; invalid disk !
 26575                              <1> 			 ; (which has not got a valid shuper block)
 26576                              <1> 	;
 26577 0000553E C6430100            <1> 	mov	byte [ebx+1], 0
 26578                              <1> 	       	; jsr r0,ppoke / read in entire file system
 26579                              <1> ;sysmnt_6: ;1:
 26580                              <1> 	;;cmp	byte [sb1+1], 0
 26581                              <1> 		; tstb sb1+1 / done reading?
 26582                              <1>    	;;jna	sysret
 26583                              <1> 	;;call	idle ; (wait for hardware interrupt)
 26584                              <1> 	;;jmp	short sysmnt_6
 26585                              <1> 		;bne 1b / no, wait
 26586                              <1>         	;br sysreta / yes
 26587 00005542 E93EDCFFFF          <1> 	jmp	sysret
 26588                              <1> 
 26589                              <1> sysumount: ; / special dismount file system
 26590                              <1> 	; 15/05/2022
 26591                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 26592                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
 26593                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 26594                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 26595                              <1> 	;
 26596                              <1> 	; 04/11/2013
 26597                              <1> 	; 09/07/2013
 26598                              <1> 	; 'sysumount' anounces to the system that the special file, 
 26599                              <1> 	; indicated as an argument is no longer contain a removable
 26600                              <1> 	; file system. 'getspl' gets the device number of the special
 26601                              <1> 	; file. If no file system was mounted on that device an error
 26602                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
 26603                              <1> 	; to 'sysret'.
 26604                              <1> 	;
 26605                              <1> 	; Calling sequence:
 26606                              <1> 	;	sysmount; special
 26607                              <1> 	; Arguments:
 26608                              <1> 	;	special - special file to dismount (device)
 26609                              <1> 	;
 26610                              <1> 	; Inputs: - 
 26611                              <1> 	; Outputs: -
 26612                              <1> 	; ...............................................................
 26613                              <1> 	;				
 26614                              <1> 	; Retro UNIX 8086 v1 modification: 
 26615                              <1> 	;       'sysumount' system call has one argument; so,
 26616                              <1> 	;	* Single argument, special is pointed to by BX register
 26617                              <1> 	;
 26618                              <1> 	
 26619                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
 26620                              <1> 	;call	arg
 26621                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
 26622 00005547 891D[C06C0000]      <1>         mov	[u.namep], ebx
 26623 0000554D E86C000000          <1> 	call	getspl
 26624                              <1> 		; jsr r0,getspl / get the device number in r1
 26625                              <1> 	;;;
 26626                              <1> 	; 09/05/2022 - Erdogan Tan
 26627                              <1> 	; (I have added [mnti] check because
 26628                              <1> 	;  retro unix device number of /dev/fd0 is 0
 26629                              <1> 	;  .. so, 'cmp al, [mdev]' is not enough
 26630                              <1> 	;  for dismounting /dev/fd0. sysumount system call would give
 26631                              <1> 	;  wrong cf=0 result while /dev/fd0 is not mounted.)
 26632 00005552 66833D[8A6C0000]00  <1> 	cmp	word [mnti], 0
 26633 0000555A 767A                <1> 	jna	short sysmnt_err0 ; there is not a mounted device !
 26634                              <1> 	;;;	
 26635                              <1> 
 26636 0000555C 3A05[836C0000]      <1> 	cmp	al, [mdev]
 26637                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
 26638 00005562 7572                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
 26639                              <1> 	;jne	error
 26640                              <1>         	; bne errora / no error
 26641 00005564 30C0                <1> 	xor	al, al ; ah = 0
 26642                              <1> 	; (eax = 0) ; 11/01/2022
 26643                              <1> sysumnt_0: ;1:
 26644                              <1>      	; 11/01/2022
 26645                              <1> 	;cmp 	[sb1+1], al ; 0
 26646                              <1> 	;	; tstb sb1+1 / yes, is the device still doing I/O 
 26647                              <1> 	;		   ; / (inhibit bit set)?
 26648                              <1> 	;jna	short sysumnt_1		
 26649                              <1> 	;	; bne 1b / yes, wait
 26650                              <1> 	;call	idle ; (wait for hardware interrupt)
 26651                              <1> 	;jmp	short sysumnt_0
 26652                              <1> sysumnt_1:
 26653                              <1> 	; 15/05/2022
 26654                              <1> 	; change user's current directory to mounting directory
 26655                              <1> 	; if it is on the mounted device (chdir back to root fs)
 26656 00005566 3805[AC6C0000]      <1> 	cmp	byte [u.cdrv], al ; 0
 26657 0000556C 7641                <1> 	jna	short sysumnt_4
 26658                              <1> 	;;;
 26659                              <1> 	; 15/05/2022
 26660                              <1> 	; It is needed to change the parent process's current
 26661                              <1> 	; directory because shell runs (/etc/umount) 
 26662                              <1> 	; as child process.
 26663 0000556E 31DB                <1> 	xor	ebx, ebx 
 26664 00005570 8A1D[F56C0000]      <1> 	mov	bl, [u.uno]
 26665 00005576 D0E3                <1> 	shl	bl, 1 ; >= 2 .. <= 32
 26666 00005578 81C3[82680000]      <1> 	add	ebx, p.ppid-2
 26667 0000557E 668B13              <1> 	mov	dx, [ebx] ; process id of the parent [p.ppid]	
 26668 00005581 BE[64680000]        <1> 	mov	esi, p.pid
 26669 00005586 29C9                <1> 	sub	ecx, ecx
 26670 00005588 B110                <1> 	mov	cl, nproc ; 16  
 26671                              <1> sysumnt_2:	
 26672 0000558A 66AD                <1> 	lodsw
 26673 0000558C 6639D0              <1> 	cmp	ax, dx
 26674 0000558F 7402                <1> 	je	short sysumnt_3
 26675 00005591 E2F7                <1> 	loop	sysumnt_2
 26676                              <1> sysumnt_3:
 26677 00005593 31C0                <1> 	xor	eax, eax
 26678 00005595 81EE[64680000]      <1> 	sub	esi, p.pid
 26679 0000559B D1E6                <1> 	shl	esi, 1
 26680 0000559D 8B9E[D0680000]      <1> 	mov	ebx, [esi+p.upage-4] ; the parent's upage
 26681                              <1> 	; ebx points to user (u) structure in upage
 26682 000055A3 8B15[8A6C0000]      <1> 	mov	edx, [mnti] ; * (32 bit inumber but < 65536)
 26683                              <1> 	;mov	[u.cdir], dx
 26684                              <1> 	;mov	[u.cdrv], al ; 0
 26685 000055A9 89530C              <1> 	mov	[ebx+u.cdir-user], edx 
 26686                              <1> 			    ; * (32 bit inumber but < 65536)
 26687 000055AC 884310              <1> 	mov	[ebx+u.cdrv-user], al ; 0
 26688                              <1> 	;;;
 26689                              <1> sysumnt_4:
 26690 000055AF A2[836C0000]        <1> 	mov	[mdev], al ; 0
 26691                              <1> 	     	; clr mntd / no, clear these
 26692 000055B4 A3[8A6C0000]        <1>    	mov	[mnti], eax ; 11/01/2022 (eax = 0)
 26693                              <1> 	;mov	[mnti], ax ; 0
 26694                              <1>         	; clr mnti
 26695                              <1> 
 26696                              <1> 	;; 15/05/2022
 26697                              <1> 	;mov	[cdev], al ; 0 ; [u.cdrv] = 0
 26698                              <1> 	;mov	eax, edx  ; [u.cdir]
 26699                              <1> 	;call	iget
 26700                              <1> 
 26701 000055B9 E9C7DBFFFF          <1>         jmp	sysret
 26702                              <1> 		; br sysreta / return
 26703                              <1> 
 26704                              <1> 	; 11/01/2022 - Retro UNIX 386 v1.2
 26705                              <1> 	;	(runix v2 fs inode numbers)
 26706                              <1> getspl: ; / get device number from a special file name
 26707 000055BE E8B9EAFFFF          <1> 	call	namei
 26708                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 26709                              <1> 		       ; ax = 0 -> file not found 	
 26710                              <1> 	;jc	sysmnt_err2 ; 'file not found !' error
 26711                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
 26712 000055C3 7305                <1> 	jnc	short getspl_0
 26713 000055C5 E9B1FEFFFF          <1> 	jmp	sysmnt_err2
 26714                              <1> getspl_0:
 26715                              <1> 	;jz	error
 26716                              <1> 	;jc	error
 26717                              <1> 		; jsr r0,namei / get the i-number of the special file
 26718                              <1>                 ; br errora / no such file
 26719                              <1>         ; 11/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode numbers)
 26720 000055CA 6683E80A            <1> 	sub	ax, 10 ; fd0 inode number = 10, hd3 inode number = 15
 26721                              <1> 		      ;	i-number-10, 0 = fd0, 5 = hd3 
 26722                              <1> 	;sub	ax, 3 ; Retro UNIX 8086 v1 modification !
 26723                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
 26724                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
 26725 000055CE 7206                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
 26726                              <1> 	;jc	error
 26727                              <1> 		; ble errora / less than 0?  yes, error
 26728 000055D0 6683F805            <1>         cmp	ax, 5 ; 5 = hd3
 26729                              <1> 		; cmp r1,$9. / greater than 9  tap 7
 26730                              <1> 	;ja	short sysmnt_err0 ; 'permission denied !' error
 26731                              <1> 	;;ja	error
 26732                              <1> 		; bgt errora / yes, error
 26733                              <1> 	; 11/01/2022
 26734 000055D4 760F                <1> 	jna	short getspl_retn
 26735                              <1> 	; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
 26736                              <1> ;iopen_retn:
 26737                              <1> ;	retn
 26738                              <1> 		; rts    r0 / return with device number in r1
 26739                              <1> sysmnt_err0:
 26740 000055D6 C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 26741 000055DE 0000                <1>
 26742 000055E0 E980DBFFFF          <1> 	jmp	error
 26743                              <1> 
 26744                              <1> getspl_retn:
 26745                              <1> 	; 11/01/2022
 26746                              <1> 	; eax = Retro UNIX 386 v1 device number (0 to 5)
 26747                              <1> iopen_retn:
 26748 000055E5 C3                  <1> 	retn
 26749                              <1> 
 26750                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 
 26751                              <1> 	;			(Printer initialization)
 26752                              <1> 	; 11/02/2022
 26753                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
 26754                              <1> iopen:
 26755                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 26756                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
 26757                              <1> 	; 19/05/2015
 26758                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 26759                              <1> 	; 21/05/2013 - 27/08/2013 (Retro UNIX 8086 v1)
 26760                              <1> 	;
 26761                              <1> 	; open file whose i-number is in r1
 26762                              <1> 	; 
 26763                              <1> 	; INPUTS ->
 26764                              <1> 	;    r1 - inode number
 26765                              <1> 	; OUTPUTS ->
 26766                              <1> 	;    file's inode in core	
 26767                              <1> 	;    r1 - inode number (positive)
 26768                              <1> 	;
 26769                              <1> 	; ((AX = R1))
 26770                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi, ebp)) 
 26771                              <1> 	;        
 26772                              <1> ; / open file whose i-number is in r1
 26773                              <1> ;	test	ah, 80h ; Bit 15 of AX
 26774                              <1> ;		; tst r1 / write or read access?
 26775                              <1> ;       jnz	short iopen_2
 26776                              <1> ;		; blt 2f / write, go to 2f
 26777                              <1> ;	mov	dl, 2 ; read access
 26778                              <1> ;	call	access
 26779                              <1> ;       	; jsr r0,access; 2 
 26780                              <1> ;	; / get inode into core with read access
 26781                              <1> ;	; DL=2
 26782                              <1> ;iopen_0:
 26783                              <1> ;       cmp	ax, 40
 26784                              <1> ;		; cmp r1,$40. / is it a special file
 26785                              <1> ;       ja	short iopen_retn
 26786                              <1> ;		; bgt 3f / no. 3f
 26787                              <1> 
 26788                              <1> 	; 05/12/2021
 26789                              <1> 	; DL = 0 -> open for read
 26790                              <1> 	; DL = 1 -> open for write
 26791                              <1> 	; 11/02/2022
 26792                              <1> 	; DL = 2 -> create (open for write)
 26793                              <1> 		    ; (caller: syscreat)
 26794                              <1> 
 26795 000055E6 52                  <1> 	push	edx ; *
 26796                              <1> 
 26797                              <1> 	; set permission/mode flag for 'access' 
 26798                              <1> 	;	(DX = 100h -> IREAD, DX = 80h -> IWRITE)
 26799                              <1> 
 26800 000055E7 B601                <1> 	mov	dh, 1
 26801 000055E9 08D2                <1> 	or	dl, dl ; dl = 0, open for read	
 26802 000055EB 7404                <1> 	jz	short iopen_0 ; DX = IREAD (100h)
 26803                              <1> 	; dl = 1, open for write 
 26804                              <1> 	; or
 26805                              <1> 	; dl = 2, create (regular) file	; 11/02/2022
 26806 000055ED FECE                <1> 	dec	dh
 26807 000055EF B280                <1> 	mov	dl, 80h
 26808                              <1> 	; DX = IWRITE (80h)
 26809                              <1> iopen_0:
 26810                              <1> 	; 27/03/2021
 26811                              <1> 	;   EAX = inode number (in AX)
 26812                              <1> 	;    DX = access mode, 100h = read, 80h = write
 26813                              <1> 
 26814                              <1> 	; 24/06/2020 - Retro UNIX 386 v2	
 26815 000055F1 E869F6FFFF          <1> 	call	access
 26816                              <1> 		; jsr r0,access; 1 / get inode in core
 26817                              <1> 	
 26818                              <1> 	; 27/03/2021
 26819                              <1> 	; DX return value from 'access' subroutine
 26820                              <1> 	;    may be 100h, 20h, 04h for DX = 100h (IREAD) input
 26821                              <1> 	;	     80h, 10h, 02h for DX = 80h (IWRITE) input
 26822                              <1> 
 26823                              <1> 	; 05/12/2021
 26824 000055F6 5A                  <1> 	pop	edx ; * ; dl = 0 -> open for read
 26825                              <1> 			; dl = 1 -> open for write
 26826                              <1> 			; 11/02/2022
 26827                              <1> 			; dl = 2 -> create (regular) file
 26828                              <1> 			;	   (open for writing)
 26829                              <1> 	; 24/06/2020
 26830 000055F7 8A0D[25680000]      <1> 	mov	cl, [i.flgs+1]
 26831                              <1> 
 26832 000055FD F6C180              <1> 	test	cl, 80h		; regular file ?
 26833 00005600 7525                <1> 	jnz	short iopen_1	; yes ; 05/12/2021
 26834 00005602 F6C120              <1> 	test	cl, 20h 	; device file ?
 26835                              <1> 	;jnz	short iopen_2	; yes
 26836                              <1> 	; 11/02/2022
 26837 00005605 7414                <1> 	jz	short iopen_invf ; no, invalid file/inode !
 26838                              <1> 	; device file/inode
 26839 00005607 F6C202              <1> 	test	dl, 2 ; create file ?
 26840 0000560A 7425                <1> 	jz	short iopen_2	; device file r/w (dl=0 or dl=1)
 26841                              <1> 	; an attempt to create a file 
 26842                              <1> 	; whith name of existing device file in same directory!
 26843                              <1> iopen_pdnd:
 26844 0000560C C705[186D0000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; 11
 26845 00005614 0000                <1>
 26846                              <1> 				; 'permission denied !' error
 26847                              <1> iopen_err:
 26848 00005616 E94ADBFFFF          <1> 	jmp	error
 26849                              <1> iopen_invf:
 26850                              <1> 	; invalid inode (flags)
 26851 0000561B C705[186D0000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
 26852 00005623 0000                <1>
 26853 00005625 EBEF                <1> 	jmp	short iopen_err
 26854                              <1> 
 26855                              <1> iopen_1:
 26856                              <1> 	; 05/12/2021
 26857                              <1> 	; (If open mode is 'write' and the file/inode is a directory,
 26858                              <1> 	;  open request will/must be rejected.)
 26859                              <1> 	;
 26860                              <1> 	; (If inode is a regular file and it is not a directory,
 26861                              <1> 	; there is nothing to do here, we need to return to 'sysopen'
 26862                              <1> 	; for completing the rest of file opening procedure.) 
 26863                              <1> 	
 26864 00005627 F6C140              <1> 	test	cl, 40h	; directory ?
 26865 0000562A 74B9                <1> 	jz	short iopen_retn ; no
 26866                              <1> 	
 26867 0000562C 20D2                <1> 	and	dl, dl ; open mode is 1 (write) 
 26868                              <1> 	;jz	short iopen_retn ; no
 26869                              <1> 	; 11/02/2022
 26870                              <1> 	; open mode 1 (write) or 2 (create)
 26871 0000562E 75DC                <1> 	jnz	short iopen_pdnd ; 'permission denied !' error
 26872                              <1> ;iopen_retn:
 26873 00005630 C3                  <1> 	retn
 26874                              <1> 
 26875                              <1> 	; !!!	
 26876                              <1> 	; 'sysopen' for writing
 26877                              <1> 	;	 is not applicable for directories
 26878                              <1> 	; (Directory entries must be created or deleted by
 26879                              <1> 	; relevant system calls.)
 26880                              <1> 
 26881                              <1> 	;;mov	dword [u.error], ERR_DIR_ACCESS ; 11
 26882                              <1> 	;mov	dword [u.error], ERR_PERM_DENIED ; 11
 26883                              <1> 	;			; 'permission denied !' error
 26884                              <1> 	;;jmp	error
 26885                              <1> 	;jmp	short iopen_err
 26886                              <1> 
 26887                              <1> ;iopen_retn:
 26888                              <1> ;	retn
 26889                              <1> 
 26890                              <1> iopen_2:
 26891                              <1> 	;push	ax
 26892                              <1> 	;	; mov r1,-(sp) / yes, figure out
 26893                              <1> 	;movzx	ebx, al
 26894                              <1> 	;shl	bx, 2
 26895                              <1> 	;	; asl r1
 26896                              <1>         ;add	ebx, iopen_1 - 4
 26897                              <1> 	;jmp	dword [ebx]
 26898                              <1>         ;	; jmp *1f-2(r1) / which one and transfer to it
 26899                              <1> 	
 26900                              <1> 	; 05/12/2021
 26901 00005631 50                  <1> 	push	eax ; save inode number
 26902                              <1> 	; device file
 26903 00005632 BB[4E560000]        <1> 	mov	ebx, iopen_4
 26904 00005637 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 26905 0000563A 720E                <1> 	jb	short iopen_3 ; null
 26906 0000563C 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 26907 0000563F 7709                <1> 	ja	short iopen_3 ; null	
 26908                              <1> 	; convert v2 inode number to v1 device inode number
 26909 00005641 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 26910 00005643 89C1                <1> 	mov	ecx, eax
 26911 00005645 C0E102              <1> 	shl	cl, 2 ; * 4
 26912 00005648 01CB                <1> 	add	ebx, ecx
 26913                              <1> iopen_3:
 26914 0000564A FEC2                <1> 	inc	dl ; 1 = read, 2 = write
 26915 0000564C FF23                <1> 	jmp	dword [ebx]	
 26916                              <1> 		; jmp *1f-2(r1)
 26917                              <1> ;iopen_1: ; 1:
 26918                              <1> iopen_4:
 26919 0000564E [7E4F0000]          <1> 	dd	null ; 05/12/2021
 26920 00005652 [9E560000]          <1> 	dd	otty ; tty, AX = 1 (runix)
 26921                              <1>  		 ;otty / tty ; r1=2
 26922                              <1>         	 ;oppt / ppt ; r1=4
 26923 00005656 [56570000]          <1> 	dd	sret ; mem, AX = 2 (runix)
 26924                              <1> 		 ;sret / mem ; r1=6
 26925                              <1> 		 ;sret / rf0
 26926                              <1>         	 ;sret / rk0
 26927                              <1>         	 ;sret / tap0
 26928                              <1>         	 ;sret / tap1
 26929                              <1>         	 ;sret / tap2
 26930                              <1>         	 ;sret / tap3
 26931                              <1>         	 ;sret / tap4
 26932                              <1>         	 ;sret / tap5
 26933                              <1>         	 ;sret / tap6
 26934                              <1>         	 ;sret / tap7
 26935 0000565A [56570000]          <1>         dd	sret ; fd0, AX = 3 (runix only)
 26936 0000565E [56570000]          <1>         dd	sret ; fd1, AX = 4 (runix only)
 26937 00005662 [56570000]          <1>         dd	sret ; hd0, AX = 5 (runix only)
 26938 00005666 [56570000]          <1>         dd	sret ; hd1, AX = 6 (runix only) 
 26939 0000566A [56570000]          <1>         dd	sret ; hd2, AX = 7 (runix only)
 26940 0000566E [56570000]          <1>         dd	sret ; hd3, AX = 8 (runix only) 
 26941                              <1> 	;;dd	error ; lpr, AX = 9 (error !)
 26942                              <1>         ;dd	sret ; lpr, AX = 9 (runix)
 26943                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 (lpt_init)
 26944 00005672 [32580000]          <1>         dd	ejec ; lpr, AX = 9 (runix)	
 26945 00005676 [AF560000]          <1> 	dd	ocvt ; tty0, AX = 10 (runix)	  
 26946                              <1> 		 ;ocvt / tty0
 26947 0000567A [AF560000]          <1> 	dd	ocvt ; tty1, AX = 11 (runix)	  
 26948                              <1> 		 ;ocvt / tty1
 26949 0000567E [AF560000]          <1> 	dd	ocvt ; tty2, AX = 12 (runix)	  
 26950                              <1> 		 ;ocvt / tty2
 26951 00005682 [AF560000]          <1> 	dd	ocvt ; tty3, AX = 13 (runix)	  
 26952                              <1> 		 ;ocvt / tty3
 26953 00005686 [AF560000]          <1> 	dd	ocvt ; tty4, AX = 14 (runix)	  
 26954                              <1> 		 ;ocvt / tty4
 26955 0000568A [AF560000]          <1> 	dd	ocvt ; tty5, AX = 15 (runix)	  
 26956                              <1> 		 ;ocvt / tty5
 26957 0000568E [AF560000]          <1> 	dd	ocvt ; tty6, AX = 16 (runix)	  
 26958                              <1> 		 ;ocvt / tty6
 26959 00005692 [AF560000]          <1> 	dd	ocvt ; tty7, AX = 17 (runix)	  
 26960                              <1> 		 ;ocvt / tty7
 26961 00005696 [AF560000]          <1> 	dd	ocvt ; COM1, AX = 18 (runix only)	  
 26962                              <1> 		 ;error / crd
 26963 0000569A [AF560000]          <1> 	dd	ocvt ; COM2, AX = 19 (runix only)
 26964                              <1> 
 26965                              <1> ;iopen_2: ; 2: / check open write access
 26966                              <1> ;	neg	ax
 26967                              <1> ;		; neg r1 / make inode number positive
 26968                              <1> ;	mov	dl, 1 ; write access
 26969                              <1> ;	call	access
 26970                              <1> ;		; jsr r0,access; 1 / get inode in core
 26971                              <1> ;	; DL=1
 26972                              <1> ;	test	word [i.flgs], 4000h ; Bit 14 : Directory flag
 26973                              <1> ;		;bit $40000,i.flgs / is it a directory?
 26974                              <1> ;	jz	short iopen_0
 26975                              <1> ;	;mov	[u.error], ERR_DIR_ACCESS
 26976                              <1> ;	;jmp	error ; permission denied !
 26977                              <1> ;	jmp	sysmnt_err0
 26978                              <1> ;	;;jnz	error		
 26979                              <1> ;      		; bne 2f / yes, transfer (error)
 26980                              <1> ;       ;;jmp     short iopen_0
 26981                              <1> ;	;cmp	ax, 40
 26982                              <1> ;		; cmp r1,$40. / no, is it a special file?
 26983                              <1> ;        ;ja	short iopen_2
 26984                              <1> ;		; bgt 3f / no, return
 26985                              <1> ;	;push	ax
 26986                              <1> ;		; mov r1,-(sp) / yes
 26987                              <1> ;	;movzx	ebx, al
 26988                              <1> ;	;shl	bx, 1
 26989                              <1> ;		; asl r1
 26990                              <1> ;	;add	ebx, ipen_3 - 2
 26991                              <1> ;	;jmp	dword [ebx]
 26992                              <1> ;		; jmp *1f-2(r1) / figure out 
 26993                              <1> ;			; / which special file it is and transfer
 26994                              <1> ;iopen_3: ; 1:
 26995                              <1> ;	dd 	otty ; tty, AX = 1 (runix)
 26996                              <1> ; 		 ;otty / tty ; r1=2
 26997                              <1> ;        	 ;leadr / ppt ; r1=4
 26998                              <1> ;	dd	sret ; mem, AX = 2 (runix)
 26999                              <1> ;		 ;sret / mem ; r1=6
 27000                              <1> ;		 ;sret / rf0
 27001                              <1> ;        	 ;sret / rk0
 27002                              <1> ;        	 ;sret / tap0
 27003                              <1> ;        	 ;sret / tap1
 27004                              <1> ;        	 ;sret / tap2
 27005                              <1> ;        	 ;sret / tap3
 27006                              <1> ;        	 ;sret / tap4
 27007                              <1> ;        	 ;sret / tap5
 27008                              <1> ;        	 ;sret / tap6
 27009                              <1> ;        	 ;sret / tap7
 27010                              <1> ;	dd 	sret ; fd0, AX = 3 (runix only)
 27011                              <1> ;	dd 	sret ; fd1, AX = 4 (runix only)
 27012                              <1> ;	dd 	sret ; hd0, AX = 5 (runix only)
 27013                              <1> ;	dd 	sret ; hd1, AX = 6 (runix only)	
 27014                              <1> ;	dd 	sret ; hd2, AX = 7 (runix only)
 27015                              <1> ;	dd 	sret ; hd3, AX = 8 (runix only)	
 27016                              <1> ;	dd	sret ; lpr, AX = 9  (runix)
 27017                              <1> ;	;dd	ejec ; lpr, AX = 9  (runix)
 27018                              <1> ;	dd	sret ; tty0, AX = 10 (runix)	  
 27019                              <1> ;		 ;ocvt / tty0
 27020                              <1> ;	dd	sret ; tty1, AX = 11 (runix)	  
 27021                              <1> ;		 ;ocvt / tty1
 27022                              <1> ;	dd	sret ; tty2, AX = 12 (runix)	  
 27023                              <1> ;		 ;ocvt / tty2
 27024                              <1> ;	dd	sret ; tty3, AX = 13 (runix)	  
 27025                              <1> ;		 ;ocvt / tty3
 27026                              <1> ;	dd	sret ; tty4, AX = 14 (runix)	  
 27027                              <1> ;		 ;ocvt / tty4
 27028                              <1> ;	dd	sret ; tty5, AX = 15 (runix)	  
 27029                              <1> ;		 ;ocvt / tty5
 27030                              <1> ;	dd	sret ; tty6, AX = 16 (runix)	  
 27031                              <1> ;		 ;ocvt / tty6
 27032                              <1> ;	dd	sret ; tty7, AX = 17 (runix)	  
 27033                              <1> ;		 ;ocvt / tty7
 27034                              <1> ;	dd	ocvt ; COM1, AX = 18 (runix only)	  
 27035                              <1> ;		 ;/ ejec / lpr
 27036                              <1> ;	dd	ocvt ; COM2, AX = 19 (runix only)
 27037                              <1> 
 27038                              <1> otty: ;/ open console tty for reading or writing
 27039                              <1> 	; 03/03/2022
 27040                              <1> 	; 23/02/2022
 27041                              <1> 	; 22/02/2022
 27042                              <1> 	; 09/02/2022
 27043                              <1> 	; 06/02/2022
 27044                              <1> 	; 08/01/2022
 27045                              <1> 	; 01/01/2022
 27046                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27047                              <1> 	; 16/11/2015
 27048                              <1> 	; 12/11/2015
 27049                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 27050                              <1> 	; 21/05/2013 - 13/07/2014 (Retro UNIX 8086 v1)
 27051                              <1> 	; 16/07/2013
 27052                              <1> 	; Retro UNIX 8086 v1 modification:
 27053                              <1> 	;  If a tty is open for read or write by
 27054                              <1> 	;     a process (u.uno), only same process can open
 27055                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 27056                              <1> 	;
 27057                              <1> 	; (INPUT: DL=2 for Read, DL=1 for Write, DL=0 for sysstty)
 27058                              <1> 	;
 27059                              <1> 
 27060 0000569E 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 27061 000056A5 8A83[A3680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 27062                              <1> 	; 13/01/2014
 27063                              <1> 	;jmp	short ottyp
 27064                              <1> 	; 23/02/2022
 27065 000056AB 88C4                <1> 	mov	ah, al
 27066                              <1> 	; 06/02/2022
 27067 000056AD EB06                <1> 	jmp	short otty_0
 27068                              <1> ocvt:
 27069 000056AF 2C0A                <1> 	sub	al, 10
 27070                              <1> ;ottyp:	; (call from sysstty)
 27071                              <1> 	; 08/01/2022
 27072 000056B1 31DB                <1> 	xor	ebx, ebx
 27073                              <1> ottyp:	; 03/03/2022
 27074                              <1> 	; (ebx < 256) ; 06/02/2022
 27075                              <1> 	; 23/02/2022
 27076 000056B3 B4FF                <1> 	mov	ah, 0FFh
 27077                              <1> 	; 22/02/2022
 27078                              <1> otty_0:
 27079                              <1> 	; 09/02/2022
 27080                              <1> 	; INPUT:
 27081                              <1> 	;	DL=1 for read, DL=2 for write, DL=0 for sysstty
 27082                              <1> 	;
 27083                              <1> 	; 08/01/2022
 27084                              <1> 	; 01/01/2022
 27085                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27086                              <1> 	; 16/11/2015
 27087                              <1> 	; 12/11/2015
 27088                              <1> 	; 18/05/2015 (32 bit modifications)
 27089                              <1> 	; 06/12/2013 - 13/07/2014
 27090 000056B5 88C6                <1> 	mov	dh, al ; tty number
 27091                              <1> 	;movzx 	ebx, al ; AL = tty number (0 to 9), AH = 0
 27092                              <1> 	; 08/01/2022
 27093 000056B7 88C3                <1> 	mov	bl, al
 27094 000056B9 D0E3                <1> 	shl 	bl, 1  ; aligned to word
 27095                              <1> 	; 26/01/2014	
 27096 000056BB 81C3[B4670000]      <1> 	add 	ebx, ttyl
 27097 000056C1 668B0B              <1> 	mov 	cx, [ebx]
 27098                              <1> 		   ; CL = lock value (0 or process number)
 27099                              <1> 		   ; CH = open count 
 27100 000056C4 20C9                <1> 	and 	cl, cl
 27101                              <1> 	; 13/01/2014
 27102                              <1> 	;jz 	short otty_ret
 27103                              <1> 	; 05/12/2021
 27104 000056C6 7447                <1> 	jz 	short ottys_0
 27105                              <1> 	;
 27106                              <1> 	; 16/11/2015
 27107 000056C8 3A0D[F56C0000]      <1> 	cmp 	cl, [u.uno]
 27108 000056CE 746E                <1> 	je	short ottys_3
 27109                              <1> 	;
 27110                              <1> 	; 23/02/2022
 27111                              <1> 	; (is it the console tty of the current process?)
 27112                              <1> 	; ((fast check/permit for console tty open function))
 27113 000056D0 38E0                <1> 	cmp	al, ah ; cmp dh, ah
 27114 000056D2 746A                <1> 	je	short ottys_3 ; bypass parent process check
 27115                              <1> 	;
 27116                              <1> 	;
 27117                              <1> 	; 22/02/2022
 27118                              <1> 	;movzx 	ebx, cl ; the process which has locked the tty
 27119                              <1> 	;shl 	bl, 1
 27120                              <1> 	;mov 	ax, [ebx+p.pid-2]
 27121                              <1> 	;;movzx ebx, byte [u.uno]
 27122                              <1> 	;mov	bl, [u.uno]
 27123                              <1> 	;shl 	bl, 1
 27124                              <1> 	;cmp 	ax, [ebx+p.ppid-2]
 27125                              <1> 	;je 	short ottys_3  ; 16/11/2015
 27126                              <1> 	; 22/02/2022 (BugFix) ; *
 27127 000056D4 0FB6F1              <1> 	movzx 	esi, cl ; the process which has locked the tty
 27128 000056D7 D1E6                <1> 	shl 	esi, 1
 27129 000056D9 668B86[62680000]    <1> 	mov 	ax, [esi+p.pid-2]
 27130 000056E0 96                  <1> 	xchg	esi, eax
 27131 000056E1 A0[F56C0000]        <1> 	mov	al, [u.uno]
 27132 000056E6 D0E0                <1> 	shl 	al, 1
 27133 000056E8 663BB0[82680000]    <1> 	cmp 	si, [eax+p.ppid-2]	
 27134 000056EF 744D                <1> 	je 	short ottys_3 ; *
 27135                              <1> 	; 23/02/2022
 27136                              <1> 	; check console tty of the process
 27137                              <1> 	; (open permission must be given if the -requested- tty is
 27138                              <1> 	;  console tty of current process)
 27139 000056F1 D0E8                <1> 	shr	al, 1
 27140 000056F3 38B0[A3680000]      <1> 	cmp	[eax+p.ttyc-1], dh ; console tty ?
 27141 000056F9 7443                <1> 	je 	short ottys_3
 27142                              <1> 	;
 27143                              <1> 	; the tty is locked by another process
 27144                              <1> 	; except the parent process (p.ppid)
 27145                              <1>         ; 09/02/2022
 27146                              <1> 	;mov	dword [u.error], ERR_DEV_ACCESS
 27147                              <1> 	;		; permission denied ! error
 27148                              <1> otty_err: ; 13/01/2014
 27149                              <1> 	;or 	dl, dl	; DL = 0 -> called by sysstty
 27150                              <1> 	;;jnz	error
 27151                              <1> 	; 05/12/2021
 27152                              <1> 	;jz	short otty_stc_retn
 27153                              <1> 	;jmp	error
 27154                              <1> 	; 09/02/2022
 27155 000056FB 80FA01              <1> 	cmp	dl, 1 ; dl = 0 ?
 27156 000056FE 7257                <1> 	jb	short otty_retn ; yes, cf=1, called by sysstty
 27157                              <1> 	; iopen (dl=1 or dl=2)
 27158 00005700 C705[186D0000]0B00- <1> 	mov     dword [u.error], ERR_DEV_ACCESS
 27159 00005708 0000                <1>
 27160                              <1> 			; permission denied ! error
 27161 0000570A E956DAFFFF          <1> 	jmp	error
 27162                              <1> ;otty_stc_retn:
 27163                              <1> 	;stc
 27164                              <1> 	;retn
 27165                              <1> ottys_0:
 27166                              <1> 	; 05/12/2021
 27167                              <1> otty_ret:
 27168                              <1> 	; 13/01/2014
 27169 0000570F 80FE07              <1> 	cmp 	dh, 7
 27170 00005712 7624                <1> 	jna	short ottys_2
 27171                              <1> 	; 16/11/2015
 27172                              <1> com_port_check:
 27173 00005714 BE[D2670000]        <1> 	mov	esi, com1p
 27174 00005719 80FE08              <1> 	cmp	dh, 8	; COM1 (tty8) ?
 27175 0000571C 7601                <1> 	jna	short ottys_1 ; yes, it is COM1
 27176 0000571E 46                  <1> 	inc	esi	; no, it is COM2 (tty9)
 27177                              <1> ottys_1:
 27178                              <1> 	; 12/11/2015
 27179 0000571F 803E00              <1> 	cmp	byte [esi], 0 ; E3h (or 23h)
 27180 00005722 7714                <1> 	ja	short com_port_ready
 27181                              <1> 	;
 27182                              <1> 	; 09/02/2022
 27183 00005724 80FA01              <1> 	cmp	dl, 1 ; dl = 0 ?
 27184 00005727 722E                <1> 	jb	short otty_retn ; yes, cf=1, called by sysstty
 27185 00005729 C705[186D0000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY
 27186 00005731 0000                <1>
 27187                              <1> 			   ; device not ready ! error
 27188                              <1> 	;jmp	short otty_err
 27189 00005733 E92DDAFFFF          <1> 	jmp	error	 
 27190                              <1> com_port_ready:
 27191                              <1> ottys_2:
 27192                              <1> 	; 03/03/2022
 27193                              <1> 	;or	cl, cl  ; cl = lock/owner, ch = open count
 27194                              <1> 	;jnz	short ottys_3
 27195 00005738 8A0D[F56C0000]      <1> 	mov	cl, [u.uno]
 27196                              <1> ottys_3:
 27197 0000573E FEC5                <1> 	inc 	ch
 27198 00005740 66890B              <1> 	mov 	[ebx], cx ; set tty lock again
 27199                              <1> 	; 06/12/2013
 27200 00005743 FEC6                <1> 	inc	dh ; tty number + 1
 27201 00005745 BB[DA6C0000]        <1> 	mov	ebx, u.ttyp
 27202                              <1> 	; 13/01/2014
 27203                              <1> 	;test	dl, 2 ; open for read sign
 27204                              <1> 	;jnz	short ottys_4
 27205                              <1> 	; 05/12/2021
 27206                              <1> 	;test	dl, 2
 27207                              <1> 	;jz	short ottys_4 ; open for read
 27208                              <1> 	; 01/01/2022
 27209 0000574A F6C201              <1> 	test	dl, 1
 27210 0000574D 7501                <1> 	jnz	short ottys_4 ; open for read (dl=1)
 27211                              <1> 	; dl=2 (open for write) or dl=0 (sysstty)
 27212 0000574F 43                  <1> 	inc	ebx
 27213                              <1> ottys_4:
 27214                              <1> 	; Set 'u.ttyp' ('the recent TTY') value
 27215 00005750 8833                <1> 	mov 	[ebx], dh ; tty number + 1
 27216                              <1> 	; 09/02/2022
 27217 00005752 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 27218 00005754 7401                <1> 	jz	short otty_retn ; 03/03/2022
 27219                              <1> sret:
 27220                              <1> 	;pop 	ax
 27221                              <1> 	; 05/12/2021
 27222 00005756 58                  <1> 	pop	eax
 27223                              <1> otty_retn:	; 09/02/2022
 27224                              <1> iclose_retn:	
 27225 00005757 C3                  <1> 	retn
 27226                              <1> 
 27227                              <1> 	;
 27228                              <1> 	; Original UNIX v1 'otty' routine:
 27229                              <1> 	;	
 27230                              <1> 	;mov    $100,*$tks / set interrupt enable bit (zero others) in
 27231                              <1>         ;                 / reader status reg
 27232                              <1>         ;mov    $100,*$tps / set interrupt enable bit (zero others) in
 27233                              <1>         ;                 / punch status reg
 27234                              <1>         ;mov    tty+[ntty*8]-8+6,r5 / r5 points to the header of the
 27235                              <1>         ;                          / console tty buffer
 27236                              <1>         ;incb   (r5) / increment the count of processes that opened the
 27237                              <1>         ;            / console tty
 27238                              <1>         ;tst    u.ttyp / is there a process control tty (i.e., has a tty
 27239                              <1>         ;             / buffer header
 27240                              <1>         ;bne    sret / address been loaded into u.ttyp yet)?  yes, branch
 27241                              <1>         ;mov    r5,u.ttyp / no, make the console tty the process control
 27242                              <1>         ;                 / tty
 27243                              <1>         ;br     sret / ?
 27244                              <1> ;sret:
 27245                              <1> 		;clr *$ps / set processor priority to zero
 27246                              <1> ;	pop	ax
 27247                              <1>         	;mov (sp)+,r1 / pop stack to r1
 27248                              <1> ;3:
 27249                              <1> ;	retn
 27250                              <1>         	;rts r0
 27251                              <1> 	
 27252                              <1> ;ocvt:	; < open tty >
 27253                              <1> 	; 13/01/2014
 27254                              <1> 	; 06/12/2013 (major modification: p.ttyc, u.ttyp)
 27255                              <1> 	; 24/09/2013 consistency check -> ok
 27256                              <1> 	; 16/09/2013
 27257                              <1> 	; 03/09/2013
 27258                              <1> 	; 27/08/2013
 27259                              <1> 	; 16/08/2013
 27260                              <1> 	; 16/07/2013
 27261                              <1> 	; 27/05/2013
 27262                              <1> 	; 21/05/2013
 27263                              <1> 	;
 27264                              <1> 	; Retro UNIX 8086 v1 modification !
 27265                              <1> 	; 
 27266                              <1> 	; In original UNIX v1, 'ocvt' routine 
 27267                              <1> 	;		(exactly different than this one)
 27268                              <1> 	;	was in 'u9.s' file.
 27269                              <1> 	;
 27270                              <1> 	; 16/07/2013
 27271                              <1> 	; Retro UNIX 8086 v1 modification:
 27272                              <1> 	;  If a tty is open for read or write by
 27273                              <1> 	;     a process (u.uno), only same process can open
 27274                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 27275                              <1> 	;
 27276                              <1> 	; INPUT: DL=2 for Read DL=1 for Write
 27277                              <1> 
 27278                              <1> 	; 16/09/2013
 27279                              <1> 	; sub 	al, 10
 27280                              <1> 	
 27281                              <1> 	; 06/12/2013
 27282                              <1> 	;cmp	al, 7
 27283                              <1>         ;jna	short ottyp
 27284                              <1> 	; 13/01/2014
 27285                              <1> 	;jmp	short ottyp
 27286                              <1> 
 27287                              <1> ;oppt: / open paper tape for reading or writing
 27288                              <1> ;        mov    $100,*$prs / set reader interrupt enable bit
 27289                              <1> ;        tstb   pptiflg / is file already open
 27290                              <1> ;        bne    2f / yes, branch
 27291                              <1> ;1:
 27292                              <1> ;        mov    $240,*$ps / no, set processor priority to 5
 27293                              <1> ;        jsr    r0,getc; 2 / remove all entries in clist
 27294                              <1> ;               br .+4 / for paper tape input and place in free list
 27295                              <1> ;        br     1b
 27296                              <1> ;        movb   $2,pptiflg / set pptiflg to indicate file just open
 27297                              <1> ;        movb   $10.,toutt+1 / place 10 in paper tape input tout entry
 27298                              <1> ;        br     sret
 27299                              <1> ;2:
 27300                              <1> ;        jmp    error / file already open
 27301                              <1> 
 27302                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
 27303                              <1> iclose:
 27304                              <1> 	; 09/02/2022
 27305                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 27306                              <1> 	; 10/04/2021
 27307                              <1> 	; 08/04/2021
 27308                              <1> 	; 04/04/2021 - Retro UNIX 386 v2
 27309                              <1> 	; 19/05/2015
 27310                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 27311                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 27312                              <1> 	;
 27313                              <1> 	; close file whose i-number is in r1
 27314                              <1> 	; 
 27315                              <1> 	; INPUTS ->
 27316                              <1> 	;    r1 - inode number
 27317                              <1> 	; OUTPUTS ->
 27318                              <1> 	;    file's inode in core	
 27319                              <1> 	;    r1 - inode number (positive)
 27320                              <1> 	;
 27321                              <1> 	; ((AX = R1))
 27322                              <1>         ;    ((Modified registers: -ebx-, edx)) 
 27323                              <1> 	;        
 27324                              <1> ;;/ close file whose i-number is in r1
 27325                              <1> ;	mov	dl, 2 ; 12/01/2014
 27326                              <1> ;	test	ah, 80h ; Bit 15 of AX
 27327                              <1> ;		;tst r1 / test i-number
 27328                              <1> ;	;jnz	short iclose_2
 27329                              <1> ;		;blt 2f / if neg., branch
 27330                              <1> ;	jz	short iclose_0 ; 30/07/2013
 27331                              <1> ;	; 16/07/2013 
 27332                              <1> ;	neg	ax ; make it positive
 27333                              <1> ;	; 12/01/2014
 27334                              <1> ;	dec	dl ; dl = 1 (open for write)
 27335                              <1> ;iclose_0:
 27336                              <1> ;	cmp	ax, 40
 27337                              <1> ;		;cmp r1,$40. / is it a special file
 27338                              <1> ;       ja	short iclose_retn  ; 13/01/2014
 27339                              <1> ;		;bgt 3b / no, return
 27340                              <1> ;	; 12/01/2014
 27341                              <1> ;	; DL=2 -> special file was opened for reading
 27342                              <1> ;	; DL=1 -> special file was opened for writing
 27343                              <1> 
 27344                              <1> 	; 04/04/2021
 27345                              <1> 	; INPUT:
 27346                              <1> 	;	(e)ax = inode number
 27347                              <1> 	;	   dl = open mode
 27348                              <1> 	;		0 = control mode
 27349                              <1> 	;		1 = read
 27350                              <1> 	;		2 = write
 27351                              <1> 	; OUTPUT:
 27352                              <1> 	;	none
 27353                              <1> 	;	(if cf=1 -> eax = error code)
 27354                              <1> 	;	(if cf=0 -> ax = inode number)
 27355                              <1> 
 27356                              <1> 	; 10/04/2021
 27357                              <1>         ; Modified registers: ebx, ecx, edx, esi, edi, (ebp) 
 27358                              <1> 
 27359                              <1> 	; 05/12/2021
 27360                              <1> 	; 08/04/2021
 27361                              <1> 
 27362 00005758 52                  <1> 	push	edx
 27363 00005759 E817F4FFFF          <1> 	call	iget
 27364 0000575E 5A                  <1> 	pop	edx 
 27365                              <1> 
 27366 0000575F 8A0D[25680000]      <1> 	mov	cl, [i.flgs+1]
 27367                              <1> 
 27368                              <1> 	; if i.flgs bit 15 is 1, it is regular file 
 27369                              <1> 	;test	byte [i.flgs+1], 80h ; is it a special file?
 27370 00005765 F6C180              <1> 	test	cl, 80h ; is it a special file?
 27371 00005768 75ED                <1> 	jnz	short iclose_retn ; no
 27372                              <1> 
 27373                              <1> 	;; inode flags - bit 13 must be 1 
 27374                              <1> 	;test	cl, 20h ; is it a valid device inode
 27375                              <1> 	;jz	short iclose_retn ; no ; 19/01/2022
 27376                              <1> 	
 27377                              <1> 	;push	ax
 27378                              <1> 	;	;mov r1,-(sp) / yes, save r1 on stack
 27379                              <1> 	;movzx	ebx, al
 27380                              <1> 	;shl	bx, 2
 27381                              <1> 	;	; asl r1
 27382                              <1> 	;add	ebx, iclose_1 - 4
 27383                              <1> 	;jmp	dword [ebx]
 27384                              <1> 	;	; jmp *1f-2(r1) / compute jump address and transfer
 27385                              <1> 
 27386                              <1> 	; 05/12/2021
 27387 0000576A 50                  <1> 	push	eax ; save inode number
 27388                              <1> 	; device file
 27389 0000576B BB[85570000]        <1> 	mov	ebx, iclose_1
 27390 00005770 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 27391 00005773 720E                <1> 	jb	short iclose_0
 27392 00005775 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 27393 00005778 7709                <1> 	ja	short iclose_0
 27394                              <1> 	; convert v2 inode number to v1 device inode number
 27395 0000577A 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 27396 0000577C 89C1                <1> 	mov	ecx, eax
 27397 0000577E C0E102              <1> 	shl	cl, 2 ; * 4
 27398 00005781 01CB                <1> 	add	ebx, ecx
 27399                              <1> iclose_0:
 27400 00005783 FF23                <1> 	jmp	dword [ebx]	
 27401                              <1> 		; jmp *1f-2(r1)
 27402                              <1> iclose_1: ; 1:
 27403 00005785 [7E4F0000]          <1> 	dd	null ; 05/12/2021
 27404 00005789 [D5570000]          <1> 	dd	ctty ; tty, AX = 1 (runix)
 27405 0000578D [30580000]          <1> 	dd	cret ; mem, AX = 2 (runix)
 27406 00005791 [30580000]          <1> 	dd	cret ; fd0, AX = 3 (runix only)
 27407 00005795 [30580000]          <1> 	dd	cret ; fd1, AX = 4 (runix only)
 27408 00005799 [30580000]          <1> 	dd	cret ; hd0, AX = 5 (runix only)
 27409 0000579D [30580000]          <1> 	dd	cret ; hd1, AX = 6 (runix only)	
 27410 000057A1 [30580000]          <1> 	dd	cret ; hd2, AX = 7 (runix only)
 27411 000057A5 [30580000]          <1> 	dd	cret ; hd3, AX = 8 (runix only)	
 27412 000057A9 [30580000]          <1> 	dd	cret ; lpr, AX = 9 (runix)
 27413                              <1> 	;dd	error; lpr, AX = 9 (error!)
 27414                              <1> 	;;dd	ejec ;;lpr, AX = 9  
 27415 000057AD [E4570000]          <1> 	dd	ccvt ; tty0, AX = 10 (runix)	  
 27416 000057B1 [E4570000]          <1> 	dd	ccvt ; tty1, AX = 11 (runix)	  
 27417 000057B5 [E4570000]          <1> 	dd	ccvt ; tty2, AX = 12 (runix)	  
 27418 000057B9 [E4570000]          <1> 	dd	ccvt ; tty3, AX = 13 (runix)	  
 27419 000057BD [E4570000]          <1> 	dd	ccvt ; tty4, AX = 14 (runix)	  
 27420 000057C1 [E4570000]          <1> 	dd	ccvt ; tty5, AX = 15 (runix)	  
 27421 000057C5 [E4570000]          <1> 	dd	ccvt ; tty6, AX = 16 (runix)	  
 27422 000057C9 [E4570000]          <1> 	dd	ccvt ; tty7, AX = 17 (runix)	  
 27423 000057CD [E4570000]          <1> 	dd	ccvt ; COM1, AX = 18 (runix only)	  
 27424 000057D1 [E4570000]          <1> 	dd	ccvt ; COM2, AX = 19 (runix only)
 27425                              <1> 
 27426                              <1> 	; 1:
 27427                              <1> 	;        ctty   / tty
 27428                              <1> 	;        cppt   / ppt
 27429                              <1> 	;        sret   / mem
 27430                              <1> 	;        sret   / rf0
 27431                              <1> 	;        sret   / rk0
 27432                              <1> 	;        sret   / tap0
 27433                              <1> 	;        sret   / tap1
 27434                              <1> 	;        sret   / tap2
 27435                              <1> 	;        sret   / tap3
 27436                              <1> 	;        sret   / tap4
 27437                              <1> 	;        sret   / tap5
 27438                              <1> 	;        sret   / tap6
 27439                              <1> 	;        sret   / tap7
 27440                              <1> 	;        ccvt   / tty0
 27441                              <1> 	;        ccvt   / tty1
 27442                              <1> 	;        ccvt   / tty2
 27443                              <1> 	;        ccvt   / tty3
 27444                              <1> 	;        ccvt   / tty4
 27445                              <1> 	;        ccvt   / tty5
 27446                              <1> 	;        ccvt   / tty6
 27447                              <1> 	;        ccvt   / tty7
 27448                              <1> 	;        error / crd
 27449                              <1> 
 27450                              <1> ;iclose_2: ; 2: / negative i-number
 27451                              <1> 	;neg	ax
 27452                              <1> 		;neg r1 / make it positive
 27453                              <1> 	;cmp	ax, 40
 27454                              <1> 		;cmp r1,$40. / is it a special file?
 27455                              <1>         ;ja	short @b
 27456                              <1> 		;bgt 3b / no. return
 27457                              <1> 	;push	ax
 27458                              <1> 		;mov r1,-(sp)
 27459                              <1> 	;movzx	ebx, al
 27460                              <1> 	;shl	bx, 1
 27461                              <1> 		;asl r1 / yes. compute jump address and transfer
 27462                              <1> 	;add	ebx, iclose_3 - 2
 27463                              <1> 	;jmp	dword [ebx]
 27464                              <1> 		;jmp *1f-2(r1) / figure out 
 27465                              <1> ;iclose_3:
 27466                              <1> 	;dd	ctty ; tty, AX = 1 (runix)
 27467                              <1> 	;dd	sret ; mem, AX = 2 (runix)
 27468                              <1> 	;dd	sret ; fd0, AX = 3 (runix only)
 27469                              <1> 	;dd	sret ; fd1, AX = 4 (runix only)
 27470                              <1> 	;dd	sret ; hd0, AX = 5 (runix only)
 27471                              <1> 	;dd	sret ; hd1, AX = 6 (runix only)	
 27472                              <1> 	;dd	sret ; hd2, AX = 7 (runix only)
 27473                              <1> 	;dd	sret ; hd3, AX = 8 (runix only)
 27474                              <1> 	;;dd	sret ; lpr, AX = 9	
 27475                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 27476                              <1> 	;dd	ccvt ; tty0, AX = 10 (runix)	  
 27477                              <1> 	;dd	ccvt ; tty1, AX = 11 (runix)	  
 27478                              <1> 	;dd	ccvt ; tty2, AX = 12 (runix)	  
 27479                              <1> 	;dd	ccvt ; tty3, AX = 13 (runix)	  
 27480                              <1> 	;dd	ccvt ; tty4, AX = 14 (runix)	  
 27481                              <1> 	;dd	ccvt ; tty5, AX = 15 (runix)	  
 27482                              <1> 	;dd	ccvt ; tty6, AX = 16 (runix)	  
 27483                              <1> 	;dd	ccvt ; tty7, AX = 17 (runix)	  
 27484                              <1> 	;dd	ccvt ; COM1, AX = 18 (runix only)	  
 27485                              <1> 	;dd	ccvt ; COM2, AX = 19 (runix only) 
 27486                              <1> 	
 27487                              <1> 	;1:
 27488                              <1> 	;      	ctty   / tty
 27489                              <1> 	;       leadr  / ppt
 27490                              <1> 	;       sret   / mem
 27491                              <1> 	;       sret   / rf0
 27492                              <1> 	;       sret   / rk0
 27493                              <1> 	;       sret   / tap0
 27494                              <1> 	;       sret   / tap1
 27495                              <1> 	;       sret   / tap2
 27496                              <1> 	;       sret   / tap3
 27497                              <1> 	;       sret   / tap4
 27498                              <1> 	;       sret   / tap5
 27499                              <1> 	;       sret   / tap6
 27500                              <1> 	;       sret   / tap7
 27501                              <1> 	;       ccvt   / tty0
 27502                              <1> 	;       ccvt   / tty1
 27503                              <1> 	;       ccvt   / tty2
 27504                              <1> 	;       ccvt   / tty3
 27505                              <1> 	;       ccvt   / tty4
 27506                              <1> 	;       ccvt   / tty5
 27507                              <1> 	;       ccvt   / tty6
 27508                              <1> 	;       ccvt   / tty7
 27509                              <1> 	;/      ejec   / lpr
 27510                              <1> 
 27511                              <1> ctty: ; / close console tty
 27512                              <1> 	; 09/02/2022
 27513                              <1> 	; 06/02/2022
 27514                              <1> 	; 08/01/2022
 27515                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27516                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 27517                              <1> 	; 21/05/2013 - 26/01/2014 (Retro UNIX 8086 v1)
 27518                              <1> 	;
 27519                              <1> 	; Retro UNIX 8086 v1 modification !
 27520                              <1> 	; (DL = 2 -> it is open for reading)
 27521                              <1> 	; (DL = 1 -> it is open for writing)
 27522                              <1> 	; (DL = 0 -> it is open for sysstty system call)
 27523                              <1> 	;
 27524                              <1> 	; 06/12/2013
 27525 000057D5 0FB61D[F56C0000]    <1>         movzx   ebx, byte [u.uno] ; process number
 27526 000057DC 8A83[A3680000]      <1>         mov     al, [ebx+p.ttyc-1]
 27527                              <1> 	; 13/01/2014
 27528                              <1> 	;jmp	short cttyp
 27529                              <1> 	; 06/02/2022
 27530 000057E2 EB04                <1> 	jmp	short ctty_0
 27531                              <1> ccvt:
 27532 000057E4 2C0A                <1> 	sub 	al, 10
 27533                              <1> cttyp:
 27534                              <1> 	; 08/01/2022
 27535 000057E6 31DB                <1> 	xor	ebx, ebx
 27536                              <1> ctty_0:		; 06/02/2022
 27537                              <1> 	; 09/02/2022
 27538                              <1> 	;    DL=2 -> open for writing
 27539                              <1> 	;    DL=1 -> open for reading
 27540                              <1> 	;    DL=0 -> open for sysstty system call	
 27541                              <1> 	; 08/01/2022
 27542                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27543                              <1> 	; 18/05/2015 (32 bit modifications)
 27544                              <1> 	; 16/08/2013 - 26/01/2014
 27545                              <1> 	;movzx 	ebx, al ; tty number (0 to 9)
 27546                              <1> 	; 08/01/2022
 27547 000057E8 88C3                <1> 	mov	bl, al
 27548 000057EA D0E3                <1> 	shl 	bl, 1  ; aligned to word	
 27549                              <1> 	; 26/01/2014
 27550 000057EC 81C3[B4670000]      <1> 	add 	ebx, ttyl
 27551 000057F2 88C6                <1> 	mov 	dh, al ; tty number
 27552 000057F4 668B03              <1> 	mov 	ax, [ebx]
 27553                              <1> 		   ; AL = lock value (0 or process number)
 27554                              <1> 		   ; AH = open count 
 27555 000057F7 20E4                <1> 	and 	ah, ah
 27556 000057F9 7514                <1> 	jnz	short ctty_ret
 27557                              <1> 	; 09/02/2022
 27558 000057FB 80FA01              <1> 	cmp	dl, 1	; DL = 0 -> called by sysstty
 27559 000057FE 7231                <1> 	jb	short ctty_stc_retn ; cf=1
 27560                              <1> 	; iclose (dl=1 or dl=2)
 27561 00005800 C705[186D0000]0A00- <1>         mov     dword [u.error], ERR_DEV_NOT_OPEN
 27562 00005808 0000                <1>
 27563                              <1> 			; device not open ! error
 27564                              <1> 	;jmp 	short ctty_err ; open count = 0, it is not open !
 27565 0000580A E956D9FFFF          <1> 	jmp	error
 27566                              <1> 	; 26/01/2014
 27567                              <1> ctty_ret:
 27568 0000580F FECC                <1> 	dec 	ah ; decrease open count
 27569 00005811 7502                <1> 	jnz	short ctty_1
 27570 00005813 30C0                <1> 	xor	al, al ; unlock/free tty
 27571                              <1> ctty_1:
 27572 00005815 668903              <1> 	mov 	[ebx], ax ; close tty instance
 27573                              <1> 	;
 27574 00005818 BB[DA6C0000]        <1> 	mov	ebx, u.ttyp
 27575                              <1> 	;;test	dl, 1 ; open for write sign
 27576                              <1> 	;;jz	short ctty_2
 27577                              <1> 	; 05/12/2021
 27578                              <1> 	;test	dl, 2 ; open for write sign
 27579                              <1> 	;jz	short ctty_2	
 27580                              <1> 	; 09/02/2022
 27581 0000581D F6C201              <1> 	test	dl, 1 ; open for read sign
 27582 00005820 7501                <1> 	jnz	short ctty_2
 27583                              <1> 	; open for write (dl=0 or dl=2)
 27584 00005822 43                  <1> 	inc	ebx
 27585                              <1> ctty_2:
 27586 00005823 FEC6                <1> 	inc	dh ; tty number + 1
 27587 00005825 3A33                <1> 	cmp	dh, [ebx]
 27588                              <1> 	;jne	short cret
 27589 00005827 7503                <1> 	jne	short ctty_3 ; 09/02/2022
 27590                              <1> 	; Reset/Clear 'u.ttyp' ('the recent TTY') value
 27591 00005829 C60300              <1> 	mov	byte [ebx], 0
 27592                              <1> ctty_3:
 27593                              <1> 	; 09/02/2022
 27594 0000582C 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 27595 0000582E 7401                <1> 	jz	short ctty_4
 27596                              <1> cret:
 27597                              <1> 	;pop	ax
 27598                              <1> 	; 05/12/2021
 27599 00005830 58                  <1> 	pop	eax
 27600                              <1> ctty_stc_retn:	; 09/02/2022
 27601                              <1> ctty_4:
 27602 00005831 C3                  <1> 	retn
 27603                              <1> 
 27604                              <1> ;ctty_err: ; 13/01/2014
 27605                              <1> ;	or 	dl, dl ; DL = 0 -> called by sysstty
 27606                              <1> ;	jnz	error
 27607                              <1> ;	stc
 27608                              <1> ;	retn
 27609                              <1> 
 27610                              <1> 	; Original UNIX v1 'ctty' routine:
 27611                              <1> 	;	
 27612                              <1>         ;mov    tty+[ntty*8]-8+6,r5 
 27613                              <1> 	;		;/ point r5 to the console tty buffer
 27614                              <1>         ;decb   (r5) / dec number of processes using console tty
 27615                              <1>         ;br     sret / return via sret
 27616                              <1> 
 27617                              <1> ;ccvt:	; < close tty >
 27618                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 27619                              <1> 	;
 27620                              <1> 	; Retro UNIX 8086 v1 modification !
 27621                              <1> 	; 
 27622                              <1> 	; In original UNIX v1, 'ccvt' routine 
 27623                              <1> 	;		(exactly different than this one)
 27624                              <1> 	;	was in 'u9.s' file.
 27625                              <1> 	;
 27626                              <1> 	; DL = 2 -> it is open for reading
 27627                              <1> 	; DL = 1 -> it is open for writing
 27628                              <1> 	;
 27629                              <1> 	; 17/09/2013
 27630                              <1> 	;sub 	al, 10
 27631                              <1> 	;cmp	al, 7
 27632                              <1> 	;jna	short cttyp
 27633                              <1> 	; 13/01/2014
 27634                              <1> 	;jmp	short cttyp
 27635                              <1> 
 27636                              <1> ;cppt: / close paper tape
 27637                              <1> ;        clrb   pptiflg / set pptiflg to indicate file not open
 27638                              <1> ;1:
 27639                              <1> ;        mov    $240,*$ps /set process or priority to 5
 27640                              <1> ;        jsr    r0,getc; 2 / remove all ppt input entries from clist
 27641                              <1> ;                          / and assign to free list
 27642                              <1> ;               br sret
 27643                              <1> ;        br     1b
 27644                              <1> 
 27645                              <1> ;ejec:	
 27646                              <1> ;	jmp	error
 27647                              <1> ;/ejec:
 27648                              <1> ;/       mov    $100,*$lps / set line printer interrupt enable bit
 27649                              <1> ;/       mov    $14,r1 / 'form feed' character in r1 (new page).
 27650                              <1> ;/       jsr    r0,lptoc / space the printer to a new page
 27651                              <1> ;/       br     sret / return to caller via 'sret'
 27652                              <1> 
 27653                              <1> ejec:
 27654                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 - Printer Initialization
 27655                              <1> lpt_init:	
 27656                              <1> 	; Ref: IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985
 27657                              <1> 	;
 27658                              <1> 	; Default printer port: 378h ; LPT1
 27659                              <1> 	
 27660 00005832 B401                <1>  	mov	ah, 1  ; INITIALIZE THE PRINTER PORT
 27661                              <1> 	;call	int17h
 27662 00005834 E846FAFFFF          <1> 	call	PRNOP
 27663 00005839 7414                <1> 	jz	short lpt_init_ok
 27664                              <1> 	
 27665                              <1> 	; replace error code with 'device not ready' error
 27666                              <1> 	; (this may be better for 'sysopen')
 27667 0000583B B80F000000          <1> 	mov	eax, ERR_PRN_NOT_RDY
 27668 00005840 A3[186D0000]        <1> 	mov	[u.error], eax
 27669                              <1> 	;jmp	sysret ; (may be) ? ([u.r0] = file descriptor)
 27670 00005845 A3[A46C0000]        <1> 	mov	[u.r0], eax
 27671 0000584A E916D9FFFF          <1> 	jmp	error ; (better)	
 27672                              <1> 	
 27673                              <1> lpt_init_ok:
 27674                              <1> 	;jmp	short cret
 27675 0000584F 58                  <1> 	pop	eax    ; inode number
 27676 00005850 C3                  <1> 	retn
 27677                              <1> 	
 27678                                  %include 'u8.s'      ; 11/06/2015
 27679                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 27680                              <1> ; (re-write kernel for test by using previous version without a major defect)
 27681                              <1> ; ****************************************************************************
 27682                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - SYS8.INC
 27683                              <1> ; Last Modification: 19/07/2022
 27684                              <1> ; ----------------------------------------------------------------------------
 27685                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 27686                              <1> ; (v0.1 - Beginning: 11/07/2012)
 27687                              <1> ;
 27688                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 27689                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 27690                              <1> ; <Bell Laboratories (17/3/1972)>
 27691                              <1> ; <Preliminary Release of UNIX Implementation Document>
 27692                              <1> ;
 27693                              <1> ; Retro UNIX 8086 v1 - U8.ASM (18/01/2014) //// UNIX v1 -> u8.s
 27694                              <1> ;
 27695                              <1> ; ****************************************************************************
 27696                              <1> 
 27697                              <1> ; 15/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 27698                              <1> ; 15/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
 27699                              <1> ; 14/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
 27700                              <1> ;---------------------------------------------------------------------
 27701                              <1> ; Buffer Header: -8 bytes-
 27702                              <1> ; word 1 - byte 0 - device (disk index) number (0 to 5)
 27703                              <1> ;	   byte 1 - status bits
 27704                              <1> ;	 	bit 0 - valid buffer bit (1 = valid, 0 = invalid, new)
 27705                              <1> ;		bit 1 - write bit (also modified bit)
 27706                              <1> ;		bit 2 - read bit	
 27707                              <1> ;		bit 3 to bit 7 are not used
 27708                              <1> ; word 2 - byte & byte 3 not used
 27709                              <1> ; word 3 & word 4 - byte 3, byte 5, byte 6, byte 7:
 27710                              <1> ;		physical block/sector address (32 bit LBA)
 27711                              <1> ;---------------------------------------------------------------------
 27712                              <1> 
 27713                              <1> ;; I/O Buffer - Retro UNIX 386 v1 modification
 27714                              <1> ;;     (8+512 bytes, 8 bytes header, 512 bytes data)
 27715                              <1> ;; Word 1, byte 0 = device id
 27716                              <1> ;; Word 1, byte 1 = status bits (bits 8 to 15)
 27717                              <1> ;;          bit 9 = write bit
 27718                              <1> ;;	    bit 10 = read bit	  
 27719                              <1> ;;	    bit 12 = waiting to write bit	
 27720                              <1> ;;	    bit 13 = waiting to read bit
 27721                              <1> ;;	    bit 15 = inhibit bit
 27722                              <1> ;; Word 2 (byte 2 & byte 3) = reserved (for now - 07/06/2015)
 27723                              <1> ;; Word 3 + Word 4 (byte 4,5,6,7) = physical block number 
 27724                              <1> ;;		   (In fact, it is 32 bit LBA for Retro UNIX 386 v1)
 27725                              <1> ;;
 27726                              <1> ;; I/O Buffer ((8+512 bytes in original Unix v1))
 27727                              <1> ;;	      ((4+512 bytes in Retro UNIX 8086 v1))
 27728                              <1> ;;
 27729                              <1> ;; I/O Queue Entry (of original UNIX operating system v1)
 27730                              <1> ;; Word 1, Byte 0 = device id
 27731                              <1> ;; Word 1, Byte 1 = (bits 8 to 15)
 27732                              <1> ;;          bit 9 = write bit
 27733                              <1> ;;	    bit 10 = read bit	  
 27734                              <1> ;;	    bit 12 = waiting to write bit	
 27735                              <1> ;;	    bit 13 = waiting to read bit
 27736                              <1> ;;	    bit 15 = inhibit bit
 27737                              <1> ;; Word 2 = physical block number (In fact, it is LBA for Retro UNIX 8086 v1)
 27738                              <1> ;;
 27739                              <1> ;; Original UNIX v1 ->
 27740                              <1> ;;		Word 3 = number of words in buffer (=256) 		
 27741                              <1> ;; Original UNIX v1 -> 
 27742                              <1> ;;		Word 4 = bus address (addr of first word of data buffer)
 27743                              <1> ;;
 27744                              <1> ;; Retro UNIX 8086 v1 -> Buffer Header (I/O Queue Entry) size is 4 bytes !
 27745                              <1> ;;
 27746                              <1> ;; Device IDs (of Retro Unix 8086 v1)
 27747                              <1> ;;          0 = fd0
 27748                              <1> ;;	    1 = fd1
 27749                              <1> ;;	    2 = hd0
 27750                              <1> ;;	    3 = hd1
 27751                              <1> ;;	    4 = hd2
 27752                              <1> ;;	    5 = hd3
 27753                              <1> 
 27754                              <1> ; Retro UNIX 386 v1 - 32 bit modifications (rfd, wfd, rhd, whd) - 09/06/2015
 27755                              <1> 
 27756                              <1> 	; 08/02/2022
 27757                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27758                              <1> rfd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27759                              <1> 	; 26/04/2013
 27760                              <1>    	; 13/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27761                              <1>    	;sub 	ax, 3 ; zero based device number (Floppy disk)
 27762                              <1>       	;jmp 	short bread ; **** returns to routine that called readi			
 27763                              <1> 
 27764                              <1> 	; 08/02/2022
 27765                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27766                              <1> rhd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27767                              <1> 	; 26/04/2013
 27768                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27769                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 27770                              <1>    	;jmp	short bread ; **** returns to routine that called readi	
 27771                              <1> 
 27772                              <1> bread: 
 27773                              <1> 	; 19/07/2022
 27774                              <1> 	; 15/07/2022
 27775                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 27776                              <1> 	; 08/02/2022
 27777                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27778                              <1> 	; 14/07/2015
 27779                              <1> 	; 10/07/2015
 27780                              <1> 	; 09/06/2015
 27781                              <1> 	; 07/06/2015 (Retro UNIX 386 v1 - Beginning)
 27782                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 27783                              <1> 	;	
 27784                              <1> 	; / read a block from a block structured device
 27785                              <1> 	;
 27786                              <1> 	; INPUTS ->
 27787                              <1> 	;    [u.fopf] points to the block number
 27788                              <1> 	;    ECX = maximum block number allowed on device
 27789                              <1> 	;	 ; that was an arg to bread, in original Unix v1, but
 27790                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 27791                              <1> 	;    [u.count] number of bytes to read in
 27792                              <1> 	; OUTPUTS ->
 27793                              <1> 	;    [u.base] starting address of data block or blocks in user area  	
 27794                              <1> 	;    [u.fopf] points to next consecutive block to be read
 27795                              <1> 	;
 27796                              <1> 	; ((Modified registers: eax, edx, ecx, ebx, esi, edi))
 27797                              <1> 	;
 27798                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if read
 27799                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 27800                              <1> 	;	is increased by 1. For example: If user/program request 
 27801                              <1> 	;       to read 16 bytes in current block, 'sys read' increases
 27802                              <1> 	;  	the next block number just as 512 byte reading is done.
 27803                              <1> 	;       This wrong is done in 'bread'. So, in Retro UNIX 8086 v1, 
 27804                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 27805                              <1> 	;       enough to keep byte position/offset of the disk), this
 27806                              <1> 	;	defect will not be corrected, user/program must request
 27807                              <1> 	;	512 byte read per every 'sys read' call to block devices
 27808                              <1> 	;       for achieving correct result. In future version(s), 
 27809                              <1> 	;	this defect will be corrected by using different 
 27810                              <1> 	;       user (u) structure. 26/07/2013 - Erdogan Tan 	
 27811                              <1> 
 27812                              <1> 	   	; jsr r0,tstdeve / error on special file I/O 
 27813                              <1> 			       ; / (only works on tape)
 27814                              <1> 		; mov *u.fofp,r1 / move block number to r1
 27815                              <1> 		; mov $2.-cold,-(sp) / "2-cold" to stack
 27816                              <1> ;1:
 27817                              <1> 		; cmp r1,(r0) / is this block # greater than or equal to
 27818                              <1> 			    ; / maximum block # allowed on device
 27819                              <1> 		; jnb short @f
 27820                              <1> 		; bhis	1f / yes, 1f (error)
 27821                              <1> 		; mov r1,-(sp) / no, put block # on stack
 27822                              <1> 		; jsr r0,preread / read in the block into an I/O buffer
 27823                              <1> 		; mov (sp)+,r1 / return block # to r1
 27824                              <1> 		; inc r1 / bump block # to next consecutive block
 27825                              <1> 		; dec (sp) / "2-1-cold" on stack
 27826                              <1> 		; bgt 1b / 2-1-cold = 0? No, go back and read in next block
 27827                              <1> ;1:
 27828                              <1> 		; tst (sp)+ / yes, pop stack to clear off cold calculation
 27829                              <1> 	;push	ecx ; **
 27830                              <1> 	; 26/04/2013
 27831                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 27832 00005851 2C03                <1> 	sub	al, 3
 27833                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 27834 00005853 A2[176D0000]        <1> 	mov	[u.brwdev], al
 27835                              <1> 	; 09/06/2015
 27836                              <1> 	;movzx	ebx, al
 27837                              <1> 	;mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 27838                              <1> 	; 12/01/2022 (BugFix)
 27839 00005858 C0E002              <1> 	shl	al, 2 ; * 4
 27840 0000585B 8B88[92620000]      <1> 	mov	ecx, [eax+drv.size] ; disk size (in sectors)
 27841                              <1> bread_0:
 27842 00005861 51                  <1> 	push	ecx ; ** ; 09/06/2015 
 27843                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 27844                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 27845 00005862 8B1D[B86C0000]      <1> 	mov	ebx, [u.fofp]
 27846 00005868 8B03                <1> 	mov	eax, [ebx]
 27847 0000586A C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 27848                              <1> 		; mov *u.fofp,r1 / restore r1 to initial value of the
 27849                              <1> 			       ; / block #
 27850 0000586D 39C8                <1> 	cmp	eax, ecx
 27851                              <1> 		; cmp r1,(r0)+ / block # greater than or equal to maximum
 27852                              <1>        	                     ; / block number allowed
 27853                              <1> 	;jnb	error 	     ; 18/04/2013
 27854                              <1> 		; bhis error10 / yes, error
 27855                              <1> 	; 08/02/2022
 27856                              <1> 	;jb	short bread_1
 27857                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
 27858                              <1> 	;jmp	error
 27859 0000586F 7346                <1> 	jnb	short brw_oov_err ; 'out of volume' error
 27860                              <1> bread_1:
 27861                              <1> 	;inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 27862                              <1> 		; inc *u.fofp / no, *u.fofp has next block number
 27863                              <1> 	; EAX = Block number (zero based)
 27864                              <1> 		;;jsr r0,preread / read in the block whose number is in r1
 27865                              <1> preread: ;; call preread
 27866 00005871 BF[176D0000]        <1> 	mov	edi, u.brwdev ; block device number for direct I/O
 27867 00005876 E8E1010000          <1> 	call	bufaloc_0 ; 26/04/2013
 27868                              <1> 	;; jc 	error
 27869                              <1> 	; EBX = Buffer (Header) Address -Physical-
 27870                              <1>         ; EAX = Block/Sector number (r1)
 27871                              <1> 	       ; jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
 27872                              <1> 	; 14/03/2013
 27873 0000587B 7411                <1>         jz	short bread_2 ; Retro UNIX 8086 v1 modification
 27874                              <1>        		; br 1f / branch if block already in a I/O buffer
 27875 0000587D 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 27876                              <1>         	; bis $2000,(r5) / set read bit (bit 10 in I/O buffer)
 27877 00005882 E8AD010000          <1> 	call	poke
 27878                              <1>         	; jsr r0,poke / perform the read
 27879                              <1> 	;;jc	error ;2 0/07/2013
 27880                              <1> ; 1:
 27881                              <1>  		; clr *$ps / ps = 0
 27882                              <1>         	; rts r0
 27883                              <1> 	; 08/02/2022
 27884 00005887 7305                <1> 	jnc	short bread_2
 27885 00005889 E919010000          <1> 	jmp	dskrd_err
 27886                              <1> 	;
 27887                              <1> ;; return from preread
 27888                              <1> bread_2:
 27889                              <1> 	; 15/07/2022
 27890                              <1> 	;or	word [ebx], 4000h 
 27891                              <1> 	;	; bis $40000,(r5) 
 27892                              <1> 	;		; / set bit 14 of the 1st word of the I/O buffer
 27893                              <1> bread_3: ; 1:
 27894                              <1> 	; 15/07/2022
 27895                              <1> 	;test	word [ebx], 2400h
 27896                              <1> 	;	; bit $22000,(r5) / are 10th and 13th bits set (read bits)
 27897                              <1> 	;jz	short bread_4
 27898                              <1> 	;	; beq 1f / no
 27899                              <1> 	;	; cmp cdev,$1 / disk or drum?
 27900                              <1> 	;	; ble 2f / yes
 27901                              <1> 	;	; tstb uquant / is the time quantum = 0?
 27902                              <1> 	;	; bne 2f / no, 2f
 27903                              <1> 	;	; mov r5,-(sp) / yes, save r5 (buffer address)
 27904                              <1> 	;	; jsr r0,sleep; 31. 
 27905                              <1> 	;		; / put process to sleep in channel 31 (tape)
 27906                              <1> 	;	; mov (sp)+,r5 / restore r5
 27907                              <1> 	;	; br 1b / go back
 27908                              <1> ; 2: / drum or disk
 27909                              <1>         ;; mov     cx, [s.wait_]+2 ;; 29/07/2013
 27910                              <1> 	;call	idle
 27911                              <1> 	;	; jsr r0,idle; s.wait+2 / wait
 27912                              <1> 	;jmp	short bread_3
 27913                              <1>        	;	; br 1b
 27914                              <1> bread_4: ; 1: / 10th and 13th bits not set
 27915                              <1> 	;and	word [ebx], 0BFFFh ; 1011111111111111b
 27916                              <1> 	;	; bic $40000,(r5) / clear bit 14
 27917                              <1>        	;	; jsr r0,tstdeve / test device for error (tape)
 27918                              <1> 	; 15/07/2022
 27919 0000588E 83C308              <1> 	add	ebx, 8
 27920                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 27921                              <1> 	; 09/06/2015
 27922 00005891 66833D[106D0000]00  <1> 	cmp	word [u.pcount], 0
 27923 00005899 7705                <1> 	ja	short bread_5
 27924 0000589B E8FCF7FFFF          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 27925                              <1> bread_5:
 27926                              <1> 	; EBX = system (I/O) buffer address
 27927 000058A0 E87C000000          <1> 	call	dioreg
 27928                              <1>        		; jsr r0,dioreg / do bookkeeping on u.count etc.
 27929                              <1> 
 27930                              <1> 	; 19/07/2022
 27931                              <1> 	; EDI = user data offset (previous value of [u.pbase])
 27932                              <1> 	; ESI = pointer to file offset 
 27933                              <1> 	; EAX = system (I/O) buffer offset (>= EBX)
 27934                              <1> 	; ECX = byte count
 27935                              <1> 	; EBX = system buffer (data) address
 27936                              <1> 
 27937                              <1> 	; 19/07/2022
 27938 000058A5 010E                <1> 	add	[esi], ecx ; new file (disk) offset
 27939 000058A7 89C6                <1> 	mov	esi, eax
 27940                              <1> 
 27941                              <1> 	; esi = start address of the transfer (in the buffer)
 27942                              <1> 	; edi = [u.pbase], destination address in user's memory space
 27943                              <1> 	; ecx = transfer count (in bytes)
 27944                              <1> 	;
 27945                              <1> ;1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
 27946                              <1> ;   / of users data
 27947 000058A9 F3A4                <1> 	rep	movsb
 27948                              <1> 		; movb (r5)+,(r2)+ / move data from the I/O buffer
 27949                              <1>        		; dec r3 / to the user's area in core starting at u.base
 27950                              <1>        		; bne 1b
 27951 000058AB 59                  <1> 	pop	ecx ; **
 27952 000058AC 833D[CC6C0000]00    <1> 	cmp	dword [u.count], 0
 27953                              <1> 		; tst u.count / done
 27954 000058B3 77AC                <1> 	ja	short bread_0 ; 09/06/2015
 27955                              <1>        		; beq 1f / yes, return
 27956                              <1> 		; tst -(r0) / no, point r0 to the argument again
 27957                              <1>        		; br bread / read some more
 27958                              <1> ; 1:
 27959 000058B5 58                  <1> 	pop	eax ; ****
 27960                              <1>        		; mov (sp)+,r0
 27961 000058B6 C3                  <1>         retn		; 09/06/2015
 27962                              <1> 	;jmp	ret_ 
 27963                              <1> 		;jmp ret / jump to routine that called readi
 27964                              <1> 
 27965                              <1> 	; 08/02/2022
 27966                              <1> brw_oov_err:
 27967 000058B7 C705[186D0000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
 27968 000058BF 0000                <1>
 27969 000058C1 E99FD8FFFF          <1> 	jmp	error
 27970                              <1> 
 27971                              <1> 	; 08/02/2022
 27972                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27973                              <1> wfd:    ; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27974                              <1> 	; 26/04/2013
 27975                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27976                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 27977                              <1>    	;jmp	short bwrite ; **** returns to routine that called writei
 27978                              <1> 
 27979                              <1> 	; 08/02/2022
 27980                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)				
 27981                              <1> whd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27982                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27983                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 27984                              <1>    	;jmp 	short bwrite ; **** returns to routine that called writei ('jmp ret')
 27985                              <1> 
 27986                              <1> bwrite:
 27987                              <1> 	; 19/07/2022
 27988                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 27989                              <1> 	; 15/07/2022
 27990                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3) 
 27991                              <1> 	; 08/02/2022
 27992                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27993                              <1> 	; 14/07/2015
 27994                              <1> 	; 10/07/2015
 27995                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27996                              <1> 	; 14/03/2013 - 20/07/2013 (Retro UNIX 8086 v1)
 27997                              <1> 	;	
 27998                              <1> 	;; / write on block structured device
 27999                              <1> 	;
 28000                              <1> 	; INPUTS ->
 28001                              <1> 	;    [u.fopf] points to the block number
 28002                              <1> 	;    ECX = maximum block number allowed on device
 28003                              <1> 	;	 ; that was an arg to bwrite, in original Unix v1, but
 28004                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 28005                              <1> 	;    [u.count]	number of bytes to user desires to write
 28006                              <1> 	; OUTPUTS ->
 28007                              <1> 	;    [u.fopf] points to next consecutive block to be written into
 28008                              <1> 	;
 28009                              <1> 	; ((Modified registers: edx, ecx, ebx, esi, edi))
 28010                              <1> 	;
 28011                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if write
 28012                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 28013                              <1> 	;	is increased by 1. For example: If user/program request 
 28014                              <1> 	;       to write 16 bytes in current block, 'sys write' increases
 28015                              <1> 	;  	the next block number just as 512 byte writing is done.
 28016                              <1> 	;       This wrong is done in 'bwrite'. So, in Retro UNIX 8086 v1, 
 28017                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 28018                              <1> 	;       enough to keep byte position/offset of the disk), this
 28019                              <1> 	;	defect will not be corrected, user/program must request
 28020                              <1> 	;	512 byte write per every 'sys write' call to block devices
 28021                              <1> 	;       for achieving correct result. In future version(s), 
 28022                              <1> 	;	this defect will be corrected by using different 
 28023                              <1> 	;       user (u) structure. 26/07/2013 - Erdogan Tan 	
 28024                              <1> 
 28025                              <1>        		; jsr r0,tstdeve / test the device for an error
 28026                              <1> 	;push	ecx ; **
 28027                              <1> 	;26/04/2013
 28028                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 28029 000058C6 2C03                <1> 	sub	al, 3
 28030                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 28031 000058C8 A2[176D0000]        <1> 	mov	[u.brwdev], al
 28032                              <1> 	; 09/06/2015
 28033                              <1> 	;movzx	ebx, al
 28034                              <1> 	;mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 28035                              <1> 	; 12/01/2022 (BugFix)
 28036 000058CD C0E002              <1> 	shl	al, 2 ; * 4
 28037 000058D0 8B88[92620000]      <1> 	mov	ecx, [eax+drv.size] ; disk size (in sectors)
 28038                              <1> bwrite_0:
 28039 000058D6 51                  <1> 	push	ecx ; ** ; 09/06/2015
 28040                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 28041                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 28042 000058D7 8B1D[B86C0000]      <1> 	mov	ebx, [u.fofp]
 28043 000058DD 8B03                <1> 	mov	eax, [ebx]       
 28044 000058DF C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 28045                              <1> 		; mov *u.fofp,r1 / put the block number in r1
 28046 000058E2 39C8                <1> 	cmp	eax, ecx
 28047                              <1> 		; cmp r1,(r0)+ / does block number exceed maximum allowable #
 28048                              <1>        	                     ; / block number allowed
 28049                              <1> 	;jnb	error	     ; 18/04/2013
 28050                              <1> 		; bhis error10 / yes, error
 28051                              <1>      	; 08/02/2022
 28052                              <1> 	;jb	short bwrite_1
 28053                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
 28054                              <1> 	;jmp	error
 28055 000058E4 73D1                <1> 	jnb	short brw_oov_err ; 'out of volume' error
 28056                              <1> bwrite_1:
 28057                              <1> 	;inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 28058                              <1> 		; inc *u.fofp / no, increment block number
 28059                              <1> 	; 09/06/2015 - 10/07/2015
 28060 000058E6 66833D[106D0000]00  <1> 	cmp	word [u.pcount], 0
 28061 000058EE 7705                <1> 	ja	short bwrite_2
 28062 000058F0 E8A3F7FFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 28063                              <1> bwrite_2:
 28064 000058F5 BF[176D0000]        <1> 	mov	edi, u.brwdev  ; block device number for direct I/O
 28065 000058FA E8C9000000          <1>        	call	bwslot ; 26/04/2013 (wslot -> bwslot)	 				
 28066                              <1> 		; jsr r0,wslot / get an I/O buffer to write into
 28067                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 28068 000058FF E81D000000          <1>         call	dioreg
 28069                              <1> 		; jsr r0,dioreg / do the necessary bookkeeping
 28070                              <1> 
 28071                              <1> 	; 19/07/2022
 28072                              <1> 	; EDI = user data offset (previous value of [u.pbase])
 28073                              <1> 	; ESI = pointer to file offset 
 28074                              <1> 	; EAX = system (I/O) buffer offset (>= EBX)
 28075                              <1> 	; ECX = byte count
 28076                              <1> 	; EBX = system buffer (data) address
 28077                              <1> 
 28078                              <1> 	; 19/07/2022 - Erdogan Tan
 28079                              <1> 	; ((Against a possible disk write failure/error, 
 28080                              <1> 	;   file offset must not be updated/increased before 'dskwr'
 28081                              <1> 	;   but it was updated in 'dioreg'. I have modified 'dioreg'
 28082                              <1> 	;   and 'bwrite' procedures for that.))
 28083                              <1> 
 28084                              <1> 	; 19/07/2022
 28085 00005904 56                  <1> 	push	esi ; (!)  ; save file offset (pointer)
 28086 00005905 51                  <1> 	push	ecx ; (!!) ; save byte count
 28087                              <1> 	;mov	esi, eax
 28088                              <1> 	
 28089                              <1> 	; esi = destination address (in the buffer)
 28090                              <1> 	; edi = [u.pbase], start address of transfer in user's memory space
 28091                              <1> 	; ecx = transfer count (in bytes)
 28092                              <1> ; 1: / r2 points to the users data; r5 points to the I/O buffers data area
 28093                              <1> 	;xchg 	esi, edi ; 14/07/2015
 28094                              <1> 
 28095                              <1> 	; 19/07/2022
 28096 00005906 89FE                <1> 	mov	esi, edi
 28097 00005908 89C7                <1> 	mov	edi, eax
 28098                              <1> 
 28099 0000590A F3A4                <1> 	rep	movsb
 28100                              <1> 		; movb (r2)+,(r5)+ / ; r3, has the byte count
 28101                              <1>        		; dec r3 / area to the I/O buffer
 28102                              <1>        		; bne 1b
 28103                              <1> 
 28104 0000590C E8F0000000          <1> 	call	dskwr
 28105                              <1> 		; jsr r0,dskwr / write it out on the device
 28106                              <1> 
 28107                              <1> 	; 19/07/2022
 28108                              <1> 	; (there is not a disk write error, we can increase file offset)
 28109 00005911 58                  <1> 	pop	eax ; (!!) ; byte count
 28110 00005912 5F                  <1> 	pop	edi ; (!)  ; file offset (pointer)
 28111                              <1> 	;
 28112 00005913 0107                <1> 	add	[edi], eax ; new file offset (old offset + byte count)
 28113                              <1> 
 28114 00005915 59                  <1> 	pop	ecx ; **
 28115                              <1> 
 28116 00005916 833D[CC6C0000]00    <1>         cmp     dword [u.count], 0
 28117                              <1> 		; tst u.count / done
 28118 0000591D 77B7                <1> 	ja	short bwrite_0 ; 09/06/2015
 28119                              <1> 		; beq 1f / yes, 1f
 28120                              <1> 		; tst -(r0) / no, point r0 to the argument of the call
 28121                              <1>        		; br bwrite / go back and write next block
 28122                              <1> ; 1:
 28123 0000591F 58                  <1> 	pop	eax ; ****
 28124                              <1>        		; mov (sp)+,r0
 28125 00005920 C3                  <1> 	retn		; 09/06/2015
 28126                              <1>         ;jmp	ret_ 
 28127                              <1> 		; jmp ret / return to routine that called writei
 28128                              <1> ;error10:
 28129                              <1> ;       jmp     error  ; / see 'error' routine
 28130                              <1> 
 28131                              <1> dioreg:
 28132                              <1> 	; 19/07/2022
 28133                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 28134                              <1> 	;
 28135                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
 28136                              <1> 	; 14/07/2015
 28137                              <1> 	; 10/07/2015 (UNIX v1 bugfix - [u.fofp]: byte pos., not block)
 28138                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28139                              <1> 	; 14/03/2013 (Retro UNIX 8086 v1)
 28140                              <1> 	;	
 28141                              <1> 	; bookkeeping on block transfers of data
 28142                              <1> 	;
 28143                              <1> 	; * returns value of u.pbase before it gets updated, in EDI
 28144                              <1> 	; * returns byte count (to transfer) in ECX (<=512)
 28145                              <1> 	; 10/07/2015
 28146                              <1> 	; * returns byte offset from beginning of current sector buffer
 28147                              <1> 	; (beginning of data) in ESI
 28148                              <1> 
 28149                              <1> 	; 19/07/2022
 28150                              <1> 	; OUTPUTS:
 28151                              <1> 	;   EDI = user data offset (previous value of [u.pbase])
 28152                              <1> 	;   ESI = pointer to file offset 
 28153                              <1> 	;   EAX = system (I/O) buffer offset
 28154                              <1> 	;   ECX = byte count
 28155                              <1> 	;   EBX = system buffer (data) address	
 28156                              <1> 
 28157 00005921 8B0D[CC6C0000]      <1> 	mov	ecx, [u.count]
 28158                              <1> 		; mov u.count,r3 / move char count to r3
 28159                              <1> 	; 08/02/2022
 28160 00005927 31D2                <1> 	xor	edx, edx
 28161 00005929 B602                <1> 	mov	dh, 2
 28162                              <1> 	; edx = 512
 28163 0000592B 39D1                <1> 	cmp	ecx, edx ; 512
 28164                              <1> 	;cmp 	ecx, 512
 28165                              <1> 		; cmp r3,$512. / more than 512. char?
 28166 0000592D 7602                <1> 	jna	short dioreg_0
 28167                              <1> 		; blos 1f / no, branch
 28168 0000592F 89D1                <1> 	mov	ecx, edx ; 512
 28169                              <1> 	;mov	ecx, 512
 28170                              <1> 		; mov $512.,r3 / yes, just take 512.
 28171                              <1> dioreg_0:
 28172                              <1> 	; 09/06/2015
 28173 00005931 663B0D[106D0000]    <1> 	cmp	cx, [u.pcount]
 28174 00005938 7607                <1> 	jna	short dioreg_1
 28175 0000593A 668B0D[106D0000]    <1> 	mov	cx, [u.pcount]
 28176                              <1> dioreg_1:
 28177                              <1> ; 1:
 28178 00005941 8B15[C86C0000]      <1> 	mov	edx, [u.base] ; 09/06/2015 (eax -> edx)
 28179                              <1> 	        ; mov u.base,r2 / put users base in r2
 28180 00005947 010D[D06C0000]      <1> 	add	[u.nread], ecx
 28181                              <1> 		; add r3,u.nread / add the number to be read to u.nread
 28182 0000594D 290D[CC6C0000]      <1> 	sub	[u.count], ecx
 28183                              <1> 		; sub r3,u.count / update count
 28184 00005953 010D[C86C0000]      <1> 	add	[u.base], ecx
 28185                              <1> 		; add r3,u.base / update base
 28186                              <1> 	; 10/07/2015
 28187                              <1> 	; Retro UNIX 386 v1 - modification !
 28188                              <1> 	; (File pointer points to byte position, not block/sector no.)
 28189                              <1> 	; (It will point to next byte position instead of next block no.)
 28190 00005959 8B35[B86C0000]      <1> 	mov	esi, [u.fofp] ; u.fopf points to byte position pointer  
 28191 0000595F 8B06                <1> 	mov	eax, [esi] ; esi points to current byte pos. on the disk
 28192                              <1> 	; 19/07/2022
 28193                              <1> 	;add	[esi], ecx ; ecx is added to set the next byte position
 28194 00005961 25FF010000          <1> 	and	eax, 1FFh  ; get offset from beginning of current block	
 28195                              <1> 	;mov	esi, ebx   ; beginning of data in sector/block buffer
 28196                              <1> 	;add	esi, eax   ; esi contains start address of the transfer
 28197                              <1> 	; 19/07/2022
 28198 00005966 01D8                <1> 	add	eax, ebx   ; eax contains start address of the transfer	
 28199                              <1> 	; 09/06/2015 - 10/07/2015
 28200 00005968 66290D[106D0000]    <1> 	sub	[u.pcount], cx
 28201 0000596F 81E2FF0F0000        <1> 	and	edx, PAGE_OFF ; 0FFFh
 28202 00005975 8B3D[0C6D0000]      <1> 	mov	edi, [u.pbase]
 28203 0000597B 81E700F0FFFF        <1> 	and	edi, ~PAGE_OFF
 28204 00005981 01D7                <1> 	add	edi, edx
 28205 00005983 893D[0C6D0000]      <1> 	mov	[u.pbase], edi
 28206 00005989 010D[0C6D0000]      <1> 	add	[u.pbase], ecx ; 14/07/2015
 28207 0000598F C3                  <1> 	retn
 28208                              <1> 		; rts r0 / return
 28209                              <1> 
 28210                              <1> dskrd:
 28211                              <1> 	; 15/07/2022
 28212                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28213                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
 28214                              <1> 	; 18/08/2015
 28215                              <1> 	; 02/07/2015
 28216                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28217                              <1> 	; 14/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 28218                              <1> 	;
 28219                              <1> 	; 'dskrd' acquires an I/O buffer, puts in the proper
 28220                              <1> 	; I/O queue entries (via bufaloc) then reads a block
 28221                              <1> 	; (number specified in r1) in the acquired buffer.)
 28222                              <1> 	; If the device is busy at the time dskrd is called,	
 28223                              <1> 	; dskrd calls idle.
 28224                              <1> 	; 
 28225                              <1> 	; INPUTS ->
 28226                              <1> 	;    r1 - block number
 28227                              <1> 	;    cdev - current device number 
 28228                              <1> 	; OUTPUTS ->
 28229                              <1> 	;    r5 - points to first data word in I/O buffer
 28230                              <1> 	;
 28231                              <1> 	; ((AX = R1)) input/output
 28232                              <1> 	; ((BX = R5)) output 
 28233                              <1> 	;
 28234                              <1>         ; ((Modified registers: edx, ecx, ebx, esi, edi))  
 28235                              <1> 	;
 28236 00005990 E8BA000000          <1> 	call 	bufaloc
 28237                              <1> 		; jsr r0,bufaloc / shuffle off to bufaloc; 
 28238                              <1> 			       ; / get a free I/O buffer
 28239                              <1> 	;;jc	error ; 20/07/2013
 28240 00005995 740C                <1> 	jz	short dskrd_1 ; Retro UNIX 8086 v1 modification
 28241                              <1>        		; br 1f / branch if block already in a I/O buffer
 28242                              <1> 	
 28243                              <1> 	; 15/07/2022
 28244                              <1> 	; (buffer header byte 1, bit 2 is disk read bit/flag)
 28245                              <1> dskrd_0:
 28246                              <1> 	; 10/07/2015 (wslot)
 28247 00005997 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 28248                              <1>         	; bis $2000,(r5) / set bit 10 of word 1 of 
 28249                              <1> 		               ; / I/O queue entry for buffer
 28250 0000599C E893000000          <1> 	call	poke
 28251                              <1> 		; jsr r0,poke / just assigned in bufaloc, 
 28252                              <1> 			    ; /	bit 10=1 says read
 28253                              <1> 	; 09/06/2015
 28254                              <1> 	;jnc	short dskrd_1
 28255                              <1> 	;mov	dword [u.error], ERR_DRV_READ ; disk read error !
 28256                              <1> 	;jmp	error
 28257                              <1> 	; 08/02/2022
 28258 000059A1 7204                <1> 	jc	short dskrd_3
 28259                              <1> dskrd_1: ; 1:
 28260                              <1>        	; 15/07/2022
 28261                              <1> 	;
 28262                              <1> 	;	;clr *$ps
 28263                              <1>        	;test	word [ebx], 2400h
 28264                              <1> 	;	; bit $22000,(r5) / if either bits 10, or 13 are 1; 
 28265                              <1> 	;			; / jump to idle
 28266                              <1>        	;jz	short dskrd_2
 28267                              <1> 	;	; beq 1f
 28268                              <1>         ;;;mov   ecx, [s.wait_]
 28269                              <1>        	;call	idle
 28270                              <1> 	;	; jsr r0,idle; s.wait+2
 28271                              <1> 	;jmp 	short dskrd_1
 28272                              <1>        	;	; br 1b
 28273                              <1> dskrd_2: ; 1:
 28274 000059A3 83C308              <1>         add	ebx, 8
 28275                              <1> 		; add $8,r5 / r5 points to first word of data in block 
 28276                              <1> 			  ; / just read in
 28277 000059A6 C3                  <1>        	retn
 28278                              <1> 		; rts r0
 28279                              <1> dskrd_err: 
 28280                              <1> 	; 08/02/2022
 28281                              <1> 	; (jump from 'bread' error)	
 28282                              <1> dskrd_3:	
 28283                              <1> 	; 08/02/2022
 28284 000059A7 803D[176D0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
 28285 000059AE 7509                <1> 	jne	short dskrd_4 ; no
 28286                              <1> 	; yes, clear [u.brwdev] for next check and jump to 'error'
 28287 000059B0 C605[176D0000]00    <1> 	mov	byte [u.brwdev], 0
 28288 000059B7 EB0A                <1> 	jmp	short dskrd_5
 28289                              <1> dskrd_4:
 28290 000059B9 C705[186D0000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; disk read error !
 28291 000059C1 0000                <1>
 28292                              <1> dskrd_5:
 28293 000059C3 E99DD7FFFF          <1> 	jmp	error
 28294                              <1> 
 28295                              <1> bwslot:
 28296                              <1> 	; 15/07/2022
 28297                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28298                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 28299                              <1> 	; 10/07/2015
 28300                              <1> 	;	If the block/sector is not placed in a buffer
 28301                              <1> 	;	before 'wslot', it must be read before
 28302                              <1> 	;	it is written! (Otherwise transfer counts less
 28303                              <1> 	;	than 512 bytes will be able to destroy existing 
 28304                              <1> 	;	data on disk.)
 28305                              <1> 	;
 28306                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28307                              <1> 	; 26/04/2013(Retro UNIX 8086 v1)
 28308                              <1> 	; Retro UNIX 8086 v1 modification !
 28309                              <1> 	; ('bwslot' will be called from 'bwrite' only!)
 28310                              <1> 	; INPUT -> EDI - points to device id (in u.brwdev)	
 28311                              <1> 	;	-> EAX = block number
 28312                              <1> 	;
 28313 000059C8 E88F000000          <1> 	call	bufaloc_0
 28314 000059CD 742A                <1> 	jz	short wslot_0 ; block/sector already is in the buffer
 28315                              <1> 	; 12/01/2022
 28316                              <1> 	; ebx = buffer header address
 28317                              <1> bwslot_0:
 28318                              <1> 	; 10/07/2015
 28319 000059CF 8B35[B86C0000]      <1> 	mov	esi, [u.fofp]
 28320 000059D5 8B06                <1> 	mov	eax, [esi]
 28321 000059D7 25FF010000          <1> 	and	eax, 1FFh ; offset from beginning of the sector/block
 28322 000059DC 750C                <1> 	jnz 	short bwslot_1 ; it is not a full sector write
 28323                              <1> 		       ; recent disk data must be placed in the buffer
 28324 000059DE 813D[CC6C0000]0002- <1> 	cmp	dword [u.count], 512
 28325 000059E6 0000                <1>
 28326 000059E8 730F                <1> 	jnb	short wslot_0	
 28327                              <1> bwslot_1:
 28328 000059EA E8A8FFFFFF          <1> 	call	dskrd_0
 28329                              <1> 	; 12/01/2022
 28330                              <1> 	; ebx = buffer data address = buffer header addr + 8
 28331 000059EF 83EB08              <1> 	sub	ebx, 8 ; set ebx to the buffer header address again	
 28332 000059F2 EB05                <1> 	jmp 	short wslot_0
 28333                              <1> 
 28334                              <1> wslot:
 28335                              <1> 	; 16/07/2022
 28336                              <1> 	; 15/07/2022
 28337                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28338                              <1> 	;
 28339                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28340                              <1> 	; 		(32 bit modifications)
 28341                              <1> 	; 14/03/2013 - 29/07/2013(Retro UNIX 8086 v1)
 28342                              <1> 	;
 28343                              <1> 	; 'wslot' calls 'bufaloc' and obtains as a result, a pointer
 28344                              <1> 	; to the I/O queue of an I/O buffer for a block structured
 28345                              <1> 	; device. It then checks the first word of I/O queue entry.	
 28346                              <1> 	; If bits 10 and/or 13 (read bit, waiting to read bit) are set,
 28347                              <1> 	; wslot calls 'idle'. When 'idle' returns, or if bits 10 
 28348                              <1> 	; and/or 13 are not set, 'wslot' sets bits 9 and 15 of the first
 28349                              <1> 	; word of the I/O queue entry (write bit, inhibit bit).
 28350                              <1> 	;
 28351                              <1> 	; INPUTS ->
 28352                              <1>  	;    r1 - block number
 28353                              <1> 	;    cdev - current (block/disk) device number
 28354                              <1>  	;
 28355                              <1> 	; OUTPUTS ->
 28356                              <1> 	;    bufp - bits 9 and 15 are set, 
 28357                              <1> 	;           the remainder of the word left unchanged
 28358                              <1> 	;    r5 - points to first data word in I/O buffer
 28359                              <1> 	;
 28360                              <1> 	; ((AX = R1)) input/output
 28361                              <1> 	; ((BX = R5)) output 
 28362                              <1> 	;
 28363                              <1>         ; ((Modified registers: edx, ecx, ebx, esi, edi)) 
 28364                              <1> 
 28365 000059F4 E856000000          <1> 	call	bufaloc
 28366                              <1> 	; 10/07/2015
 28367                              <1> 		; jsr r0,bufaloc / get a free I/O buffer; pointer to first
 28368                              <1>         	; br 1f / word in buffer in r5
 28369                              <1> 	; EBX = Buffer (Header) Address (r5) (ES=CS=DS, system/kernel segment)
 28370                              <1>         ; EAX = Block/Sector number (r1)
 28371                              <1> wslot_0: ;1:
 28372                              <1> 	; 15/07/2022
 28373                              <1> 	;
 28374                              <1>      	;test	word [ebx], 2400h
 28375                              <1> 	;	; bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
 28376                              <1> 	;			; / of I/O queue entry
 28377                              <1> 	;jz	short wslot_1
 28378                              <1>         ;       ; beq 1f  / branch if 10, 13 zero (i.e., not reading, 
 28379                              <1> 	;	       ; / or not waiting to read)
 28380                              <1> 	;
 28381                              <1> 	;;mov	ecx, [s.wait_] ; 29/07/2013
 28382                              <1> 	;call	idle
 28383                              <1> 	;	; jsr r0,idle; / if buffer is reading or writing to read,
 28384                              <1>        	;                   ; / idle
 28385                              <1> 	;jmp	short wslot_0
 28386                              <1> 	;	; br 1b / till finished
 28387                              <1> wslot_1: ;1:
 28388                              <1> 	;or	word [ebx], 8200h
 28389                              <1>        	;	; bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
 28390                              <1>         ;			; / (write, inhibit bits)
 28391                              <1> 	;	; clr *$ps / clear processor status
 28392                              <1> 
 28393                              <1> 	; 16/07/2022
 28394                              <1> ;dskwr_1:	; 09/03/2022
 28395                              <1> 	;add	ebx, 8 ; 11/06/2015
 28396                              <1> 		; add $8,r5 / r5 points to first word in data area 
 28397                              <1> 			  ; / for this block
 28398                              <1> 	; 15/07/2022
 28399                              <1> 	; (set disk write bit/flag)
 28400                              <1> 	;or	word [ebx], 200h	
 28401 000059F9 43                  <1> 	inc	ebx
 28402 000059FA 800B02              <1> 	or	byte [ebx], 2
 28403 000059FD 83C307              <1> 	add	ebx, 7
 28404                              <1> 	; 16/07/2022
 28405                              <1> dskwr_1:	; 08/02/2022
 28406 00005A00 C3                  <1>        	retn
 28407                              <1> 		; rts r0
 28408                              <1> dskwr:
 28409                              <1> 	; 16/07/2022
 28410                              <1> 	; 15/07/2022
 28411                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28412                              <1> 	; 09/03/2022
 28413                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
 28414                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28415                              <1> 	; 14/03/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 28416                              <1> 	;
 28417                              <1> 	; 'dskwr' writes a block out on disk, via ppoke. The only
 28418                              <1> 	; thing dskwr does is clear bit 15 in the first word of I/O queue
 28419                              <1> 	; entry pointed by 'bufp'. 'wslot' which must have been called
 28420                              <1> 	; previously has supplied all the information required in the
 28421                              <1> 	; I/O queue entry.
 28422                              <1> 	;
 28423                              <1> 	; (Modified registers: ebx, ecx, edx, esi, edi)
 28424                              <1> 	;
 28425 00005A01 8B1D[346C0000]      <1> 	mov	ebx, [bufp]
 28426 00005A07 668123FF7F          <1> 	and	word [ebx], 7FFFh ; 0111111111111111b
 28427                              <1> 		; bic $100000,*bufp / clear bit 15 of I/O queue entry at
 28428                              <1>                                   ; / bottom of queue
 28429 00005A0C E823000000          <1> 	call	poke
 28430                              <1> 	; 09/06/2015
 28431 00005A11 73ED                <1> 	jnc	short dskwr_1 ; 16/07/2022
 28432                              <1> 	; ebx = buffer header ; 09/03/2022
 28433                              <1> 	; 08/02/2022
 28434 00005A13 803D[176D0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
 28435 00005A1A 7509                <1> 	jne	short dskwr_0 ; no
 28436                              <1> 	; yes, clear [u.brwdev] for next check and jump to 'error'
 28437 00005A1C C605[176D0000]00    <1> 	mov	byte [u.brwdev], 0
 28438 00005A23 EB0A                <1> 	jmp	short dskwr_2
 28439                              <1> dskwr_0:
 28440 00005A25 C705[186D0000]1200- <1> 	mov	dword [u.error], ERR_DRV_WRITE ; disk write error !
 28441 00005A2D 0000                <1>
 28442                              <1> dskwr_2:
 28443 00005A2F E931D7FFFF          <1> 	jmp	error
 28444                              <1> ;dskwr_1:
 28445                              <1> ;	add	ebx, 8 ; 09/03/2022
 28446                              <1> ;	; ebx = buffer data address
 28447                              <1> ;	retn
 28448                              <1> 
 28449                              <1> ;ppoke:
 28450                              <1>        		; mov $340,*$ps
 28451                              <1>        		; jsr r0,poke
 28452                              <1>        		; clr *$ps
 28453                              <1> 		; rts r0
 28454                              <1> 
 28455                              <1> poke:
 28456                              <1> 	; 15/07/2022
 28457                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28458                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
 28459                              <1> 	; 14/07/2022
 28460                              <1> 	;	! Major Modification !
 28461                              <1> 	;	Retro UNIX 386 v1 (Kernel v0.2.0.22)
 28462                              <1> 	;
 28463                              <1> 	; 04/02/2022 (32 bit reg push pop)
 28464                              <1> 	; 24/10/2015
 28465                              <1> 	; 20/08/2015
 28466                              <1> 	; 18/08/2015
 28467                              <1> 	; 02/07/2015
 28468                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28469                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 28470                              <1> 	;
 28471                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 28472                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 28473                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 28474                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 28475                              <1> 	;
 28476                              <1> 	; Basic I/O functions for all block structured devices
 28477                              <1> 	;
 28478                              <1>         ; (Modified registers: ECX, EDX, ESI, EDI)
 28479                              <1> 	;
 28480                              <1> 	; 20/07/2013 modifications
 28481                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 28482                              <1> 	; INPUTS -> 
 28483                              <1> 	;        EBX = buffer header address
 28484                              <1> 	; OUTPUTS ->
 28485                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 28486                              <1> 	;	 cf=1 -> error, word [EBX] = 0FFFFh
 28487                              <1> 	;		(drive not ready or r/w error!)
 28488                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 28489                              <1> 	;	 (dword [EBX+4] = 0FFFFFFFFh means RW/IO error)
 28490                              <1> 	;        (also it indicates invalid buffer data)
 28491                              <1> 	
 28492                              <1> 	; 15/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
 28493                              <1> 	; 14/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
 28494                              <1> 	; Buffer header:
 28495                              <1> 	;	byte 0 - device/disk (index) number
 28496                              <1> 	;	byte 1 - status
 28497                              <1> 	;	    before 'poke'	
 28498                              <1> 	;		bit 0 - valid bit 
 28499                              <1> 	;		   (0 for new buffer)
 28500                              <1> 	;		   (1 for existing buffer)	
 28501                              <1> 	;		bit 1 - write (modified) bit, disk write flag
 28502                              <1> 	;		bit 2 - read bit, disk read flag
 28503                              <1> 	;	    after 'poke'
 28504                              <1> 	;		if disk r/w is successed
 28505                              <1> 	;		   bit 0 = 1
 28506                              <1> 	;		   bit 1 = 0
 28507                              <1> 	;		   bit 2 = 0
 28508                              <1> 	;		if disk r/w is failed
 28509                              <1> 	;		   bit 0 = 0 (invalid buffer)
 28510                              <1> 	;		   bit 1 = 0 (write bit)
 28511                              <1> 	;		   bit 2 = 0 (read bit)	
 28512                              <1>  	;
 28513                              <1> 	;	byte 2 & byte 3 - not used
 28514                              <1> 	;	byte 4 to byte 7 - disk block/sector address
 28515                              <1> 	
 28516                              <1> 	; 04/02/2022
 28517 00005A34 50                  <1> 	push	eax
 28518 00005A35 E896000000          <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 28519 00005A3A 58                  <1> 	pop	eax
 28520 00005A3B 730D                <1> 	jnc	short seta ; 14/07/2022
 28521                              <1> 	
 28522                              <1> 	; 14/07/2022
 28523                              <1> 	; (invalidate buffer)
 28524                              <1> 	
 28525                              <1> 	; 02/07/2015 (32 bit modification)
 28526                              <1> 	; 20/07/2013
 28527 00005A3D C74304FFFFFFFF      <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 28528                              <1>        		; mov $-1,2(r1) / destroy associativity
 28529 00005A44 66C703FF00          <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 28530                              <1> 		; clrb 1(r1) / do not do I/O
 28531                              <1> 	;stc
 28532 00005A49 C3                  <1> 	retn
 28533                              <1>         	; rts r0
 28534                              <1> seta: 
 28535 00005A4A C6430101            <1> 	mov	byte [ebx+1], 1 ; clear write/read bits, set valid bit
 28536                              <1> 	;clc
 28537 00005A4E C3                  <1> 	retn
 28538                              <1> 
 28539                              <1> %if 0
 28540                              <1> 
 28541                              <1> poke:
 28542                              <1> 	; 29/11/2021 (32 bit reg push-pop)
 28543                              <1> 	; 24/10/2015
 28544                              <1> 	; 20/08/2015
 28545                              <1> 	; 18/08/2015
 28546                              <1> 	; 02/07/2015
 28547                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28548                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 28549                              <1> 	;
 28550                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 28551                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 28552                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 28553                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 28554                              <1> 	;
 28555                              <1> 	; Basic I/O functions for all block structured devices
 28556                              <1> 	;
 28557                              <1>         ; (Modified registers: ecx, edx, esi, edi)
 28558                              <1> 	;
 28559                              <1> 	; 20/07/2013 modifications
 28560                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 28561                              <1> 	; INPUTS -> 
 28562                              <1> 	;        (EBX = buffer header address)
 28563                              <1> 	; OUTPUTS ->
 28564                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 28565                              <1> 	;	 cf=1 -> error, word [EBX] = 0FFFFh
 28566                              <1> 	;		(drive not ready or r/w error!)
 28567                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 28568                              <1> 	;	 (dword [EBx+4] = 0FFFFFFFFh means RW/IO error)
 28569                              <1> 	;        (also it indicates invalid buffer data)
 28570                              <1> 	;
 28571                              <1> 	push	ebx
 28572                              <1>        		; mov r1,-(sp)
 28573                              <1>        		; mov r2,-(sp)
 28574                              <1>        		; mov r3,-(sp)
 28575                              <1> 	push 	eax ; Physical Block Number (r1) (mget)
 28576                              <1> 	;
 28577                              <1> 	; 09/06/2015
 28578                              <1> 	; (permit read/write after a disk R/W error)
 28579                              <1> 	mov	cl, [ebx] ; device id (0 to 5)
 28580                              <1> 	mov	al, 1
 28581                              <1> 	shl	al, cl
 28582                              <1> 	test 	al, [active] ; busy ? (error)
 28583                              <1> 	jz	short poke_0
 28584                              <1> 	not	al
 28585                              <1> 	and	[active], al ; reset busy bit for this device only
 28586                              <1> poke_0:
 28587                              <1>         mov     esi, bufp + (4*(nbuf+2)) 
 28588                              <1> 		; mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority
 28589                              <1> 					 ; / I/O queue pointer
 28590                              <1> poke_1: ; 1:
 28591                              <1>         sub	esi, 4
 28592                              <1> 	mov	ebx, [esi]
 28593                              <1> 		; mov -(r2),r1 / r1 points to an I/O queue entry
 28594                              <1> 	mov	ax, [ebx] ; 17/07/2013
 28595                              <1>        	test	ah, 06h
 28596                              <1> 	;test	word [ebx], 600h ; 0000011000000000b
 28597                              <1> 		; bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O 
 28598                              <1> 			       ; / queue entry
 28599                              <1>         jz      short poke_5
 28600                              <1> 		; beq 2f / branch to 2f if both are clear
 28601                              <1> 	; 31/07/2013
 28602                              <1> 	;test	ah, 0B0h ; (*)
 28603                              <1> 	;;test	word [ebx], 0B000h ; 1011000000000000b
 28604                              <1> 		; bit $130000,(r1) / test bits 12, 13, and 15
 28605                              <1>         ;jnz	short poke_5 ; 31/07/2013 (*)
 28606                              <1> 		; bne 2f / branch if any are set
 28607                              <1> 	;movzx	ecx, byte [ebx] ; 09/06/2015 ; Device Id
 28608                              <1>     		; movb (r1),r3 / get device id
 28609                              <1> 	movzx	ecx, al ; 18/08/2015
 28610                              <1> 	;mov	edi, ecx ; 26/04/2013
 28611                              <1> 	xor 	eax, eax ; 0
 28612                              <1> 	;cmp 	[edi+drv.error], al ; 0
 28613                              <1> 		; tstb deverr(r3) / test for errors on this device
 28614                              <1>        	;jna	short poke_2 
 28615                              <1> 		; beq 3f / branch if no errors
 28616                              <1> 	; 02/07/2015
 28617                              <1> 	;dec	eax
 28618                              <1> 	;mov	[ebx+4], ax ; 0FFFFFFFFh ; -1 
 28619                              <1>        		; mov $-1,2(r1) / destroy associativity
 28620                              <1> 	;shr	eax, 24
 28621                              <1> 	;mov	[ebx], eax ; 000000FFh, reset
 28622                              <1> 		; clrb 1(r1) / do not do I/O
 28623                              <1> 	;jmp	short poke_5
 28624                              <1>         ;       ; br 2f
 28625                              <1>                 ; rts r0
 28626                              <1> poke_2: ; 3:
 28627                              <1> 	; 02/07/2015
 28628                              <1> 	inc	cl ; 0FFh -> 0
 28629                              <1> 	jz	short poke_5
 28630                              <1> 	inc	al ; mov ax, 1
 28631                              <1> 	dec	cl
 28632                              <1> 	jz	short poke_3
 28633                              <1> 	; 26/04/2013 Modification
 28634                              <1> 	;inc	al ; mov ax, 1
 28635                              <1> 	;or	cl, cl ; Retro UNIX 8086 v1 device id.
 28636                              <1> 	;jz	short poke_3 ; cl = 0
 28637                              <1> 	shl	al, cl ; shl ax, cl
 28638                              <1> poke_3:
 28639                              <1> 	;test	[active], ax
 28640                              <1> 	test	[active], al
 28641                              <1> 		; bit $2,active / test disk busy bit
 28642                              <1> 	jnz     short poke_5
 28643                              <1> 		; bne 2f / branch if bit is set
 28644                              <1> 	;or	[active], ax
 28645                              <1> 	or	[active], al
 28646                              <1> 		; bis $2,active / set disk busy bit
 28647                              <1> 	push	eax ; 29/11/2021
 28648                              <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 28649                              <1> 	;mov    [edi+drv.error], ah
 28650                              <1> 	pop	eax
 28651                              <1> 	jnc	short poke_4 ; 20/07/2013
 28652                              <1> 	;cmp 	[edi+drv.error], al ; 0	
 28653                              <1> 	;jna	short poke_4
 28654                              <1> 		; tstb deverr(r3) / test for errors on this device
 28655                              <1>        		; beq 3f / branch if no errors
 28656                              <1> 	; 02/07/2015 (32 bit modification)
 28657                              <1> 	; 20/07/2013
 28658                              <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 28659                              <1>        		; mov $-1,2(r1) / destroy associativity
 28660                              <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 28661                              <1> 		; clrb 1(r1) / do not do I/O
 28662                              <1> 	jmp     short poke_5
 28663                              <1> poke_4:	; 20/07/2013
 28664                              <1> 	; 17/07/2013
 28665                              <1> 	not 	al 
 28666                              <1> 	and	[active], al ; reset, not busy
 28667                              <1> 	; EBX = system I/O buffer header (queue entry) address
 28668                              <1> seta: ; / I/O queue bookkeeping; set read/write waiting bits.
 28669                              <1> 	mov	ax, [ebx]
 28670                              <1>        		; mov (r1),r3 / move word 1 of I/O queue entry into r3
 28671                              <1>         and	ax, 600h
 28672                              <1> 		; bic $!3000,r3 / clear all bits except 9 and 10
 28673                              <1> 	and 	word [ebx], 0F9FFh
 28674                              <1>        		; bic $3000,(r1) / clear only bits 9 and 10
 28675                              <1> 	shl	ah, 3
 28676                              <1>        		; rol r3
 28677                              <1>                 ; rol r3
 28678                              <1>                 ; rol r3	
 28679                              <1> 	or	[ebx], ax
 28680                              <1> 		; bis r3,(r1) / or old value of bits 9 and 10 with 
 28681                              <1> 			   ; bits 12 and 13
 28682                              <1> 	call	idle ; 18/01/2014
 28683                              <1> 	;; sti
 28684                              <1> 	;hlt 	; wait for a hardware interrupt
 28685                              <1> 	;; cli
 28686                              <1> 	; NOTE: In fact, disk controller's 'disk I/O completed' 
 28687                              <1>         ; interrupt would be used to reset busy bits, but INT 13h
 28688                              <1> 	; returns when disk I/O is completed. So, here, as temporary
 28689                              <1> 	; method, this procedure will wait for a time according to
 28690                              <1> 	; multi tasking and time sharing concept.
 28691                              <1> 	;
 28692                              <1> 	; 24/10/2015
 28693                              <1> 	;not	ax 
 28694                              <1> 	mov 	ax, 0FFh ; 24/10/2015 (temporary)
 28695                              <1> 	and	[ebx], ax ; clear bits 12 and 13
 28696                              <1> poke_5: ;2:
 28697                              <1>         cmp     esi, bufp
 28698                              <1> 		; cmp r2,$bufp / test to see if entire I/O queue 
 28699                              <1>                             ; / has been scanned
 28700                              <1> 	ja      short poke_1
 28701                              <1> 		; bhi 1b
 28702                              <1> 	; 24/03/2013
 28703                              <1>        		; mov (sp)+,r3
 28704                              <1>        		; mov (sp)+,r2
 28705                              <1>        		; mov (sp)+,r1
 28706                              <1>         pop 	eax  ; Physical Block Number (r1) (mget)
 28707                              <1> 	pop 	ebx
 28708                              <1> 	; 02/07/2015 (32 bit modification)
 28709                              <1> 	; 20/07/2013
 28710                              <1> 	;cmp 	dword [ebx+4], 0FFFFFFFFh
 28711                              <1> 	cmp	byte [ebx], 0FFh ; 20/08/2015
 28712                              <1> 	;	
 28713                              <1> 	; 'poke' returns with cf=0 if the requested buffer is read 
 28714                              <1> 	; or written successfully; even if an error occurs while
 28715                              <1> 	; reading to or writing from other buffers. 20/07/2013
 28716                              <1> 	;
 28717                              <1> 	; 09/06/2015
 28718                              <1> 	cmc
 28719                              <1> 	retn
 28720                              <1>                 ; rts r0
 28721                              <1> 
 28722                              <1> %endif
 28723                              <1> 
 28724                              <1> bufaloc:
 28725                              <1> 	; 15/07/2022
 28726                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28727                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 28728                              <1> 	; 20/08/2015
 28729                              <1> 	; 19/08/2015
 28730                              <1> 	; 02/07/2015
 28731                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28732                              <1> 	;	     (32 bit modifications)	
 28733                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 28734                              <1> 	;
 28735                              <1> 	; bufaloc - Block device I/O buffer allocation
 28736                              <1> 	; 
 28737                              <1> 	; INPUTS ->
 28738                              <1> 	;    r1 - block number
 28739                              <1> 	;    cdev - current (block/disk) device number
 28740                              <1> 	;    bufp+(2*n)-2 --- n = 1 ... nbuff
 28741                              <1> 	; OUTPUTS ->
 28742                              <1> 	;    r5 - pointer to buffer allocated
 28743                              <1> 	;    bufp ... bufp+12 --- (bufp), (bufp)+2
 28744                              <1> 	;
 28745                              <1> 	; ((AX = R1)) input/output
 28746                              <1> 	; ((BX = R5)) output
 28747                              <1>         ;    ((Modified registers: DX, CX, BX, SI, DI, BP))
 28748                              <1> 	;    zf=1 -> block already in a I/O buffer
 28749                              <1> 	;    zf=0 -> a new I/O buffer has been allocated
 28750                              <1> 	;    ((DL = Device ID))
 28751                              <1> 	;    (((DH = 0 or 1)))
 28752                              <1> 	;    (((CX = previous value of word ptr [bufp])))
 28753                              <1> 	;    ((CX and DH will not be used after return)))
 28754                              <1> 
 28755                              <1> 	; 15/07/2022
 28756                              <1> 	;	Modified registers: EBX, ECX, EDX, ESI, EDI
 28757                              <1> 
 28758                              <1> 	;;push 	esi ; ***
 28759                              <1> 		; mov r2,-(sp) / save r2 on stack
 28760                              <1>        		; mov $340,*$ps / set processor priority to 7
 28761                              <1> 	; 20/07/2013
 28762                              <1> 	; 26/04/2013
 28763                              <1> 	;movzx	ebx, byte [cdev] ; 0 or 1
 28764                              <1> 	;mov	edi, rdev ; offset mdev = offset rdev + 1
 28765                              <1> 	;add	edi, ebx
 28766                              <1> 	; 09/01/2022
 28767 00005A4F 0FB63D[816C0000]    <1> 	movzx	edi, byte [cdev] ; 0 or 1
 28768 00005A56 81C7[826C0000]      <1> 	add	edi, rdev
 28769                              <1> bufaloc_0: ; 26/04/2013 !! here is called from bread or bwrite !!
 28770                              <1> 			;; EDI points to device id.
 28771 00005A5C 0FB61F              <1> 	movzx	ebx, byte [edi] ; [EDI] -> rdev/mdev or brwdev
 28772                              <1> 	; 11/06/2021
 28773 00005A5F 80BB[AE620000]F0    <1> 	cmp 	byte [ebx+drv.status], 0F0h ; Drive not ready !
 28774 00005A66 720F                <1> 	jb	short bufaloc_9
 28775 00005A68 C705[186D0000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 28776 00005A70 0000                <1>
 28777 00005A72 E9EED6FFFF          <1> 	jmp	error
 28778                              <1> bufaloc_9:
 28779 00005A77 89DA                <1> 	mov	edx, ebx ; dh = 0, dl = device number (0 to 5)
 28780                              <1> bufaloc_10: ; 02/07/2015
 28781                              <1> 	; 14/07/2022
 28782                              <1> 	;xor 	ebp, ebp ; 0
 28783                              <1> 	;push	ebp ; 0
 28784                              <1>         ;mov	ebp, esp
 28785 00005A79 31FF                <1> 	xor	edi, edi ; 0
 28786 00005A7B 57                  <1> 	push	edi
 28787                              <1> bufaloc_1: ;1:
 28788                              <1> 		; clr -(sp) / vacant buffer
 28789 00005A7C BE[346C0000]        <1>         mov 	esi, bufp
 28790                              <1> 		; mov $bufp,r2 / bufp contains pointers to I/O queue 
 28791                              <1> 			     ; / entrys in buffer area
 28792                              <1> bufaloc_2: ;2:
 28793 00005A81 8B1E                <1> 	mov	ebx, [esi]
 28794                              <1>        		; mov (r2)+,r5 / move pointer to word 1 of an I/O 
 28795                              <1> 			    ; queue entry into r5
 28796                              <1> 	; 15/07/2022
 28797 00005A83 8B0B                <1> 	mov	ecx, [ebx]	
 28798                              <1> 	;test	word [ebx], 0F600h
 28799                              <1> 	; 15/07/2022
 28800 00005A85 F6C501              <1> 	test	ch, 1 ; valid buffer (content) ?
 28801                              <1> 		; bit $173000,(r5) / lock+keep+active+outstanding
 28802 00005A88 7505                <1>         jnz	short bufaloc_3 ; yes
 28803                              <1> 		; bne 3f / branch when 
 28804                              <1> 		       ; / any of bits 9,10,12,13,14,15 are set
 28805                              <1>                        ; / (i.e., buffer busy)
 28806                              <1> 	;mov    [ebp], esi ; pointer to I/0 queue entry
 28807                              <1> 	; 15/07/2022
 28808                              <1> 	; save free buffer pointer 
 28809 00005A8A 893424              <1> 	mov	[esp], esi
 28810                              <1>                 ; mov r2,(sp) ;/ save pointer to last non-busy buffer
 28811                              <1> 			; / found points to word 2 of I/O queue entry)
 28812                              <1> 	; continue to see if requested sector/block buffer
 28813                              <1> 	;	already is one of existing (valid) buffers
 28814                              <1> 	;jmp	short bufaloc_4
 28815 00005A8D EB0E                <1> 	jmp	short bufaloc_11 ; 15/07/2022
 28816                              <1> bufaloc_3: ;3:
 28817                              <1> 	;mov	dl, [edi] ; 26/04/2013
 28818                              <1> 	;
 28819 00005A8F 38D1                <1> 	cmp	cl, dl ; 15/07/2022
 28820                              <1> 	;cmp	[ebx], dl	
 28821                              <1> 		; cmpb (r5),cdev / is device in I/O queue entry same 
 28822                              <1> 			       ; / as current device
 28823 00005A91 7508                <1> 	jne	short bufaloc_4
 28824                              <1>        		; bne 3f
 28825 00005A93 394304              <1> 	cmp	[ebx+4], eax
 28826                              <1>        		; cmp 2(r5),r1 / is block number in I/O queue entry, 
 28827                              <1> 			     ; / same as current block number
 28828 00005A96 7503                <1>        	jne	short bufaloc_4
 28829                              <1> 		; bne 3f
 28830                              <1> 	;add	esp, 4
 28831 00005A98 59                  <1> 	pop	ecx
 28832                              <1>        		; tst (sp)+ / bump stack pointer
 28833 00005A99 EB1D                <1> 	jmp	short bufaloc_7 ; Retro Unix 8086 v1 modification
 28834                              <1> 				; jump to bufaloc_6 in original Unix v1
 28835                              <1>        		; br 1f / use this buffer
 28836                              <1> bufaloc_4: ;3:
 28837                              <1> 	; 15/07/2022
 28838                              <1> 	; save last valid buffer 
 28839                              <1> 	; (will be used if there is not a free buffer)
 28840 00005A9B 89F7                <1> 	mov	edi, esi	
 28841                              <1> bufaloc_11:
 28842 00005A9D 83C604              <1> 	add	esi, 4 ; 20/08/2015
 28843                              <1> 	;
 28844 00005AA0 81FE[746C0000]      <1> 	cmp	esi, bufp + (nbuf*4)
 28845                              <1> 		; cmp r2,$bufp+nbuf+nbuf
 28846 00005AA6 72D9                <1> 	jb	short bufaloc_2
 28847                              <1> 		; blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
 28848                              <1>                        ; / buffers not checked)
 28849 00005AA8 5E                  <1>         pop	esi
 28850                              <1> 		; mov (sp)+,r2 / once all bufs are examined move pointer
 28851                              <1> 			     ; / to last free block
 28852 00005AA9 09F6                <1>        	or	esi, esi 
 28853 00005AAB 7502                <1> 	jnz	short bufaloc_5
 28854                              <1> 		; bne 2f / if (sp) is non zero, i.e., 
 28855                              <1> 	        ; / if a free buffer is found branch to 2f
 28856                              <1> 
 28857                              <1> 	; 15/07/2022        
 28858                              <1> 	; if there is not a free buffer
 28859                              <1> 	; we can use last valid buffer (the oldest buffer)
 28860                              <1> 	; ((ptr to new buffer is located at head of buff ptr chain))
 28861 00005AAD 89FE                <1> 	mov	esi, edi
 28862                              <1> 
 28863                              <1> 	;;mov  ecx, [s.wait_]
 28864                              <1> 	;call	idle
 28865                              <1> 	;	; jsr r0,idle; s.wait+2 / idle if no free buffers
 28866                              <1> 	;jmp 	short bufaloc_10 ; 02/07/2015
 28867                              <1>        	;	; br 1b
 28868                              <1> bufaloc_5: ;2:
 28869                              <1> 		; tst (r0)+ / skip if warmed over buffer
 28870                              <1> 	; 15/07/2022
 28871                              <1> 	;inc	dh ; Retro UNIX 8086 v1 modification
 28872                              <1> bufaloc_6: ;1:
 28873 00005AAF 8B1E                <1>         mov    	ebx, [esi] 
 28874                              <1> 		; mov -(r2),r5 / put pointer to word 1 of I/O queue 
 28875                              <1> 			     ; / entry in r5
 28876                              <1> 	;; 26/04/2013
 28877                              <1>         ;;mov	dl, [edi] ; byte [rdev] or byte [mdev]
 28878                              <1> 	;mov 	[ebx], dl
 28879                              <1> 		; movb cdev,(r5) / put current device number 
 28880                              <1> 				 ; / in I/O queue entry
 28881                              <1> 	; 15/07/2022
 28882                              <1> 	; invalidate buffer before r/w (new) disk sector/block
 28883                              <1> 	;mov	[ebx+1], dh ; 0
 28884                              <1> 	; 15/07/2022
 28885 00005AB1 8913                <1> 	mov	[ebx], edx  ; dh = 0
 28886                              <1> 	
 28887 00005AB3 894304              <1> 	mov 	[ebx+4], eax
 28888                              <1> 		; mov r1,2(r5) / move block number into word 2
 28889                              <1> 			     ; / of I/O queue entry
 28890                              <1> 	; 15/07/2022
 28891 00005AB6 FEC6                <1> 	inc	dh ; dh = 1
 28892                              <1> bufaloc_7: ;1:
 28893 00005AB8 81FE[346C0000]      <1>         cmp	esi, bufp
 28894                              <1> 		; cmp r2,$bufp / bump all entrys in bufp 
 28895                              <1> 			     ; / and put latest assigned
 28896 00005ABE 760B                <1> 	jna	short bufaloc_8	
 28897                              <1>        		; blos 1f / buffer on the top 
 28898                              <1> 			; / (this makes if the lowest priority)
 28899                              <1> 	; 15/07/2022
 28900 00005AC0 89F7                <1> 	mov	edi, esi
 28901 00005AC2 83EE04              <1> 	sub	esi, 4
 28902 00005AC5 8B0E                <1> 	mov	ecx, [esi]
 28903 00005AC7 890F                <1> 	mov	[edi], ecx ; 15/07/2022
 28904                              <1> 	;mov	[esi+4], ecx
 28905                              <1> 		; mov -(r2),2(r2) / job for a particular device
 28906 00005AC9 EBED                <1> 	jmp 	short bufaloc_7
 28907                              <1> 		; br 1b
 28908                              <1> bufaloc_8: ;1:
 28909 00005ACB 891E                <1>         mov	[esi], ebx
 28910                              <1> 		; mov r5,(r2)
 28911                              <1> 	;;pop	esi ; ***
 28912                              <1>        		; mov (sp)+,r2 / restore r2
 28913 00005ACD 08F6                <1>        	or 	dh, dh ; 0 or 1 ?
 28914                              <1> 		; Retro UNIX 8086 v1 modification
 28915                              <1> 		; zf=1 --> block already is in an I/O buffer
 28916                              <1> 		; zf=0 --> a new I/O buffer has been allocated
 28917 00005ACF C3                  <1> 	retn
 28918                              <1> 		; rts r0
 28919                              <1> 
 28920                              <1> diskio:
 28921                              <1> 	; 16/07/2022
 28922                              <1> 	; 12/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28923                              <1> 	; 08/07/2022
 28924                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 28925                              <1> 	;	((simplified and shortened 'diskio.s' code))
 28926                              <1> 	; 12/02/2022
 28927                              <1> 	; 10/02/2022
 28928                              <1> 	; 08/02/2022
 28929                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 28930                              <1> 	; 28/11/2021
 28931                              <1> 	; 10/07/2015
 28932                              <1> 	; 02/07/2015
 28933                              <1> 	; 16/06/2015
 28934                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28935                              <1> 	;	     (80386 protected mode modifications)	
 28936                              <1> 	; 15/03/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 28937                              <1> 	;
 28938                              <1> 	; Retro UNIX 8086 v1 feature only !
 28939                              <1> 	;
 28940                              <1> 	; Derived from proc_chs_read procedure of TRDOS DISKIO.ASM (2011)
 28941                              <1> 	; 04/07/2009 - 20/07/2011
 28942                              <1> 	;
 28943                              <1> 	; NOTE: Reads only 1 block/sector (sector/block size is 512 bytes)
 28944                              <1> 	;
 28945                              <1>         ; INPUTS ->
 28946                              <1> 	; 	   ebx = System I/O Buffer header address
 28947                              <1> 	;
 28948                              <1>         ; OUTPUTS -> cf=0 --> done 
 28949                              <1> 	; 	     cf=1 --> error code in AH
 28950                              <1> 	;	     ; 08/02/2022
 28951                              <1> 	;	     cf=1 & [u.brwdev] = 0FFh -->
 28952                              <1> 	;		error code in [u.error]
 28953                              <1> 	;		
 28954                              <1> 	; (Modified registers: eax, ecx, edx)
 28955                              <1> 	
 28956                              <1> ;rw_disk_sector:
 28957                              <1> 	; 16/07/2022
 28958                              <1> 	; 12/07/2022
 28959                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28960                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 28961                              <1> 	; 12/02/2022
 28962                              <1> 	; 10/02/2022
 28963                              <1> 	; 08/02/2022
 28964                              <1> 	; 28/11/2021
 28965                              <1> 	; 10/07/2015
 28966                              <1> 	; 02/07/2015
 28967                              <1> 	; 11/06/2015 - Retro UNIX 386 v1 - 'u8.s' 
 28968                              <1> 	; 21/02/2015 ('dsectpm.s', 'read_disk_sector')
 28969                              <1> 	; 16/02/2015 (Retro UNIX 386 v1 test - 'unix386.s')
 28970                              <1> 	; 01/12/2014 - 18/01/2015 ('dsectrm2.s')
 28971                              <1> 	;
 28972                              <1> 	;;mov	dx, 0201h ; Read 1 sector/block
 28973                              <1> 	;mov	dh, 2
 28974                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 28975 00005AD0 B602                <1> 	mov	dh, 2 ; Write 1 sector/block
 28976 00005AD2 668B03              <1> 	mov	ax, [ebx] 
 28977                              <1> 	;
 28978 00005AD5 56                  <1> 	push	esi ; ****
 28979 00005AD6 53                  <1> 	push	ebx ; ***
 28980                              <1> 	;
 28981 00005AD7 0FB6C8              <1> 	movzx	ecx, al
 28982                              <1> 	; 28/11/2021
 28983                              <1> 	;mov	ecx, eax
 28984 00005ADA 89CE                <1> 	mov	esi, ecx
 28985                              <1> 	;
 28986 00005ADC 38F1                <1> 	cmp	cl, dh ; 2
 28987 00005ADE 7202                <1> 	jb	short rwdsk0
 28988 00005AE0 047E                <1> 	add	al, 7Eh  ; 80h, 81h, 82h, 83h
 28989                              <1> rwdsk0:
 28990                              <1> 	; 16/07/2022
 28991                              <1> 	; 12/07/2022
 28992                              <1> 	;mov	[drv], al
 28993 00005AE2 81C6[AE620000]      <1> 	add	esi, drv.status
 28994                              <1> 	; 11/06/2015
 28995 00005AE8 803EF0              <1> 	cmp	byte [esi], 0F0h 
 28996 00005AEB 7204                <1> 	jb      short rwdsk1
 28997                              <1> 	; 'drive not ready' error
 28998                              <1> 	; 10/02/2022
 28999                              <1> 	; 08/02/2022
 29000                              <1> 	;mov	byte [u.brwdev], 0FFh ; error code in [u.error]
 29001                              <1> 	;mov	dword [u.error], ERR_DRV_NOT_RDY
 29002                              <1> 	;;jmp	error
 29003                              <1> 	;stc	; cf = 1
 29004                              <1> 	;retn
 29005                              <1> 	; 10/02/2022
 29006 00005AED B10F                <1> 	mov	cl, ERR_DRV_NOT_RDY
 29007 00005AEF EB1F                <1> 	jmp	short rwdsk_err1
 29008                              <1> rwdsk1:
 29009                              <1> 	; 16/07/2022
 29010                              <1> 	;test	ah, 2
 29011                              <1> 	;;test	ax, 200h ; Bit 9 of word 0 (status word)
 29012                              <1> 	;		 ; write bit
 29013                              <1> 	;jz	short rwdsk2
 29014                              <1> 	
 29015                              <1> 	;;test	ah, 4
 29016                              <1> 	;;;test	ax, 400h ; Bit 10 of word 0 (status word)
 29017                              <1> 	;;		 ; read bit
 29018                              <1> 	;;jz	short diskio_ret
 29019                              <1> 
 29020                              <1> 	;inc	dh ; 03h = write
 29021                              <1> 
 29022                              <1> 	; 08/07/2022
 29023 00005AF1 84F4                <1> 	test	ah, dh ; test ah, 2
 29024 00005AF3 7502                <1> 	jnz	short rwdsk2 ; dh = 02h = write
 29025 00005AF5 FECE                <1> 	dec	dh
 29026                              <1> 		; dh = 01h = read
 29027                              <1> rwdsk2:
 29028 00005AF7 88C2                <1> 	mov	dl, al
 29029 00005AF9 83C304              <1> 	add	ebx, 4 ; sector/block address/number pointer
 29030 00005AFC 8B03                <1> 	mov	eax, [ebx] ; sector/block number (LBA)
 29031 00005AFE C0E102              <1> 	shl	cl, 2
 29032 00005B01 81C1[92620000]      <1> 	add	ecx, drv.size ; disk size
 29033 00005B07 3B01                <1> 	cmp	eax, [ecx] ; Last sector + 1 (number of secs.)
 29034 00005B09 7214                <1> 	jb      short rwdsk3
 29035                              <1>  	; 'out of volume' error
 29036                              <1> 	; 10/02/2022
 29037                              <1> 	; 08/02/2022
 29038                              <1> 	;mov	byte [u.brwdev], 0FFh ; error code in [u.error]
 29039                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE
 29040                              <1> 	;;jmp	error
 29041                              <1> 	;stc	; cf = 1
 29042                              <1> 	;retn
 29043                              <1> 	; 10/02/2022
 29044 00005B0B B910000000          <1> 	mov	ecx, ERR_DEV_VOL_SIZE
 29045                              <1> rwdsk_err1:
 29046 00005B10 C605[176D0000]FF    <1> 	mov	byte [u.brwdev], 0FFh
 29047 00005B17 890D[186D0000]      <1> 	mov	[u.error], ecx ; 12/02/2022
 29048 00005B1D EB27                <1> 	jmp	short rwdsk_err2
 29049                              <1> rwdsk3:
 29050                              <1> 	; 11/06/2015
 29051 00005B1F 83C304              <1> 	add	ebx, 4 ; buffer address
 29052 00005B22 C605[3B6D0000]04    <1> 	mov	byte [retry_count], 4
 29053                              <1> 	; 12/07/2022
 29054                              <1> 	;test	byte [esi], 1 ; LBA ready ?
 29055                              <1>         ;jz	short rwdsk_chs
 29056                              <1> rwdsk_lba:
 29057                              <1> 	; LBA read/write (with private LBA function) 
 29058                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 29059 00005B29 83C607              <1>         add     esi, drv.error - drv.status ; 10/07/2015
 29060 00005B2C 89C1                <1> 	mov	ecx, eax ; sector number
 29061                              <1> 	; ebx = buffer (data) address
 29062                              <1> 	; dl = physical drive number (0, 1, 80h, 81h, 82h, 83h)
 29063                              <1> rwdsk_lba_retry:
 29064                              <1> 	;mov	dl, [drv]
 29065                              <1> 		; Function 1Bh = LBA read, 1Ch = LBA write
 29066                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29067                              <1> 	;;mov	ah, 1Ch - 03h ; LBA write function number - 3
 29068                              <1> 	;mov	ah, 2 ; LBA write function number - 2
 29069                              <1> 	;add	ah, dh		
 29070                              <1> 	;mov	al, 1
 29071                              <1> 	;int	13h
 29072                              <1> 	;call	int13h
 29073                              <1> 	; 12/07/2022
 29074 00005B2E 88F0                <1> 	mov	al, dh	; function (1 or 2)
 29075                              <1> 			; (1 = read, 2 = write )
 29076                              <1> 	; ecx = disk sector address (LBA)
 29077                              <1> 	; ebx = buffer address
 29078                              <1> 	;  dl = (physical) disk number
 29079                              <1> 	;  al = function (r/w)
 29080 00005B30 E831C4FFFF          <1> 	call	DISK_IO
 29081                              <1> 
 29082 00005B35 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 29083 00005B37 730E                <1> 	jnc	short rwdsk_lba_ok
 29084 00005B39 80FC80              <1> 	cmp	ah, 80h ; time out ?
 29085 00005B3C 7408                <1>         je      short rwdsk_lba_fails
 29086 00005B3E FE0D[3B6D0000]      <1> 	dec	byte [retry_count]
 29087 00005B44 7504                <1>         jnz     short rwdsk_lba_reset ; 10/07/2015
 29088                              <1> rwdsk_err2:	; 10/02/2022
 29089                              <1> rwdsk_lba_fails:
 29090 00005B46 F9                  <1> 	stc
 29091                              <1> rwdsk_lba_ok:
 29092 00005B47 5B                  <1> 	pop	ebx ; ***
 29093 00005B48 5E                  <1> 	pop	esi ; ****
 29094 00005B49 C3                  <1> 	retn
 29095                              <1> rwdsk_lba_reset:
 29096                              <1> 	;mov	ah, 0Dh ; Alternate reset
 29097                              <1> 	;int	13h
 29098                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29099                              <1> 	;mov	ah, 5 ; Alternate reset	 
 29100                              <1> 	;call	int13h
 29101                              <1> 	;jnc	short rwdsk_lba_retry
 29102                              <1> 	; 12/07/2022
 29103 00005B4A 30C0                <1> 	xor	al, al ; 0 ; reset
 29104 00005B4C E815C4FFFF          <1> 	call	DISK_IO
 29105 00005B51 73DB                <1> 	jnc	short rwdsk_lba_retry
 29106                              <1> 
 29107 00005B53 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 29108 00005B55 EBF0                <1> 	jmp	short rwdsk_lba_ok
 29109                              <1> 
 29110                              <1> 	; 12/07/2022 
 29111                              <1> 	;	(CHS Read/Write setup is not needed here.)
 29112                              <1> 	; 	(LBA address will be converted to CHS parameters 
 29113                              <1> 	;	in 'DISK_IO' procedure when/if it is required.)
 29114                              <1>  
 29115                              <1> ;	; CHS read (convert LBA address to CHS values)	
 29116                              <1> ;rwdsk_chs:
 29117                              <1> ;	; 10/07/2015
 29118                              <1> ;	sub	esi, drv.status
 29119                              <1> ;	mov	ecx, esi
 29120                              <1> ;	add 	esi, drv.error
 29121                              <1> ;	; 02/07/2015
 29122                              <1> ;	; 16/06/2015
 29123                              <1> ;	; 11/06/2015 
 29124                              <1> ;	push	ebx ; ** ; buffer
 29125                              <1> ;	shl	ecx, 1
 29126                              <1> ;	push	ecx ; * 
 29127                              <1> ;	;
 29128                              <1> ;	mov	ebx, ecx
 29129                              <1> ;	mov	[rwdsk], dh ; 02/07/2015
 29130                              <1> ;	xor	edx, edx ; 0
 29131                              <1> ;	; 09/01/2022
 29132                              <1> ;	;sub	ecx, ecx 
 29133                              <1> ;       add     ebx, drv.spt
 29134                              <1> ;	mov	cx, [ebx] ; sector per track
 29135                              <1> ;		; EDX:EAX = LBA
 29136                              <1> ;	div	ecx
 29137                              <1> ;	mov	cl, dl	; sector number - 1
 29138                              <1> ;	inc	cl	; sector number (1 based)
 29139                              <1> ;	pop	ebx ; * ; 11/06/2015
 29140                              <1> ;	;push	cx
 29141                              <1> ;	; 09/01/2022
 29142                              <1> ;	push	ecx
 29143                              <1> ;	add     ebx, drv.heads
 29144                              <1> ;	mov	cx, [ebx] ; heads
 29145                              <1> ;	xor	edx, edx
 29146                              <1> ;		; EAX = cylinders * heads + head
 29147                              <1> ;	div	ecx
 29148                              <1> ;	;pop	cx     ; sector number
 29149                              <1> ;	; 09/01/2022
 29150                              <1> ;	pop	ecx
 29151                              <1> ;	mov	dh, dl ; head number
 29152                              <1> ;	mov	dl, [drv]
 29153                              <1> ;	mov	ch, al ; cylinder (bits 0-7)
 29154                              <1> ;	shl	ah, 6
 29155                              <1> ;	or	cl, ah ; cylinder (bits 8-9)
 29156                              <1> ;		       ; sector (bits 0-7)
 29157                              <1> ;	pop	ebx ; ** ; buffer ; 11/06/2015
 29158                              <1> ;		; CL = sector (bits 0-5)
 29159                              <1> ;		;      cylinder (bits 8-9 -> bits 6-7)
 29160                              <1> ;		; CH = cylinder (bits 0-7)
 29161                              <1> ;		; DH = head
 29162                              <1> ;		; DL = drive
 29163                              <1> ;	;
 29164                              <1> ;	mov	byte [retry_count], 4
 29165                              <1> ;rwdsk_retry:	
 29166                              <1> ;	;mov	ah, [rwdsk] ; 02h = read, 03h = write
 29167                              <1> ;	; 08/07/2022
 29168                              <1> ;	mov	ah, [rwdsk] ; 01h = read, 02h = write
 29169                              <1> ;	mov	al, 1 ; sector count	
 29170                              <1> ;	;int	13h
 29171                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29172                              <1> ;	call	int13h
 29173                              <1> ;	mov	[esi], ah ; error code ; 10/07/2015
 29174                              <1> ;	jnc	short rwdsk_ok ; ah = 0
 29175                              <1> ;	cmp	ah, 80h ; time out ?
 29176                              <1> ;	je	short rwdsk_fails
 29177                              <1> ;	dec	byte [retry_count]
 29178                              <1> ;	jnz	short rwdsk_reset
 29179                              <1> ;rwdsk_fails:
 29180                              <1> ;	stc
 29181                              <1> ;rwdsk_ok:
 29182                              <1> ;	pop	ebx ; ***
 29183                              <1> ;	pop	esi ; ****
 29184                              <1> ;	retn
 29185                              <1> ;rwdsk_reset:
 29186                              <1> ;	; 02/02/2015
 29187                              <1> ;	sub	ah, ah
 29188                              <1> ;	cmp	dl, 80h
 29189                              <1> ;	jb	short rwdsk_fd_reset
 29190                              <1> ;	;mov	ah, 0Dh ; Alternate reset
 29191                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29192                              <1> ;	mov	ah, 5  ; Alternate reset
 29193                              <1> ;rwdsk_fd_reset:
 29194                              <1> ;	;int	13h
 29195                              <1> ;	call	int13h
 29196                              <1> ;	jnc	short rwdsk_retry
 29197                              <1> ;	mov	[esi], ah ; error code ; 10/07/2015
 29198                              <1> ;	jmp 	short rwdsk_ok
 29199                              <1> 
 29200                              <1> ; Original UNIX v1 - drum (& disk) interrupt routine
 29201                              <1> ;	(Equivalent to IRQ 14 & IRQ 15 disk/hardware interrupts)
 29202                              <1> ;
 29203                              <1> ; This feature is not used in Retro UNIX 386 (& 8086) for now.
 29204                              <1> ; Because, current Retro UNIX 386 disk I/O -INT13H- routine is 
 29205                              <1> ; derived from IBM PC AT -infact: XT286- BIOS source code, int 13h
 29206                              <1> ; that uses hardware -transfer has been completed- interrupt inside it. 
 29207                              <1> ; In a next Retro UNIX 386 version, these interrupts
 29208                              <1> ; (fdc_int, hdc1_int, hdc2_int) will be handled by a separate routine
 29209                              <1> ; as in original unix v1.
 29210                              <1> ; I am not removing IBM BIOS source code derivatives -compatible code-
 29211                              <1> ; for now, regarding the new/next 32 bit TRDOS project by me
 29212                              <1> ; (to keep source code files easy adaptable to 32 bit TRDOS.)
 29213                              <1> ;
 29214                              <1> ; Erdogan tan (10/07/2015) 
 29215                              <1> 
 29216                              <1> ;drum: / interrupt handler
 29217                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 29218                              <1> ;       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
 29219                              <1> ;                                      / error
 29220                              <1> ;               br 3f / no, error
 29221                              <1> ;       br      2f / error
 29222                              <1> ;
 29223                              <1> ;disk:
 29224                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 29225                              <1> ;       jmp     *$0f
 29226                              <1> ;0:
 29227                              <1> ;       jsr     r0,trapt; rkcs; rkap; 2
 29228                              <1> ;      	        br 3f / no, errors
 29229                              <1> ;       mov     $115,(r2) / drive reset, errbit was set
 29230                              <1> ;       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
 29231                              <1> ;                        / to 1f
 29232                              <1> ;       br      4f
 29233                              <1> ;1:
 29234                              <1> ;       bit     $20000,rkcs
 29235                              <1> ;       beq     4f / wait for seek complete
 29236                              <1> ;       mov     $0b,0b-2
 29237                              <1> ;       mov     rkap,r1
 29238                              <1> ;2:
 29239                              <1> ;       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
 29240                              <1> ;                          / the disk buffer
 29241                              <1> ;       bne     3f / no, branch ignore error if outstanding
 29242                              <1> ;       inc     r1
 29243                              <1> ;       asr     (r1)
 29244                              <1> ;       asr     (r1)
 29245                              <1> ;       asr     (r1) / reissue request
 29246                              <1> ;       dec     r1
 29247                              <1> ;3:
 29248                              <1> ;       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
 29249                              <1> ;       mov     ac,-(sp)
 29250                              <1> ;       mov     mq,-(sp) / put these on the stack
 29251                              <1> ;       mov     sc,-(sp)
 29252                              <1> ;       jsr     r0,poke
 29253                              <1> ;       mov     (sp)+,sc
 29254                              <1> ;       mov     (sp)+,mq / pop them off stack
 29255                              <1> ;       mov     (sp)+,ac
 29256                              <1> ;4:
 29257                              <1> ;       jmp     retisp / u4-3
 29258                              <1> ;
 29259                              <1> ;trapt:                  / r2 points to the
 29260                              <1> ;       mov     (r0)+,r2 / device control register
 29261                              <1> ;       mov     *(r0)+,r1 / transaction pointer points to buffer
 29262                              <1> ;       tst     (sp)+
 29263                              <1> ;       tstb    (r2) / is ready bit of dcs set?
 29264                              <1> ;       bge     4b / device still active so branch
 29265                              <1> ;       bit     (r0),active / was device busy?
 29266                              <1> ;       beq     4b / no, stray interrupt
 29267                              <1> ;       bic     (r0)+,active / yes, set active to zero
 29268                              <1> ;       tst     (r2) / test the err(bit is) of dcs
 29269                              <1> ;       bge     2f / if no error jump to 2f
 29270                              <1> ;       tst     (r0)+ / skip on error
 29271                              <1> ; 2:
 29272                              <1> ;       jmp     (r0)
 29273                              <1> 
 29274                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatibility code
 29275                              <1> get_system_time:
 29276                              <1> 	; 27/10/2021
 29277                              <1> 	; 21/02/2020 - Retro UNIX 386 v2
 29278                              <1> 	; get system time
 29279                              <1> 	;  (from recent value which is saved in RTC interrupt)
 29280                              <1> 	; Input:
 29281                              <1> 	; 	none
 29282                              <1> 	; Return:
 29283                              <1> 	;   	eax = system time in unix epoch format 
 29284                              <1> 	;
 29285                              <1> 	; Modified registers: eax, ecx, edx
 29286                              <1> 	
 29287                              <1> 	; 27/11/2021
 29288 00005B57 53                  <1> 	push	ebx
 29289 00005B58 E8DDD0FFFF          <1> 	call	epoch
 29290 00005B5D 5B                  <1> 	pop	ebx
 29291 00005B5E C3                  <1> 	retn
 29292                              <1> 	
 29293                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 29294                              <1> 	;  ('get_serial_number' is not used in v1.2 kernel)
 29295                              <1> ;get_serial_number:
 29296                              <1> 	; temporary - 21/02/2020
 29297                              <1> 	; 26/04/2020 (esi)
 29298                              <1> 	; 25/04/2020
 29299                              <1> 	; (Possible) Modified registers: eax, ecx, edx
 29300                              <1> 	; (edi, ebx & esi registers must be preserved)
 29301                              <1> 	; Return:
 29302                              <1> 	; eax = 32 bit serial number  
 29303                              <1> 	; (edx = high 32 bit of 64 bit serial number)
 29304                              <1> 	; -64 bit serial numbers will not be used in RUNIX 386 v2-
 29305                              <1> 	
 29306                              <1> 	;retn
 29307                                  %include 'u9.s'      ; 29/06/2015
 29308                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 29309                              <1> ; (re-write kernel for test by using previous version without a major defect)
 29310                              <1> ; ****************************************************************************
 29311                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.4) - SYS9.INC
 29312                              <1> ; Last Modification: 27/12/2022 (Previous: 08/08/2022)
 29313                              <1> ; ----------------------------------------------------------------------------
 29314                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 29315                              <1> ; (v0.1 - Beginning: 11/07/2012)
 29316                              <1> ;
 29317                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 29318                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 29319                              <1> ; <Bell Laboratories (17/3/1972)>
 29320                              <1> ; <Preliminary Release of UNIX Implementation Document>
 29321                              <1> ;
 29322                              <1> ; Retro UNIX 8086 v1 - U9.ASM (01/09/2014) //// UNIX v1 -> u9.s
 29323                              <1> ;
 29324                              <1> ; ****************************************************************************
 29325                              <1> 
 29326                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - Printer BIOS (Functions)
 29327                              <1> 
 29328                              <1> getch:
 29329                              <1> 	; 30/06/2015
 29330                              <1> 	; 18/02/2015 - Retro UNIX 386 v1 - feature only!
 29331 00005B5F 28C0                <1> 	sub	al, al ; 0
 29332                              <1> getch_q: ; 06/08/2015
 29333 00005B61 8A25[96670000]      <1> 	mov 	ah, [ptty] ; active (current) video page
 29334 00005B67 EB06                <1>         jmp     short getc_n
 29335                              <1> 
 29336                              <1> getc: 
 29337                              <1> 	; 12/11/2015
 29338                              <1> 	; 15/09/2015
 29339                              <1> 	; 01/07/2015
 29340                              <1> 	; 30/06/2015
 29341                              <1> 	; 18/02/2015 (Retro UNIX 386 v1 - Beginning)
 29342                              <1> 	; 13/05/2013 - 04/07/2014 (Retro UNIX 8086 v1)
 29343                              <1> 	;
 29344                              <1> 	; Retro UNIX 8086 v1 modification !
 29345                              <1> 	; 
 29346                              <1> 	; 'getc' gets (next) character 
 29347                              <1> 	;	 from requested TTY (keyboard) buffer 
 29348                              <1> 	; INPUTS ->
 29349                              <1> 	;     [u.ttyn] = tty number (0 to 7) (8 is COM1, 9 is COM2)	
 29350                              <1> 	;     AL=0 -> Get (next) character from requested TTY buffer
 29351                              <1> 	;	(Keyboard buffer will point to 
 29352                              <1> 	;			next character at next call)
 29353                              <1> 	;     AL=1 -> Test a key is available in requested TTY buffer
 29354                              <1> 	;	(Keyboard buffer will point to 
 29355                              <1> 	;			current character at next call)
 29356                              <1> 	; OUTPUTS ->
 29357                              <1> 	;     (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 29358                              <1> 	;     			 ZF=0 -> AX has (current) character
 29359                              <1> 	;      AL = ascii code
 29360                              <1> 	;      AH = scan code	(AH = line status for COM1 or COM2)	 			
 29361                              <1> 	; 		        (cf=1 -> error code/flags in AH)
 29362                              <1> 	; Original UNIX V1 'getc': 
 29363                              <1> 	;		get a character off character list
 29364                              <1> 	;
 29365                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))	
 29366                              <1> 	;
 29367                              <1> 	; 30/06/2015 (32 bit modifications)
 29368                              <1> 	; 16/07/2013
 29369                              <1> 	; mov 	[getctty], ah
 29370                              <1> 	;
 29371                              <1> 
 29372 00005B69 8A25[D96C0000]      <1> 	mov	ah, [u.ttyn] 	; 28/07/2013
 29373                              <1> getc_n:
 29374                              <1> 	; 30/06/2015
 29375 00005B6F 08E4                <1> 	or	ah, ah
 29376 00005B71 740D                <1> 	jz	short getc0 
 29377 00005B73 D0E4                <1> 	shl	ah, 1
 29378 00005B75 0FB6DC              <1> 	movzx	ebx, ah
 29379 00005B78 81C3[98670000]      <1> 	add	ebx, ttychr
 29380 00005B7E EB05                <1> 	jmp	short getc1
 29381                              <1> getc0:
 29382 00005B80 BB[98670000]        <1> 	mov	ebx, ttychr
 29383                              <1> getc1:
 29384 00005B85 668B0B              <1> 	mov	cx, [ebx] 	; ascii & scan code
 29385                              <1> 				; (by kb_int)	
 29386 00005B88 6609C9              <1> 	or	cx, cx
 29387 00005B8B 7507                <1> 	jnz	short getc2
 29388 00005B8D 20C0                <1> 	and 	al, al
 29389 00005B8F 7415                <1> 	jz	short getc_s
 29390                              <1> 	;xor	ax, ax
 29391                              <1> 	; 30/11/2021
 29392 00005B91 31C0                <1> 	xor	eax, eax
 29393 00005B93 C3                  <1> 	retn
 29394                              <1> getc2:	
 29395 00005B94 20C0                <1> 	and	al, al
 29396 00005B96 6689C8              <1> 	mov	ax, cx
 29397 00005B99 66B90000            <1> 	mov	cx, 0
 29398 00005B9D 7506                <1> 	jnz	short getc3
 29399                              <1> getc_sn:
 29400 00005B9F 66890B              <1> 	mov	[ebx], cx ; 0, reset
 29401 00005BA2 6639C8              <1> 	cmp	ax, cx  ; zf = 0
 29402                              <1> getc3:
 29403 00005BA5 C3                  <1> 	retn
 29404                              <1> getc_s:
 29405                              <1> 	; 12/11/2015
 29406                              <1> 	; 15/09/2015
 29407                              <1> 	; 01/07/2015
 29408                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 29409                              <1> 	; 16/07/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 29410                              <1> 	;
 29411                              <1> 	; tty  of the current process is not 
 29412                              <1> 	; current tty (ptty); so, current process only 
 29413                              <1> 	; can use keyboard input when its tty becomes 
 29414                              <1> 	; current tty (ptty).
 29415                              <1> 	; 'sleep' is for preventing an endless lock
 29416                              <1> 	; during this tty input request.
 29417                              <1> 	; (Because, the user is not looking at the video page
 29418                              <1> 	; of the process to undersand there is a keyboard
 29419                              <1> 	; input request.)
 29420                              <1> 	;
 29421                              <1> 	;((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 29422                              <1> 	;
 29423                              <1> 	; 05/10/2013
 29424                              <1> 	; ah = byte ptr [u.ttyn] ; (tty number)
 29425                              <1> 	;
 29426                              <1> 	; 10/10/2013
 29427                              <1> gcw0:
 29428 00005BA6 B10A                <1> 	mov	cl, 10 ; ch = 0
 29429                              <1> gcw1:	
 29430                              <1> 	; 12/11/2015
 29431 00005BA8 E8C5D6FFFF          <1> 	call intract ; jumps to 'sysexit' if [u.quit] = FFFFh
 29432                              <1> 	; 10/10/2013
 29433 00005BAD E841EBFFFF          <1> 	call	idle
 29434 00005BB2 668B03              <1> 	mov	ax, [ebx] 	; ascii & scan code
 29435                              <1> 				; (by kb_int)
 29436 00005BB5 6609C0              <1> 	or	ax, ax
 29437                              <1> ;	jnz	short gcw3
 29438 00005BB8 7519                <1> 	jnz	short gcw2 ; 15/09/2015
 29439                              <1> 	; 30/06/2015
 29440 00005BBA FEC9                <1> 	dec	cl
 29441 00005BBC 75EA                <1> 	jnz	short gcw1
 29442                              <1> 	;
 29443 00005BBE 8A25[D96C0000]      <1> 	mov	ah, [u.ttyn] 	; 20/10/2013
 29444                              <1> ;	; 10/12/2013
 29445                              <1> ;	cmp 	ah, [ptty]
 29446                              <1> ;	jne	short gcw2
 29447                              <1> ;	; 14/02/2014
 29448                              <1> ;	cmp	byte [u.uno], 1
 29449                              <1> ;	jna	short gcw0		
 29450                              <1> ;gcw2:
 29451 00005BC4 E8B7EBFFFF          <1> 	call	sleep
 29452                              <1> 	;
 29453                              <1> 	; 20/09/2013
 29454 00005BC9 8A25[D96C0000]      <1> 	mov	ah, [u.ttyn]
 29455 00005BCF 30C0                <1> 	xor 	al, al
 29456 00005BD1 EB9C                <1> 	jmp	short getc_n
 29457                              <1> ;gcw3:
 29458                              <1> gcw2: 	; 15/09/2015
 29459                              <1> 	; 10/10/2013
 29460 00005BD3 30C9                <1> 	xor	cl, cl
 29461 00005BD5 EBC8                <1> 	jmp	short getc_sn
 29462                              <1> 
 29463                              <1> putc:	
 29464                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 29465                              <1> 	; 13/08/2015
 29466                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 29467                              <1> 	; 15/05/2013 - 27/07/2014 (Retro UNIX 8086 v1)
 29468                              <1> 	;
 29469                              <1> 	; Retro UNIX 8086 v1 modification !
 29470                              <1> 	; 
 29471                              <1> 	; 'putc' puts a character 
 29472                              <1> 	;	 onto requested (tty) video page or
 29473                              <1> 	;	 serial port
 29474                              <1> 	; INPUTS ->
 29475                              <1> 	;     AL = ascii code of the character
 29476                              <1> 	;     AH = video page (tty) number (0 to 7)
 29477                              <1> 	;			  (8 is COM1, 9 is COM2)	
 29478                              <1> 	; OUTPUTS ->
 29479                              <1> 	;    (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 29480                              <1> 	;      			ZF=0 -> AX has (current) character
 29481                              <1> 	;     cf=0 and AH = 0 -> no error
 29482                              <1> 	;     cf=1 and AH > 0 -> error (only for COM1 and COM2)
 29483                              <1> 	; 
 29484                              <1> 	; Original UNIX V1 'putc': 
 29485                              <1> 	;     put a character at the end of character list
 29486                              <1> 	;
 29487                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 29488                              <1> 	;
 29489 00005BD7 80FC07              <1> 	cmp	ah, 7
 29490 00005BDA 770A                <1>         ja      short sndc ; 05/12/2021
 29491                              <1> 	; 30/06/2015
 29492 00005BDC 0FB6DC              <1> 	movzx	ebx, ah
 29493                              <1> 	; 13/08/2015
 29494 00005BDF B407                <1> 	mov	ah, 07h ; black background, light gray character color
 29495 00005BE1 E9CEB6FFFF          <1> 	jmp	write_tty ; 'video.inc'
 29496                              <1> 
 29497                              <1> sndc:   ; <Send character>
 29498                              <1> 	;
 29499                              <1> 	; 12/01/2022
 29500                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 29501                              <1> 	; 17/11/2015
 29502                              <1> 	; 16/11/2015
 29503                              <1> 	; 11/11/2015
 29504                              <1> 	; 10/11/2015
 29505                              <1> 	; 09/11/2015
 29506                              <1> 	; 08/11/2015
 29507                              <1> 	; 07/11/2015
 29508                              <1> 	; 06/11/2015 (serial4.asm, 'sendchr')	
 29509                              <1> 	; 29/10/2015
 29510                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 29511                              <1> 	; 14/05/2013 - 28/07/2014 (Retro UNIX 8086 v1)
 29512                              <1> 	;
 29513                              <1> 	; Retro UNIX 8086 v1 feature only !
 29514                              <1> 	;
 29515                              <1> 	; ah = [u.ttyn]
 29516                              <1> 	;
 29517                              <1> 	; 30/06/2015
 29518 00005BE6 80EC08              <1> 	sub	ah, 8 ; ; 0 = tty8 or 1 = tty9
 29519                              <1> 	; 07/11/2015
 29520 00005BE9 0FB6DC              <1> 	movzx	ebx, ah ; serial port index (0 or 1)
 29521                              <1> sndc0:
 29522                              <1> 	; 07/11/2015
 29523 00005BEC E8DDEBFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 29524 00005BF1 7405                <1> 	jz	short sndc1
 29525 00005BF3 E87AD6FFFF          <1> 	call	intract ; quit (ctrl+break) check
 29526                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 29527                              <1> sndc1:
 29528                              <1> 	; 16/11/2015
 29529                              <1> 	;mov	cx, ax	; *** al = character (to be sent)
 29530                              <1> 	; 24/12/2021
 29531 00005BF8 89C1                <1> 	mov	ecx, eax ; *** al = character (to be sent)
 29532                              <1> sndcx:
 29533 00005BFA 8A83[DA670000]      <1> 	mov	al, [ebx+schar] ; last sent character
 29534 00005C00 8AA3[D8670000]      <1> 	mov	ah, [ebx+rchar] ; last received character
 29535                              <1> 	;
 29536                              <1> 	; 17/11/2015
 29537                              <1> 	; check 'request for response' status
 29538 00005C06 80BB[D4670000]00    <1> 	cmp	byte [ebx+req_resp], 0
 29539 00005C0D 740A                <1> 	jz	short query
 29540                              <1> response:
 29541 00005C0F FE05[D7670000]      <1> 	inc 	byte [comqr] ; query or response status
 29542 00005C15 B0FF                <1> 	mov	al, 0FFh	 
 29543 00005C17 EB14                <1> 	jmp	short sndc3
 29544                              <1> query:
 29545 00005C19 08C0                <1> 	or 	al, al  ; 0 = query (also end of text)
 29546 00005C1B 750E                <1> 	jnz 	short sndc2 ; normal character
 29547                              <1> 	;cmp 	ah, 0FFh     ; is it responded by terminal ?
 29548                              <1> 	;je	short sndc2  ; yes, already responded
 29549                              <1> 	; 16/11/2015
 29550                              <1> 	; query: request for response (again)
 29551 00005C1D 8883[D8670000]      <1> 	mov	[ebx+rchar], al ; 0 ; reset
 29552 00005C23 FE05[D7670000]      <1> 	inc 	byte [comqr] ; query or response status
 29553 00005C29 EB02                <1> 	jmp	short sndc3
 29554                              <1> sndc2:
 29555 00005C2B 88C8                <1> 	mov	al, cl 	; *** character (to be sent)
 29556                              <1> sndc3:
 29557 00005C2D 8883[DA670000]      <1> 	mov	[ebx+schar], al ; current character (to be sent)
 29558 00005C33 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 29559                              <1> 	; 30/06/2015
 29560 00005C35 E865CFFFFF          <1> 	call	sp_status ; get serial port status
 29561                              <1> 	; AL = Line status, AH = Modem status
 29562                              <1> 	; 07/11/2015
 29563 00005C3A A880                <1> 	test	al, 80h
 29564 00005C3C 7504                <1> 	jnz	short sndc4
 29565 00005C3E A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 29566 00005C40 751A                <1> 	jnz	short sndc5
 29567                              <1> sndc4: 	; Check line status again
 29568                              <1> 	; 16/11/2015
 29569                              <1> 	;push	cx
 29570                              <1> 	; 24/12/2021
 29571 00005C42 51                  <1> 	push	ecx
 29572                              <1> 	;mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 29573                              <1> 	; 12/01/2022
 29574 00005C43 31C9                <1> 	xor	ecx, ecx
 29575 00005C45 B106                <1> 	mov	cl, 6
 29576 00005C47 E85FB7FFFF          <1> 	call	WAITF
 29577                              <1> 	;pop	cx
 29578                              <1> 	; 24/12/1021
 29579 00005C4C 59                  <1> 	pop	ecx
 29580                              <1> 	;
 29581 00005C4D 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 29582 00005C4F E84BCFFFFF          <1> 	call	sp_status ; get serial port status
 29583                              <1> 	; 16/11/2015
 29584                              <1> 	; 09/11/2015
 29585                              <1> 	; 08/11/2015
 29586 00005C54 A880                <1> 	test	al, 80h	; time out error
 29587 00005C56 7565                <1>         jnz     short sndc7
 29588 00005C58 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 29589 00005C5A 7461                <1>         jz	short sndc7
 29590                              <1> sndc5:  
 29591 00005C5C 8A83[DA670000]      <1> 	mov	al, [ebx+schar] ; character (to be sent)
 29592 00005C62 66BAF803            <1> 	mov	dx, 3F8h   ; data port (COM2)
 29593 00005C66 28DE                <1> 	sub	dh, bl
 29594 00005C68 EE                  <1> 	out	dx, al	   ; send on serial port
 29595                              <1> 	; 10/11/2015
 29596                              <1> 	; delay for 3*30 (3*(15..80)) micro seconds
 29597                              <1> 	; (to improve text flow to the terminal)
 29598                              <1> 	; ('diskette.inc': 'WAITF')
 29599                              <1> 	; Uses port 61h, bit 4 to have CPU speed independent waiting.
 29600                              <1> 	; (refresh periods = 1 per 30 microseconds on most machines)
 29601                              <1> 	;push	cx
 29602                              <1> 	; 24/12/2021
 29603 00005C69 51                  <1> 	push	ecx
 29604                              <1> 	;mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 29605                              <1> 	; 12/01/2022
 29606 00005C6A 29C9                <1> 	sub	ecx, ecx
 29607 00005C6C B106                <1> 	mov	cl, 6
 29608 00005C6E E838B7FFFF          <1> 	call	WAITF
 29609                              <1> 	;pop	cx
 29610                              <1> 	; 24/12/1021
 29611 00005C73 59                  <1> 	pop	ecx
 29612                              <1>     	;
 29613                              <1> 	; 07/11/2015
 29614 00005C74 88D8                <1> 	mov	al, bl ; al = 0 (tty8) or 1 (tty9)
 29615                              <1> 	;
 29616 00005C76 E824CFFFFF          <1> 	call	sp_status ; get serial port status
 29617                              <1> 	; AL = Line status, AH = Modem status
 29618                              <1> 	;
 29619 00005C7B E84EEBFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 29620 00005C80 7405                <1> 	jz	short sndc6
 29621 00005C82 E8EBD5FFFF          <1> 	call	intract ; quit (ctrl+break) check
 29622                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 29623                              <1> sndc6:
 29624 00005C87 3C80                <1> 	cmp	al, 80h
 29625 00005C89 7332                <1> 	jnb	short sndc7		
 29626                              <1> 	;
 29627 00005C8B 803D[D7670000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 29628 00005C92 7244                <1> 	jb	short sndc8 	; no, normal character
 29629 00005C94 883D[D7670000]      <1> 	mov 	byte [comqr], bh ; 0 ; reset
 29630                              <1> 	; 17/11/2015
 29631 00005C9A E854EAFFFF          <1> 	call	idle
 29632                              <1> 	;
 29633 00005C9F 38BB[DA670000]      <1> 	cmp	[ebx+schar], bh ; 0 ; query ?
 29634                              <1>         ;ja	sndc2       ; response (will be followed by
 29635                              <1> 			    ; a normal character)
 29636                              <1> 	; 24/12/2021
 29637 00005CA5 7602                <1> 	jna	short sndc_10
 29638 00005CA7 EB82                <1> 	jmp	sndc2
 29639                              <1> sndc_10:
 29640                              <1> 	; Query request must be responded by the terminal
 29641                              <1> 	; before sending a normal character !
 29642 00005CA9 53                  <1> 	push	ebx
 29643                              <1> 	;push	cx ; *** cl = character (to be sent)
 29644                              <1> 	; 24/12/2021
 29645 00005CAA 51                  <1> 	push	ecx ; *** cl = character (to be sent)
 29646 00005CAB 8A25[D96C0000]      <1> 	mov	ah, [u.ttyn]
 29647 00005CB1 E8CAEAFFFF          <1> 	call	sleep ; this process will be awakened by
 29648                              <1> 		      ; received data available interrupt
 29649                              <1> 	;pop	cx ; *** cl = character (to be sent)
 29650                              <1> 	; 24/12/2021
 29651 00005CB6 59                  <1> 	pop	ecx ; *** cl = character (to be sent) 
 29652 00005CB7 5B                  <1> 	pop	ebx
 29653 00005CB8 E93DFFFFFF          <1>         jmp	sndcx
 29654                              <1> sndc7:
 29655                              <1> 	 ; 16/11/2015
 29656 00005CBD 803D[D7670000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 29657 00005CC4 7213                <1> 	jb	short sndc9 	; no
 29658                              <1> 	;
 29659 00005CC6 88BB[D8670000]      <1> 	mov	[ebx+rchar], bh ; 0 ; reset
 29660 00005CCC 88BB[DA670000]      <1> 	mov	[ebx+schar], bh ; 0 ; reset
 29661                              <1> 	;
 29662 00005CD2 883D[D7670000]      <1> 	mov	byte [comqr], bh ; 0 ; reset  
 29663                              <1> sndc8:
 29664 00005CD8 F5                  <1> 	cmc  ; jnc -> jc, jb -> jnb
 29665                              <1> sndc9:
 29666                              <1> 	; AL = Line status, AH = Modem status
 29667 00005CD9 C3                  <1> 	retn
 29668                              <1> 
 29669                              <1> get_cpos:
 29670                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 29671                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 29672                              <1> 	;
 29673                              <1> 	; INPUT -> bl = video page number
 29674                              <1> 	; RETURN -> dx = cursor position
 29675                              <1> 
 29676 00005CDA 53                  <1> 	push	ebx
 29677 00005CDB 83E30F              <1> 	and	ebx, 0Fh ; 07h ; tty0 to tty7
 29678 00005CDE D0E3                <1> 	shl	bl, 1
 29679 00005CE0 81C3[86670000]      <1> 	add	ebx, cursor_posn
 29680 00005CE6 668B13              <1> 	mov	dx, [ebx]
 29681 00005CE9 5B                  <1> 	pop	ebx
 29682 00005CEA C3                  <1> 	retn
 29683                              <1> 
 29684                              <1> read_ac_current:
 29685                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 29686                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 29687                              <1> 	;
 29688                              <1> 	; INPUT -> bl = video page number
 29689                              <1> 	; RETURN -> ax = character (al) and attribute (ah)
 29690                              <1> 
 29691 00005CEB E82AB7FFFF          <1> 	call 	find_position ; 'video.inc'
 29692                              <1> 	; dx = status port
 29693                              <1> 	; esi = cursor location/address
 29694 00005CF0 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
 29695 00005CF6 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
 29696 00005CF9 C3                  <1> 	retn
 29697                              <1> 
 29698                              <1> syssleep:
 29699                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
 29700                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
 29701                              <1> 	;
 29702                              <1> 	; Retro UNIX 8086 v1 feature only
 29703                              <1> 	; (INPUT -> none)
 29704                              <1> 	;
 29705 00005CFA 0FB61D[F56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 29706 00005D01 8AA3[A3680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 29707 00005D07 E874EAFFFF          <1> 	call	sleep
 29708 00005D0C E974D4FFFF          <1> 	jmp	sysret
 29709                              <1> 
 29710                              <1> vp_clr:
 29711                              <1> 	; Reset/Clear Video Page
 29712                              <1> 	;
 29713                              <1> 	; 05/12/2021 - (Retro UNIX 386 v1.2)
 29714                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
 29715                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
 29716                              <1> 	;
 29717                              <1> 	; Retro UNIX 8086 v1 feature only !
 29718                              <1> 	;
 29719                              <1> 	; INPUTS -> 
 29720                              <1> 	;   BL = video page number	 
 29721                              <1> 	;
 29722                              <1> 	; OUTPUT ->
 29723                              <1> 	;   none
 29724                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
 29725                              <1> 	;
 29726                              <1> 	; 04/12/2013
 29727 00005D11 28C0                <1> 	sub	al, al
 29728                              <1> 	; al = 0 (clear video page)
 29729                              <1> 	; bl = video page
 29730 00005D13 B407                <1> 	mov	ah, 07h
 29731                              <1> 	; ah = 7 (attribute/color)
 29732                              <1> 	;xor 	cx, cx ; 0, left upper column (cl) & row (cl)
 29733                              <1> 	; 05/12/2021
 29734 00005D15 31C9                <1> 	xor	ecx, ecx
 29735 00005D17 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
 29736 00005D1B E824B7FFFF          <1> 	call	scroll_up
 29737                              <1> 	; bl = video page
 29738                              <1> 	;xor	dx, dx ; 0 (cursor position) 
 29739                              <1> 	; 05/12/2021
 29740 00005D20 31D2                <1> 	xor	edx, edx
 29741 00005D22 E997B6FFFF          <1> 	jmp 	set_cpos
 29742                              <1> 
 29743                              <1> sysmsg:
 29744                              <1> 	; 11/12/2021
 29745                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 29746                              <1> 	; 11/11/2015
 29747                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
 29748                              <1> 	; Print user-application message on user's console tty
 29749                              <1> 	;
 29750                              <1> 	; Input -> EBX = Message address
 29751                              <1> 	;	   ECX = Message length (max. 255)
 29752                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
 29753                              <1> 	;
 29754 00005D27 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
 29755                              <1> 	;ja	sysret ; nothing to do with big message size
 29756 00005D2D 7779                <1> 	ja	short sysmsg8 ; 11/12/2021
 29757 00005D2F 08C9                <1> 	or	cl, cl
 29758                              <1> 	;jz	sysret
 29759 00005D31 7475                <1> 	jz	short sysmsg8 ; 11/12/2021
 29760 00005D33 20D2                <1> 	and	dl, dl
 29761 00005D35 7502                <1> 	jnz	short sysmsg0
 29762 00005D37 B207                <1> 	mov	dl, 07h ; default color
 29763                              <1> 		; (black background, light gray character)
 29764                              <1> sysmsg0:
 29765 00005D39 891D[C86C0000]      <1> 	mov	[u.base], ebx
 29766 00005D3F 8815[97670000]      <1> 	mov	[ccolor], dl ; color attributes
 29767 00005D45 89E5                <1> 	mov	ebp, esp
 29768 00005D47 31DB                <1> 	xor	ebx, ebx ; 0
 29769 00005D49 891D[D06C0000]      <1> 	mov	[u.nread], ebx ; 0
 29770                              <1> 	;
 29771 00005D4F 381D[166D0000]      <1> 	cmp	[u.kcall], bl ; 0
 29772 00005D55 7772                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
 29773                              <1> 	;
 29774 00005D57 890D[CC6C0000]      <1> 	mov	[u.count], ecx
 29775 00005D5D 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ ; 04/12/2021
 29776                              <1> 	; 04/12/2021
 29777                              <1> 	; (dword alignment for esp)
 29778 00005D5E F6C103              <1> 	test	cl, 3
 29779 00005D61 7404                <1> 	jz	short sysmsg_7
 29780 00005D63 80C903              <1> 	or	cl, 3
 29781 00005D66 41                  <1> 	inc	ecx
 29782                              <1> sysmsg_7:
 29783 00005D67 29CC                <1> 	sub	esp, ecx
 29784 00005D69 89E7                <1> 	mov	edi, esp
 29785 00005D6B 89E6                <1> 	mov	esi, esp
 29786 00005D6D 66891D[106D0000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
 29787                              <1> 	; 11/11/2015 
 29788 00005D74 8A25[DA6C0000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
 29789                              <1> 	; 0 = none
 29790 00005D7A FECC                <1> 	dec	ah
 29791 00005D7C 790C                <1> 	jns	short sysmsg1 
 29792 00005D7E 8A1D[F56C0000]      <1> 	mov	bl, [u.uno] ; process number	
 29793 00005D84 8AA3[A3680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
 29794                              <1> sysmsg1:
 29795 00005D8A 8825[D96C0000]      <1> 	mov	[u.ttyn], ah
 29796                              <1> sysmsg2:
 29797 00005D90 E898F5FFFF          <1> 	call	cpass
 29798 00005D95 7416                <1> 	jz	short sysmsg5
 29799 00005D97 AA                  <1> 	stosb
 29800 00005D98 20C0                <1> 	and	al, al
 29801 00005D9A 75F4                <1> 	jnz	short sysmsg2
 29802                              <1> sysmsg3:
 29803 00005D9C 80FC07              <1> 	cmp	ah, 7 ; tty number
 29804 00005D9F 7711                <1> 	ja	short sysmsg6 ; serial port
 29805 00005DA1 E83E000000          <1> 	call	print_cmsg
 29806                              <1> sysmsg4:
 29807 00005DA6 89EC                <1> 	mov	esp, ebp
 29808                              <1> sysmsg8: ; 11/12/2021	
 29809 00005DA8 E9D8D3FFFF          <1> 	jmp	sysret
 29810                              <1> sysmsg5:
 29811 00005DAD C60700              <1> 	mov	byte [edi], 0
 29812 00005DB0 EBEA                <1> 	jmp	short sysmsg3
 29813                              <1> sysmsg6:
 29814 00005DB2 8A06                <1> 	mov	al, [esi]
 29815 00005DB4 E82DFEFFFF          <1> 	call	sndc
 29816 00005DB9 72EB                <1> 	jc	short sysmsg4
 29817 00005DBB 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
 29818 00005DBE 76E6                <1> 	jna	short sysmsg4
 29819 00005DC0 46                  <1> 	inc 	esi
 29820 00005DC1 8A25[D96C0000]      <1> 	mov	ah, [u.ttyn]
 29821 00005DC7 EBE9                <1> 	jmp	short sysmsg6
 29822                              <1> 
 29823                              <1> sysmsgk: ; Temporary (01/07/2015)
 29824                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
 29825                              <1> 	; (ECX -character count- will not be considered)
 29826 00005DC9 8B35[C86C0000]      <1> 	mov	esi, [u.base]
 29827 00005DCF 8A25[96670000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
 29828 00005DD5 8825[D96C0000]      <1> 	mov	[u.ttyn], ah
 29829 00005DDB C605[166D0000]00    <1> 	mov	byte [u.kcall], 0
 29830 00005DE2 EBB8                <1> 	jmp	short sysmsg3
 29831                              <1> 	
 29832                              <1> print_cmsg: 
 29833                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
 29834                              <1> 	;
 29835                              <1> 	; print message (on user's console tty) 
 29836                              <1> 	;	with requested color
 29837                              <1> 	;
 29838                              <1> 	; INPUTS:
 29839                              <1> 	;	esi = message address
 29840                              <1> 	;	[u.ttyn] = tty number (0 to 7)
 29841                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
 29842                              <1> 	;
 29843 00005DE4 AC                  <1> 	lodsb
 29844                              <1> pcmsg1:
 29845 00005DE5 56                  <1> 	push 	esi
 29846 00005DE6 0FB61D[D96C0000]    <1>         movzx   ebx, byte [u.ttyn]
 29847 00005DED 8A25[97670000]      <1> 	mov	ah, [ccolor]
 29848 00005DF3 E8BCB4FFFF          <1> 	call 	write_tty
 29849 00005DF8 5E                  <1> 	pop	esi
 29850 00005DF9 AC                  <1> 	lodsb
 29851 00005DFA 20C0                <1> 	and 	al, al  ; 0
 29852 00005DFC 75E7                <1> 	jnz 	short pcmsg1
 29853 00005DFE C3                  <1> 	retn
 29854                              <1> 
 29855                              <1> sysgeterr:
 29856                              <1> 	; 16/02/2022 - Retro UNIX 386 v1.2
 29857                              <1> 	; 09/12/2015
 29858                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
 29859                              <1> 	; Get last error number or page fault count
 29860                              <1> 	; (for debugging)
 29861                              <1> 	;
 29862                              <1> 	; Input -> EBX = return type
 29863                              <1> 	;	   0 = last error code (which is in 'u.error')	
 29864                              <1> 	;	   FFFFFFFFh = page fault count for running process
 29865                              <1> 	;	   FFFFFFFEh = total page fault count
 29866                              <1> 	;	   1 .. FFFFFFFDh = undefined 
 29867                              <1> 	;
 29868                              <1> 	; Output -> EAX = last error number or page fault count
 29869                              <1> 	;	   (depending on EBX input)
 29870                              <1> 	; 	
 29871 00005DFF 21DB                <1> 	and 	ebx, ebx
 29872 00005E01 750F                <1> 	jnz	short glerr_2
 29873                              <1> glerr_0:
 29874 00005E03 A1[186D0000]        <1> 	mov	eax, [u.error]
 29875                              <1> glerr_1:
 29876                              <1> getmem_ret:	; 27/12/2022
 29877 00005E08 A3[A46C0000]        <1> 	mov	[u.r0], eax
 29878                              <1> 	;retn
 29879                              <1>  	; 16/02/2022 (BugFix)
 29880 00005E0D E973D3FFFF          <1> 	jmp	sysret
 29881                              <1> glerr_2:
 29882 00005E12 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
 29883 00005E13 74FD                <1> 	jz	short glerr_2 ; page fault count for process
 29884 00005E15 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
 29885 00005E16 75EB                <1> 	jnz	short glerr_0
 29886 00005E18 A1[1C680000]        <1> 	mov	eax, [PF_Count] ; total page fault count
 29887 00005E1D EBE9                <1>         jmp     short glerr_1
 29888                              <1> glerr_3:
 29889 00005E1F A1[1C6D0000]        <1> 	mov 	eax, [u.pfcount]
 29890 00005E24 EBE2                <1> 	jmp	short glerr_1
 29891                              <1> 
 29892                              <1> sysmemory:
 29893                              <1> 	; 27/12/2022 - Retro UNIX 386 v1.2 feature only! 
 29894                              <1> 	; Get available (total or free) memory in pages
 29895                              <1> 	;
 29896                              <1> 	; Input -> EBX = return type
 29897                              <1> 	;	     0 = return total memory in pages (in eax)
 29898                              <1> 	;	     1 = return free memory in pages (in eax)
 29899                              <1> 	;	    >1 is invalid	
 29900                              <1> 	;
 29901                              <1> 	; Output -> EAX = available memory in pages (4096 bytes)
 29902                              <1> 	;	   (depending on EBX input)
 29903                              <1> 	; 	
 29904 00005E26 4B                  <1> 	dec	ebx
 29905 00005E27 780E                <1> 	js	short get_total_memory ; ebx = 0 -> -1
 29906 00005E29 7413                <1> 	jz	short get_free_memory  ; ebx = 1 -> 0
 29907                              <1> 
 29908                              <1> 	; invalid_memory_option (ebx input value > 1)
 29909 00005E2B B001                <1> 	mov	al, 1
 29910                              <1> 	; eax = ERR_INV_FUNC ; = 1 
 29911                              <1> 		; 'invalid system call (or function) !'
 29912 00005E2D A3[186D0000]        <1> 	mov	[u.error], eax
 29913 00005E32 E92ED3FFFF          <1> 	jmp	error
 29914                              <1> 
 29915                              <1> get_total_memory:
 29916 00005E37 A1[6C670000]        <1> 	mov	eax, [memory_size]
 29917                              <1> ;getmem_ret:
 29918                              <1> 	;mov	[u.r0], eax
 29919                              <1> 	;jmp	sysret
 29920 00005E3C EBCA                <1> 	jmp	short getmem_ret
 29921                              <1> 
 29922                              <1> get_free_memory:
 29923                              <1> 	; (! debugging !)
 29924 00005E3E E8DAB7FFFF          <1> 	call	calc_free_mem	; re-calculate free memory (without setting)
 29925                              <1> 	; edx = calculated free pages
 29926 00005E43 A1[70670000]        <1> 	mov	eax, [free_pages] ; compare with the system's set value
 29927 00005E48 39D0                <1> 	cmp	eax, edx
 29928 00005E4A 74BC                <1> 	je	short getmem_ret  ; they are same, good !
 29929                              <1> 	; something has gone wrong !?	
 29930                              <1> 	; reset free pages and first free page search start value
 29931 00005E4C 8915[70670000]      <1> 	mov	[free_pages], edx ; memory allocation procedure uses this
 29932 00005E52 8B15[7C670000]      <1> 	mov	edx, [first_page] ; start (initial) value for mem allocation
 29933                              <1> 				  ; (the 1st available page -init- for user)
 29934 00005E58 8915[74670000]      <1> 	mov	[next_page], edx ; 1st free memory page search proc uses this
 29935 00005E5E EBA8                <1> 	jmp	short getmem_ret	
 29936                              <1> 
 29937                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - PRINTER BIOS (Functions)		
 29938                              <1> 
 29939                              <1> ;;; IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985 ;;; 
 29940                              <1> ;
 29941                              <1> ;--- INT 17 H ------------------------------------------------------------------
 29942                              <1> ; PRINTER_IO								       :
 29943                              <1> ;	THIS ROUTINE PROVIDES COMMUNICATION WITH THE PRINTER		       :
 29944                              <1> ; INPUT 								       :
 29945                              <1> ;	(AH)= 00H  PRINT THE CHARACTER IN (AL)				       :
 29946                              <1> ;		    ON RETURN, (AH)= 1 IF CHARACTER NOT BE PRINTED (TIME OUT)  :
 29947                              <1> ;		    OTHER BITS SET AS ON NORMAL STATUS CALL		       :
 29948                              <1> ;	(AH)= 01H  INITIALIZE THE PRINTER PORT				       :
 29949                              <1> ;		    RETURNS WITH (AH) SET WITH PRINTER STATUS		       :
 29950                              <1> ;	(AH)= 02H  READ THE PRINTER STATUS INTO (AH)			       :
 29951                              <1> ;		   7	   6	   5	   4	   3	   2-1	   0	       :
 29952                              <1> ;		   |	   |	   |	   |	   |	   |	   |_TIME OUT  :
 29953                              <1> ;		   |	   |	   |	   |	   |	   |		       :
 29954                              <1> ;		   |	   |	   |	   |	   |	   |_ UNUSED	       :
 29955                              <1> ;		   |	   |	   |	   |	   |			       :
 29956                              <1> ;		   |	   |	   |	   |	   |_ 1 = I/O ERROR	       :
 29957                              <1> ;		   |	   |	   |	   |				       :
 29958                              <1> ;		   |	   |	   |	   |_ 1 = SELECTED		       :
 29959                              <1> ;		   |	   |	   |					       :
 29960                              <1> ;		   |	   |	   |_ 1 = OUT OF PAPER			       :
 29961                              <1> ;		   |	   |						       :
 29962                              <1> ;		   |	   |_ 1 = ACKNOWLEDGE				       :
 29963                              <1> ;		   |							       :
 29964                              <1> ;		   |_ 1 = NOT BUSY					       :
 29965                              <1> ;									       :
 29966                              <1> ;	(DX) = PRINTER TO BE USED (0,1,2) CORRESPONDING TO ACTUAL VALUES       :
 29967                              <1> ;		IN @PRINTER_BASE AREA					       :
 29968                              <1> ; DATA AREA @PRINTER_BASE CONTAINS THE BASE ADDRESS OF THE PRINTER CARD(S)     :
 29969                              <1> ; AVAILABLE (LOCATED AT BEGINNING OF DATA SEGMENT, 408H ABSOLUTE, 3 WORDS)     :
 29970                              <1> ;									       :
 29971                              <1> ; DATA AREA @PRINT_TIM_OUT (BYTE) MAY BE CHANGED TO CAUSE DIFFERENT	       :
 29972                              <1> ; TIME OUT WAITS. DEFAULT=20 * 4					       :
 29973                              <1> ;									       :
 29974                              <1> ; REGISTERS	(AH) IS MODIFIED WITH STATUS INFORMATION		       :
 29975                              <1> ;		ALL OTHERS UNCHANGED					       :
 29976                              <1> ;-------------------------------------------------------------------------------
 29977                              <1> 
 29978                              <1> int17h:
 29979                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 29980                              <1> 	; (Derived from: IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985)
 29981                              <1> 	;
 29982                              <1> 	; (Default printer port: 378h) ; LPT1
 29983                              <1> 	; (Number of printers = 1)
 29984                              <1> 	
 29985                              <1> 	PRINTER_BASE equ 378h ; LPT1
 29986                              <1> 	;PRINT_TIM_OUT equ 4*80*65536 
 29987                              <1> 			; (Ref: IBM PC-AT BIOS v2 PRT.ASM)	 
 29988                              <1> 
 29989                              <1> 	PRINT_TIM_OUT equ 36000 ; WAIT_PRN_NBUSY
 29990                              <1> 			; (Ref: AWARD BIOS 1999 ATORGS.ASM)		
 29991                              <1> 
 29992                              <1> 	; INPUT:
 29993                              <1> 	;	ah = 0 -> print the character in AL 
 29994                              <1> 	;		 (sys write with write count >0)
 29995                              <1> 	;	ah = 1 -> initialize printer port
 29996                              <1> 	;		 (sys open)	
 29997                              <1> 	;	ah = 2 -> read the printer status 
 29998                              <1> 	;		 (sys write with write count = 0)
 29999                              <1> 	; OUTPUT:
 30000                              <1> 	;	ah = printer status
 30001                              <1> 
 30002                              <1> 	; Modified registers: eax, ecx, edx
 30003                              <1> 
 30004                              <1> PRINTER_IO_1:
 30005 00005E60 08E4                <1> 	or	ah, ah
 30006 00005E62 7417                <1> 	jz	short _b20
 30007 00005E64 FECC                <1> 	dec	ah
 30008 00005E66 7444                <1> 	jz	short _b80
 30009                              <1> 	;dec 	ah
 30010                              <1> 	;jz	short _b50
 30011                              <1> _b50:
 30012                              <1> 	;-----	PRINTER STATUS
 30013                              <1> B50:
 30014 00005E68 50                  <1> 	push	eax		; SAVE (AL) REGISTER
 30015                              <1> B60:
 30016 00005E69 66BA7903            <1> 	mov	dx, PRINTER_BASE+1
 30017                              <1> 				; GET PRINTER ATTACHMENT BASE ADDRESS
 30018                              <1> 				; POINT TO CONTROL PORT
 30019 00005E6D EC                  <1> 	in	al, dx		; PRE-CHARGE +BUSY LINE IF FLOATING
 30020 00005E6E EC                  <1> 	in	al, dx		; GET PRINTER STATUS HARDWARE BITS
 30021 00005E6F 88C4                <1> 	mov	ah, al		; SAVE
 30022 00005E71 80E4F8              <1> 	and	ah, 0F8h	; TURN OFF UNUSED BITS
 30023                              <1> B70:
 30024 00005E74 5A                  <1> 	pop	edx		; RECOVER (AL) REGISTER
 30025 00005E75 88D0                <1> 	mov	al, dl		; MOVE CHARACTER INTO (AL)
 30026 00005E77 80F448              <1> 	xor	ah, 48h		; FLIP A COUPLE OF BITS
 30027                              <1> B10:
 30028 00005E7A C3                  <1> 	retn			; RETURN FROM ROUTINE WITH STATUS IN AH
 30029                              <1> _b20:
 30030                              <1> 	;-----	PRINT THE CHARACTER IN (AL)
 30031 00005E7B B9A08C0000          <1> 	mov	ecx, PRINT_TIM_OUT ; (1 second)
 30032                              <1> B20:
 30033 00005E80 50                  <1> 	push	eax		; SAVE VALUE TO PRINT
 30034 00005E81 66BA7803            <1> 	mov	dx, PRINTER_BASE
 30035 00005E85 EE                  <1> 	out	dx, al		; OUTPUT CHARACTER TO DATA PORT
 30036 00005E86 FEC2                <1> 	inc	dl		; POINT TO STATUS PORT
 30037                              <1> 
 30038                              <1> 	;-----	CHECK FOR PRINTER BUSY
 30039                              <1> B25:
 30040                              <1> 	;-----	WAIT BUSY
 30041                              <1> B35:
 30042 00005E88 EC                  <1> 	in	al, dx		; GET STATUS
 30043 00005E89 88C4                <1> 	mov	ah, al		; STATUS TO (AH) ALSO
 30044 00005E8B A880                <1> 	test	al, 80h		; IS THE PRINTER CURRENTLY BUSY? (*)
 30045 00005E8D 750F                <1> 	jnz	short B40	; GO TO OUTPUT STROBE
 30046 00005E8F E831000000          <1> 	call	WAIT_REFRESH	; (wait for 30 micro seconds)
 30047 00005E94 E2F2                <1> 	loop	B35		; LOOP IF YES (*)
 30048                              <1> 
 30049 00005E96 80CC01              <1> 	or	ah, 1		; SET ERROR FLAG
 30050 00005E99 80E4F9              <1> 	and	ah, 0F9h	; TURN OFF THE UNUSED BITS
 30051 00005E9C EBD6                <1> 	jmp	short B70	; RETURN WITH ERROR FLAG SET
 30052                              <1> 
 30053                              <1> B40:				; SEND STROBE PULSE
 30054 00005E9E B00D                <1> 	mov	al, 0Dh		; SET THE STROBE LOW (BIT ON)
 30055 00005EA0 6642                <1> 	inc	dx		; OUTPUT STROBE TO CONTROL PORT
 30056 00005EA2 FA                  <1> 	cli			; PREVENT INTERRUPT PULSE STRETCHING
 30057 00005EA3 EE                  <1> 	out	dx, al		; OUTPUT STROBE BIT > 1us < 5us
 30058                              <1> 	; IODELAY
 30059                              <1> 	;jmp	short $+2	; I/O DELAY TO ALLOW FOR LINE LOADING
 30060                              <1> 	;jmp	short $+2	; AND FOR CORRECT PULSE WIDTH
 30061                              <1> 	; NEWIODELAY
 30062 00005EA4 E6EB                <1> 	out	0EBh, al
 30063                              <1> 
 30064 00005EA6 B00C                <1> 	mov	al, 0Ch		; SET THE -STROBE HIGH
 30065 00005EA8 EE                  <1> 	out	dx, al
 30066 00005EA9 FB                  <1> 	sti			; INTERRUPTS BACK ON
 30067                              <1> 	;pop	eax		; RECOVER THE OUTPUT CHAR
 30068                              <1> 	;jmp	short B50
 30069 00005EAA EBBD                <1> 	jmp	short B60
 30070                              <1> 
 30071                              <1> _b80:
 30072                              <1> 	;-----	INITIALIZE THE PRINTER PORT
 30073                              <1> B80:
 30074 00005EAC 50                  <1> 	push	eax		; SAVE (AL)
 30075 00005EAD 66BA7A03            <1> 	mov	dx, PRINTER_BASE+2 ; POINT TO OUTPUT PORT
 30076 00005EB1 B008                <1> 	mov	al, 8		; SET INIT LINE LOW
 30077 00005EB3 EE                  <1> 	out	dx, al
 30078                              <1> 	;mov	eax, 1000*4	; ADJUST FOR INITIALIZATION DELAY LOOP
 30079 00005EB4 B989080000          <1> 	mov	ecx, WAIT_PRN_INIT ; (65536 micro seconds)
 30080                              <1> B90:				; INIT_LOOP
 30081                              <1> 	;dec	eax		; LOOP FOR RESET TO TAKE
 30082                              <1> 	;jnz	short B90	; INIT_LOOP
 30083 00005EB9 E807000000          <1> 	call	WAIT_REFRESH	; (wait for 30 micro seconds)
 30084 00005EBE E2F9                <1> 	loop	B90	
 30085 00005EC0 B00C                <1> 	mov	al, 0Ch		; NO INTERRUPTS, NON AUTO LF, INIT HIGH
 30086 00005EC2 EE                  <1> 	out	dx, al
 30087 00005EC3 EBA4                <1> 	jmp	short B60	; EXIT THROUGH STATUS ROUTINE
 30088                              <1> 
 30089                              <1> 
 30090                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
 30091                              <1> ; -------------------------------------------------------------------
 30092                              <1> ;
 30093                              <1> ;;Wait while printer initializes should be 65,536 microseconds.
 30094                              <1> ;;65536/30 = 2185
 30095                              <1> ;			PUBLIC	WAIT_PRN_INIT_LO
 30096                              <1> ;WAIT_PRN_INIT_LO	DW	2185
 30097                              <1> ;			PUBLIC	WAIT_PRN_INIT_HI
 30098                              <1> ;WAIT_PRN_INIT_HI	DW	0
 30099                              <1> ;
 30100                              <1> WAIT_PRN_INIT equ 2185 ; 12/06/2022
 30101                              <1> ;
 30102                              <1> ;;Wait for printer not busy should be 1,080,000 microseconds.
 30103                              <1> ;;Memory refresh =15 us, therefore memory refresh period = 30 Us.
 30104                              <1> ;;1,080,000 / 30 = 36,000
 30105                              <1> ;			PUBLIC	WAIT_PRN_NBUSY_LO
 30106                              <1> ;WAIT_PRN_NBUSY_LO	DW	36000
 30107                              <1> ;			PUBLIC	WAIT_PRN_NBUSY_HI
 30108                              <1> ;WAIT_PRN_NBUSY_HI	DB	0
 30109                              <1> ;
 30110                              <1> ;WAIT_PRN_NBUSY	equ 36000 ; 12/06/2022
 30111                              <1> 
 30112                              <1> ; AWARD BIOS - 1999 - ATORGS.ASM (27/5/1999)
 30113                              <1> ; ------------------------------------------
 30114                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
 30115                              <1> ;   	INPUT: BX:CX = number of refresh periods to wait
 30116                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
 30117                              <1> ;	OUTPUT: BX:CX destroyed.
 30118                              <1> ;
 30119                              <1> ;	SAVES:	AX (except when NO STACK)
 30120                              <1> ;
 30121                              <1> ;	NOTES:	This routine can be (and is) used with no stack. When
 30122                              <1> ;		used this way, AX is assumed to be destroyed.
 30123                              <1> 
 30124                              <1> WAIT_REFRESH:
 30125                              <1> 	; 08/08/2022
 30126                              <1> 	; 12/06/2022
 30127                              <1> 	; Modified for Retro UNIX 386 v1.2
 30128                              <1> 	
 30129                              <1> 	; (wait for 30 micro seconds)
 30130                              <1> 
 30131                              <1> 	; 08/08/2022
 30132                              <1> 	;SYS1	equ 61h ; PORT_B
 30133                              <1> 
 30134                              <1> WR_SHORT:
 30135 00005EC5 50                  <1> 	push	eax
 30136                              <1> WR_STAT_0:
 30137 00005EC6 E461                <1> 	in	al, SYS1	; wait for high to low
 30138 00005EC8 A810                <1> 	test	al, 10h		; transition on memory
 30139 00005ECA 75FA                <1> 	jnz	short WR_STAT_0 
 30140                              <1> WR_STAT_1:
 30141 00005ECC E461                <1> 	in	al, SYS1
 30142 00005ECE A810                <1> 	test	al, 10h
 30143 00005ED0 74FA                <1> 	jz	short WR_STAT_1
 30144 00005ED2 58                  <1> 	pop	eax
 30145 00005ED3 C3                  <1> 	retn
 30146                                  
 30147                                  ; 07/03/2015
 30148                                  ; Temporary Code
 30149                                  display_disks:
 30150 00005ED4 803D[8C620000]00        	cmp 	byte [fd0_type], 0
 30151 00005EDB 7605                    	jna 	short ddsks1
 30152 00005EDD E87D000000              	call	pdskm
 30153                                  ddsks1:
 30154 00005EE2 803D[8D620000]00        	cmp	byte [fd1_type], 0
 30155 00005EE9 760C                    	jna	short ddsks2
 30156 00005EEB C605[53640000]31        	mov	byte [dskx], '1'
 30157 00005EF2 E868000000              	call	pdskm
 30158                                  ddsks2:
 30159 00005EF7 803D[8E620000]00        	cmp	byte [hd0_type], 0
 30160 00005EFE 7654                    	jna	short ddsk6
 30161 00005F00 66C705[51640000]68-     	mov	word [dsktype], 'hd'
 30162 00005F08 64                 
 30163 00005F09 C605[53640000]30        	mov	byte [dskx], '0'
 30164 00005F10 E84A000000              	call	pdskm
 30165                                  ddsks3:
 30166 00005F15 803D[8F620000]00        	cmp	byte [hd1_type], 0
 30167 00005F1C 7636                    	jna	short ddsk6
 30168 00005F1E C605[53640000]31        	mov	byte [dskx], '1'
 30169 00005F25 E835000000              	call	pdskm
 30170                                  ddsks4:
 30171 00005F2A 803D[90620000]00        	cmp	byte [hd2_type], 0
 30172 00005F31 7621                    	jna	short ddsk6
 30173 00005F33 C605[53640000]32        	mov	byte [dskx], '2'
 30174 00005F3A E820000000              	call	pdskm
 30175                                  ddsks5:
 30176 00005F3F 803D[91620000]00        	cmp	byte [hd3_type], 0
 30177 00005F46 760C                    	jna	short ddsk6
 30178 00005F48 C605[53640000]33        	mov	byte [dskx], '3'
 30179 00005F4F E80B000000              	call	pdskm
 30180                                  ddsk6:
 30181 00005F54 BE[62640000]            	mov	esi, nextline
 30182 00005F59 E806000000              	call	pdskml
 30183                                  pdskm_ok:
 30184 00005F5E C3                      	retn
 30185                                  pdskm:
 30186 00005F5F BE[4F640000]            	mov	esi, dsk_ready_msg
 30187                                  pdskml:	
 30188 00005F64 AC                      	lodsb
 30189 00005F65 08C0                    	or	al, al
 30190 00005F67 74F5                    	jz	short pdskm_ok
 30191 00005F69 56                      	push	esi
 30192 00005F6A 31DB                    	xor	ebx, ebx ; 0
 30193                                  			; Video page 0 (bl=0)
 30194 00005F6C B407                    	mov	ah, 07h ; Black background, 
 30195                                  			; light gray forecolor
 30196 00005F6E E841B3FFFF              	call	write_tty
 30197 00005F73 5E                      	pop	esi
 30198 00005F74 EBEE                    	jmp	short pdskml
 30199                                  
 30200 00005F76 90<rept>                align 16
 30201                                  
 30202                                  gdt:	; Global Descriptor Table
 30203                                  	; (30/07/2015, conforming cs)
 30204                                  	; (26/03/2015)
 30205                                  	; (24/03/2015, tss)
 30206                                  	; (19/03/2015)
 30207                                  	; (29/12/2013)
 30208                                  	;
 30209 00005F80 0000000000000000        	dw 0, 0, 0, 0	; NULL descriptor
 30210                                  	; 18/08/2014
 30211                                  			; 08h kernel code segment, base = 00000000h		
 30212 00005F88 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
 30213                                  			; 10h kernel data segment, base = 00000000h	
 30214 00005F90 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
 30215                                  			; 1Bh user code segment, base address = 400000h ; CORE
 30216 00005F98 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
 30217                                  			; 23h user data segment, base address = 400000h ; CORE
 30218 00005FA0 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
 30219                                  			; Task State Segment
 30220 00005FA8 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
 30221                                  			       ;  no IO permission in ring 3)
 30222                                  gdt_tss0:
 30223 00005FAA 0000                    	dw 0 ; TSS base address, bits 0-15 
 30224                                  gdt_tss1:
 30225 00005FAC 00                      	db 0 ; TSS base address, bits 16-23 
 30226                                  	      		; 49h	
 30227 00005FAD E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
 30228 00005FAE 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
 30229                                  gdt_tss2:
 30230 00005FAF 00                      	db 0 ; TSS base address, bits 24-31 
 30231                                  
 30232                                  gdt_end:
 30233                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 30234                                  					;; Type= 1 (code)/C=0/R=1/A=0
 30235                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 30236                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 30237                                  
 30238                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 30239                                  					;; Type= 0 (data)/E=0/W=1/A=0
 30240                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 30241                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 30242                                  		; W= Writeable, A= Accessed
 30243                                  	
 30244                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
 30245                                  					;; Type= 1 (code)/C=0/R=1/A=0
 30246                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 30247                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 30248                                  
 30249                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
 30250                                  					;; Type= 0 (data)/E=0/W=1/A=0
 30251                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 30252                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 30253                                  	
 30254                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
 30255                                  
 30256                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
 30257                                  		;	 = 100000h * 1000h (G=1) = 4GB
 30258                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
 30259                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
 30260                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
 30261                                  		; AVL= Available to programmers	
 30262                                  
 30263                                  gdtd:
 30264 00005FB0 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
 30265 00005FB2 [805F0000]                      dd gdt			; Address of the GDT
 30266                                  
 30267                                  	; 20/08/2014
 30268                                  idtd:
 30269 00005FB6 FF01                            dw idt_end - idt - 1    ; Limit (size)
 30270 00005FB8 [00650000]                      dd idt			; Address of the IDT
 30271                                  
 30272                                  align 4
 30273                                  	; 21/08/2014
 30274                                  ilist:
 30275                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
 30276                                  	;
 30277                                  	; Exception list
 30278                                  	; 25/08/2014	
 30279 00005FBC [1D080000]              	dd	exc0	; 0h,  Divide-by-zero Error
 30280 00005FC0 [24080000]              	dd	exc1	
 30281 00005FC4 [2B080000]              	dd 	exc2	
 30282 00005FC8 [32080000]              	dd	exc3	
 30283 00005FCC [36080000]              	dd	exc4	
 30284 00005FD0 [3A080000]              	dd	exc5	
 30285 00005FD4 [3E080000]              	dd 	exc6	; 06h,  Invalid Opcode
 30286 00005FD8 [42080000]              	dd	exc7	
 30287 00005FDC [46080000]              	dd	exc8	
 30288 00005FE0 [4A080000]              	dd	exc9	
 30289 00005FE4 [4E080000]              	dd 	exc10	
 30290 00005FE8 [52080000]              	dd	exc11
 30291 00005FEC [56080000]              	dd	exc12
 30292 00005FF0 [5A080000]              	dd	exc13	; 0Dh, General Protection Fault
 30293 00005FF4 [5E080000]              	dd 	exc14	; 0Eh, Page Fault
 30294 00005FF8 [62080000]              	dd	exc15
 30295 00005FFC [66080000]              	dd	exc16
 30296 00006000 [6A080000]              	dd	exc17
 30297 00006004 [6E080000]              	dd 	exc18
 30298 00006008 [72080000]              	dd	exc19
 30299 0000600C [76080000]              	dd 	exc20
 30300 00006010 [7A080000]              	dd	exc21
 30301 00006014 [7E080000]              	dd	exc22
 30302 00006018 [82080000]              	dd	exc23
 30303 0000601C [86080000]              	dd 	exc24
 30304 00006020 [8A080000]              	dd	exc25
 30305 00006024 [8E080000]              	dd	exc26
 30306 00006028 [92080000]              	dd	exc27
 30307 0000602C [96080000]              	dd 	exc28
 30308 00006030 [9A080000]              	dd	exc29
 30309 00006034 [9E080000]              	dd 	exc30
 30310 00006038 [A2080000]              	dd	exc31
 30311                                  	; Interrupt list
 30312 0000603C [58060000]              	dd	timer_int	; INT 20h
 30313                                  		;dd	irq0	
 30314 00006040 [5C0B0000]              	dd	keyb_int	; 27/08/2014
 30315                                  		;dd	irq1
 30316 00006044 [77070000]              	dd	irq2
 30317                                  		; COM2 int
 30318 00006048 [7B070000]              	dd	irq3
 30319                                  		; COM1 int
 30320 0000604C [86070000]              	dd	irq4
 30321 00006050 [91070000]              	dd	irq5
 30322                                  ;DISKETTE_INT: ;06/02/2015
 30323 00006054 [C81E0000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
 30324                                  		;dd	irq6
 30325                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
 30326                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 30327 00006058 [0D0B0000]              	dd	default_irq7	; 25/02/2015
 30328                                  		;dd	irq7
 30329                                  ; Real Time Clock Interrupt
 30330 0000605C [AB090000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
 30331                                  		;dd	irq8	; INT 28h
 30332 00006060 [A1070000]              	dd	irq9
 30333 00006064 [A5070000]              	dd	irq10
 30334 00006068 [A9070000]              	dd	irq11
 30335 0000606C [AD070000]              	dd	irq12
 30336 00006070 [B1070000]              	dd	irq13
 30337                                  ;HDISK_INT1:  ;06/02/2015 	
 30338 00006074 [98230000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
 30339                                  		;dd	irq14
 30340                                  ;HDISK_INT2:  ;06/02/2015
 30341 00006078 [BB230000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
 30342                                  		;dd	irq15	; INT 2Fh
 30343                                  		; 14/08/2015
 30344 0000607C [5D300000]              	dd	sysent		; INT 30h (system calls)
 30345                                  	
 30346                                  	;dd	ignore_int
 30347 00006080 00000000                	dd	0
 30348                                  
 30349                                  ;;;
 30350                                  ;;; 11/03/2015
 30351                                  %include 'kybdata.s'	; KEYBOARD (BIOS) DATA
 30352                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - KYBDATA.INC
 30353                              <1> ; Last Modification: 11/06/2022
 30354                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
 30355                              <1> ;
 30356                              <1> ; ///////// KEYBOARD DATA ///////////////
 30357                              <1> 
 30358                              <1> ; 11/03/2015
 30359                              <1> ; 05/12/2014
 30360                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
 30361                              <1> ; 03/06/86  KEYBOARD BIOS
 30362                              <1> 
 30363                              <1> ;---------------------------------------------------------------------------------
 30364                              <1> ;	KEY IDENTIFICATION SCAN TABLES
 30365                              <1> ;---------------------------------------------------------------------------------
 30366                              <1> 
 30367                              <1> ;-----	TABLES FOR ALT CASE ------------
 30368                              <1> ;-----	ALT-INPUT-TABLE 
 30369 00006084 524F50514B          <1> K30:	db	82,79,80,81,75
 30370 00006089 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
 30371                              <1> ;-----	SUPER-SHIFT-TABLE 
 30372 0000608E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
 30373 00006094 161718191E1F        <1> 	db	22,23,24,25,30,31
 30374 0000609A 202122232425        <1> 	db	32,33,34,35,36,37
 30375 000060A0 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
 30376 000060A6 3132                <1> 	db	49,50
 30377                              <1> 
 30378                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
 30379                              <1> ;-----	KEY_TABLE 
 30380 000060A8 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
 30381 000060A9 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
 30382 000060AE 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
 30383                              <1> _K6L    equ     $-_K6
 30384                              <1> 
 30385                              <1> ;-----	MASK_TABLE
 30386 000060B0 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
 30387 000060B1 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
 30388 000060B6 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
 30389                              <1> 
 30390                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
 30391 000060B8 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
 30392 000060BE 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
 30393                              <1> 	;db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
 30394 000060C4 FF7F94111705        <1> 	db	-1,127,148,17,23,5 ; 11/06/2022
 30395 000060CA 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
 30396 000060D0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
 30397 000060D6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
 30398 000060DC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
 30399 000060E2 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
 30400 000060E8 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
 30401 000060EE 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
 30402                              <1> 	;				;----- FUNCTIONS ------		
 30403 000060F2 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
 30404 000060F8 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
 30405 000060FE 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
 30406 00006104 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
 30407 0000610A 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
 30408                              <1> 
 30409                              <1> ;-----	TABLES FOR LOWER CASE ----------
 30410 00006110 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
 30411 00006119 39302D3D0809        <1>
 30412 0000611F 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
 30413 00006128 705B5D0DFF61736466- <1>
 30414 00006131 67686A6B6C3B27      <1>
 30415 00006138 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
 30416 00006141 6D2C2E2FFF2AFF20FF  <1>
 30417                              <1> ;-----	LC TABLE SCAN
 30418 0000614A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
 30419 0000614F 4041424344          <1> 	db	64,65,66,67,68
 30420 00006154 FFFF                <1> 	db	-1,-1			; NL, SL
 30421                              <1> 
 30422                              <1> ;-----	KEYPAD TABLE
 30423 00006156 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
 30424 0000615C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
 30425 00006163 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
 30426                              <1> 
 30427                              <1> ;-----	TABLES FOR UPPER CASE ----------
 30428 00006168 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
 30429 00006171 28295F2B0800        <1>
 30430 00006177 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
 30431 00006180 507B7D0DFF41534446- <1>
 30432 00006189 47484A4B4C3A22      <1>
 30433 00006190 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
 30434 00006199 4D3C3E3FFF2AFF20FF  <1>
 30435                              <1> ;-----	UC TABLE SCAN
 30436 000061A2 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
 30437 000061A7 595A5B5C5D          <1> 	db	89,90,91,92,93
 30438 000061AC FFFF                <1> 	db	-1,-1			; NL, SL
 30439                              <1> 
 30440                              <1> ;-----	NUM STATE TABLE
 30441 000061AE 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
 30442 000061B7 3233302E            <1>
 30443                              <1> 	;
 30444 000061BB FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
 30445                              <1> 
 30446                              <1> Align	4
 30447                              <1> ;----------------------------------------
 30448                              <1> ;	VIDEO DISPLAY DATA AREA		;
 30449                              <1> ;----------------------------------------
 30450 000061C0 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
 30451 000061C1 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
 30452                              <1> 				; (29h default setting for video mode 3)
 30453                              <1> 				; Mode Select register Bits
 30454                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
 30455                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
 30456                              <1> 				;   BIT 2 - COLOR (0), BW (1)
 30457                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
 30458                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
 30459                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
 30460                              <1> 				;   BIT 6, 7 - Not Used
 30461                              <1> 
 30462                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
 30463                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
 30464                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
 30465                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
 30466                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
 30467                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
 30468                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
 30469                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
 30470                              <1> ; Mode & 37h = Video signal OFF
 30471                              <1> 			
 30472                              <1> 
 30473                              <1> ; 26/08/2014
 30474                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
 30475                              <1> ; Derived from IBM "pc-at" 
 30476                              <1> ; rombios source code (06/10/1985)
 30477                              <1> ; 'dseg.inc'
 30478                              <1> 
 30479                              <1> ;---------------------------------------;
 30480                              <1> ;	SYSTEM DATA AREA		;
 30481                              <1> ;----------------------------------------
 30482 000061C2 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
 30483                              <1> 
 30484                              <1> ;----------------------------------------
 30485                              <1> ;	KEYBOARD DATA AREAS		;
 30486                              <1> ;----------------------------------------
 30487                              <1> 
 30488 000061C3 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
 30489 000061C4 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
 30490 000061C5 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
 30491 000061C6 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
 30492 000061C7 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
 30493 000061C8 [D8610000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
 30494 000061CC [F8610000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
 30495 000061D0 [D8610000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
 30496 000061D4 [D8610000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
 30497                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
 30498 000061D8 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
 30499                              <1> 
 30500                              <1> ; /// End Of KEYBOARD DATA ///
 30501                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
 30502                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.INC
 30503                              <1> ; Last Modification: 11/03/2015
 30504                              <1> ;		    (Data section for 'VIDEO.INC')	
 30505                              <1> ;
 30506                              <1> ; ///////// VIDEO DATA ///////////////
 30507                              <1> 
 30508                              <1> video_params:
 30509                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
 30510                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
 30511                              <1> 	; VIDEO MODE 3
 30512 000061F8 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
 30513 000061FF 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
 30514 00006204 00000000            <1> 	db	0,0,0,0
 30515                              <1> 
 30516                              <1> ; /// End Of VIDEO DATA ///
 30517                                  %include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
 30518                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKBSS.INC
 30519                              <1> ; Last Modification: 12/07/2022 
 30520                              <1> ; *****************************************************************************
 30521                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
 30522                              <1> ; *****************************************************************************
 30523                              <1> ; Ref: Retro UNIX 386 v1 Kernel (v0.2.1.5) - DISKDATA.INC - 11/07/2022
 30524                              <1> 
 30525                              <1> ;----------------------------------------
 30526                              <1> ;	80286 INTERRUPT LOCATIONS	:
 30527                              <1> ;	REFERENCED BY POST & BIOS	:
 30528                              <1> ;----------------------------------------
 30529                              <1> 
 30530 00006208 [6B620000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
 30531                              <1> 
 30532                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
 30533                              <1> ;----------------------------------------------------------------
 30534                              <1> ; DISK_BASE							:
 30535                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
 30536                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
 30537                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
 30538                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
 30539                              <1> ;----------------------------------------------------------------
 30540                              <1> 
 30541                              <1> ;DISK_BASE:	
 30542                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30543                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30544                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30545                              <1> ;	DB	2		; 512 BYTES/SECTOR
 30546                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
 30547                              <1> ;	db	18		; (EOT for 1.44MB diskette)
 30548                              <1> ;	DB	01BH		; GAP LENGTH
 30549                              <1> ;	DB	0FFH		; DTL
 30550                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
 30551                              <1> ;	db	06ch		; (for 1.44MB dsikette)
 30552                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
 30553                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30554                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30555                              <1> 
 30556                              <1> ;----------------------------------------
 30557                              <1> ;	ROM BIOS DATA AREAS		:
 30558                              <1> ;----------------------------------------
 30559                              <1> 
 30560                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 30561                              <1> 
 30562                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
 30563                              <1> 
 30564                              <1> ;----------------------------------------
 30565                              <1> ;	DISKETTE DATA AREAS		:
 30566                              <1> ;----------------------------------------
 30567                              <1> 
 30568                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
 30569                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
 30570                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
 30571                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
 30572                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
 30573                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
 30574                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
 30575                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
 30576                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
 30577                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
 30578                              <1> 
 30579                              <1> ;----------------------------------------
 30580                              <1> ;	POST AND BIOS WORK DATA AREA	:
 30581                              <1> ;----------------------------------------
 30582                              <1> 
 30583                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
 30584                              <1> 
 30585                              <1> ;----------------------------------------
 30586                              <1> ;	TIMER DATA AREA 		:
 30587                              <1> ;----------------------------------------
 30588                              <1> 
 30589                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
 30590                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
 30591                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
 30592                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
 30593                              <1> 
 30594                              <1> ;----------------------------------------
 30595                              <1> ;	ADDITIONAL MEDIA DATA		:
 30596                              <1> ;----------------------------------------
 30597                              <1> 
 30598                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 30599                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 30600                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 30601                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 30602                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 30603                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 30604                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 30605                              <1> 
 30606                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 30607                              <1> 
 30608                              <1> ;--------------------------------------------------------
 30609                              <1> ;	DRIVE TYPE TABLE				:
 30610                              <1> ;--------------------------------------------------------
 30611                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
 30612                              <1> DR_TYPE:
 30613 0000620C 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
 30614                              <1>                 ;DW	MD_TBL1
 30615 0000620D [2A620000]          <1> 		dd	MD_TBL1
 30616 00006211 82                  <1> 		DB	02+BIT7ON
 30617                              <1> 		;DW	MD_TBL2
 30618 00006212 [37620000]          <1>                 dd      MD_TBL2
 30619 00006216 02                  <1> DR_DEFAULT:	DB	02
 30620                              <1>                 ;DW	MD_TBL3
 30621 00006217 [44620000]          <1> 		dd      MD_TBL3
 30622 0000621B 03                  <1> 		DB	03
 30623                              <1>                 ;DW	MD_TBL4
 30624 0000621C [51620000]          <1> 		dd      MD_TBL4
 30625 00006220 84                  <1> 		DB	04+BIT7ON
 30626                              <1>                 ;DW	MD_TBL5
 30627 00006221 [5E620000]          <1> 		dd      MD_TBL5
 30628 00006225 04                  <1> 		DB	04
 30629                              <1>                 ;DW	MD_TBL6
 30630 00006226 [6B620000]          <1> 		dd      MD_TBL6
 30631                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
 30632                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
 30633                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
 30634                              <1> ;--------------------------------------------------------
 30635                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
 30636                              <1> ;--------------------------------------------------------
 30637                              <1> ;--------------------------------------------------------
 30638                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
 30639                              <1> ;--------------------------------------------------------
 30640                              <1> MD_TBL1:        
 30641 0000622A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30642 0000622B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30643 0000622C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30644 0000622D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30645 0000622E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30646 0000622F 2A                  <1> 	DB	02AH		; GAP LENGTH
 30647 00006230 FF                  <1> 	DB	0FFH		; DTL
 30648 00006231 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30649 00006232 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30650 00006233 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30651 00006234 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30652 00006235 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 30653 00006236 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 30654                              <1> ;--------------------------------------------------------
 30655                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
 30656                              <1> ;--------------------------------------------------------
 30657                              <1> MD_TBL2:        
 30658 00006237 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30659 00006238 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30660 00006239 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30661 0000623A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30662 0000623B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30663 0000623C 2A                  <1> 	DB	02AH		; GAP LENGTH
 30664 0000623D FF                  <1> 	DB	0FFH		; DTL
 30665 0000623E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30666 0000623F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30667 00006240 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30668 00006241 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30669 00006242 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 30670 00006243 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
 30671                              <1> ;--------------------------------------------------------
 30672                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
 30673                              <1> ;--------------------------------------------------------
 30674                              <1> MD_TBL3:
 30675 00006244 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30676 00006245 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30677 00006246 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30678 00006247 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30679 00006248 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
 30680 00006249 1B                  <1> 	DB	01BH		; GAP LENGTH
 30681 0000624A FF                  <1> 	DB	0FFH		; DTL
 30682 0000624B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
 30683 0000624C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30684 0000624D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30685 0000624E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30686 0000624F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30687 00006250 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 30688                              <1> ;--------------------------------------------------------
 30689                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
 30690                              <1> ;--------------------------------------------------------
 30691                              <1> MD_TBL4:
 30692 00006251 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30693 00006252 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30694 00006253 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30695 00006254 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30696 00006255 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30697 00006256 2A                  <1> 	DB	02AH		; GAP LENGTH
 30698 00006257 FF                  <1> 	DB	0FFH		; DTL
 30699 00006258 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30700 00006259 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30701 0000625A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30702 0000625B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30703 0000625C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30704 0000625D 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 30705                              <1> ;--------------------------------------------------------
 30706                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
 30707                              <1> ;--------------------------------------------------------
 30708                              <1> MD_TBL5:
 30709 0000625E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30710 0000625F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30711 00006260 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30712 00006261 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30713 00006262 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30714 00006263 2A                  <1> 	DB	02AH		; GAP LENGTH
 30715 00006264 FF                  <1> 	DB	0FFH		; DTL
 30716 00006265 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30717 00006266 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30718 00006267 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30719 00006268 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30720 00006269 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30721 0000626A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 30722                              <1> ;--------------------------------------------------------
 30723                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
 30724                              <1> ;--------------------------------------------------------
 30725                              <1> MD_TBL6:
 30726 0000626B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30727 0000626C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30728 0000626D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30729 0000626E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30730 0000626F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
 30731 00006270 1B                  <1> 	DB	01BH		; GAP LENGTH
 30732 00006271 FF                  <1> 	DB	0FFH		; DTL
 30733 00006272 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
 30734 00006273 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30735 00006274 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30736 00006275 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30737 00006276 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30738 00006277 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 30739                              <1> 
 30740                              <1> 
 30741                              <1> ; << diskette.inc >>
 30742                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 30743                              <1> ;
 30744                              <1> ;----------------------------------------
 30745                              <1> ;	ROM BIOS DATA AREAS		:
 30746                              <1> ;----------------------------------------
 30747                              <1> 
 30748                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 30749                              <1> 
 30750                              <1> ;----------------------------------------
 30751                              <1> ;	FIXED DISK DATA AREAS		:
 30752                              <1> ;----------------------------------------
 30753                              <1> 
 30754                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
 30755                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
 30756                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
 30757                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
 30758                              <1> 
 30759                              <1> ;----------------------------------------
 30760                              <1> ;	ADDITIONAL MEDIA DATA		:
 30761                              <1> ;----------------------------------------
 30762                              <1> 
 30763                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 30764                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
 30765                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
 30766                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
 30767                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
 30768                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 30769                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 30770                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 30771                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 30772                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 30773                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 30774                              <1> 
 30775                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 30776                              <1> ;
 30777                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 30778                              <1> 
 30779                              <1> ERR_TBL:
 30780 00006278 E0                  <1> 	db	NO_ERR
 30781 00006279 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
 30782 0000627D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
 30783                              <1> 
 30784                              <1> ; 11/07/2022
 30785                              <1> ; 17/12/2014 (mov ax, [cfd])
 30786                              <1> ; 11/12/2014
 30787                              <1> ;cfd:		db 0			; current floppy drive (for GET_PARM)
 30788                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
 30789                              <1> ;pfd:		db 1			; previous floppy drive (for GET_PARM)
 30790                              <1> 					; (initial value of 'pfd 
 30791                              <1> 					; must be different then 'cfd' value
 30792                              <1> 					; to force updating/initializing
 30793                              <1> 					; current drive parameters) 
 30794                              <1> 
 30795                              <1> ;; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 30796 00006281 FF                  <1> pfd:		db 0FFh
 30797                              <1> 
 30798                              <1> align 2
 30799                              <1> 
 30800 00006282 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
 30801                              <1> 			      ; (170h)
 30802 00006284 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
 30803                              <1> 
 30804                              <1> ; 05/01/2015 
 30805 00006286 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
 30806                              <1> 
 30807                              <1> ; *****************************************************************************
 30808                                  ;;;
 30809                                  
 30810 00006287 90                      align 2
 30811                                  
 30812                                  ; 12/11/2014 (Retro UNIX 386 v1)
 30813 00006288 00                      boot_drv:    db 0  ; boot drive number (physical)
 30814                                  ; 24/11/2014
 30815 00006289 00                      drv:	     db 0 
 30816 0000628A 00                      last_drv:    db 0  ; last hdd
 30817 0000628B 00                      hdc:         db 0  ; number of hard disk drives
 30818                                  		     ; (present/detected)
 30819                                  ;
 30820                                  ; 24/11/2014 (Retro UNIX 386 v1)
 30821                                  ; Physical drive type & flags
 30822 0000628C 00                      fd0_type:    db 0  ; floppy drive type
 30823 0000628D 00                      fd1_type:    db 0    ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
 30824                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
 30825                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
 30826                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
 30827                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
 30828 0000628E 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 - present flag)
 30829 0000628F 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 - present flag)
 30830 00006290 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 - present flag)
 30831 00006291 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 - present flag)
 30832                                  		     ; bit 0 - Fixed disk access subset supported
 30833                                  		     ; bit 1 - Drive locking and ejecting
 30834                                  		     ; bit 2 - Enhanced disk drive support
 30835                                  		     ; bit 3 - Reserved (64 bit EDD support)
 30836                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
 30837                                  		     ; will interpret it as 'LBA ready'!)		
 30838                                  
 30839                                  ; 12/07/2022
 30840                                  ; (drv.cylinders, drv.spt, drv.spt will not be used now on)
 30841                                  ; ('diskio.inc')
 30842                                  ; ((spt and heads and cylinder counts will be taken from DPT))
 30843                                  
 30844                                  ; 11/03/2015 - 10/07/2015
 30845                                  ;drv.cylinders: dw 0,0,0,0,0,0,0
 30846                                  ;drv.heads:     dw 0,0,0,0,0,0,0
 30847                                  ;drv.spt:       dw 0,0,0,0,0,0,0
 30848                                  ; 12/07/2022 - 11/03/2015
 30849 00006292 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
 30850 0000629B 000000000000000000-
 30851 000062A4 000000000000000000-
 30852 000062AD 00                 
 30853 000062AE 00000000000000          drv.status:    db 0,0,0,0,0,0,0
 30854 000062B5 00000000000000          drv.error:     db 0,0,0,0,0,0,0
 30855                                  ;
 30856                                  
 30857                                  ; 27/08/2014
 30858                                  scr_row:
 30859 000062BC E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
 30860                                  scr_col:
 30861 000062C0 00000000                	dd 0
 30862                                  
 30863                                  ;; 14/08/2015
 30864                                  ;;msgPM:
 30865                                  ;;      db "Protected mode and paging are ENABLED ... ", 0
 30866                                  msgKVER:
 30867                                  	;;;;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.0 [18/04/2022]", 0
 30868                                  	;;;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.1 [08/06/2022]", 0
 30869                                  	;;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.2 [14/06/2022]", 0
 30870                                  	;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.3 [08/08/2022]", 0
 30871 000062C4 526574726F20554E49-     	db "Retro UNIX 386 v1.2 - Kernel v0.2.2.4 [27/12/2022]", 0
 30872 000062CD 58203338362076312E-
 30873 000062D6 32202D204B65726E65-
 30874 000062DF 6C2076302E322E322E-
 30875 000062E8 34205B32372F31322F-
 30876 000062F1 323032325D00       
 30877                                  
 30878 000062F7 90                      align 2
 30879                                  
 30880                                  ; 20/08/2014
 30881                                    ; /* This is the default interrupt "handler" :-) */ 
 30882                                    ; Linux v0.12 (head.s)
 30883                                  int_msg:
 30884 000062F8 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
 30885 00006301 6E7465727275707420-
 30886 0000630A 212000             
 30887                                  
 30888 0000630D 90                      align 2  
 30889                                  
 30890                                  ; 21/08/2014
 30891                                  timer_msg:
 30892 0000630E 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
 30893 00006317 542032306829202120-
 30894 00006320 54696D657220496E74-
 30895 00006329 657272757074203A20 
 30896                                  tcountstr:
 30897 00006332 303030303020            	db "00000 "
 30898 00006338 00                      	db 0
 30899                                  
 30900 00006339 90                      align 2
 30901                                  	; 21/08/2014
 30902                                  exc_msg:
 30903 0000633A 435055206578636570-     	db "CPU exception ! "
 30904 00006343 74696F6E202120     
 30905                                  excnstr: 		; 25/08/2014
 30906 0000634A 3F3F68202045495020-     	db "??h", "  EIP : "
 30907 00006353 3A20               
 30908                                  EIPstr: ; 29/08/2014
 30909 00006355 00<rept>                	times 12 db 0
 30910                                  rtc_msg:
 30911 00006361 5265616C2054696D65-     	db "Real Time Clock - "
 30912 0000636A 20436C6F636B202D20 
 30913                                  datestr:
 30914 00006373 30302F30302F303030-     	db "00/00/0000"
 30915 0000637C 30                 
 30916 0000637D 20                      	db " "
 30917                                  daystr:
 30918 0000637E 44415920                	db "DAY "
 30919                                  timestr:	
 30920 00006382 30303A30303A3030                db "00:00:00"
 30921 0000638A 20                      	db " "
 30922 0000638B 00                      	db 0 
 30923                                  
 30924                                  daytmp:
 30925                                  	; 28/02/2015
 30926 0000638C 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
 30927 00006395 4F4E20545545205745-
 30928 0000639E 442054485520465249-
 30929 000063A7 2053415420         
 30930                                  
 30931 000063AC FF                      ptime_seconds: db 0FFh
 30932                                  
 30933                                  	; 23/02/2015
 30934                                  	; 25/08/2014
 30935                                  ;scounter:
 30936                                  ;	db 5
 30937                                  ;	db 19
 30938                                  
 30939                                  ; 28/11/2021
 30940                                  ;; 05/11/2014
 30941                                  ;msg_out_of_memory:
 30942                                  ;	db 	07h, 0Dh, 0Ah
 30943                                  ;	db	'Insufficient memory ! (Minimum 2 MB memory is needed.)'
 30944                                  ; 	db	0Dh, 0Ah, 0
 30945                                  	;
 30946                                  setup_error_msg:
 30947 000063AD 0D0A                    	db 0Dh, 0Ah
 30948 000063AF 4469736B2053657475-     	db 'Disk Setup Error!' 
 30949 000063B8 70204572726F7221   
 30950 000063C0 0D0A00                  	db 0Dh, 0Ah,0
 30951                                  
 30952                                  ; 02/09/2014 (Retro UNIX 386 v1)
 30953                                  ;crt_ulc: db 0 ; upper left column (for scroll) 
 30954                                  ;	  db 0 ; upper left row (for scroll)	
 30955                                  
 30956                                  ;crt_lrc: db 79 ; lower right column (for scroll) 
 30957                                  ;	  db 24 ; lower right row (for scroll)
 30958                                  
 30959                                  ; 06/11/2014 (Temporary Data)
 30960                                  ; Memory Information message
 30961                                  ; 14/08/2015
 30962                                  msg_memory_info:
 30963 000063C3 07                      	db	07h
 30964 000063C4 0D0A                    	db	0Dh, 0Ah
 30965                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
 30966 000063C6 546F74616C206D656D-     	db	"Total memory : "
 30967 000063CF 6F7279203A20       
 30968                                  mem_total_b_str: ; 10 digits
 30969 000063D5 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
 30970 000063DE 302062797465730D0A 
 30971 000063E7 202020202020202020-     	db	"               ", 20h, 20h, 20h
 30972 000063F0 202020202020202020 
 30973                                  mem_total_p_str: ; 7 digits
 30974 000063F9 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
 30975 00006402 616765730D0A       
 30976 00006408 0D0A                    	db 	0Dh, 0Ah
 30977 0000640A 46726565206D656D6F-     	db	"Free memory  : "
 30978 00006413 727920203A20       
 30979                                  free_mem_b_str:  ; 10 digits
 30980 00006419 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
 30981 00006422 3F2062797465730D0A 
 30982 0000642B 202020202020202020-     	db	"               ", 20h, 20h, 20h
 30983 00006434 202020202020202020 
 30984                                  free_mem_p_str:  ; 7 digits
 30985 0000643D 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
 30986 00006446 616765730D0A       
 30987 0000644C 0D0A00                  	db	0Dh, 0Ah, 0
 30988                                  
 30989                                  dsk_ready_msg:
 30990 0000644F 0D0A                    	db 	0Dh, 0Ah
 30991                                  dsktype:
 30992 00006451 6664                    	db	'fd'
 30993                                  dskx:
 30994 00006453 30                      	db	'0'
 30995 00006454 20                      	db	20h
 30996 00006455 697320524541445920-     	db 	'is READY ...'
 30997 0000645E 2E2E2E             
 30998 00006461 00                      	db 	0
 30999                                  nextline:
 31000 00006462 0D0A00                  	db 	0Dh, 0Ah, 0
 31001                                  
 31002                                  ; KERNEL - SYSINIT Messages
 31003                                  ; 24/08/2015
 31004                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
 31005                                  ; 14/07/2013
 31006                                  ;kernel_init_err_msg:
 31007                                  ;	db 0Dh, 0Ah
 31008                                  ;	db 07h
 31009                                  ;	db 'Kernel initialization ERROR !'
 31010                                  ;	db 0Dh, 0Ah, 0 
 31011                                  ; 24/08/2015
 31012                                  ;;; (temporary kernel init message has been removed
 31013                                  ;;;  from 'sys_init' code)
 31014                                  ;kernel_init_ok_msg: 
 31015                                  ;	db 0Dh, 0Ah
 31016                                  ;	db 07h
 31017                                  ;	db 'Welcome to Retro UNIX 386 v1.1 Operating System !'
 31018                                  ;	db 0Dh, 0Ah
 31019                                  ;       db 'by Erdogan Tan - 04/02/2016 (v0.2.1.0)'
 31020                                  ;	db 0Dh, 0Ah, 0
 31021                                  panic_msg:
 31022 00006465 0D0A07                  	db 0Dh, 0Ah, 07h
 31023 00006468 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
 31024 00006471 726E656C2050616E69-
 31025 0000647A 632021             
 31026 0000647D 0D0A00                  	db 0Dh, 0Ah, 0
 31027                                  etc_init_err_msg:
 31028 00006480 0D0A                    	db 0Dh, 0Ah
 31029 00006482 07                      	db 07h
 31030 00006483 4552524F523A202F65-     	db 'ERROR: /etc/init !?'
 31031 0000648C 74632F696E69742021-
 31032 00006495 3F                 
 31033 00006496 0D0A00                  	db 0Dh, 0Ah, 0
 31034                                  
 31035                                  ; 10/05/2015
 31036                                  badsys_msg:
 31037 00006499 0D0A                    	db 0Dh, 0Ah
 31038 0000649B 07                      	db 07h
 31039 0000649C 496E76616C69642053-     	db 'Invalid System Call !'
 31040 000064A5 797374656D2043616C-
 31041 000064AE 6C2021             
 31042 000064B1 0D0A                    	db 0Dh, 0Ah
 31043 000064B3 4541583A20              	db 'EAX: '
 31044                                  bsys_msg_eax:
 31045 000064B8 303030303030303068      	db '00000000h'
 31046 000064C1 0D0A                    	db 0Dh, 0Ah
 31047 000064C3 4549503A20              	db 'EIP: '
 31048                                  bsys_msg_eip:
 31049 000064C8 303030303030303068      	db '00000000h' 
 31050 000064D1 0D0A00                  	db 0Dh, 0Ah, 0
 31051                                  
 31052                                  BSYS_M_SIZE equ $ - badsys_msg
 31053                                  
 31054                                  align 2
 31055                                  
 31056                                  ; EPOCH Variables
 31057                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
 31058                                  ; 09/04/2013 epoch variables
 31059                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
 31060                                  ;
 31061 000064D4 B207                    year: 	dw 1970
 31062                                  ;month: dw 1
 31063                                  ;day: 	dw 1
 31064                                  ;hour: 	dw 0
 31065                                  ;minute: dw 0
 31066                                  ;second: dw 0
 31067                                  ; 02/06/2022
 31068 000064D6 01                      month:	db 1
 31069 000064D7 01                      day:	db 1
 31070 000064D8 01                      hour:	db 1
 31071 000064D9 01                      minute: db 1
 31072 000064DA 01                      second:	db 1
 31073 000064DB 01                      	db 1
 31074                                  
 31075                                  DMonth:
 31076 000064DC 0000                    	dw 0
 31077 000064DE 1F00                    	dw 31
 31078 000064E0 3B00                    	dw 59
 31079 000064E2 5A00                    	dw 90
 31080 000064E4 7800                    	dw 120
 31081 000064E6 9700                    	dw 151
 31082 000064E8 B500                    	dw 181
 31083 000064EA D400                    	dw 212
 31084 000064EC F300                    	dw 243
 31085 000064EE 1101                    	dw 273
 31086 000064F0 3001                    	dw 304
 31087 000064F2 4E01                    	dw 334
 31088                                  
 31089                                  ; 02/01/2022 (Retro UNIX 386 v1.2)
 31090                                  ; 04/11/2014 (Retro UNIX 386 v1)
 31091 000064F4 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
 31092                                  		   ;   1 and 16 MB, max. 3C00h = 15 MB.
 31093 000064F6 0000                    	     dw 0  ; 02/01/2022 (Retro UNIX 386 v1.2)
 31094 000064F8 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
 31095                                  		   ;   between 16 MB and 4 GB.
 31096 000064FA 0000                    	     dw 0  ; 02/01/2022 (Retro UNIX 386 v1.2)
 31097                                  
 31098                                  ; 01/01/2022
 31099                                  KEND:
 31100                                  
 31101 000064FC 90<rept>                align 16
 31102                                  
 31103                                  bss_start:
 31104                                  
 31105                                  ABSOLUTE bss_start
 31106                                  
 31107                                  	; 11/03/2015
 31108                                  	; Interrupt Descriptor Table (20/08/2014)
 31109                                  idt:
 31110 00006500 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
 31111                                  idt_end:
 31112                                  
 31113                                  ;alignb 4
 31114                                  
 31115                                  task_state_segment:
 31116                                  	; 24/03/2015
 31117 00006700 <res 00000002>          tss.link:   resw 1
 31118 00006702 <res 00000002>          	    resw 1
 31119                                  ; tss offset 4	
 31120 00006704 <res 00000004>          tss.esp0:   resd 1
 31121 00006708 <res 00000002>          tss.ss0:    resw 1
 31122 0000670A <res 00000002>          	    resw 1	
 31123 0000670C <res 00000004>          tss.esp1:   resd 1
 31124 00006710 <res 00000002>          tss.ss1:    resw 1
 31125 00006712 <res 00000002>          	    resw 1 	
 31126 00006714 <res 00000004>          tss.esp2:   resd 1
 31127 00006718 <res 00000002>          tss.ss2:    resw 1
 31128 0000671A <res 00000002>          	    resw 1
 31129                                  ; tss offset 28
 31130 0000671C <res 00000004>          tss.CR3:    resd 1
 31131 00006720 <res 00000004>          tss.eip:    resd 1
 31132 00006724 <res 00000004>          tss.eflags: resd 1
 31133                                  ; tss offset 40
 31134 00006728 <res 00000004>          tss.eax:    resd 1		 		
 31135 0000672C <res 00000004>          tss.ecx:    resd 1
 31136 00006730 <res 00000004>          tss.edx:    resd 1
 31137 00006734 <res 00000004>          tss.ebx:    resd 1
 31138 00006738 <res 00000004>          tss.esp:    resd 1
 31139 0000673C <res 00000004>          tss.ebp:    resd 1
 31140 00006740 <res 00000004>          tss.esi:    resd 1
 31141 00006744 <res 00000004>          tss.edi:    resd 1
 31142                                  ; tss offset 72
 31143 00006748 <res 00000002>          tss.ES:     resw 1
 31144 0000674A <res 00000002>          	    resw 1	
 31145 0000674C <res 00000002>          tss.CS:	    resw 1
 31146 0000674E <res 00000002>          	    resw 1
 31147 00006750 <res 00000002>          tss.SS:	    resw 1
 31148 00006752 <res 00000002>          	    resw 1
 31149 00006754 <res 00000002>          tss.DS:	    resw 1
 31150 00006756 <res 00000002>          	    resw 1
 31151 00006758 <res 00000002>          tss.FS:	    resw 1
 31152 0000675A <res 00000002>          	    resw 1
 31153 0000675C <res 00000002>          tss.GS:	    resw 1
 31154 0000675E <res 00000002>          	    resw 1		
 31155 00006760 <res 00000002>          tss.LDTR:   resw 1
 31156 00006762 <res 00000002>          	    resw 1
 31157                                  ; tss offset 100		
 31158 00006764 <res 00000002>          	    resw 1		
 31159 00006766 <res 00000002>          tss.IOPB:   resw 1
 31160                                  ; tss offset 104 
 31161                                  tss_end:
 31162                                  
 31163 00006768 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
 31164                                  		    ;  (Physical address = Virtual address)	 	
 31165 0000676C <res 00000004>          memory_size: resd 1 ; memory size in pages
 31166 00006770 <res 00000004>          free_pages:  resd 1 ; number of free pages		
 31167 00006774 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
 31168                                  		    ;   first free page search
 31169 00006778 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
 31170                                  		    ;   next free page search will be
 31171                                  		    ;   stopped after it. (end of M.A.T.)
 31172 0000677C <res 00000004>          first_page:  resd 1 ;   offset value in M.A.T. which
 31173                                  		    ; first free page search
 31174                                  		    ;   will be started on it. (for user)
 31175 00006780 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
 31176                                  
 31177                                  ;;;
 31178                                  ; 02/09/2014 (Retro UNIX 386 v1)
 31179                                  ; 04/12/2013 (Retro UNIX 8086 v1)
 31180 00006784 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
 31181                                  			  ; NOTE: active page only
 31182 00006786 <res 00000010>          cursor_posn: resw 8 	  ; cursor positions for video pages
 31183                                  active_page: 
 31184 00006796 <res 00000001>          ptty: 	     resb 1 	  ; current tty
 31185                                  ; 01/07/2015
 31186 00006797 <res 00000001>          ccolor:	     resb 1	  ; current color attributes ('sysmsg')	
 31187                                  ; 26/10/2015
 31188                                  ; 07/09/2014
 31189 00006798 <res 00000014>          ttychr:      resw ntty+2  ; Character buffer (multiscreen)
 31190                                  
 31191                                  ; 21/08/2014
 31192 000067AC <res 00000004>          tcount:	     resd 1
 31193                                  
 31194                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
 31195 000067B0 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
 31196                                  
 31197                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
 31198                                  ; (open mode locks for pseudo TTYs)
 31199                                  ; [ major tty locks (return error in any conflicts) ]
 31200 000067B4 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
 31201                                  
 31202                                  ; 15/04/2015 (Retro UNIX 386 v1)
 31203                                  ; 22/09/2013 (Retro UNIX 8086 v1)
 31204 000067C8 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
 31205                                  ; 15/04/2015 (Retro UNIX 386 v1)
 31206                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
 31207                                  ;; 0 means serial port is not available 
 31208                                  ;;comprm: ; 25/06/2014
 31209 000067D2 <res 00000001>          com1p:       resb 1  ;;0E3h
 31210 000067D3 <res 00000001>          com2p:       resb 1  ;;0E3h
 31211                                  
 31212                                  ; 17/11/2015
 31213                                  ; request for response (from the terminal)	
 31214 000067D4 <res 00000002>          req_resp:    resw 1 			
 31215                                  ; 07/11/2015
 31216 000067D6 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
 31217                                  		    ; (0= COM1, 1= COM2)
 31218                                  ; 09/11/2015
 31219 000067D7 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
 31220                                  ; 07/11/2015
 31221 000067D8 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
 31222 000067DA <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
 31223                                  
 31224                                  ; 23/10/2015
 31225                                  ; SERIAL PORTS - COMMUNICATION MODES
 31226                                  ; (Retro UNIX 386 v1 feature only!)
 31227                                  ; 0 - command mode (default/initial mode)
 31228                                  ; 1 - terminal mode (Retro UNIX 386 v1 terminal, ascii chars)
 31229                                  ;;; communication modes for future versions:  
 31230                                  ; // 2 - keyboard mode (ascii+scancode input)
 31231                                  ; // 3 - mouse mode
 31232                                  ; // 4 - device control (output) mode
 31233                                  ; VALID COMMANDS for current version:
 31234                                  ; 	'LOGIN'
 31235                                  ;  Login request: db 0FFh, 'LOGIN', 0 
 31236                                  ;	 ("Retro UNIX 386 v1 terminal requests login")
 31237                                  ;  Login response: db 0FFh, 'login', 0
 31238                                  ;	 ("login request accepted, wait for login prompt") 
 31239                                  ; When a login requests is received and acknowledged (by
 31240                                  ; serial port interrupt handler (communication procedure),
 31241                                  ; Retro UNIX 386 v1 operating system will start terminal mode
 31242                                  ; (login procedure) by changing comm. mode to 1 (terminal mode)
 31243                                  ; and then running 'etc/getty' for tty8 (COM1) or tty9 (COM2)
 31244                                  ; 
 31245                                  ; 'sys connect' system call is used to change communication mode
 31246                                  ; except 'LOGIN' command which is used to start terminal mode
 31247                                  ; by using (COM port) terminal.
 31248                                  
 31249                                  ;com1own:     resb 1 ; COM1 owner (u.uno)
 31250                                  ;com2own:     resb 1 ; COM2 owner (u.uno)
 31251                                  ;com1mode:    resb 1 ; communication mode for COM1
 31252                                  ;com1com:     resb 1 ; communication command for COM1
 31253                                  ;com2mode:    resb 1 ; communication mode for COM1
 31254                                  ;com2com      resb 1 ; communication command for COM1
 31255                                  ;com1cbufp:   resb 8 ; COM1 command buffer char pointer	
 31256                                  ;com2cbufp:   resb 8 ; COM2 command buffer char pointer	
 31257                                  ;com1cbuf:    resb 8 ; COM2 command buffer
 31258                                  ;com2cbuf:    resb 8 ; COM2 command buffer
 31259                                  
 31260                                  ; 22/08/2014 (RTC)
 31261                                  ; (Packed BCD)
 31262 000067DC <res 00000001>          time_seconds: resb 1
 31263 000067DD <res 00000001>          time_minutes: resb 1
 31264 000067DE <res 00000001>          time_hours:   resb 1
 31265 000067DF <res 00000001>          date_wday:    resb 1
 31266 000067E0 <res 00000001>          date_day:     resb 1
 31267 000067E1 <res 00000001>          date_month:   resb 1			
 31268 000067E2 <res 00000001>          date_year:    resb 1
 31269 000067E3 <res 00000001>          date_century: resb 1
 31270                                  
 31271                                  %include 'diskbss.s' ; UNINITIALIZED DISK (BIOS) DATA
 31272                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKBSS.INC
 31273                              <1> ; Last Modification: 12/07/2022 
 31274                              <1> ; *****************************************************************************
 31275                              <1> ;	(Uninitialized Disk Parameters Data section for 'DISKIO.INC')
 31276                              <1> ; *****************************************************************************
 31277                              <1> ; Ref: Retro UNIX 386 v1 Kernel (v0.2.1.5) - DISKBSS.INC - 10/07/2022
 31278                              <1>  
 31279                              <1> 
 31280                              <1> alignb 2
 31281                              <1> 
 31282                              <1> ;----------------------------------------
 31283                              <1> ;	TIMER DATA AREA 		:
 31284                              <1> ;----------------------------------------
 31285                              <1> 
 31286                              <1> TIMER_LH:	; 16/02/2015
 31287 000067E4 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
 31288 000067E6 <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
 31289 000067E8 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
 31290                              <1> 
 31291                              <1> ;----------------------------------------
 31292                              <1> ;	DISKETTE DATA AREAS		:
 31293                              <1> ;----------------------------------------
 31294                              <1> 
 31295 000067E9 <res 00000001>      <1> SEEK_STATUS:	resb	1
 31296 000067EA <res 00000001>      <1> MOTOR_STATUS:	resb	1
 31297 000067EB <res 00000001>      <1> MOTOR_COUNT:	resb	1
 31298 000067EC <res 00000001>      <1> DSKETTE_STATUS:	resb	1
 31299 000067ED <res 00000007>      <1> NEC_STATUS:	resb	7
 31300                              <1> 
 31301                              <1> ;----------------------------------------
 31302                              <1> ;	ADDITIONAL MEDIA DATA		:
 31303                              <1> ;----------------------------------------
 31304                              <1> 
 31305 000067F4 <res 00000001>      <1> LASTRATE:	resb 	1
 31306 000067F5 <res 00000001>      <1> HF_STATUS:	resb 	1
 31307                              <1> ;HF_ERROR:	resb 	1  ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)	
 31308 000067F6 <res 00000001>      <1> HF_INT_FLAG:	resb	1
 31309                              <1> ;HF_CNTRL:	resb 	1  ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 31310                              <1> ;DSK_STATE:	resb 	4
 31311 000067F7 <res 00000002>      <1> DSK_STATE:	resb 	2  ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 31312 000067F9 <res 00000002>      <1> DSK_TRK:	resb 	2
 31313                              <1> 
 31314                              <1> ;----------------------------------------
 31315                              <1> ;	FIXED DISK DATA AREAS		:
 31316                              <1> ;----------------------------------------
 31317                              <1> 
 31318 000067FB <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
 31319 000067FC <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
 31320 000067FD <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
 31321                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
 31322                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
 31323                              <1> ;port2_off	resb	1		; Hard disk controller 2 - port offset
 31324                              <1> 
 31325 000067FE <res 00000002>      <1> alignb 4
 31326                              <1> 
 31327                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 31328                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 31329                              <1> HF_TBL_VEC: ; 22/12/2014	
 31330 00006800 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 31331 00006804 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 31332 00006808 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
 31333 0000680C <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
 31334                              <1> 
 31335                              <1> ; 03/01/2015
 31336 00006810 <res 00000001>      <1> LBAMode:     	resb	1
 31337                              <1> 
 31338                              <1> ; *****************************************************************************
 31339                                  
 31340                                  ;;; Real Mode Data (10/07/2015 - BSS)
 31341                                  
 31342                                  ;alignb 2
 31343                                  
 31344                                  ; 02/01/2022
 31345                                  ;%include 'ux.s' ; 12/04/2015 (unix system/user/process data)
 31346                                  
 31347                                  ; 17/04/2021
 31348                                  ; (memory page swap parameters are disabled as temporary)
 31349                                  ;
 31350                                  ;; Memory (swap) Data (11/03/2015)
 31351                                  ; 09/03/2015
 31352                                  ;swpq_count: resw 1 ; count of pages on the swap que
 31353                                  ;swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
 31354                                  ;swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes).	
 31355                                  ;swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 31356                                  ;swpd_next:  resd 1 ; next free page block
 31357                                  ;swpd_last:  resd 1 ; last swap page block	
 31358                                  
 31359 00006811 <res 00000003>          alignb 4
 31360                                  
 31361                                  ; 10/07/2015
 31362                                  ; 28/08/2014
 31363 00006814 <res 00000004>          error_code:  resd 1
 31364                                  ; 29/08/2014
 31365 00006818 <res 00000004>          FaultOffset: resd 1
 31366                                  ; 21/09/2015
 31367 0000681C <res 00000004>          PF_Count:    resd 1 ; total page fault count
 31368                                  		    ; (for debugging - page fault analyze)
 31369                                  		    ; 'page _fault_handler' (memory.s)
 31370                                  		    ; 'sysgeterr' (u9.s)
 31371                                  ; 23/02/2022
 31372 00006820 <res 00000004>          rtc_ticks:  resd 1  ; (temporary! this rtc counter value may be used 
 31373                                  		    ;  for a system call in next retro unix 386 version)
 31374                                  		    ; -2 ticks per second-
 31375                                  ;; 21/08/2015
 31376                                  ;;buffer: resb (nbuf*520) ;; sysdefs.s, ux.s
 31377                                  
 31378                                  ; 02/01/2022
 31379                                  %include 'ux.s'	; 12/04/2015 (unix system/user/process data)
 31380                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 31381                              <1> ; (re-write kernel for test by using previous version without a major defect)
 31382                              <1> ; ****************************************************************************
 31383                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - ux.s 
 31384                              <1> ; Last Modification: 15/07/2022
 31385                              <1> ;
 31386                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 31387                              <1> ; (Modified from 
 31388                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 31389                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 31390                              <1> ; ----------------------------------------------------------------------------
 31391                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 31392                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 31393                              <1> ; <Bell Laboratories (17/3/1972)>
 31394                              <1> ; <Preliminary Release of UNIX Implementation Document>
 31395                              <1> ; (Section E10 (17/3/1972) - ux.s)
 31396                              <1> ; ****************************************************************************
 31397                              <1> 
 31398                              <1> ; 15/07/2022
 31399                              <1> ; 08/06/2022
 31400                              <1> ; 15/05/2022
 31401                              <1> ; 21/03/2022
 31402                              <1> ; 27/02/2022
 31403                              <1> ; 12/01/2022
 31404                              <1> ; 22/11/2021 (Modification in Runix v1.1 'ux.s' for runix v2 fs compatibility)
 31405                              <1> ; 18/07/2021
 31406                              <1> ; 15/07/2021
 31407                              <1> ; 12/05/2021
 31408                              <1> ; 09/05/2021
 31409                              <1> ; 06/05/2021
 31410                              <1> ; 02/05/2021
 31411                              <1> ; 26/01/2020 (NASM version of SuperBlock structure in UNIXHDCP.ASM)
 31412                              <1> 
 31413                              <1> ; 21/12/2019 (UNIXCOPY.COM, UNIXCOPY.ASM, UNIXHDCP.COM, UNIXHDCP.ASM)
 31414                              <1> ; 19/12/2019 (UNIXHDFS.COM, RUFSHDI.ASM)
 31415                              <1> ; 01/09/2019 - Retro UNIX 386 v2 SuperBlock
 31416                              <1> 
 31417                              <1> ; 14/01/2020 - Super Block modification:
 31418                              <1> ;	     - Extended sections/divisions (consequental sectors)
 31419                              <1> ;	     - (for swapping, configuration, boot space etc.)	
 31420                              <1> 
 31421                              <1> ; 26/01/2020 (unix386.s, ux.s)
 31422                              <1> ; 14/01/2020
 31423                              <1> SB.HiddenSects	equ SB.BootSectAddr
 31424                              <1> SB.TotalSects	equ SB.VolumeSize
 31425                              <1> 
 31426                              <1> ; 11/05/2021 (Retro UNIX 386 v2)
 31427                              <1> ; Super block status byte (byte 0 of SB.status dword)
 31428                              <1> ; 	bit 0 - superblock modified flag
 31429                              <1> ; 	bit 1 - inode map modified flag
 31430                              <1> ; 	bit 2 - free blocks map modified flag
 31431                              <1> ; 	bit 3 - inode table modified flag
 31432                              <1> ;; 	bit 4 - boot sector modified flag ; 17/08/2021
 31433                              <1> ; 17/08/2021
 31434                              <1> ;	bit 4 - file data write error (for SB.LastInode)
 31435                              <1> ;	bit 5 - inode table write error (for SB.LastInode)
 31436                              <1> ;	bit 6 - inode map write error (for SB.LastInode)
 31437                              <1> ;	bit 7 - free blocks map write error (for SB.LastInode)
 31438                              <1> 	
 31439                              <1> ; 21/12/2019
 31440                              <1> ; 19/12/2019 - Retro UNIX 386 v2 HD (071h) partition boot sector 
 31441                              <1> ;	       (UNIXHDFS.ASM)
 31442                              <1> ; 04/12/2015 (14 byte file names - Retro UNIX 386 v1.1)
 31443                              <1> ; 14/07/2015 (8 byte file names - Retro UNIX 8086 v1 & Retro UNIX 386 v1.0)
 31444                              <1> 
 31445                              <1> bsFSystemID 	equ 2  ; db 'RUFS'	
 31446                              <1> bsVolumeSerial 	equ 6  ; dd 0 ; (4 bytes)
 31447                              <1> bsFDSign	equ 10 ; db 'fd'
 31448                              <1> bsDriveNumber 	equ 12 ; db 0 ; fd0 or fd1 (0 or 1)
 31449                              <1> bsReserved 	equ 13 ; db 0 ; (512 bytes per sector)	
 31450                              <1> bsSecPerTrack	equ 14 ; db 18 ; (9 or 15)	
 31451                              <1> bsHeads		equ 15 ; db  ; 2
 31452                              <1> bsTracks	equ 16 ; dw 80 ; bsCylinders
 31453                              <1> bs_bf_inode_number equ 18 ; dw 0 ; 0 or Boot/Startup File I-Number
 31454                              <1> bsInfoEndsign	equ 20 ; db '@'
 31455                              <1> ; 21/12/2019
 31456                              <1> bsMagic		equ 20 ; db '@'
 31457                              <1> bsPartitionID	equ 21 ; db 0 ; db 71h
 31458                              <1> bsHiddenSects	equ 22 ; dd 0 ; Hidden sectors (Boot Sector LBA)
 31459                              <1> 
 31460                              <1> ; 22/11/2021 - Retro UNIX v2 I-node Flags
 31461                              <1> ; ------------------------------------------------------------------
 31462                              <1> ; UINSTALL.ASM (included in UNIXFDFS.ASM) - 23/01/2020
 31463                              <1> ; ------------------------------------------------------------------
 31464                              <1> 
 31465                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
 31466                              <1> ; 1000000000000000b 	IFREG - 1 = regular file (8000h)
 31467                              <1> ; 0100000000000000b	IFDIR - 1 = directory (4000h)
 31468                              <1> ; 0010000000000000b	IRSVD - 0 = reserved bit (2000h) ; Mounted flag
 31469                              <1> ; 0001000000000000b	ILARG - large file addressing bit (1000h)
 31470                              <1> ; 0000100000000000b	ISUID - set user id on exec (800h)
 31471                              <1> ; 0000010000000000b	ISGID - set group id on exec (400h)
 31472                              <1> ; 0000001000000000b	IEXTT - 1 = use extents (200h)
 31473                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 31474                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 31475                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 31476                              <1> ; 0000000000100000b	read, group (20h)
 31477                              <1> ; 0000000000010000b	write, group (10h)
 31478                              <1> ; 0000000000001000b	execute, group (08h)
 31479                              <1> ; 0000000000000100b	read, others (04h)
 31480                              <1> ; 0000000000000010b	write, others (02h)
 31481                              <1> ; 0000000000000001b	execute, others (01h)
 31482                              <1> 
 31483                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
 31484                              <1> ; 1000000000000000b 	IFREG - 0 = device file (8000h)
 31485                              <1> ; 0100000000000000b	IFBLK - 1 = block device (4000h)
 31486                              <1> ; 0010000000000000b	IFCHR - character special (2000h) -always 1-
 31487                              <1> ; 0001000000000000b	IFIFO - fifo special (1000h)
 31488                              <1> ; 0000100000000000b	IPIPE - pipe special (800h) ; 07/02/2020
 31489                              <1> ; 0000010000000000b	IREDIR - redirected (400h)  ; 07/02/2020
 31490                              <1> ; 0000001000000000b	IEXTR - 1 = external device driver (200h)
 31491                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 31492                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 31493                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 31494                              <1> ; 0000000000100000b	read, group (20h)
 31495                              <1> ; 0000000000010000b	write, group (10h)
 31496                              <1> ; 0000000000001000b	execute, group (08h)
 31497                              <1> ; 0000000000000100b	read, others (04h)
 31498                              <1> ; 0000000000000010b	write, others (02h)
 31499                              <1> ; 0000000000000001b	execute, others (01h)
 31500                              <1> 
 31501                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 31502                              <1> ; (SB structure has been moved from here to 'sysdefs.s'
 31503                              <1> ;	to overcome NASM's bss addressing bug !!!)
 31504                              <1> ; (('ux.s' bss section addresses are being overlapped
 31505                              <1> ;    when SB structure is defined in 'ux.s'))
 31506                              <1> 
 31507                              <1> %if 0
 31508                              <1> 
 31509                              <1> struc SB ; SuperBlock
 31510                              <1> 
 31511                              <1> .Header:	resd 1
 31512                              <1> ;.HiddenSects:
 31513                              <1> .BootSectAddr:	resd 1	; Hidden Sectors
 31514                              <1> ;.TotalSects:
 31515                              <1> .VolumeSize:	resd 1	; Entire Volume/Partition Size (includes ext. volume)
 31516                              <1> .Version:	resd 1	
 31517                              <1> .BlockSize:	resd 1	
 31518                              <1> .InodeCount:	resd 1	
 31519                              <1> .FreeMapAddr:	resd 1	
 31520                              <1> .FreeMapSize:	resd 1	
 31521                              <1> .InodeMapAddr:	resd 1	
 31522                              <1> .InodeMapSize:	resd 1	
 31523                              <1> .InodeTblAddr:	resd 1	
 31524                              <1> .InodeTblSize:	resd 1	
 31525                              <1> .FreeInodes:	resd 1	
 31526                              <1> .FirstFreeIno:	resd 1	
 31527                              <1> .FreeBlocks:	resd 1	
 31528                              <1> .FirstFreeBlk:	resd 1	
 31529                              <1> .BootSecParms:	resb 19	; v1
 31530                              <1> .BSExtension:	resb 5	; v2 HDFS
 31531                              <1> .Status:	resb 1	; 12/05/2021 (system modification status) (*)
 31532                              <1> .Pdrv:		resb 1  ; Physical disk number (index) ; 12/05/2021 (*) 
 31533                              <1> .Uno:		resw 1	; user/process number ; 12/05/2021 (*)
 31534                              <1> .ModifTime:	resd 1	; (last) modification time (*)
 31535                              <1> .ExtdVolTbl:	resd 1	; Extended Volume Start/Table Address
 31536                              <1> .ExtdVolSize:	resd 1	; Extended Volume (swap section etc.) Size	
 31537                              <1> .LBA_rw:	resb 1
 31538                              <1> .ClusterSize:	resb 1
 31539                              <1> .ReadOnly:	resb 1	; (SB will not be written to disk if bit 0 is 1)
 31540                              <1> .Mounted:	resb 1
 31541                              <1> .MountInode:	resd 1  ; double word
 31542                              <1> .DevMajor:	resb 1
 31543                              <1> .DevMinor:	resb 1
 31544                              <1> .LongName:	resb 1
 31545                              <1> .Direntry32:	resb 1
 31546                              <1> ; 18/07/2021
 31547                              <1> .FileBuffer:	resd 1
 31548                              <1> .ItabBuffer:	resd 1
 31549                              <1> .ImapBuffer:	resd 1
 31550                              <1> .FmapBuffer:	resd 1
 31551                              <1>  ; 15/07/2021
 31552                              <1> .LastInode:	resd 1
 31553                              <1> ; 02/05/2021
 31554                              <1> .FmapIndex:	resd 1
 31555                              <1> .ImapIndex:	resd 1
 31556                              <1> .ItableIndex:	resd 1
 31557                              <1> .Reserved:	resb 508-148 ; 18/07/2021
 31558                              <1> .Footer:	resd 1
 31559                              <1> 
 31560                              <1> endstruc
 31561                              <1> 
 31562                              <1> %endif
 31563                              <1> 
 31564                              <1> alignb 2
 31565                              <1> 
 31566                              <1> inode:
 31567                              <1> 	;; 11/03/2013. 
 31568                              <1> 	;;Derived from UNIX v1 source code 'inode' structure (ux).
 31569                              <1> 	;;i.
 31570                              <1> 	;
 31571                              <1> 	;i.flgs: resw 1
 31572                              <1> 	;i.nlks: resb 1
 31573                              <1> 	;i.uid:	 resb 1
 31574                              <1>         ;i.size: resw 1 ; size
 31575                              <1> 	;i.dskp: resw 8 ; 16 bytes
 31576                              <1> 	;i.ctim: resd 1
 31577                              <1> 	;i.mtim: resd 1
 31578                              <1> 	;i.rsvd: resw 1 ; Reserved (ZERO/Undefined word for UNIX v1)
 31579                              <1> 
 31580                              <1> 	; 26/01/2020
 31581                              <1> 	; Retro UNIX 386 v2.0 - Modified UNIX v7 inode model
 31582                              <1> 	;	(15/09/2029 .. 18/12/2019)
 31583                              <1> 
 31584 00006824 <res 00000002>      <1> 	i.flgs:   resw 1	; /* mode and type of file */
 31585 00006826 <res 00000002>      <1> 	i.nlks:	  resw 1	; /* number of links to file */
 31586 00006828 <res 00000002>      <1> 	i.uid:	  resw 1	; /* owner's user id */  - 0 to 65535 -
 31587 0000682A <res 00000001>      <1> 	i.gid:	  resb 1	; /* owner's group id */ - o to 255 -
 31588 0000682B <res 00000001>      <1> 	i.size_h: resb 1	; /* number of bytes in file */ ; byte 5
 31589 0000682C <res 00000004>      <1> 	i.size:	  resd 1 ; size	; /* number of bytes in file */
 31590 00006830 <res 00000028>      <1> 	i.dskp:	  resd 10 ; 40 bytes ; /* disk block addresses */
 31591 00006858 <res 00000004>      <1> 	i.atim:	  resd 1	; /* time last accessed */
 31592 0000685C <res 00000004>      <1> 	i.mtim:	  resd 1	; /* time last modified */
 31593 00006860 <res 00000004>      <1> 	i.ctim:	  resd 1	; /* time created */
 31594                              <1> 
 31595                              <1> I_SIZE	equ $ - inode
 31596                              <1> 
 31597                              <1> process:
 31598                              <1> 	; 27/02/2022
 31599                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2) 
 31600                              <1> 	; 06/05/2015
 31601                              <1> 	; 11/03/2013 - 05/02/2014
 31602                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
 31603                              <1> 	;p.
 31604                              <1> 	
 31605 00006864 <res 00000020>      <1>         p.pid:   resw nproc
 31606 00006884 <res 00000020>      <1>         p.ppid:  resw nproc
 31607                              <1> 	;p.break: resw nproc ; 12/01/2022 (p.break is not used)
 31608 000068A4 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
 31609                              <1> 	; 27/02/2022 (p.waitc is not used)
 31610                              <1> 	;p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
 31611 000068B4 <res 00000010>      <1> 	p.link:	 resb nproc
 31612 000068C4 <res 00000010>      <1> 	p.stat:	 resb nproc
 31613                              <1> 
 31614                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 feature only !) 
 31615 000068D4 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
 31616                              <1> 			    ; 'user' structure	
 31617                              <1> 
 31618                              <1> P_SIZE	equ $ - process
 31619                              <1> 
 31620                              <1> ; fsp table (original UNIX v1)
 31621                              <1> ;
 31622                              <1> ;Entry
 31623                              <1> ;          15                                      0
 31624                              <1> ;  1     |---|---------------------------------------|
 31625                              <1> ;        |r/w|       i-number of open file           |
 31626                              <1> ;        |---|---------------------------------------| 
 31627                              <1> ;        |               device number               |
 31628                              <1> ;        |-------------------------------------------|
 31629                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
 31630                              <1> ;        |-------------------------------------------| 
 31631                              <1> ;        |  flag that says    | number of processes  |
 31632                              <1> ;        |   file deleted     | that have file open  |
 31633                              <1> ;        |-------------------------------------------| 
 31634                              <1> ;  2     |                                           |
 31635                              <1> ;        |-------------------------------------------| 
 31636                              <1> ;        |                                           |
 31637                              <1> ;        |-------------------------------------------|
 31638                              <1> ;        |                                           |
 31639                              <1> ;        |-------------------------------------------|
 31640                              <1> ;        |                                           |
 31641                              <1> ;        |-------------------------------------------| 
 31642                              <1> ;  3     |                                           | 
 31643                              <1> ;        |                                           |  
 31644                              <1> ;
 31645                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
 31646                              <1> 
 31647                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
 31648                              <1> 
 31649                              <1> ;Entry
 31650                              <1> ;         15                    7                   0
 31651                              <1> ;  1     |-------------------------------------------|
 31652                              <1> ;        |   	     i-number of open file           |
 31653                              <1> ;        |-------------------------------------------| 
 31654                              <1> ;        |        high word of 32 bit i-number       |
 31655                              <1> ;        |-------------------------------------------|
 31656                              <1> ;        | open mode & status  |   device number     |
 31657                              <1> ;        |-------------------------------------------|
 31658                              <1> ;        |    reserved byte    |     open count      |
 31659                              <1> ;        |-------------------------------------------| 
 31660                              <1> ;        | offset pointer, i.e., r/w pointer to file |
 31661                              <1> ;        |-------------------------------------------|
 31662                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
 31663                              <1> ;        |-------------------------------------------|
 31664                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
 31665                              <1> ;        |-------------------------------------------|
 31666                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
 31667                              <1> ;        |-------------------------------------------|
 31668                              <1> ;  2     |                                           |
 31669                              <1> ;        |-------------------------------------------| 
 31670                              <1> ;        |                                           |
 31671                              <1> ;        |-------------------------------------------|
 31672                              <1> ;        |                                           |
 31673                              <1> ;        |-------------------------------------------|
 31674                              <1> ;        |                                           |
 31675                              <1> ;        |-------------------------------------------| 
 31676                              <1> ;        |                                           | 
 31677                              <1> 
 31678                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 31679                              <1> ; (file structure has been moved from here to 'sysdefs.s'
 31680                              <1> ;	to overcome NASM's bss addressing bug !!!)
 31681                              <1> ; (('ux.s' bss section addresses are being overlapped
 31682                              <1> ;    when file file structure is defined in 'ux.s'))
 31683                              <1> 
 31684                              <1> %if 0
 31685                              <1> 
 31686                              <1> ; 22/11/2021
 31687                              <1> ; 21/07/2021 - Retro UNIX 386 v2 open file structure revision
 31688                              <1> 
 31689                              <1> struc file	; open files (fsp) structure
 31690                              <1>   .inode:  resw 1  ; inode number of open file (32 bit)
 31691                              <1>   .i32:	   resw 1  ; higher word of inode number (reserved)
 31692                              <1>   .drive:  resb 1  ; logical drive (disk) number
 31693                              <1>   .flags:  resb 1  ; open mode and status
 31694                              <1>   .count:  resb 1  ; number of processes that have file open
 31695                              <1>   ;.rsvd:  resb 1  ; reserved byte (for next versions)
 31696                              <1>   .mnt:    resb 1  ; mnttab index+1 (0 = not mounted)
 31697                              <1>   .offset: resd 1  ; file offset/pointer (64 bit) 
 31698                              <1>   .o64:	   resd 1  ; higher 32 bit of file offset
 31699                              <1>  .size:  ; = 16		
 31700                              <1> endstruc
 31701                              <1> 
 31702                              <1> %endif
 31703                              <1> 
 31704                              <1> ; 01/01/2022
 31705                              <1> ; 22/11/2021
 31706                              <1> ;fp.size equ file.size
 31707                              <1> 
 31708                              <1> ; 02/01/2022
 31709 00006914 <res 00000320>      <1> fsp:	resb nfiles*16 ; (NFILES*fp.size)
 31710                              <1> ; 01/01/2022
 31711                              <1> ; 22/11/2021 (16/05/2021)
 31712                              <1> ;fsp:	resb NFILES*16 ; (NFILES*fp.size)
 31713                              <1> ; 15/04/2015
 31714                              <1> ;fsp:	resb nfiles*10 ; 11/05/2015 (8 -> 10)
 31715                              <1> 
 31716 00006C34 <res 00000048>      <1> bufp:	resd (nbuf+2) ; will be initialized 
 31717 00006C7C <res 00000004>      <1> ii:	resd 1 ; 22/11/2021 ; 32 bit inode number (high word is 0)
 31718                              <1> ; 22/11/2021
 31719 00006C80 <res 00000001>      <1> idev:	resb 1 ; logical drive number of current inode, [ii]
 31720 00006C81 <res 00000001>      <1> cdev:	resb 1 ; current logical drive number for current user
 31721                              <1> 
 31722                              <1> ; 18/05/2015
 31723                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
 31724                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
 31725                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
 31726                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
 31727                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
 31728                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
 31729                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
 31730                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
 31731                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
 31732                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
 31733                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
 31734 00006C82 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
 31735                              <1> 	        ; as above, for physical drives numbers in following table
 31736 00006C83 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
 31737                              <1> ; 15/04/2015
 31738                              <1> ;active: resb 1 ; 15/07/2022
 31739                              <1> ;	 resb 1 ; 09/06/2015
 31740 00006C84 <res 00000002>      <1> mpid:	 resw 1
 31741                              <1> ; 22/11/2021 (32 bit inode numbers)
 31742 00006C86 <res 00000004>      <1> rootdir: resd 1
 31743 00006C8A <res 00000004>      <1> mnti:	 resd 1
 31744                              <1> ; 15/05/2022 ; (parent dir inumber of [mnti])
 31745 00006C8E <res 00000004>      <1> mntp:	 resd 1 
 31746                              <1> 
 31747                              <1> ; 14/02/2014
 31748                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
 31749                              <1> ;		      Single level run queue
 31750                              <1> ;		      (in order to solve sleep/wakeup lock)
 31751 00006C92 <res 00000002>      <1> runq:	resw 1
 31752 00006C94 <res 00000001>      <1> imod:	resb 1
 31753 00006C95 <res 00000001>      <1> imodx:	resb 1 ; 09/01/2022 - Retro UNIX 386 v1.2
 31754 00006C96 <res 00000001>      <1> smod:	resb 1
 31755 00006C97 <res 00000001>      <1> mmod:	resb 1
 31756                              <1> ;	resb 1 ; 09/01/2022 
 31757 00006C98 <res 00000001>      <1> sysflg:	resb 1
 31758                              <1> 
 31759 00006C99 <res 00000003>      <1> alignb 4
 31760                              <1> 
 31761                              <1> user:
 31762                              <1> 	; 01/01/2022
 31763                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 31764                              <1> 	; 24/10/2021
 31765                              <1> 	; 18/10/2021
 31766                              <1> 	; 10/06/2021
 31767                              <1> 	; 30/05/2021
 31768                              <1> 	; 29/05/2021
 31769                              <1> 	; 21/05/2021
 31770                              <1> 	; 20/05/2021
 31771                              <1> 	; 16/05/2021
 31772                              <1> 	; 01/05/2021
 31773                              <1> 	; 27/03/2021
 31774                              <1> 	; 17/04/2020, 28/04/2020
 31775                              <1> 	; 25/03/2020, 28/03/2020
 31776                              <1> 	; 20/03/2020, 22/03/2020, 23/03/2020
 31777                              <1> 	; 05/03/2020, 08/03/2020, 14/03/2020
 31778                              <1> 	; 07/02/2020 - Retro UNIX 386 v2
 31779                              <1> 	;
 31780                              <1> 	; 27/02/2017 - TRDOS 386
 31781                              <1> 	; 13/01/2017 - TRDOS 386
 31782                              <1> 	; 10/01/2017 - TRDOS 386
 31783                              <1> 	; 19/12/2016 - TRDOS 386	
 31784                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0) 
 31785                              <1> 	; 	       [u.pri] usage method modification
 31786                              <1> 	;
 31787                              <1> 	; 04/12/2015 - Retro UNIX 386 v1.1 (14 byte file/directory names)
 31788                              <1> 	; 18/10/2015
 31789                              <1> 	; 12/10/2015
 31790                              <1> 	; 21/09/2015
 31791                              <1> 	; 24/07/2015
 31792                              <1> 	; 16/06/2015
 31793                              <1> 	; 09/06/2015
 31794                              <1> 	; 11/05/2015
 31795                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 31796                              <1> 	; 10/10/2013
 31797                              <1> 	; 11/03/2013. 
 31798                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
 31799                              <1> 	;u.
 31800                              <1> 
 31801 00006C9C <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
 31802 00006CA0 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
 31803 00006CA4 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
 31804 00006CA8 <res 00000002>      <1> 	u.cdir:	  resw 1
 31805 00006CAA <res 00000002>      <1> 		  resw 1 ; 28/03/2020 - reserved for 32 bit inode number
 31806                              <1> 	;u.cdrv:  resw 1 ; 17/04/2020 (dword alignment) 
 31807 00006CAC <res 00000001>      <1> 	u.cdrv:   resb 1 ; 01/05/2021
 31808 00006CAD <res 00000001>      <1> 		  resb 1 ; 01/05/2021 (dword alignment)
 31809 00006CAE <res 0000000A>      <1> 	u.fp:	  resb 10 ; Retro UNIX 386 v1
 31810                              <1> 	;u.fp:	  resb OPENFILES ; Retro UNIX 386 v2 ; 28/03/2020 
 31811                              <1> 	u.fsp:	  ; 16/05/2021
 31812 00006CB8 <res 00000004>      <1> 	u.fofp:	  resd 1 ; 16/05/2021 (pointer to fsp entry)
 31813 00006CBC <res 00000004>      <1> 	u.dirp:	  resd 1
 31814 00006CC0 <res 00000004>      <1> 	u.namep:  resd 1
 31815 00006CC4 <res 00000004>      <1> 	u.off:	  resd 1
 31816                              <1> 	;	  resd 1 ; 08/03/2020 - Retro UNIX 386 v2 - 64 bit fptr
 31817 00006CC8 <res 00000004>      <1> 	u.base:	  resd 1
 31818 00006CCC <res 00000004>      <1> 	u.count:  resd 1
 31819 00006CD0 <res 00000004>      <1> 	u.nread:  resd 1
 31820 00006CD4 <res 00000004>      <1> 	u.break:  resd 1 ; break
 31821                              <1> 	; 16/05/2021 (Retro UNIX 386 v2)
 31822 00006CD8 <res 00000001>      <1> 	u.mode:   resb 1 ; 16/05/2021 (sysread, syswrite, 'rdwr' file mode)
 31823                              <1> 	; 10/01/2017 (TRDOS 386, relocation and dword alignment)
 31824                              <1> 	; tty number (rtty, rcvt, wtty)
 31825 00006CD9 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
 31826 00006CDA <res 00000002>      <1> 	u.ttyp:	  resw 1 
 31827 00006CDC <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
 31828                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
 31829 00006CEC <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
 31830 00006CED <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 31831 00006CEE <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
 31832 00006CEF <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 31833                              <1> 	; 10/06/2021
 31834                              <1> 	;u.signal: resw 1 ; 21/05/2021 - Retro UNIX 386 v2
 31835                              <1> 	;	  resw 1 ; reserved ; 21/05/2021	
 31836 00006CF0 <res 00000002>      <1> 	u.intr:	  resw 1
 31837 00006CF2 <res 00000002>      <1> 	u.quit:	  resw 1
 31838                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
 31839                              <1> 	;u.ilgins: resw 1 ; 10/01/2017
 31840                              <1> 	;u.cdrv:  resw 1 ; cdev ; 17/04/2020 (moved to up)
 31841                              <1> 	;u.uid:	  resb 1 ; uid
 31842                              <1> 	;u.ruid:  resb 1
 31843 00006CF4 <res 00000001>      <1> 	u.bsys:	  resb 1
 31844 00006CF5 <res 00000001>      <1> 	u.uno:	  resb 1
 31845 00006CF6 <res 00000002>      <1>         u.uid:	  resw 1 ; uid	; 27/03/2021 - Retro UNIX 386 v2
 31846 00006CF8 <res 00000002>      <1> 	u.ruid:	  resw 1	; 16 bit uid
 31847 00006CFA <res 00000001>      <1> 	u.gid:	  resb 1 ; gid 	; 27/03/2021 - Retro UNIX 386 v2
 31848 00006CFB <res 00000001>      <1> 	u.rgid:	  resb 1
 31849                              <1> 	; 20/05/2021 - Retro UNIX 386 v2
 31850 00006CFC <res 00000004>      <1> 	u.procp:  resd 1 ; /* pointer to proc structure */		
 31851 00006D00 <res 00000004>      <1> 	u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
 31852 00006D04 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
 31853 00006D08 <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
 31854 00006D0C <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
 31855                              <1> 		; 24/10/2021 (32 bit value for Retro UNIX 386 v2)
 31856 00006D10 <res 00000004>      <1> 	u.pcount: resd 1 ; 20/05/2015 (byte -transfer- count for page)
 31857                              <1> 	;u.pncount: resw 1 
 31858                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
 31859                              <1> 	;u.pnbase:  resd 1 
 31860                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
 31861 00006D14 <res 00000002>      <1> 	u.rsvd:	  resw 1 ; 04/12/2021 (dword alignment)
 31862                              <1> 			 ; 09/06/2015
 31863 00006D16 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign
 31864                              <1> 		; 08/03/2020 (block device read/write flag for 'sioreg')		
 31865 00006D17 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
 31866                              <1> 			 ; 24/07/2015 - 24/06/2015
 31867                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
 31868                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
 31869                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
 31870                              <1>  			 ; 24/06/2015	  	
 31871                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
 31872                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
 31873                              <1> 	; last error number
 31874 00006D18 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
 31875                              <1> 			; Retro UNIX 8086/386 v1 feature only!
 31876                              <1> 			; 21/09/2015 (debugging - page fault analyze)
 31877 00006D1C <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
 31878                              <1> 		; 29/05/2021 - Retro UNIX 386 v2, 2021 (sleep, psig)
 31879                              <1> ;	u.signal: resd 1 ; unix signal recognition (enabling, accepting) bits	
 31880                              <1> ;	u.srb:	  resb 1 ; signal handling/responding method
 31881                              <1> ;	u.snum:	  resb 1 ; signal number (last signal number)
 31882                              <1> ;	u.exit:	  resb 1 ; exit code ; 30/05/2021 - Retro UNIX 386 v2
 31883                              <1> ;	u.s_lock: resb 1 ; signal handling (phase) lock	
 31884                              <1> ;	u.s_addr: resd 1 ; Signal Response Byte or signal handler (callback) address
 31885                              <1> ;	u.s_time: resd 1 ; signal time in unix epoch format		
 31886                              <1> 		; 19/12/2016 (TRDOS 386)	
 31887                              <1> ;	u.tcb:	  resd 1 ; Timer callback address/flag which will be used by timer int
 31888                              <1> 		; 13/01/2017 (TRDOS 386)
 31889                              <1> ;	u.t_lock: resb 1 ; Timer interrupt (callback) lock (unlocked by 'sysrele')
 31890                              <1> ;	u.t_mode: resb 1 ; running mode during timer interrupt (0= system, 0FFh= user)
 31891                              <1> 		; 26/02/2017 (TRDOS 386)
 31892                              <1> ;	u.irqc:	  resb 1  ; Count of IRQ callback services (IRQs in use)
 31893                              <1> 		; 28/02/2017 (TRDOS 386) 
 31894                              <1> ;	u.irqwait: resb 1 ; IRQ waiting for callback service flag (IRQ number, If > 0)
 31895                              <1> ;	u.r_lock:  resb 1 ; 'IRQ callback service is in progress' flag (IRQ lock)
 31896                              <1> ;	u.r_mode:  resb 1 ; running mode during hardware interrupt
 31897                              <1> 		; 07/02/2020 - Retro UNIX 386 v2
 31898                              <1> ;	u.redir:  resb 1 ; device func redirection permitted by user (if u.redir > 0)
 31899                              <1> 		; 26/02/2020 - Retro UNIX 386 v2
 31900                              <1> ;	u.rwm:	  resb 1  ; read & write mode for devices/drives, 0 = direct, 1 = fs r/w 
 31901                              <1> 		; 24/02/2020 - Retro UNIX 386 v2
 31902                              <1> 		; 24/10/2021 (32 bit value)
 31903                              <1> ;	u.scount: resd 1 ; sub byte count ; 22/03/2020 
 31904                              <1> 		; 07/03/2020 - Retro UNIX 386 v2
 31905                              <1> ;	u.bps:	  resw 1 ; u.bps = bytes per sector, for readi and writei
 31906                              <1> ;		  resw 1 ; 24/10/2021 (32 bit value for using with 32 bit registers)	
 31907                              <1> 		; 23/03/2020 - Retro UNIX 386 v2
 31908                              <1> ;	u.timeout: resw 1 ; timeout setting (seconds) -for 'sleep'-
 31909                              <1> 		; 28/04/2020 - Retro UNIX 386 v2
 31910                              <1> ;	u.lock:	  resb 1 ; Device lock flag (bit 0 is for device/disk read/write)
 31911                              <1> 		; 24/04/2020
 31912                              <1> 		; 17/04/2020 - Retro UNIX 386 v2
 31913                              <1> ;	u.ifs:	  resb 1 ; (current) installable file system driver index number
 31914                              <1> 		; 25/03/2020
 31915                              <1> 		; 20/03/2020
 31916                              <1> 	;u.lcount: resd 1 ; last byte count for 'writei' (for restoring write count)	
 31917                              <1> 
 31918                              <1> 		; 08/03/2020 - Retro UNIX 386 v2 ('sioreg, 'readi')
 31919                              <1> 	;u.limit: resd 1  ; disk/file size limit for block device read/write ('sioreg')			
 31920                              <1> 	;	  resd 1  ; 08/03/2020 - 64 bit limit (disk size in bytes)
 31921                              <1> 	;	; 26/02/2020 - Retro UNIX 386 v2
 31922                              <1> 	;u.sector: resd 1  ; current sector (for readi and writei, device r/w)  		
 31923                              <1> 	;u.buffer: resd 1  ; current buffer (for readi and writei, device r/w) 
 31924                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 31925                              <1> 	;u.devmm: resw 1 ; device major (hb) and minor (lb) numbers
 31926                              <1> 	;u.zero:  resw 1 ; 14/03/2020 - Must be ZERO for current version
 31927                              <1> 		; 22/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 31928                              <1> ;	u.device: resd 1 ; (blk, chr) device description table (entry) address 	
 31929                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 31930                              <1> ;	u.function: resd 1 ; device function (read, write)
 31931                              <1> 		; 22/03/2020 - Retro UNIX 386 v2, 2020 (readi, writei)
 31932                              <1> ;	u.buffer: resd 1  ; for saving buffer header address for 'poke'
 31933                              <1> ;	u.inode:  resw 1  ; for saving inode number of current (device) inode
 31934                              <1> ;		  resw 1  ; 18/10/2021 Retro UNIX 386 v2 - 32 bit inode number			
 31935                              <1> ;	u.idev:	  resb 1  ; for saving logical drv number of current (dev) inode
 31936                              <1> 		; 04/12/2021
 31937                              <1> ;	u.rsvd2:  resw 1  ; (for dword alignment)	
 31938                              <1> 		; 27/02/2017 (TRDOS 386) 
 31939                              <1> ;; 31/12/2021 - temporary !
 31940                              <1> ;	u.fpsave: resb 1  ; TRDOS 386, 'save/restore FPU registers' flag
 31941                              <1> alignb 4
 31942                              <1> 	; !! wrong sizing in TRDOS 386 v2.0.4 (in 'ubss.s', 28/02/2017) !! 
 31943                              <1> 	;u.fpregs: resb 94 ; 94 byte area for saving and restoring FPU registers
 31944                              <1> 	; 30/05/2021 - Retro UNIX 386 v2
 31945                              <1> ;	u.fpregs: resb 108 ; 108 byte area for saving and restoring FPU registers	
 31946                              <1> alignb 4
 31947                              <1> 
 31948                              <1> U_SIZE	equ $ - user
 31949                              <1> 
 31950                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
 31951 00006D20 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
 31952 00006D24 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
 31953 00006D28 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
 31954                              <1> ;ncount: resw 1 ; remain byte count in page for 'namei' & 'sysexec'
 31955                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'ncount')
 31956 00006D2C <res 00000004>      <1> ncount: resd 1	; remain byte count in page for 'namei' & 'sysexec'
 31957                              <1> ;argc:	resw 1	; argument count for 'sysexec'
 31958                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'argc')
 31959 00006D30 <res 00000004>      <1> argc:	resd 1	; argument count for 'sysexec'
 31960 00006D34 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
 31961                              <1> 
 31962                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
 31963                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
 31964 00006D38 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
 31965 00006D39 <res 00000001>      <1> rwdsk:	 resb 1 ;; Read/Write function number (diskio) - 16/06/2015
 31966 00006D3A <res 00000001>      <1> mget_rw: resb 1 ; 22/11/2021 
 31967 00006D3B <res 00000001>      <1> retry_count: resb 1 ; Disk I/O retry count - 11/06/2015
 31968                              <1> 
 31969                              <1> ; 08/06/2022 - (BugFix) ! (level: resd 0) !
 31970                              <1> ; 22/11/2021 - Retro UNIX 386 v2 compatibility
 31971 00006D3C <res 00000004>      <1> level:	resd 1  ; level, level+1, level+2, level+3  ; for 'mget' procedure
 31972                              <1> 
 31973                              <1> ; (02/01/2022)
 31974                              <1> ; 27/11/2021
 31975                              <1> ; these are will be used for disk block allocation ('alloc' proc)
 31976                              <1> free_map_offset: 
 31977 00006D40 <res 00000004>      <1> 		resd 1
 31978 00006D44 <res 00000004>      <1> free_map_index:	resd 1
 31979                              <1> free_map_sector:
 31980 00006D48 <res 00000004>      <1> 		resd 1
 31981                              <1> ;free_map_buffer:
 31982                              <1> ;		resd 1
 31983                              <1> 
 31984                              <1> ; 12/01/2022
 31985                              <1> ; 27/11/2021 - temporary !
 31986                              <1> ;s.time:	resd 1
 31987                              <1> 
 31988                              <1> ;alignb 4
 31989                              <1> 
 31990                              <1> ; (02/01/2022)
 31991                              <1> ; 22/08/2015
 31992                              <1> ;buffer: resb nbuf * 520
 31993                              <1> 
 31994 00006D4C <res 00000008>      <1> sb0:	resd 2
 31995                              <1> ;s:
 31996                              <1> ; (root disk) super block buffer
 31997                              <1> systm:
 31998                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatible super block
 31999                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
 32000                              <1> 	; 11/03/2013. 
 32001                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
 32002                              <1> 	;s.
 32003                              <1> 
 32004                              <1> 	;resw 1
 32005                              <1> 	;resb 360 ; 2880 sectors ; original UNIX v1 value: 128
 32006                              <1> 	;resw 1
 32007                              <1> 	;resb 32 ; 256+40 inodes ; original UNIX v1 value: 64
 32008                              <1> 	;s.time: resd 1
 32009                              <1> 	;s.syst: resd 1
 32010                              <1>         ;s.wait_: resd 1 ; wait
 32011                              <1> 	;s.idlet: resd 1
 32012                              <1> 	;s.chrgt: resd 1
 32013                              <1> 	;s.drerr: resw 1
 32014                              <1> 
 32015                              <1> 	; 27/11/2021
 32016 00006D54 <res 00000200>      <1> 	resb 512	
 32017                              <1> 
 32018                              <1> ;S_SIZE	equ $ - systm
 32019                              <1> 
 32020                              <1> 	;resb 512-S_SIZE ; 03/06/2015
 32021                              <1> 
 32022 00006F54 <res 00000008>      <1> sb1:	resd 2
 32023                              <1> ; (mounted disk) super block buffer
 32024                              <1> mount:	
 32025 00006F5C <res 00000200>      <1> 	resb 512  ; 03/06/2015
 32026                              <1> 
 32027                              <1> ; 21/03/2022
 32028                              <1> ; hard disk masterboot sector buffer
 32029 0000715C <res 00000008>      <1> mbrbuf: resd 2
 32030 00007164 <res 00000200>      <1> 	resb 512
 32031                              <1> 
 32032                              <1> ; 10/01/2022
 32033 00007364 <res 00000200>      <1> dbli_buf: resb 512  ; double indir ptr buff for 'itrunc', 'tloop'
 32034 00007564 <res 00000200>      <1> trpi_buf: resb 512  ; triple indir ptr buff for 'itrunc', 'tloop'
 32035                              <1> 
 32036                              <1> ;/ ux -- unix
 32037                              <1> ;
 32038                              <1> ;systm:
 32039                              <1> ;
 32040                              <1> ;	.=.+2
 32041                              <1> ;	.=.+128.
 32042                              <1> ;	.=.+2
 32043                              <1> ;	.=.+64.
 32044                              <1> ;	s.time: .=.+4
 32045                              <1> ;	s.syst: .=.+4
 32046                              <1> ;	s.wait: .=.+4
 32047                              <1> ;	s.idlet:.=.+4
 32048                              <1> ;	s.chrgt:.=.+4
 32049                              <1> ;	s.drerr:.=.+2
 32050                              <1> ;inode:
 32051                              <1> ;	i.flgs: .=.+2
 32052                              <1> ;	i.nlks: .=.+1
 32053                              <1> ;	i.uid:  .=.+1
 32054                              <1> ;	i.size: .=.+2
 32055                              <1> ;	i.dskp: .=.+16.
 32056                              <1> ;	i.ctim: .=.+4
 32057                              <1> ;	i.mtim: .=.+4
 32058                              <1> ;	. = inode+32.
 32059                              <1> ;mount:	.=.+1024.
 32060                              <1> ;proc:
 32061                              <1> ;	p.pid:  .=.+[2*nproc]
 32062                              <1> ;	p.dska: .=.+[2*nproc]
 32063                              <1> ;	p.ppid: .=.+[2*nproc]
 32064                              <1> ;	p.break:.=.+[2*nproc]
 32065                              <1> ;	p.link: .=.+nproc
 32066                              <1> ;	p.stat: .=.+nproc
 32067                              <1> ;tty:
 32068                              <1> ;	. = .+[ntty*8.]
 32069                              <1> ;fsp:	.=.+[nfiles*8.]
 32070                              <1> ;bufp:	.=.+[nbuf*2]+6
 32071                              <1> ;sb0:	.=.+8
 32072                              <1> ;sb1:	.=.+8
 32073                              <1> ;swp:	.=.+8
 32074                              <1> ;ii:	.=.+2
 32075                              <1> ;idev:	.=.+2
 32076                              <1> ;cdev:	.=.+2
 32077                              <1> ;deverr: .=.+12.
 32078                              <1> ;active: .=.+2
 32079                              <1> ;rfap:	.=.+2
 32080                              <1> ;rkap:	.=.+2
 32081                              <1> ;tcap:	.=.+2
 32082                              <1> ;tcstate:.=.+2
 32083                              <1> ;tcerrc: .=.+2
 32084                              <1> ;mnti:	.=.+2
 32085                              <1> ;mntd:	.=.+2
 32086                              <1> ;mpid:	.=.+2
 32087                              <1> ;clockp: .=.+2
 32088                              <1> ;rootdir:.=.+2
 32089                              <1> ;toutt:	.=.+16.
 32090                              <1> ;touts: .=.+32.
 32091                              <1> ;runq:	.=.+6
 32092                              <1> ;
 32093                              <1> ;wlist:	.=.+40.
 32094                              <1> ;cc:	.=.+30.
 32095                              <1> ;cf:	.=.+31.
 32096                              <1> ;cl:	.=.+31.
 32097                              <1> ;clist:	.=.+510.
 32098                              <1> ;imod:	.=.+1
 32099                              <1> ;smod:	.=.+1
 32100                              <1> ;mmod:	.=.+1
 32101                              <1> ;uquant: .=.+1
 32102                              <1> ;sysflg: .=.+1
 32103                              <1> ;pptiflg:.=.+1
 32104                              <1> ;ttyoch: .=.+1
 32105                              <1> ; .even
 32106                              <1> ; .=.+100.; sstack:
 32107                              <1> ;buffer: .=.+[ntty*140.]
 32108                              <1> ;	.=.+[nbuf*520.]
 32109                              <1> ;
 32110                              <1> ; . = core-64.
 32111                              <1> ;user:
 32112                              <1> ;	u.sp:    .=.+2
 32113                              <1> ;	u.usp:   .=.+2
 32114                              <1> ;	u.r0:    .=.+2
 32115                              <1> ;	u.cdir:  .=.+2
 32116                              <1> ;	u.fp:    .=.+10.
 32117                              <1> ;	u.fofp:  .=.+2
 32118                              <1> ;	u.dirp:  .=.+2
 32119                              <1> ;	u.namep: .=.+2
 32120                              <1> ;	u.off:   .=.+2
 32121                              <1> ;	u.base:  .=.+2
 32122                              <1> ;	u.count: .=.+2
 32123                              <1> ;	u.nread: .=.+2
 32124                              <1> ;	u.break: .=.+2
 32125                              <1> ;	u.ttyp:  .=.+2
 32126                              <1> ;	u.dirbuf:.=.+10.
 32127                              <1> ;	u.pri:   .=.+2
 32128                              <1> ;	u.intr:  .=.+2
 32129                              <1> ;	u.quit:  .=.+2
 32130                              <1> ;	u.emt:   .=.+2
 32131                              <1> ;	u.ilgins:.=.+2
 32132                              <1> ;	u.cdev:  .=.+2
 32133                              <1> ;	u.uid:   .=.+1
 32134                              <1> ;	u.ruid:  .=.+1
 32135                              <1> ;	u.bsys:  .=.+1
 32136                              <1> ;	u.uno:   .=.+1
 32137                              <1> ;. = core
 32138                                  
 32139                                  ; 27/12/2021
 32140 00007764 <res 00002080>          buffer:	resb (nbuf*520)
 32141                                  
 32142                                  bss_end:
 32143                                  
 32144                                  ; 12/12/2021
 32145                                  BSS_SIZE equ bss_end - bss_start
 32146                                  
 32147                                  ; 27/12/2013
 32148                                  _end: ; end of kernel code (and read only data, just before bss)
