     1                                  ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
     2                                  ; (re-write kernel for test by using previous version without a major defect)
     3                                  ; ****************************************************************************
     4                                  ; UNIX386.ASM (RETRO UNIX 386 Kernel) - v0.2.2.3
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; NASM version 2.15 (unix386.s)
     7                                  ;
     8                                  ; RETRO UNIX 386 (Retro Unix == Turkish Rational Unix)
     9                                  ; Operating System Project (v0.2) by ERDOGAN TAN (Beginning: 24/12/2013)
    10                                  ;
    11                                  ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
    12                                  ; (v0.1 - Beginning: 11/07/2012)
    13                                  ;
    14                                  ; [ Last Modification: 08/08/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[4862]              	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[B464]              	mov	[mem_1m_1k], cx
   175 00000017 8916[B864]              	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[4B62]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   254 0000008A 8816[4A62]          <1>         mov     [last_drv], dl  ; last hard disk number
   255 0000008E BB[CE61]            <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[4C62]            <1> 	mov	si, fd0_type
   273                              <1> L3:
   274                              <1> 	; 14/01/2015
   275 0000009F 8816[4962]          <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[4C62]          <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[4B62]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[4962]          <1>         mov     [drv], dl
   316 000000CB 8816[4A62]          <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[4B62]          <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[4962]          <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[4962]          <1> 	inc	byte [drv]
   389 00000133 BB[CE61]            <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[4B62]            <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[4962]          <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[4962]          <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[CE61]          <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[4C62]          <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[6E62]          <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[5262]          <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[5462]          <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[CE61]00        <1> 	mov	byte [bx+hd0_type-80h], 0
   680 00000259 808F[F061]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[F061]FE        <1> 	and	byte [bx+drv.status-7Eh], 0FEh
   699                              <1> 	; 'diskio' procedure will check this bit !
   700                              <1> L11b:
   701 0000026F 3A16[4A62]          <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[4962]          <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[6E62]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[5262]          <1> 	mov	[bx+drv.size], ax
   785 000002BF 8997[5462]          <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 B95E32                  	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[705F]                  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[C0640000]            	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[B4640000]          	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[30670000]          	mov	[free_pages], ecx
   933 00000342 8B15[B8640000]          	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[30670000]          	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[2C670000]            	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[40670000]            	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[28670000]          	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[38670000]            	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[40670000]          	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[30670000]          	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[2C670000]          	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[30670000]          	sub	[free_pages], ecx ; 07/11/2014
  1074                                  	;
  1075 0000041B 8B35[28670000]          	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[28670000]          	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[2C670000]          	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[3C670000]            	mov	[first_page], eax
  1155 00000485 A3[34670000]            	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[28670000]                    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[84620000]            	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[7C5F0000]            	mov	esi, ilist
  1248 000004E0 8D3D[C0640000]          	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[765F0000]        	lidt 	[idtd]
  1294                                  	;
  1295                                  	; TSS descriptor setup ; 24/03/2015
  1296 00000536 B8[C0660000]            	mov	eax, task_state_segment
  1297 0000053B 66A3[6A5F0000]          	mov	[gdt_tss0], ax
  1298 00000541 C1C010                  	rol	eax, 16
  1299 00000544 A2[6C5F0000]            	mov	[gdt_tss1], al
  1300 00000549 8825[6F5F0000]          	mov	[gdt_tss2], ah
  1301 0000054F 66C705[26670000]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[2C670000]          	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[C4660000]          	mov	[tss.esp0], esp
  1336 0000057D 66C705[C8660000]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[4E620000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1375 000005AD 668B1D[4C620000]        	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[6D630000]            	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 E89F580000              	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[56670000]          	mov 	ah, [ptty] ; active (current) video page
  1436 00000606 E860550000              	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[56670000]          	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[58670000]          	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[28670000]          	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[646C0000]            	mov 	[u.r0], eax
  1577 00000681 89E1                    	mov	ecx, esp
  1578 00000683 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1579 00000686 890D[5C6C0000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1580 0000068C 8925[606C0000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1581                                  	;
  1582 00000692 8B0D[28670000]          	mov	ecx, [k_page_dir]
  1583 00000698 0F22D9                  	mov	cr3, ecx
  1584                                  T3:
  1585 0000069B FB                      	sti				; INTERRUPTS BACK ON
  1586 0000069C 66FF05[A4670000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1587 000006A3 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1588 000006A5 66FF05[A6670000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1589                                  T4:					; TEST_DAY
  1590 000006AC 66833D[A6670000]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[A4670000]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[A4670000]            	mov	[TIMER_LH], eax
  1602                                  	;	
  1603 000006C8 C605[A8670000]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[AB670000]            	mov	al, [MOTOR_COUNT]
  1614 000006D6 FEC8                    	dec	al
  1615                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1616 000006D8 A2[AB670000]            	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[AA670000]          	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[6C670000]          	inc	dword [tcount]
  1688 0000071B BB[F6620000]            	mov	ebx, tcountstr + 4
  1689                                  	;mov	ax, [tcount]
  1690                                  	; 04/12/2021
  1691 00000720 A1[6C670000]            	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[F2620000]          	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[CE620000]            	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[7C620000]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[7C620000]                  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[D4670000]          	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[28670000]          	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[D8670000]          	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[0A630000]          	mov	[excnstr], ax
  2093                                  	;
  2094                                  	; 29/08/2014
  2095 00000930 A1[D8670000]            	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[15630000]            	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[FA620000]            	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[B8620000]            	mov	esi, int_msg ; message offset
  2176                                  piemsg:
  2177                                          ; 27/08/2014
  2178 00000983 8105[7C620000]A000-             add     dword [scr_row], 0A0h
  2179 0000098B 0000               
  2180 0000098D 8B3D[7C620000]                  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[9C670000]            	mov	[time_seconds], al 
  2251 000009E0 B002                    	mov	al, CMOS_MINUTES
  2252 000009E2 E83B010000              	call	CMOS_READ
  2253 000009E7 A2[9D670000]            	mov	[time_minutes], al 
  2254 000009EC B004                    	mov	al, CMOS_HOURS
  2255 000009EE E82F010000              	call	CMOS_READ
  2256 000009F3 A2[9E670000]                    mov     [time_hours], al
  2257 000009F8 B006                    	mov	al, CMOS_DAY_WEEK 
  2258 000009FA E823010000              	call	CMOS_READ
  2259 000009FF A2[9F670000]            	mov	[date_wday], al
  2260 00000A04 B007                     	mov	al, CMOS_DAY_MONTH
  2261 00000A06 E817010000              	call	CMOS_READ
  2262 00000A0B A2[A0670000]            	mov	[date_day], al
  2263 00000A10 B008                    	mov	al, CMOS_MONTH
  2264 00000A12 E80B010000              	call	CMOS_READ
  2265 00000A17 A2[A1670000]            	mov	[date_month], al
  2266 00000A1C B009                    	mov	al, CMOS_YEAR
  2267 00000A1E E8FF000000              	call	CMOS_READ
  2268 00000A23 A2[A2670000]            	mov	[date_year], al
  2269 00000A28 B032                    	mov	al, CMOS_CENTURY
  2270 00000A2A E8F3000000              	call	CMOS_READ
  2271 00000A2F A2[A3670000]            	mov	[date_century], al
  2272                                  	;
  2273 00000A34 B000                    	mov	al, CMOS_SECONDS
  2274 00000A36 E8E7000000              	call 	CMOS_READ
  2275 00000A3B 3A05[9C670000]          	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[E0670000]          	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[6C630000]          	cmp	al, [ptime_seconds]
  2302 00000A58 74E9                            je      short rtc_retn ; 29/08/2014
  2303                                  	;
  2304 00000A5A A2[6C630000]            	mov	[ptime_seconds], al
  2305                                  	;
  2306 00000A5F A0[A3670000]            	mov	al, [date_century]
  2307 00000A64 E8EA000000              	call	bcd_to_ascii
  2308 00000A69 66A3[39630000]          	mov	[datestr+6], ax
  2309 00000A6F A0[A2670000]            	mov	al, [date_year]
  2310 00000A74 E8DA000000              	call	bcd_to_ascii
  2311 00000A79 66A3[3B630000]          	mov	[datestr+8], ax
  2312 00000A7F A0[A1670000]            	mov	al, [date_month]
  2313 00000A84 E8CA000000              	call	bcd_to_ascii
  2314 00000A89 66A3[36630000]          	mov	[datestr+3], ax
  2315 00000A8F A0[A0670000]            	mov	al, [date_day]
  2316 00000A94 E8BA000000              	call	bcd_to_ascii
  2317 00000A99 66A3[33630000]          	mov	[datestr], ax
  2318                                  	;
  2319 00000A9F 0FB61D[9F670000]        	movzx	ebx, byte [date_wday]
  2320 00000AA6 C0E302                  	shl 	bl, 2
  2321 00000AA9 81C3[4C630000]          	add	ebx, daytmp
  2322 00000AAF 8B03                    	mov	eax, [ebx]
  2323 00000AB1 A3[3E630000]            	mov	[daystr], eax
  2324                                  	;
  2325 00000AB6 A0[9E670000]            	mov	al, [time_hours]
  2326 00000ABB E893000000              	call	bcd_to_ascii
  2327 00000AC0 66A3[42630000]          	mov	[timestr], ax
  2328 00000AC6 A0[9D670000]            	mov	al, [time_minutes]
  2329 00000ACB E883000000              	call	bcd_to_ascii
  2330 00000AD0 66A3[45630000]          	mov	[timestr+3], ax
  2331 00000AD6 A0[9C670000]            	mov	al, [time_seconds]
  2332 00000ADB E873000000              	call	bcd_to_ascii
  2333 00000AE0 66A3[48630000]          	mov	[timestr+6], ax
  2334                                  	;		
  2335 00000AE6 BE[21630000]            	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[56670000]    <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[58670000]      <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[56670000]        <1>         mov     al, [ptty]
  2604 00000BBE E88B3B0000          <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[90610000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2932 00000BF4 3B1D[94610000]      <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[90610000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2947 00000C05 3B1D[94610000]      <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[85610000]      <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[90610000]      <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[90610000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2972 00000C3F 3B1D[94610000]      <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[85610000]      <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[8C610000]      <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[88610000]      <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[85610000]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[85610000]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[85610000]      <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[86610000]      <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[86610000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  3249                              <1> RST_RD_ID:
  3250 00000CFC 8025[86610000]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[86610000]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[83610000]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[86610000]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[86610000]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[86610000]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[6E600000]        <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[6C600000]        <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[84610000]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[84610000]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[84610000]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[84610000]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[83610000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  3371 00000DD5 BF[68600000]        <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[69600000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  3383 00000DF0 8AA7[70600000]      <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[83610000]      <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[86610000]      <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[84610000]      <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[84610000]      <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[84610000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  3451 00000E78 3025[83610000]      <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[83610000]      <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[86610000]      <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[84610000]      <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[86610000]        <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[84610000]      <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[83610000]      <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[87610000]        <1> 	mov	al, [ALT_INPUT]
  3504 00000EE5 B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  3505 00000EE7 8825[87610000]      <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[84610000]      <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[84610000]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[84610000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  3524                              <1> 	;
  3525                              <1> K26:
  3526 00000F16 8025[86610000]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[84610000]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[44600000]        <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[45600000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3614 00000F98 A0[87610000]        <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[87610000]        <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[87610000]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[90610000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3704 0000103A 891D[94610000]      <1> 	mov	[BUFFER_TAIL], ebx
  3705 00001040 C605[82610000]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[84610000]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[80610000]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[81610000]        <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[84610000]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[78600000]        <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[86610000]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[4E600000]        <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[D0600000]        <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[28610000]        <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[D0600000]        <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[28610000]        <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[86610000]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[86610000]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[94610000]      <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[90610000]      <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[94610000]      <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[85610000]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[85610000]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[85610000]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[85610000]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[85610000]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[85610000]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[85610000]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[85610000]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[85610000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  4067 00001278 0805[85610000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  4068 0000127E F605[85610000]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[85610000]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[85610000]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[83610000]        <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[46670000]      <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[56670000]      <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[46670000]        <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[56670000]      <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[44670000]    <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[46670000]    <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[56670000]      <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[44670000]    <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[56670000]      <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[56670000]      <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[56670000]        <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[44670000]      <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[46670000]      <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[2C670000]            	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[95630000]            	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[B9630000]            	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[30670000]            	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[D9630000]            	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[FD630000]            	mov	esi, free_mem_p_str
  5301 00001585 E876000000              	call	bintdstr
  5302                                  pmim:
  5303 0000158A BE[83630000]            	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[40670000]          	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[AC670000]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[AA670000]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[AA670000]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[B7670000]      <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[B7670000]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[B7670000]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[CC610000]        <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[EA610000]        <1> 	mov	ebx, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  6041 0000171D F687[B7670000]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[04620000]        <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[AB670000]      <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[AC670000]      <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[AA670000]        <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[A9670000]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[AD670000]      <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[AC670000]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[CC610000]        <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[2B620000]        <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[B7670000]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[AD670000]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[B7670000]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[B7670000]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[B7670000]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[B7670000]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[B7670000]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[B7670000]1F    <1> 	and	byte [DSK_STATE+edi], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  6455 00001908 08A7[B7670000]      <1> 	or	[DSK_STATE+edi], ah	; RATE FIRST TO TRY
  6456 0000190E 8025[B4670000]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[B4670000]      <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[B7670000]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[AA670000]      <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[AC670000]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[AC670000]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[B4670000]3F    <1> 	and	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  6522 00001974 8A87[B7670000]      <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[B4670000]      <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[B4670000]      <1> 	mov	ah, [LASTRATE] ; 08/07/2022 (BugFix) 
  6549                              <1> 					; GET LAST DATA RATE SELECTED
  6550 00001991 8A87[B7670000]      <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[AC670000]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[AD670000]        <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[AC670000]      <1> 	or	[DSKETTE_STATUS], ah
  6851                              <1> SET_END:
  6852 00001AB6 803D[AC670000]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[AC670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; CHECK FOR ERROR
  6867 00001ACA 753E                <1> 	jne	short SETBAC		; IF ERROR JUMP
  6868 00001ACC 808F[B7670000]10    <1> 	or	byte [DSK_STATE+edi], MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  6869 00001AD3 F687[B7670000]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[B7670000]      <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[B7670000]FD    <1> 	and	byte [DSK_STATE+edi], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  6886 00001AFA 808F[B7670000]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[B7670000]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[AC670000]00    <1> 	cmp	byte [DSKETTE_STATUS], 0 ; GET STATUS OF OPERATION
  6904 00001B12 7444                <1> 	je	short NO_RETRY		; SUCCESSFUL OPERATION
  6905 00001B14 803D[AC670000]80    <1> 	cmp	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT NO RETRY
  6906 00001B1B 743B                <1> 	je	short NO_RETRY
  6907 00001B1D 8AA7[B7670000]      <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[B4670000]      <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[B7670000]1F    <1> 	and	byte [DSK_STATE+edi], ~(RATE_MSK+DBL_STEP)
  6926                              <1> 					; RATE, DBL STEP OFF
  6927 00001B4A 08A7[B7670000]      <1> 	or	[DSK_STATE+edi], ah	; TURN ON NEW RATE
  6928 00001B50 C605[AC670000]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[AC670000]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[B2670000]        <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[B1670000]      <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[B0670000]      <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[B7670000]      <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[A9670000]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[B7670000]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[AB670000]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[AC670000]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[B0670000]      <1> 	mov	cl, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  7051 00001BFE 888F[B9670000]      <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[B7670000]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[4C620000]      <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[41620000]      <1> 	cmp	al, [pfd] ; is same with previous drive # ?
  7133 00001C45 7423                <1> 	je	short gpndc	
  7134                              <1> 
  7135 00001C47 A2[41620000]        <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[4C620000]      <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[2B620000]        <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[C8610000]      <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[C8610000]      <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[AB670000]FF    <1> 	mov	byte [MOTOR_COUNT], 0FFh ; ENSURE MOTOR STAYS ON FOR OPERATION
  7235 00001CA9 A0[AA670000]        <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[AA670000]      <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[AA670000]      <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[AA670000]CF    <1> 	and	byte [MOTOR_STATUS], 11001111b ; CLEAR OUT DRIVE SELECT
  7254 00001CD2 0825[AA670000]      <1> 	or	[MOTOR_STATUS], ah	; OR IN DRIVE SELECTED AND MOTOR ON
  7255 00001CD8 A0[AA670000]        <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[AA670000]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[B7670000]      <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[AC670000]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[A9670000]      <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[A9670000]      <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[AC670000]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[B9670000]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[B7670000]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[B9670000]      <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[B9670000]      <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[B9670000]      <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[AD670000]        <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[AC670000]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[A9670000]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[AC670000]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[A9670000]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[AD670000]        <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[AC670000]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[AC670000]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[A9670000]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[B7670000]    <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[B4670000]C0    <1> 	or	byte [LASTRATE], SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  7845 00001EF1 880D[A9670000]      <1> 	mov	[SEEK_STATUS], cl ; 0	; INDICATE RECALIBRATE NEEDED
  7846 00001EF7 880D[AB670000]      <1> 	mov	[MOTOR_COUNT], cl ; 0	; INITIALIZE MOTOR COUNT
  7847 00001EFD 880D[AA670000]      <1> 	mov	[MOTOR_STATUS], cl ; 0	; INITIALIZE DRIVES TO OFF STATE
  7848 00001F03 880D[AC670000]      <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[C0670000]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[C4670000]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[C8670000]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[CC670000]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[4E620000]        <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[BC670000]      <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[BC670000]      <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[BB670000]      <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[BB670000]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[BC670000]      <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[D0670000]      <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[42620000]      <1> 	mov	[HF_PORT], ax
  8483 00001FC8 668B5312            <1> 	mov	dx, [ebx+18]   ; control port address (3F6h, 376h)
  8484 00001FCC 668915[44620000]    <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[D0670000]      <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[46620000]        <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[BD670000]      <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[BD670000]      <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[D0670000]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[46620000]      <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[BB670000]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[46620000]        <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[42620000]    <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[42620000]    <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[42620000]    <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[BB670000]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[44620000]    <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[BD670000]        <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[42620000]    <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[BB670000]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[46620000]        <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[BB670000]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[D0670000]      <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[46620000]      <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[D0670000]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[BB670000]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[42620000]    <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[BB670000]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[BB670000]40    <1> 	cmp	byte [DISK_STATUS1], BAD_SEEK ; SEEK NOT COMPLETE
  9213 00002222 7507                <1> 	jne	short RECAL_EXIT	; IS OK
  9214 00002224 C605[BB670000]00    <1> 	mov	byte [DISK_STATUS1], 0
  9215                              <1> RECAL_EXIT:
  9216 0000222B 803D[BB670000]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[BB670000]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[BB670000]20    <1> 	mov	byte [DISK_STATUS1], BAD_CNTLR
  9245                              <1> COMMAND4:
  9246                              <1> 	;;pop	ebx ; 10/07/2022
  9247 0000224A 803D[BB670000]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[B6670000]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[42620000]    <1> 	mov	dx, [HF_PORT]
  9275 00002278 FEC2                <1> 	inc	dl
  9276 0000227A F605[BD670000]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[B6670000]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[B6670000]        <1> 	mov	byte [HF_INT_FLAG], al
  9369                              <1> WT4:
  9370                              <1> NB2:	
  9371 000022CD A2[BB670000]        <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[42620000]    <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[42620000]    <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[BB670000]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[42620000]    <1> 	mov	dx, [HF_PORT]
  9482 0000232E 80C207              <1> 	add	dl, 7
  9483 00002331 EC                  <1> 	in	al, dx
  9484 00002332 A2[B5670000]        <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[BB670000]      <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[42620000]    <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[38620000]      <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[BB670000]      <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[C0670000]      <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[B6670000]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[B6670000]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[30670000]        <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[34670000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
 10090                              <1> 				 ; next_free_page >> 5
 10091 000023F7 030D[38670000]      <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[34670000]      <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[30670000]        <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[34670000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
 10154                              <1> 				 ; address/offset (to the next)
 10155 00002430 FF0D[30670000]      <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[C46C0000]        <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[C46C0000]      <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[C46C0000]        <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[34670000]      <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[34670000]      <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[30670000]      <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[C46C0000]      <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[C46C0000]      <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[DC6C0000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
 11070 00002699 FF05[DC670000]      <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[D4670000]      <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[C46C0000]      <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[C46C0000]      <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[C86C0000]      <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[C46C0000]        <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[C46C0000]        <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[C46C0000]      <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[C46C0000]      <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.2) - SYSDEFS.INC
 12563                              <1> ; Last Modification: 12/06/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> ; 12/01/2022 (37,38,39)
 12708                              <1> ; 21/09/2015 (36) 
 12709                              <1> ; 01/07/2015 (35)
 12710                              <1> ; 14/07/2013 (0-34)
 12711                              <1> ; UNIX v1 system calls
 12712                              <1> _rele 	equ 0
 12713                              <1> _exit 	equ 1
 12714                              <1> _fork 	equ 2
 12715                              <1> _read 	equ 3
 12716                              <1> _write	equ 4
 12717                              <1> _open	equ 5
 12718                              <1> _close 	equ 6
 12719                              <1> _wait 	equ 7
 12720                              <1> _creat 	equ 8
 12721                              <1> _link 	equ 9
 12722                              <1> _unlink	equ 10
 12723                              <1> _exec	equ 11
 12724                              <1> _chdir	equ 12
 12725                              <1> _time 	equ 13
 12726                              <1> _mkdir 	equ 14
 12727                              <1> _chmod	equ 15
 12728                              <1> _chown	equ 16
 12729                              <1> _break	equ 17
 12730                              <1> _stat	equ 18
 12731                              <1> _seek	equ 19
 12732                              <1> _tell 	equ 20
 12733                              <1> _mount	equ 21
 12734                              <1> _umount	equ 22
 12735                              <1> _setuid	equ 23
 12736                              <1> _getuid	equ 24
 12737                              <1> _stime	equ 25
 12738                              <1> _quit	equ 26	
 12739                              <1> _intr	equ 27
 12740                              <1> _fstat	equ 28
 12741                              <1> _emt 	equ 29
 12742                              <1> _mdate 	equ 30
 12743                              <1> _stty 	equ 31
 12744                              <1> _gtty	equ 32
 12745                              <1> _ilgins	equ 33
 12746                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
 12747                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
 12748                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
 12749                              <1> ; 12/01/2022 - Retro UNIX 386 v1.2
 12750                              <1> ; Retro UNIX 386 v2 system calls
 12751                              <1> _setgid	equ 37
 12752                              <1> _getgid	equ 38
 12753                              <1> _sysver	equ 39 ; (get) Retro Unix 386 version
 12754                              <1> 
 12755                              <1> %macro sys 1-4
 12756                              <1>     ; 13/04/2015
 12757                              <1>     ; Retro UNIX 386 v1 system call.
 12758                              <1>     mov eax, %1
 12759                              <1>     %if %0 >= 2   
 12760                              <1>         mov ebx, %2
 12761                              <1>         %if %0 >= 3    
 12762                              <1>             mov ecx, %3
 12763                              <1>             %if %0 = 4
 12764                              <1>                mov edx, %4   
 12765                              <1>             %endif
 12766                              <1>         %endif
 12767                              <1>     %endif
 12768                              <1>     int 30h	   
 12769                              <1> %endmacro
 12770                              <1> 
 12771                              <1> ; 13/05/2015 - ERROR CODES
 12772                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
 12773                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
 12774                              <1> ; 14/05/2015
 12775                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
 12776                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
 12777                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
 12778                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error
 12779                              <1> ; 16/05/2015		
 12780                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
 12781                              <1> ; 18/05/2015
 12782                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
 12783                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
 12784                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
 12785                              <1> ; 07/06/2015
 12786                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
 12787                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
 12788                              <1> ; 09/06/2015
 12789                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
 12790                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
 12791                              <1> ; 16/06/2015
 12792                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
 12793                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
 12794                              <1> ; 22/06/2015
 12795                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
 12796                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
 12797                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
 12798                              <1> ; 23/06/2015
 12799                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
 12800                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
 12801                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
 12802                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
 12803                              <1> ; 27/06/2015
 12804                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
 12805                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
 12806                              <1> ; 29/06/2015
 12807                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error
 12808                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error
 12809                              <1> ; 08/02/2022 
 12810                              <1> ; (error numbers from TRDOS 386 v2.0 'sysdefs.s')
 12811                              <1> ; 10/10/2016
 12812                              <1> ERR_INV_FILE_NAME  equ 26 ; 'invalid file name !' error
 12813                              <1> ; 18/05/2016
 12814                              <1> ERR_MISC	   equ 27 ; miscellaneous/other errors
 12815                              <1> ; 15/10/2016
 12816                              <1> ERR_INV_FORMAT	   equ 28 ; 'invalid format !' error
 12817                              <1> ERR_INV_DATA	   equ 29 ; 'invalid data !' error
 12818                              <1> ; 16/10/2016
 12819                              <1> ERR_DISK_WRITE	   equ 30 ; 'disk write protected !'
 12820                              <1> ; 08/02/2022
 12821                              <1> ERR_INV_FS	   equ 28 ;'invalid fs/superblock !' error
 12822                              <1> 
 12823                              <1> ; 12/06/2022
 12824                              <1> ; printer errors
 12825                              <1> ERR_PRN_NOT_RDY	   equ 15 ; 'device not ready !' error
 12826                              <1> ERR_PRN_TIMEOUT	   equ 25 ; 'time out !' error
 12827                              <1> ERR_PRN_PAPER	   equ 31 ; 'out of paper !' error
 12828                              <1> ERR_PRN_IO	   equ 32 ; 'io error !' error
 12829                              <1> ERR_PRN_BUSY	   equ 34 ; 'busy !' error
 12830                              <1> 
 12831                              <1> ; 26/08/2015
 12832                              <1> ; 24/07/2015
 12833                              <1> ; 24/06/2015
 12834                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
 12835                              <1> ; 01/07/2015
 12836                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
 12837                              <1> ;
 12838                              <1> ; 26/11/2021 ('no free blocks on disk !' error)
 12839                              <1> ERR_ALLOC	   equ 33  ; 'disk allocation error !'	
 12840                              <1> ; 22/11/2021
 12841                              <1> ERR_READ_ONLY_FS   equ 30  ; 'read only file system !' error
 12842                              <1> ; 28/11/2021
 12843                              <1> ERR_INV_FILE	   equ 255 ; 'invalid file (inode) !' error
 12844                              <1> ; 04/12/2021
 12845                              <1> ERR_PERM_DENIED	   equ 11  ; 'permission denied !' error
 12846                              <1> ; 11/12/2021
 12847                              <1> ERR_INV_FUNC	   equ 1   ; 'invalid system call !' error
 12848                              <1> ; 10/01/2022
 12849                              <1> ERR_INO_ALLOC	   equ 33  ; 'inode allocation error !'
 12850                              <1> ERR_NOT_REGULAR    equ 255 ; 'not regular file directory !' error
 12851                              <1> 
 12852                              <1> ; 12/01/2022 - Retro UNIX 386 v1.2
 12853                              <1> %define s.time systm+504 ; boot/sysinit time (or current time)
 12854                              <1> 		
 12855                                  %include 'u0.s'      ; 15/03/2015
 12856                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 12857                              <1> ; (re-write kernel for test by using previous version without a major defect)
 12858                              <1> ; ****************************************************************************
 12859                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS0.INC
 12860                              <1> ; Last Modification: 17/07/2022
 12861                              <1> ; ----------------------------------------------------------------------------
 12862                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 12863                              <1> ; (v0.1 - Beginning: 11/07/2012)
 12864                              <1> ;
 12865                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 12866                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 12867                              <1> ; <Bell Laboratories (17/3/1972)>
 12868                              <1> ; <Preliminary Release of UNIX Implementation Document>
 12869                              <1> ;
 12870                              <1> ; Retro UNIX 8086 v1 - U0.ASM (28/07/2014) //// UNIX v1 -> u0.s
 12871                              <1> ;
 12872                              <1> ; ****************************************************************************
 12873                              <1> 
 12874                              <1> sys_init:
 12875                              <1> 	; 23/02/2022
 12876                              <1> 	; 08/01/2022
 12877                              <1> 	; 01/01/2022
 12878                              <1> 	; 26/12/2021
 12879                              <1> 	; 27/11/2021
 12880                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 (test) compatibility modification
 12881                              <1> 	; 18/10/2015
 12882                              <1> 	; 28/08/2015
 12883                              <1> 	; 24/08/2015
 12884                              <1> 	; 14/08/2015
 12885                              <1> 	; 24/07/2015 
 12886                              <1> 	; 02/07/2015
 12887                              <1> 	; 01/07/2015
 12888                              <1> 	; 23/06/2015
 12889                              <1> 	; 15/04/2015
 12890                              <1> 	; 13/04/2015
 12891                              <1> 	; 11/03/2015 (Retro UNIX 386 v1 - Beginning)
 12892                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 12893                              <1> 	;
 12894                              <1> 	;call	ldrv_init ; Logical drive description tables initialization
 12895                              <1> 	;
 12896                              <1> 	;; 14/02/2014
 12897                              <1> 	;; 14/07/2013
 12898                              <1> 	;mov	ax, 41
 12899                              <1> 	;mov	[rootdir], ax
 12900                              <1> 	;mov	[u.cdir], ax
 12901                              <1> 	;and	al, 1 ; 15/04/2015
 12902                              <1> 	
 12903                              <1> 	; 27/11/2021
 12904                              <1> 	; 18/04/2021 - Retro UNIX 386 v2
 12905 000028D4 31C0                <1> 	xor	eax, eax
 12906 000028D6 FEC0                <1> 	inc	al	; eax = 1 (root directory inode) ; runix v2 fs
 12907 000028D8 A3[466C0000]        <1> 	mov	[rootdir], eax ; = 1 ; 28/10/2021 (32 bit)
 12908 000028DD A3[686C0000]        <1> 	mov	[u.cdir], eax ; 28/10/2021 (32 bit)
 12909                              <1> 
 12910 000028E2 A2[B56C0000]        <1> 	mov	[u.uno], al ; = 1
 12911                              <1> 	;mov	[mpid], ax ; 1 
 12912                              <1> 	;mov	[p.pid], ax ; 1
 12913                              <1> 	; 01/01/2022
 12914 000028E7 A2[446C0000]        <1> 	mov	[mpid], al
 12915 000028EC A2[24680000]        <1> 	mov	[p.pid], al
 12916 000028F1 A2[84680000]        <1> 	mov	[p.stat], al ; SRUN, 05/02/2014
 12917                              <1> 	;
 12918 000028F6 B004                <1> 	mov	al, time_count ; 30/08/2013
 12919 000028F8 A2[AC6C0000]        <1> 	mov	[u.quant], al ; 14/07/2013
 12920                              <1> 	; 02/07/2015
 12921 000028FD A1[28670000]        <1> 	mov	eax, [k_page_dir]
 12922 00002902 A3[C46C0000]        <1> 	mov	[u.pgdir], eax ; reset
 12923                              <1> 	; 18/10/2015
 12924                              <1> 	;sub	eax, eax
 12925                              <1> 	;mov	[u.ppgdir], eax ; 0
 12926                              <1>         ;
 12927                              <1>  	; 23/02/2022
 12928                              <1>  	;call	epoch
 12929                              <1> 	;mov	[s.time], eax ; 13/03/2015
 12930                              <1> 	; 17/07/2013
 12931 00002907 E881060000          <1> 	call 	bf_init ; buffer initialization
 12932                              <1> 	; 23/02/2022
 12933                              <1> 	; (save sysinit time on sb0)
 12934 0000290C E829030000          <1> 	call	epoch
 12935 00002911 A3[0C6F0000]        <1> 	mov	[s.time], eax ; 13/03/2015
 12936                              <1> 	; 23/06/2015
 12937 00002916 E8C4FAFFFF          <1> 	call	allocate_page
 12938                              <1> 	;;jc	error
 12939                              <1> 	;jc	panic   ; jc short panic (01/07/2015)
 12940                              <1> 	; 05/12/2021
 12941 0000291B 7305                <1> 	jnc	short sysinit_1
 12942 0000291D E989000000          <1> 	jmp	panic
 12943                              <1> sysinit_1:
 12944 00002922 A3[C06C0000]        <1> 	mov	[u.upage], eax ; user structure page	
 12945 00002927 A3[94680000]        <1> 	mov	[p.upage], eax
 12946                              <1> 	;
 12947 0000292C E81FFBFFFF          <1> 	call	clear_page
 12948                              <1> 	;
 12949                              <1> 	; 14/08/2015
 12950 00002931 FA                  <1> 	cli
 12951                              <1> 	; 14/03/2015
 12952                              <1> 	; 17/01/2014
 12953 00002932 E8D0010000          <1> 	call	sp_init ; serial port initialization
 12954                              <1> 	; 14/08/2015
 12955 00002937 FB                  <1> 	sti
 12956                              <1> 	;
 12957                              <1> 	; 30/06/2015
 12958                              <1> 	;mov	esi, kernel_init_ok_msg
 12959                              <1> 	;call 	print_msg
 12960                              <1> 	;
 12961 00002938 30DB                <1> 	xor	bl, bl ; video page 0
 12962                              <1> vp_clr_nxt:  ; clear video pages (reset cursor positions)
 12963 0000293A E8CE330000          <1> 	call 	vp_clr  ; 17/07/2013
 12964 0000293F FEC3                <1> 	inc	bl
 12965 00002941 80FB08              <1> 	cmp	bl, 8
 12966 00002944 72F4                <1> 	jb	short vp_clr_nxt
 12967                              <1> 	;
 12968                              <1> 	; 24/07/2015
 12969                              <1> 	;push	KDATA
 12970                              <1>         ;push	esp
 12971                              <1> 	;mov	[tss.esp0], esp
 12972                              <1>         ;mov	word [tss.ss0], KDATA
 12973                              <1> 	;
 12974                              <1> 	; 08/01/2022
 12975                              <1> 	; 24/08/2015
 12976                              <1> 	;; temporary (01/07/2015)
 12977                              <1> 	;mov	byte [u.quant], time_count ; 4 
 12978                              <1> 	;		       ; it is not needed here !
 12979                              <1> 	;;inc	byte [u.kcall] ; 'the caller is kernel' sign
 12980 00002946 FE0D[586C0000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
 12981                              <1> 			      ; 0 = executing a system call
 12982                              <1> 	;;sys 	_msg, kernel_init_ok_msg, 255, 0
 12983                              <1> 	;
 12984                              <1> 	;;; 06/08/2015
 12985                              <1> 	;;;call	getch ; wait for a key stroke
 12986                              <1> 	;;mov 	ecx, 0FFFFFFFh	
 12987                              <1> ;;sys_init_msg_wait:
 12988                              <1> ;;	push 	ecx
 12989                              <1> ;;	mov	al, 1
 12990                              <1> ;;	mov 	ah, [ptty] ; active (current) video page
 12991                              <1> ;;	call	getc_n
 12992                              <1> ;;	pop	ecx
 12993                              <1> ;;	jnz	short sys_init_msg_ok
 12994                              <1> ;;	loop	sys_init_msg_wait
 12995                              <1> 	;
 12996                              <1> ;;sys_init_msg_ok:
 12997                              <1> 	; 28/08/2015 (initial settings for the 1st 'rswap')
 12998 0000294C 6A10                <1> 	push	KDATA ; ss
 12999 0000294E 54                  <1> 	push	esp
 13000 0000294F 9C                  <1> 	pushfd
 13001 00002950 6A08                <1> 	push	KCODE ; cs
 13002 00002952 68[7F290000]        <1> 	push	init_exec ; eip
 13003 00002957 8925[5C6C0000]      <1> 	mov	[u.sp], esp
 13004 0000295D 1E                  <1> 	push	ds
 13005 0000295E 06                  <1> 	push	es
 13006 0000295F 0FA0                <1> 	push	fs
 13007 00002961 0FA8                <1> 	push	gs	
 13008 00002963 60                  <1> 	pushad
 13009 00002964 8925[606C0000]      <1> 	mov	[u.usp], esp
 13010 0000296A E8051D0000          <1> 	call	wswap ; save current user (u) structure, user registers
 13011                              <1> 		      ; and interrupt return components (for IRET)
 13012 0000296F 61                  <1> 	popad
 13013 00002970 6658                <1> 	pop	ax ; gs
 13014 00002972 6658                <1> 	pop	ax ; fs
 13015 00002974 6658                <1> 	pop	ax ; es
 13016 00002976 6658                <1> 	pop	ax ; ds	
 13017 00002978 58                  <1> 	pop	eax ; eip (init_exec)
 13018 00002979 6658                <1> 	pop	ax ; cs (KCODE)
 13019 0000297B 58                  <1> 	pop	eax ; E-FLAGS
 13020 0000297C 58                  <1> 	pop	eax ; esp
 13021 0000297D 6658                <1> 	pop	ax ; ss (KDATA)
 13022                              <1> 	;
 13023                              <1> 	; 26/12/2021 ([u.ppgdir] is zero already)
 13024                              <1> 	;xor	eax, eax ; 0
 13025                              <1> 	;mov	[u.ppgdir], eax ; reset (to zero) for '/etc/init'
 13026                              <1> 	;
 13027                              <1> 	; 02/07/2015
 13028                              <1> 	; [u.pgdir ] = [k_page_dir]
 13029                              <1> 	; [u.ppgdir] = 0 (page dir of the parent process)
 13030                              <1> 	;     (The caller is os kernel sign for 'sysexec')
 13031                              <1> init_exec:
 13032                              <1> 	; 13/03/2013
 13033                              <1> 	; 24/07/2013
 13034 0000297F BB[A1290000]        <1> 	mov	ebx, init_file
 13035 00002984 B9[99290000]        <1> 	mov	ecx, init_argp
 13036                              <1> 	; EBX contains 'etc/init' asciiz file name address  
 13037                              <1> 	; ECX contains address of argument list pointer
 13038                              <1> 	;
 13039                              <1> 	;dec 	byte [sysflg] ; FFh = ready for system call
 13040                              <1> 			      ; 0 = executing a system call
 13041                              <1> 	sys	_exec  ; execute file
 13042                              <2> 
 13043                              <2> 
 13044 00002989 B80B000000          <2>  mov eax, %1
 13045                              <2>  %if %0 >= 2
 13046                              <2>  mov ebx, %2
 13047                              <2>  %if %0 >= 3
 13048                              <2>  mov ecx, %3
 13049                              <2>  %if %0 = 4
 13050                              <2>  mov edx, %4
 13051                              <2>  %endif
 13052                              <2>  %endif
 13053                              <2>  %endif
 13054 0000298E CD30                <2>  int 30h
 13055 00002990 7319                <1> 	jnc	short panic
 13056                              <1> 	;
 13057 00002992 BE[40640000]        <1> 	mov	esi, etc_init_err_msg
 13058                              <1> 	; 22/11/2021
 13059                              <1> 	;call 	print_msg
 13060 00002997 EB17                <1> 	jmp	short key_to_reboot
 13061                              <1> 
 13062                              <1> ;align 4
 13063                              <1> init_argp:
 13064 00002999 [A1290000]00000000  <1> 	dd 	init_file, 0  ; 23/06/2015 (dw -> dd)
 13065                              <1> init_file:
 13066                              <1> 	; 24/08/2015
 13067 000029A1 2F6574632F696E6974- <1> 	db 	'/etc/init', 0
 13068 000029AA 00                  <1>
 13069                              <1> panic:
 13070                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13071                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13072 000029AB BE[25640000]        <1> 	mov 	esi, panic_msg
 13073                              <1> key_to_reboot: ; 22/11/2021
 13074 000029B0 E819000000          <1> 	call 	print_msg
 13075                              <1> ;key_to_reboot:
 13076                              <1> 	; 15/11/2015
 13077 000029B5 E8A1310000          <1> 	call 	getch 
 13078                              <1> 		; wait for a character from the current tty
 13079                              <1> 	;
 13080 000029BA B00A                <1> 	mov	al, 0Ah
 13081 000029BC 8A1D[56670000]      <1> 	mov	bl, [ptty] ; [active_page]
 13082 000029C2 B407                <1> 	mov	ah, 07h ; Black background, 
 13083                              <1> 			; light gray forecolor
 13084 000029C4 E8EBE8FFFF          <1> 	call 	write_tty
 13085 000029C9 E98AE5FFFF          <1> 	jmp	cpu_reset 
 13086                              <1> 
 13087                              <1> print_msg:
 13088                              <1> 	; 01/07/2015
 13089                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13090                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13091                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
 13092                              <1> 	;
 13093                              <1> 	;
 13094 000029CE AC                  <1> 	lodsb
 13095                              <1> pmsg1:
 13096 000029CF 56                  <1> 	push 	esi
 13097 000029D0 0FB61D[56670000]    <1> 	movzx	ebx, byte [ptty]
 13098 000029D7 B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
 13099 000029D9 E8D6E8FFFF          <1> 	call 	write_tty
 13100 000029DE 5E                  <1> 	pop	esi
 13101 000029DF AC                  <1> 	lodsb
 13102 000029E0 20C0                <1> 	and 	al, al
 13103 000029E2 75EB                <1> 	jnz 	short pmsg1
 13104 000029E4 C3                  <1> 	retn
 13105                              <1> 	
 13106                              <1> ctrlbrk:
 13107                              <1> 	; 06/02/2022
 13108                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 13109                              <1> 	; 12/11/2015
 13110                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13111                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
 13112                              <1> 	;
 13113                              <1> 	; INT 1Bh (control+break) handler		
 13114                              <1> 	;
 13115                              <1>       	; Retro Unix 8086 v1 feature only!
 13116                              <1>       	;
 13117 000029E5 66833D[B06C0000]00  <1> 	cmp 	word [u.intr], 0
 13118 000029ED 764B                <1> 	jna 	short cbrk4
 13119                              <1> cbrk0:
 13120                              <1> 	; 12/11/2015
 13121                              <1> 	; 06/12/2013
 13122 000029EF 66833D[B26C0000]00  <1> 	cmp 	word [u.quit], 0
 13123 000029F7 7441                <1> 	jz	short cbrk4
 13124                              <1> 	;
 13125                              <1> 	; 20/09/2013	
 13126                              <1> 	;push 	ax
 13127                              <1> 	; 04/12/2021
 13128 000029F9 50                  <1> 	push	eax
 13129                              <1> 
 13130                              <1> 	; 06/02/2022
 13131                              <1> 	; (repetitive ctrl+brk check) 
 13132 000029FA 66A1[B26C0000]      <1> 	mov	ax, [u.quit]
 13133 00002A00 6640                <1> 	inc	ax ; 0FFFFh -> 0
 13134 00002A02 7435                <1> 	jz	short cbrk3
 13135                              <1> 
 13136                              <1> 	; 06/12/2013
 13137 00002A04 A0[56670000]        <1> 	mov	al, [ptty]
 13138                              <1> 	;
 13139                              <1> 	; 12/11/2015
 13140                              <1> 	;
 13141                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
 13142                              <1> 	; or ctrl+break from console (pseudo) tty
 13143                              <1> 	; (!redirection!)
 13144                              <1> 	;
 13145 00002A09 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
 13146 00002A0B 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
 13147                              <1> 	;	
 13148                              <1> 	; Serial port interrupt handler sets [ptty]
 13149                              <1> 	; to the port's tty number (as temporary).
 13150                              <1> 	;
 13151                              <1> 	; If active process is using a stdin or 
 13152                              <1> 	; stdout redirection (by the shell),
 13153                              <1>         ; console tty keyboard must be available
 13154                              <1> 	; to terminate running process,
 13155                              <1> 	; in order to prevent a deadlock. 
 13156                              <1> 	;
 13157 00002A0D 52                  <1> 	push	edx
 13158 00002A0E 0FB615[B56C0000]    <1> 	movzx	edx, byte [u.uno]
 13159 00002A15 3A82[63680000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
 13160 00002A1B 5A                  <1> 	pop	edx
 13161 00002A1C 7412                <1> 	je	short cbrk2
 13162                              <1> cbrk1:
 13163 00002A1E FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
 13164                              <1> 	; 06/12/2013
 13165 00002A20 3A05[9A6C0000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
 13166 00002A26 7408                <1> 	je	short cbrk2	
 13167 00002A28 3A05[9B6C0000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
 13168 00002A2E 7509                <1> 	jne	short cbrk3	
 13169                              <1> cbrk2:
 13170                              <1> 	;; 06/12/2013
 13171                              <1> 	;mov	ax, [u.quit]
 13172                              <1> 	;and	ax, ax
 13173                              <1> 	;jz	short cbrk3
 13174                              <1> 	;
 13175                              <1> 	;xor	ax, ax ; 0
 13176                              <1> 	;dec	ax
 13177                              <1> 	; 04/12/2021
 13178 00002A30 31C0                <1> 	xor	eax, eax ; 0
 13179 00002A32 48                  <1> 	dec	eax ; 0FFFFFFFFh
 13180                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
 13181 00002A33 66A3[B26C0000]      <1> 	mov	[u.quit], ax
 13182                              <1> cbrk3:
 13183                              <1> 	;pop	ax
 13184                              <1> 	; 04/12/2021
 13185 00002A39 58                  <1> 	pop	eax
 13186                              <1> cbrk4:
 13187 00002A3A C3                  <1> 	retn
 13188                              <1> 
 13189                              <1> com2_int:
 13190                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 13191                              <1> 	; 07/11/2015 
 13192                              <1> 	; 24/10/2015
 13193                              <1> 	; 23/10/2015
 13194                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13195                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13196                              <1> 	; < serial port 2 interrupt handler >
 13197                              <1> 	;
 13198 00002A3B 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13199                              <1> 	;;push	eax
 13200                              <1> 	; 08/01/2022
 13201 00002A3E 29C0                <1> 	sub	eax, eax
 13202 00002A40 B009                <1> 	mov	al, 9
 13203                              <1> 	;mov	ax, 9
 13204 00002A42 EB07                <1> 	jmp	short comm_int
 13205                              <1> com1_int:
 13206                              <1> 	; 07/11/2015
 13207                              <1> 	; 24/10/2015
 13208 00002A44 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13209                              <1> 	; 23/10/2015
 13210                              <1> 	;push	eax
 13211                              <1> 	; 08/01/2022
 13212 00002A47 29C0                <1> 	sub	eax, eax
 13213 00002A49 B008                <1> 	mov	al, 8
 13214                              <1> 	;mov	ax, 8
 13215                              <1> comm_int:
 13216                              <1> 	; 08/01/2022
 13217                              <1> 	; 20/11/2015
 13218                              <1> 	; 18/11/2015
 13219                              <1> 	; 17/11/2015
 13220                              <1> 	; 16/11/2015
 13221                              <1> 	; 09/11/2015
 13222                              <1> 	; 08/11/2015
 13223                              <1> 	; 07/11/2015
 13224                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
 13225                              <1> 	; 01/11/2015
 13226                              <1> 	; 26/10/2015
 13227                              <1> 	; 23/10/2015
 13228 00002A4B 53                  <1> 	push	ebx
 13229 00002A4C 56                  <1> 	push	esi
 13230 00002A4D 57                  <1> 	push	edi
 13231 00002A4E 1E                  <1> 	push 	ds
 13232 00002A4F 06                  <1> 	push 	es
 13233                              <1> 	; 18/11/2015
 13234 00002A50 0F20DB              <1> 	mov	ebx, cr3
 13235 00002A53 53                  <1> 	push	ebx ; ****
 13236                              <1> 	;
 13237 00002A54 51                  <1> 	push	ecx ; ***
 13238 00002A55 52                  <1> 	push	edx ; **
 13239                              <1> 	;
 13240 00002A56 BB10000000          <1> 	mov	ebx, KDATA
 13241 00002A5B 8EDB                <1> 	mov	ds, bx
 13242 00002A5D 8EC3                <1> 	mov	es, bx
 13243                              <1> 	;
 13244 00002A5F 8B0D[28670000]      <1> 	mov	ecx, [k_page_dir]
 13245 00002A65 0F22D9              <1> 	mov	cr3, ecx
 13246                              <1> 	; 20/11/2015
 13247                              <1> 	; Interrupt identification register
 13248 00002A68 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
 13249                              <1> 	;
 13250 00002A6C 3C08                <1> 	cmp 	al, 8 
 13251 00002A6E 7702                <1> 	ja 	short com_i0
 13252                              <1> 	;
 13253                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.1)
 13254                              <1> 	; 20/11/2015
 13255                              <1> 	; 17/11/2015
 13256                              <1> 	; 16/11/2015
 13257                              <1> 	; 15/11/2015
 13258                              <1> 	; 24/10/2015
 13259                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13260                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13261                              <1> 	; < serial port 1 interrupt handler >
 13262                              <1> 	;
 13263 00002A70 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
 13264                              <1> com_i0:
 13265                              <1> 	;push	eax ; *
 13266                              <1> 	; 07/11/2015
 13267 00002A72 A2[96670000]        <1> 	mov 	byte [ccomport], al
 13268                              <1> 	; 09/11/2015
 13269                              <1> 	;movzx	ebx, ax ; 8 or 9
 13270                              <1> 	; 08/01/2022
 13271 00002A77 89C3                <1> 	mov	ebx, eax ; 8 or 9
 13272                              <1> 	; 17/11/2015
 13273                              <1>  	; reset request for response status
 13274 00002A79 88A3[8C670000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
 13275                              <1> 	;
 13276                              <1> 	; 20/11/2015
 13277 00002A7F EC                  <1> 	in	al, dx		; read interrupt id. register
 13278 00002A80 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13279 00002A82 2404                <1> 	and	al, 4		; received data available?	
 13280 00002A84 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
 13281                              <1> 	;
 13282                              <1> 	; 20/11/2015
 13283 00002A86 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
 13284 00002A89 EC                  <1> 	in	al, dx     	; read character
 13285                              <1> 	;JMP	$+2	   	; I/O DELAY
 13286                              <1> 	; 08/11/2015
 13287                              <1> 	; 07/11/2015
 13288 00002A8A 89DE                <1> 	mov	esi, ebx 
 13289 00002A8C 89DF                <1> 	mov	edi, ebx
 13290 00002A8E 81C6[90670000]      <1> 	add 	esi, rchar - 8 ; points to last received char
 13291 00002A94 81C7[92670000]      <1> 	add	edi, schar - 8 ; points to last sent char
 13292 00002A9A 8806                <1> 	mov	[esi], al ; received char (current char)
 13293                              <1> 	; query
 13294 00002A9C 20C0                <1> 	and	al, al
 13295 00002A9E 7527                <1> 	jnz	short com_i2
 13296                              <1>    	; response
 13297                              <1> 	; 17/11/2015
 13298                              <1> 	; set request for response status
 13299 00002AA0 FE83[8C670000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
 13300                              <1> 	;
 13301 00002AA6 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
 13302 00002AAA EC                  <1> 	in	al, dx	   	; read line status register 
 13303 00002AAB EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13304 00002AAD 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
 13305 00002AAF 7445                <1> 	jz	short com_eoi 	; no
 13306 00002AB1 B0FF                <1> 	mov 	al, 0FFh   	; response			
 13307 00002AB3 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
 13308 00002AB7 EE                  <1> 	out	dx, al	   	; send on serial port
 13309                              <1> 	; 17/11/2015
 13310 00002AB8 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
 13311 00002ABB 7502                <1> 	jne 	short com_i1    ; no
 13312 00002ABD 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
 13313                              <1> com_i1:
 13314                              <1> 	; 17/11/2015
 13315                              <1> 	; reset request for response status (again)
 13316 00002ABF FE8B[8C670000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
 13317 00002AC5 EB2F                <1> 	jmp	short com_eoi
 13318                              <1> com_i2:	
 13319                              <1> 	; 08/11/2015
 13320 00002AC7 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
 13321 00002AC9 7417                <1> 	je	short com_i3	; (check for response signal)
 13322                              <1> 	; 07/11/2015
 13323 00002ACB 3C04                <1> 	cmp	al, 04h	; EOT
 13324 00002ACD 751C                <1> 	jne	short com_i4	
 13325                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
 13326                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
 13327                              <1> 	; 08/11/2015
 13328                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
 13329 00002ACF 861D[56670000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
 13330 00002AD5 E80BFFFFFF          <1> 	call 	ctrlbrk
 13331 00002ADA 861D[56670000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
 13332                              <1> 	;mov	al, 04h ; EOT
 13333                              <1> 	; 08/11/2015
 13334 00002AE0 EB09                <1> 	jmp	short com_i4	
 13335                              <1> com_i3:
 13336                              <1> 	; 08/11/2015
 13337                              <1> 	; If 0FFh has been received just after a query
 13338                              <1> 	; (schar, ZERO), it is a response signal.
 13339                              <1> 	; 17/11/2015
 13340 00002AE2 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
 13341 00002AE5 7704                <1> 	ja	short com_i4 ; no
 13342                              <1> 	; reset query status (schar)
 13343 00002AE7 8807                <1> 	mov	[edi], al ; 0FFh
 13344 00002AE9 FEC0                <1> 	inc	al ; 0
 13345                              <1> com_i4:
 13346                              <1> 	; 27/07/2014
 13347                              <1> 	; 09/07/2014
 13348 00002AEB D0E3                <1> 	shl	bl, 1	
 13349 00002AED 81C3[58670000]      <1> 	add	ebx, ttychr
 13350                              <1> 	; 23/07/2014 (always overwrite)
 13351                              <1> 	;;cmp	word [ebx], 0
 13352                              <1> 	;;ja	short com_eoi
 13353                              <1> 	;
 13354 00002AF3 668903              <1> 	mov	[ebx], ax   ; Save ascii code
 13355                              <1> 			    ; scan code = 0
 13356                              <1> com_eoi:
 13357                              <1> 	;mov	al, 20h
 13358                              <1> 	;out	20h, al	   ; end of interrupt
 13359                              <1> 	;
 13360                              <1> 	; 07/11/2015
 13361                              <1>       	;pop	eax ; *
 13362 00002AF6 A0[96670000]        <1> 	mov	al, byte [ccomport] ; current COM port
 13363                              <1> 	; al = tty number (8 or 9)
 13364 00002AFB E84E1C0000          <1>         call	wakeup
 13365                              <1> com_iret:
 13366                              <1> 	; 23/10/2015
 13367 00002B00 5A                  <1> 	pop	edx ; **
 13368 00002B01 59                  <1> 	pop	ecx ; ***
 13369                              <1> 	; 18/11/2015
 13370                              <1> 	;pop	eax ; ****
 13371                              <1> 	;mov	cr3, eax
 13372                              <1> 	;jmp	iiret
 13373 00002B02 E995DEFFFF          <1> 	jmp	iiretp
 13374                              <1> 
 13375                              <1> ;iiretp: ; 01/09/2015
 13376                              <1> ;	; 28/08/2015
 13377                              <1> ;	pop	eax ; (*) page directory
 13378                              <1> ;	mov	cr3, eax
 13379                              <1> ;iiret:
 13380                              <1> ;	; 22/08/2014
 13381                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
 13382                              <1> ;	out	20h, al	; 8259 PORT
 13383                              <1> ;	;
 13384                              <1> ;	pop	es
 13385                              <1> ;	pop	ds
 13386                              <1> ;	pop	edi
 13387                              <1> ;	pop	esi
 13388                              <1> ;	pop	ebx ; 29/08/2014
 13389                              <1> ;	pop 	eax
 13390                              <1> ;	iretd
 13391                              <1> 
 13392                              <1> sp_init:
 13393                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 13394                              <1> 	; 07/11/2015
 13395                              <1> 	; 29/10/2015
 13396                              <1> 	; 26/10/2015
 13397                              <1> 	; 23/10/2015
 13398                              <1> 	; 29/06/2015
 13399                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
 13400                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
 13401                              <1> 	; Initialization of Serial Port Communication Parameters
 13402                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13403                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13404                              <1> 	;
 13405                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13406                              <1> 	;
 13407                              <1> 	; INPUT:  (29/06/2015)
 13408                              <1> 	;	AL = 0 for COM1
 13409                              <1> 	;	     1 for COM2
 13410                              <1> 	;	AH = Communication parameters	
 13411                              <1> 	;
 13412                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13413                              <1> 	;	Bit	4	3	2	1	0
 13414                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13415                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13416                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13417                              <1> 	;		11 = even
 13418                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13419                              <1> 	;		Retro UNIX 386 v1 feature only !
 13420                              <1> 	;	Bit	7    6    5  | Baud rate
 13421                              <1> 	;		------------------------
 13422                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13423                              <1> 	;		0    0    1  | 9600 (12)
 13424                              <1> 	;		0    1    0  | 19200 (6) 
 13425                              <1> 	;		0    1	  1  | 38400 (3) 
 13426                              <1> 	;		1    0	  0  | 14400 (8)
 13427                              <1> 	;		1    0	  1  | 28800 (4)
 13428                              <1> 	;		1    1    0  | 57600 (2)
 13429                              <1> 	;		1    1    1  | 115200 (1) 	
 13430                              <1> 	
 13431                              <1> 	; References:	
 13432                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
 13433                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
 13434                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
 13435                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
 13436                              <1> 	;
 13437                              <1> 	; Set communication parameters for COM1 (= 03h)	
 13438                              <1> 	;
 13439 00002B07 BB[92670000]        <1> 	mov	ebx, com1p		; COM1 parameters  
 13440 00002B0C 66BAF803            <1> 	mov	dx, 3F8h		; COM1
 13441                              <1> 	; 29/10/2015
 13442 00002B10 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13443 00002B14 E84F000000          <1> 	call	sp_i3	; call A4	
 13444 00002B19 A880                <1> 	test	al, 80h
 13445 00002B1B 740E                <1> 	jz	short sp_i0 ; OK..
 13446                              <1> 		; Error !
 13447                              <1> 	;mov	dx, 3F8h
 13448 00002B1D 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
 13449                              <1> 	;mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13450                              <1> 	; 08/01/2022
 13451 00002B20 B10E                <1> 	mov	cl, 0Eh ; cx = 30Eh, divisor = 12 (9600 baud)
 13452 00002B22 E841000000          <1> 	call	sp_i3	; call A4	
 13453 00002B27 A880                <1> 	test	al, 80h
 13454 00002B29 7508                <1> 	jnz	short sp_i1
 13455                              <1> sp_i0:
 13456                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
 13457                              <1>         ; (INT 14h initialization code disables interrupts.)
 13458                              <1> 	;
 13459 00002B2B C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13460 00002B2E E8BF000000          <1> 	call	sp_i5 ; 29/06/2015
 13461                              <1> sp_i1:
 13462 00002B33 43                  <1> 	inc	ebx
 13463 00002B34 66BAF802            <1> 	mov	dx, 2F8h		; COM2
 13464                              <1> 	; 29/10/2015
 13465                              <1> 	;mov	cx, 301h  ; divisor = 1 (115200 baud)
 13466                              <1> 	; 08/01/2022
 13467 00002B38 B101                <1> 	mov	cl, 01h ; cx = 301h, divisor = 1 (115200 baud)
 13468 00002B3A E829000000          <1> 	call	sp_i3	; call A4	
 13469 00002B3F A880                <1> 	test	al, 80h
 13470 00002B41 740E                <1> 	jz	short sp_i2 ; OK..
 13471                              <1> 		; Error !
 13472                              <1> 	;mov	dx, 2F8h
 13473 00002B43 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
 13474                              <1> 	;mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13475                              <1> 	; 08/01/2022
 13476 00002B46 B10E                <1> 	mov	cl, 0Eh ; cx = 30Eh, divisor = 12 (9600 baud)
 13477 00002B48 E81B000000          <1> 	call	sp_i3	; call A4	
 13478 00002B4D A880                <1> 	test	al, 80h
 13479 00002B4F 7516                <1> 	jnz	short sp_i7
 13480                              <1> sp_i2:
 13481 00002B51 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13482                              <1> sp_i6:
 13483                              <1> 	;; COM2 - enabling IRQ 3
 13484                              <1> 	; 08/01/2022
 13485 00002B54 B4F7                <1> 	mov	ah, 0F7h ; enable IRQ 3 (COM2)
 13486                              <1> 	; 07/11/2015
 13487                              <1> 	; 26/10/2015
 13488                              <1> 	;pushf
 13489                              <1> 	;cli
 13490                              <1> 	;;
 13491                              <1> 	;;mov	dx, 2FCh   		; modem control register
 13492                              <1> 	;mov	dl, 0FCh ; 08/01/2022
 13493                              <1> 	;in	al, dx 	   		; read register
 13494                              <1> 	;JMP	$+2	   		; I/O DELAY
 13495                              <1> 	;or	al, 8      		; enable bit 3 (OUT2)
 13496                              <1> 	;out	dx, al     		; write back to register
 13497                              <1> 	;JMP	$+2	   		; I/O DELAY
 13498                              <1> 	;;mov	dx, 2F9h   		; interrupt enable register
 13499                              <1> 	;mov	dl, 0F9h ; 08/01/2022
 13500                              <1> 	;in	al, dx     		; read register
 13501                              <1> 	;JMP	$+2	   		; I/O DELAY
 13502                              <1> 	;;or	al, 1      		; receiver data interrupt enable and
 13503                              <1> 	;or	al, 3	   		; transmitter empty interrupt enable
 13504                              <1> 	;out	dx, al 	   		; write back to register
 13505                              <1> 	;JMP	$+2        		; I/O DELAY
 13506                              <1> 	;in	al, 21h    		; read interrupt mask register
 13507                              <1> 	;JMP	$+2	   		; I/O DELAY
 13508                              <1> 	;and	al, 0F7h   		; enable IRQ 3 (COM2)
 13509                              <1> 	;out	21h, al    		; write back to register
 13510                              <1> 	;
 13511                              <1> 	; 08/01/2022
 13512 00002B56 9C                  <1> 	pushf
 13513 00002B57 E8AA000000          <1> 	call	sp_i8
 13514                              <1> 	; 23/10/2015
 13515 00002B5C B8[3B2A0000]        <1> 	mov 	eax, com2_int
 13516 00002B61 A3[58300000]        <1> 	mov	[com2_irq3], eax
 13517                              <1> 	; 26/10/2015
 13518 00002B66 9D                  <1> 	popf	
 13519                              <1> sp_i7:
 13520 00002B67 C3                  <1> 	retn
 13521                              <1> 
 13522                              <1> sp_i3:
 13523                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
 13524                              <1> 	; 28/10/2015
 13525 00002B68 FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
 13526 00002B6A B000                <1> 	mov	al, 0
 13527 00002B6C EE                  <1> 	out	dx, al			; disable serial port interrupt
 13528 00002B6D EB00                <1> 	JMP	$+2			; I/O DELAY
 13529 00002B6F 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
 13530 00002B72 B080                <1> 	mov	al, 80h			
 13531 00002B74 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
 13532                              <1> 	;-----	SET BAUD RATE DIVISOR
 13533                              <1> 	; 26/10/2015
 13534 00002B75 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
 13535                              <1> 					; of the divisor value
 13536 00002B78 88C8                <1> 	mov	al, cl	; 1
 13537 00002B7A EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
 13538                              <1> 					; 2 = 57600 baud
 13539                              <1> 					; 3 = 38400 baud
 13540                              <1> 					; 6 = 19200 baud
 13541                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
 13542 00002B7B EB00                <1> 	JMP	$+2			; I/O DELAY
 13543 00002B7D 28C0                <1> 	sub	al, al
 13544 00002B7F FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
 13545                              <1> 					; of the divisor value
 13546 00002B81 EE                  <1> 	out	dx, al ; 0
 13547 00002B82 EB00                <1> 	JMP	$+2			; I/O DELAY
 13548                              <1> 	;	
 13549 00002B84 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
 13550                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
 13551 00002B86 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
 13552 00002B89 EE                  <1> 	out	dx, al			
 13553 00002B8A EB00                <1> 	JMP	$+2			; I/O DELAY
 13554                              <1> 	; 29/10/2015
 13555 00002B8C FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
 13556 00002B8E 30C0                <1> 	xor	al, al			; 0
 13557 00002B90 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
 13558 00002B91 EB00                <1> 	JMP	$+2	
 13559                              <1> sp_i4:
 13560                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
 13561                              <1> 	; 29/06/2015 (line status after modem status)
 13562 00002B93 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
 13563                              <1> sp_i4s:
 13564 00002B96 EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
 13565 00002B97 EB00                <1> 	JMP	$+2			; I/O DELAY
 13566 00002B99 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
 13567 00002B9B FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
 13568                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
 13569 00002B9D EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
 13570                              <1> 	; AL = Line status, AH = Modem status
 13571 00002B9E C3                  <1> 	retn
 13572                              <1> 
 13573                              <1> sp_status:
 13574                              <1> 	; 29/06/2015
 13575                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
 13576                              <1> 	; Get serial port status
 13577 00002B9F 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
 13578 00002BA3 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
 13579                              <1> 					; dx = 2FEh for COM2
 13580 00002BA5 EBEF                <1> 	jmp	short sp_i4s
 13581                              <1> 
 13582                              <1> sp_setp: ; Set serial port communication parameters
 13583                              <1> 	; 08/01/2022
 13584                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 13585                              <1> 	; 07/11/2015
 13586                              <1> 	; 29/10/2015
 13587                              <1> 	; 29/06/2015
 13588                              <1> 	; Retro UNIX 386 v1 feature only !	
 13589                              <1> 	;
 13590                              <1> 	; INPUT:
 13591                              <1> 	;	AL = 0 for COM1
 13592                              <1> 	;	     1 for COM2
 13593                              <1> 	;	AH = Communication parameters (*)
 13594                              <1> 	; OUTPUT:
 13595                              <1> 	;	CL = Line status
 13596                              <1> 	;	CH = Modem status
 13597                              <1> 	;   If cf = 1 -> Error code in [u.error]
 13598                              <1> 	;		 'invalid parameter !' 
 13599                              <1> 	;		 	 or
 13600                              <1> 	;		 'device not ready !' error
 13601                              <1> 	;	
 13602                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13603                              <1> 	;	Bit	4	3	2	1	0
 13604                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13605                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13606                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13607                              <1> 	;		11 = even
 13608                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13609                              <1> 	;		Retro UNIX 386 v1 feature only !
 13610                              <1> 	;	Bit	7    6    5  | Baud rate
 13611                              <1> 	;		------------------------
 13612                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13613                              <1> 	;		0    0    1  | 9600 (12)
 13614                              <1> 	;		0    1    0  | 19200 (6) 
 13615                              <1> 	;		0    1	  1  | 38400 (3) 
 13616                              <1> 	;		1    0	  0  | 14400 (8)
 13617                              <1> 	;		1    0	  1  | 28800 (4)
 13618                              <1> 	;		1    1    0  | 57600 (2)
 13619                              <1> 	;		1    1    1  | 115200 (1) 
 13620                              <1> 	;
 13621                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13622                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13623                              <1> 	;
 13624                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13625                              <1> 	;
 13626 00002BA7 66BAF803            <1> 	mov	dx, 3F8h
 13627 00002BAB BB[92670000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
 13628 00002BB0 3C01                <1> 	cmp	al, 1
 13629 00002BB2 7770                <1> 	ja 	short sp_invp_err
 13630 00002BB4 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
 13631 00002BB6 FECE                <1> 	dec	dh ; 2F8h
 13632 00002BB8 43                  <1> 	inc	ebx ; COM2 control byte offset
 13633                              <1> sp_setp1:
 13634                              <1> 	; 29/10/2015
 13635 00002BB9 8823                <1> 	mov	[ebx], ah
 13636 00002BBB 0FB6CC              <1> 	movzx 	ecx, ah
 13637 00002BBE C0E905              <1> 	shr	cl, 5 ; -> baud rate index
 13638 00002BC1 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
 13639 00002BC4 8A81[332C0000]      <1> 	mov	al, [ecx+b_div_tbl]
 13640 00002BCA 6689C1              <1> 	mov	cx, ax
 13641 00002BCD E896FFFFFF          <1> 	call	sp_i3
 13642 00002BD2 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
 13643 00002BD5 A880                <1> 	test	al, 80h
 13644 00002BD7 740F                <1> 	jz	short sp_setp2
 13645 00002BD9 C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
 13646                              <1> stp_dnr_err:
 13647 00002BDC C705[D86C0000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
 13648 00002BE4 0000                <1>
 13649                              <1> 	; CL = Line status, CH = Modem status
 13650 00002BE6 F9                  <1> 	stc
 13651 00002BE7 C3                  <1> 	retn
 13652                              <1> sp_setp2:
 13653 00002BE8 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
 13654                              <1>         ;jna	sp_i6
 13655                              <1> 		      ; COM1 (3F?h)
 13656                              <1> 	; 24/12/2021
 13657 00002BEB 7705                <1> 	ja	short sp_i5
 13658 00002BED E962FFFFFF          <1> 	jmp	sp_i6
 13659                              <1> sp_i5: 
 13660                              <1> 	; 08/01/2022
 13661 00002BF2 B4EF                <1> 	mov	ah, 0EFh ; enable IRQ 4 (COM1)
 13662                              <1> 	; 07/11/2015
 13663                              <1> 	; 26/10/2015
 13664                              <1> 	; 29/06/2015
 13665                              <1> 	;
 13666                              <1> 	;; COM1 - enabling IRQ 4
 13667                              <1> 	;pushf
 13668                              <1> 	;cli
 13669                              <1> 	;;mov	dx, 3FCh   		; modem control register
 13670                              <1> 	;mov	dl, 0FCh ; 08/01/2022
 13671                              <1> 	;in	al, dx 	   		; read register
 13672                              <1> 	;JMP	$+2			; I/O DELAY
 13673                              <1> 	;or	al, 8      		; enable bit 3 (OUT2)
 13674                              <1> 	;out	dx, al     		; write back to register
 13675                              <1> 	;JMP	$+2			; I/O DELAY
 13676                              <1> 	;;mov	dx, 3F9h   		; interrupt enable register
 13677                              <1> 	;mov	dl, 0F9h ; 08/01/2022
 13678                              <1> 	;in	al, dx     		; read register
 13679                              <1> 	;JMP	$+2			; I/O DELAY
 13680                              <1> 	;;or	al, 1      		; receiver data interrupt enable and
 13681                              <1> 	;or	al, 3	   		; transmitter empty interrupt enable
 13682                              <1> 	;out	dx, al 	   		; write back to register
 13683                              <1> 	;JMP	$+2        		; I/O DELAY
 13684                              <1> 	;in	al, 21h    		; read interrupt mask register
 13685                              <1> 	;JMP	$+2			; I/O DELAY
 13686                              <1> 	;and	al, 0EFh   		; enable IRQ 4 (COM1)
 13687                              <1> 	;out	21h, al    		; write back to register
 13688                              <1> 	;
 13689                              <1> 	; 08/01/2022
 13690 00002BF4 9C                  <1> 	pushf
 13691 00002BF5 E80C000000          <1> 	call	sp_i8
 13692                              <1> 	; 23/10/2015
 13693 00002BFA B8[442A0000]        <1> 	mov 	eax, com1_int
 13694 00002BFF A3[54300000]        <1> 	mov	[com1_irq4], eax
 13695                              <1> 	; 26/10/2015
 13696 00002C04 9D                  <1> 	popf
 13697 00002C05 C3                  <1> 	retn
 13698                              <1> 
 13699                              <1> sp_i8:
 13700                              <1> 	; 08/01/2022
 13701                              <1> 	;pushf
 13702 00002C06 FA                  <1> 	cli
 13703                              <1> 	;
 13704                              <1> 	;mov	dx, 2FCh  ; 3FCh	; modem control register
 13705 00002C07 B2FC                <1> 	mov	dl, 0FCh
 13706 00002C09 EC                  <1> 	in	al, dx 	   		; read register
 13707 00002C0A EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13708 00002C0C 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13709 00002C0E EE                  <1> 	out	dx, al     		; write back to register
 13710 00002C0F EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13711                              <1> 	;mov	dx, 2F9h  ; 3F9h 	; interrupt enable register
 13712 00002C11 B2F9                <1> 	mov	dl, 0F9h
 13713 00002C13 EC                  <1> 	in	al, dx     		; read register
 13714 00002C14 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13715                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13716 00002C16 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13717 00002C18 EE                  <1> 	out	dx, al 	   		; write back to register
 13718 00002C19 EB00                <1> 	JMP	$+2        		; I/O DELAY
 13719 00002C1B E421                <1> 	in	al, 21h    		; read interrupt mask register
 13720 00002C1D EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13721                              <1> 	;and	al, 0F7h  ; 0EFh	; enable IRQ 3 (COM2)
 13722 00002C1F 20E0                <1> 	and	al, ah	; 0F7h or 0EFh 
 13723 00002C21 E621                <1> 	out	21h, al    		; write back to register
 13724                              <1> 	;
 13725                              <1> 	;popf	
 13726 00002C23 C3                  <1> 	retn
 13727                              <1> 
 13728                              <1> sp_invp_err:
 13729 00002C24 C705[D86C0000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 13730 00002C2C 0000                <1>
 13731 00002C2E 31C9                <1> 	xor	ecx, ecx
 13732 00002C30 49                  <1> 	dec	ecx ; 0FFFFh
 13733 00002C31 F9                  <1> 	stc
 13734 00002C32 C3                  <1> 	retn
 13735                              <1> 
 13736                              <1> ; 29/10/2015
 13737                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
 13738 00002C33 010C0603080401      <1> 	db	1, 12, 6, 3, 8, 4, 1
 13739                              <1> 
 13740                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014) 
 13741                              <1> epoch:
 13742                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 13743                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13744                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
 13745                              <1> 	; 'epoch' procedure prototype: 
 13746                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13747                              <1> 	; 14/11/2012
 13748                              <1> 	; unixboot.asm (boot file configuration)
 13749                              <1> 	; version of "epoch" procedure in "unixproc.asm"
 13750                              <1> 	; 21/7/2012
 13751                              <1> 	; 15/7/2012
 13752                              <1> 	; 14/7/2012		
 13753                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
 13754                              <1> 	; compute current date and time as UNIX Epoch/Time
 13755                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
 13756                              <1> 	;
 13757                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
 13758                              <1> 	;
 13759 00002C3A E818010000          <1> 	call 	get_rtc_time		; Return Current Time
 13760 00002C3F 86E9                <1>         xchg 	ch,cl
 13761 00002C41 66890D[98640000]    <1>         mov 	[hour], cx
 13762 00002C48 86F2                <1>         xchg 	dh,dl
 13763 00002C4A 668915[9A640000]    <1>         mov 	[second], dx
 13764                              <1> 	;
 13765 00002C51 E832010000          <1>         call 	get_rtc_date		; Return Current Date
 13766 00002C56 86E9                <1>         xchg 	ch,cl
 13767 00002C58 66890D[94640000]    <1>         mov 	[year], cx
 13768 00002C5F 86F2                <1>         xchg 	dh,dl
 13769 00002C61 668915[96640000]    <1>         mov 	[month], dx
 13770                              <1> 	;
 13771 00002C68 66B93030            <1> 	mov 	cx, 3030h
 13772                              <1> 	;
 13773 00002C6C A0[98640000]        <1> 	mov 	al, [hour] ; Hour
 13774                              <1>         	; AL <= BCD number)
 13775 00002C71 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13776                              <1> 					; AH = AL / 10h
 13777                              <1> 					; AL = AL MOD 10h
 13778 00002C73 D50A                <1>         aad 	; AX= AH*10+AL
 13779 00002C75 A2[98640000]        <1> 	mov 	[hour], al
 13780 00002C7A A0[99640000]        <1> 	mov 	al, [hour+1] ; Minute
 13781                              <1>         	; AL <= BCD number)
 13782 00002C7F D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13783                              <1> 					; AH = AL / 10h
 13784                              <1> 					; AL = AL MOD 10h
 13785 00002C81 D50A                <1>         aad 	; AX= AH*10+AL
 13786 00002C83 A2[99640000]        <1> 	mov 	[minute], al
 13787 00002C88 A0[9A640000]        <1> 	mov 	al, [second] ; Second
 13788                              <1>         	; AL <= BCD number)
 13789 00002C8D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13790                              <1> 					; AH = AL / 10h
 13791                              <1> 					; AL = AL MOD 10h
 13792 00002C8F D50A                <1>         aad 	; AX= AH*10+AL
 13793 00002C91 A2[9A640000]        <1> 	mov 	[second], al
 13794 00002C96 66A1[94640000]      <1> 	mov 	ax, [year] ; Year (century)
 13795                              <1> 	;push 	ax
 13796                              <1> 	; 04/12/2021
 13797 00002C9C 50                  <1> 	push	eax
 13798                              <1> 	   	; AL <= BCD number)
 13799 00002C9D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13800                              <1> 					; AH = AL / 10h
 13801                              <1> 					; AL = AL MOD 10h
 13802 00002C9F D50A                <1>         aad 	; AX= AH*10+AL
 13803 00002CA1 B464                <1> 	mov 	ah, 100
 13804 00002CA3 F6E4                <1> 	mul 	ah
 13805 00002CA5 66A3[94640000]      <1> 	mov 	[year], ax
 13806                              <1> 	;pop	ax
 13807                              <1> 	; 04/12/2021
 13808 00002CAB 58                  <1> 	pop	eax
 13809 00002CAC 88E0                <1> 	mov	al, ah
 13810                              <1>         	; AL <= BCD number)
 13811 00002CAE D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13812                              <1> 					; AH = AL / 10h
 13813                              <1> 					; AL = AL MOD 10h
 13814 00002CB0 D50A                <1>         aad 	; AX= AH*10+AL
 13815 00002CB2 660105[94640000]    <1> 	add 	[year], ax
 13816 00002CB9 A0[96640000]        <1> 	mov 	al, [month] ; Month
 13817                              <1>            	; AL <= BCD number)
 13818 00002CBE D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13819                              <1> 					; AH = AL / 10h
 13820                              <1> 					; AL = AL MOD 10h
 13821 00002CC0 D50A                <1>         aad 	; AX= AH*10+AL
 13822 00002CC2 A2[96640000]        <1> 	mov 	[month], al	
 13823 00002CC7 A0[97640000]        <1>         mov     al, [month+1]      	; Day
 13824                              <1>            	; AL <= BCD number)
 13825 00002CCC D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 13826                              <1> 					; AH = AL / 10h
 13827                              <1> 					; AL = AL MOD 10h
 13828 00002CCE D50A                <1>         aad 	; AX= AH*10+AL
 13829 00002CD0 A2[97640000]        <1>         mov     [day], al
 13830                              <1> 	
 13831                              <1> _epoch:
 13832                              <1> 	; 17/07/2022
 13833                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
 13834                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1)
 13835                              <1> 	;
 13836                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
 13837                              <1> 	;
 13838                              <1> 	; Derived from DALLAS Semiconductor
 13839                              <1> 	; Application Note 31 (DS1602/DS1603)
 13840                              <1> 	; 6 May 1998
 13841 00002CD5 29C0                <1> 	sub 	eax, eax
 13842 00002CD7 66A1[94640000]      <1> 	mov 	ax, [year]
 13843 00002CDD 662DB207            <1> 	sub 	ax, 1970
 13844 00002CE1 BA6D010000          <1> 	mov 	edx, 365
 13845 00002CE6 F7E2                <1> 	mul 	edx
 13846 00002CE8 31DB                <1> 	xor 	ebx, ebx
 13847 00002CEA 8A1D[96640000]      <1> 	mov 	bl, [month]
 13848 00002CF0 FECB                <1> 	dec 	bl
 13849 00002CF2 D0E3                <1> 	shl 	bl, 1
 13850                              <1> 	;sub	edx, edx
 13851 00002CF4 668B93[9C640000]    <1> 	mov 	dx, [EBX+DMonth]
 13852 00002CFB 8A1D[97640000]      <1>         mov     bl, [day]
 13853 00002D01 FECB                <1> 	dec 	bl
 13854 00002D03 01D0                <1> 	add 	eax, edx
 13855 00002D05 01D8                <1> 	add 	eax, ebx
 13856                              <1> 			; EAX = days since 1/1/1970
 13857 00002D07 668B15[94640000]    <1> 	mov 	dx, [year]
 13858 00002D0E 6681EAB107          <1> 	sub 	dx, 1969
 13859                              <1> 	;shr 	dx, 1
 13860                              <1> 	;shr 	dx, 1		
 13861                              <1> 	; 17/07/2022
 13862 00002D13 C1EA02              <1> 	shr	edx, 2
 13863                              <1> 		; (year-1969)/4
 13864 00002D16 01D0                <1> 	add 	eax, edx
 13865                              <1> 			; + leap days since 1/1/1970
 13866 00002D18 803D[96640000]02    <1> 	cmp 	byte [month], 2	; if past february
 13867 00002D1F 7610                <1> 	jna 	short cte1
 13868 00002D21 668B15[94640000]    <1> 	mov 	dx, [year]
 13869 00002D28 6683E203            <1> 	and 	dx, 3 ; year mod 4
 13870 00002D2C 7503                <1> 	jnz 	short cte1		
 13871                              <1> 			; and if leap year
 13872 00002D2E 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
 13873                              <1> cte1: 			; compute seconds since 1/1/1970
 13874 00002D31 BA18000000          <1> 	mov 	edx, 24
 13875 00002D36 F7E2                <1> 	mul	edx
 13876 00002D38 8A15[98640000]      <1> 	mov 	dl, [hour]
 13877 00002D3E 01D0                <1> 	add 	eax, edx
 13878                              <1> 		; EAX = hours since 1/1/1970 00:00:00
 13879                              <1> 	;mov	ebx, 60
 13880 00002D40 B33C                <1> 	mov	bl, 60
 13881 00002D42 F7E3                <1> 	mul	ebx
 13882 00002D44 8A15[99640000]      <1> 	mov 	dl, [minute]
 13883 00002D4A 01D0                <1> 	add 	eax, edx
 13884                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
 13885                              <1> 	;mov 	ebx, 60
 13886 00002D4C F7E3                <1> 	mul	ebx
 13887 00002D4E 8A15[9A640000]      <1> 	mov 	dl, [second]
 13888 00002D54 01D0                <1> 	add 	eax, edx
 13889                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
 13890 00002D56 C3                  <1> 	retn
 13891                              <1> 
 13892                              <1> get_rtc_time:
 13893                              <1> 	; 15/03/2015
 13894                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13895                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13896                              <1> 	; INT 1Ah
 13897                              <1> 	; (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,	:
 13898                              <1> 	;       (CH) = HOURS IN BCD (00-23)			:
 13899                              <1> 	;       (CL) = MINUTES IN BCD (00-59)			:
 13900                              <1> 	;       (DH) = SECONDS IN BCD (00-59)			:
 13901                              <1> 	;       (DL) = DAYLIGHT SAVINGS ENABLE (00-01).		:
 13902                              <1> 	;								
 13903                              <1> RTC_20: 				; GET RTC TIME
 13904 00002D57 FA                  <1> 	cli
 13905 00002D58 E8DBDDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13906 00002D5D 7227                <1> 	JC	short RTC_29		; EXIT IF ERROR (CY= 1)
 13907                              <1> 
 13908 00002D5F B000                <1> 	MOV	AL, CMOS_SECONDS 	; SET ADDRESS OF SECONDS
 13909 00002D61 E8BCDDFFFF          <1> 	CALL	CMOS_READ		; GET SECONDS
 13910 00002D66 88C6                <1> 	MOV	DH, AL			; SAVE
 13911 00002D68 B00B                <1> 	MOV	AL, CMOS_REG_B		; ADDRESS ALARM REGISTER
 13912 00002D6A E8B3DDFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 13913 00002D6F 2401                <1> 	AND	AL, 00000001B		; MASK FOR VALID DSE BIT
 13914 00002D71 88C2                <1> 	MOV	DL, AL			; SET [DL] TO ZERO FOR NO DSE BIT
 13915 00002D73 B002                <1> 	MOV	AL, CMOS_MINUTES 	; SET ADDRESS OF MINUTES
 13916 00002D75 E8A8DDFFFF          <1> 	CALL	CMOS_READ		; GET MINUTES
 13917 00002D7A 88C1                <1> 	MOV	CL, AL			; SAVE
 13918 00002D7C B004                <1> 	MOV	AL, CMOS_HOURS		; SET ADDRESS OF HOURS
 13919 00002D7E E89FDDFFFF          <1> 	CALL	CMOS_READ		; GET HOURS
 13920 00002D83 88C5                <1> 	MOV	CH, AL			; SAVE
 13921 00002D85 F8                  <1> 	CLC				; SET CY= 0
 13922                              <1> RTC_29:
 13923 00002D86 FB                  <1> 	sti
 13924 00002D87 C3                  <1> 	RETn				; RETURN WITH RESULT IN CARRY FLAG
 13925                              <1> 
 13926                              <1> get_rtc_date:
 13927                              <1> 	; 15/03/2015
 13928                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 13929                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 13930                              <1> 	; INT 1Ah
 13931                              <1> 	; (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,:
 13932                              <1> 	;      (CH) = CENTURY IN BCD (19 OR 20) 		       :
 13933                              <1> 	;      (CL) = YEAR IN BCD (00-99)			       :
 13934                              <1> 	;      (DH) = MONTH IN BCD (01-12)			       :
 13935                              <1> 	;      (DL) = DAY IN BCD (01-31).		
 13936                              <1> 	;
 13937                              <1> RTC_40: 				; GET RTC DATE
 13938 00002D88 FA                  <1> 	cli
 13939 00002D89 E8AADDFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 13940 00002D8E 7225                <1> 	JC	short RTC_49		; EXIT IF ERROR (CY= 1)
 13941                              <1> 
 13942 00002D90 B007                <1> 	MOV	AL, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
 13943 00002D92 E88BDDFFFF          <1> 	CALL	CMOS_READ		; READ DAY OF MONTH
 13944 00002D97 88C2                <1> 	MOV	DL, AL			; SAVE
 13945 00002D99 B008                <1> 	MOV	AL, CMOS_MONTH		; ADDRESS MONTH
 13946 00002D9B E882DDFFFF          <1> 	CALL	CMOS_READ		; READ MONTH
 13947 00002DA0 88C6                <1> 	MOV	DH, AL			; SAVE
 13948 00002DA2 B009                <1> 	MOV	AL, CMOS_YEAR		; ADDRESS YEAR
 13949 00002DA4 E879DDFFFF          <1> 	CALL	CMOS_READ		; READ YEAR
 13950 00002DA9 88C1                <1> 	MOV	CL, AL			; SAVE
 13951 00002DAB B032                <1> 	MOV	AL, CMOS_CENTURY 	; ADDRESS CENTURY LOCATION
 13952 00002DAD E870DDFFFF          <1> 	CALL	CMOS_READ		; GET CENTURY BYTE
 13953 00002DB2 88C5                <1> 	MOV	CH, AL			; SAVE
 13954 00002DB4 F8                  <1> 	CLC				; SET CY=0
 13955                              <1> RTC_49:
 13956 00002DB5 FB                  <1> 	sti
 13957 00002DB6 C3                  <1> 	RETn				; RETURN WITH RESULTS IN CARRY FLAG
 13958                              <1> 
 13959                              <1> set_date_time:
 13960                              <1> convert_from_epoch:
 13961                              <1> 	; 02/06/2022 (BugFix)
 13962                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 13963                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 13964                              <1> 	; 'convert_from_epoch' procedure prototype: 
 13965                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 13966                              <1> 	;
 13967                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
 13968                              <1> 	;
 13969                              <1> 	; Derived from DALLAS Semiconductor
 13970                              <1> 	; Application Note 31 (DS1602/DS1603)
 13971                              <1> 	; 6 May 1998
 13972                              <1> 	;
 13973                              <1> 	; INPUT:
 13974                              <1> 	; EAX = Unix (Epoch) Time
 13975                              <1> 	;
 13976 00002DB7 31D2                <1> 	xor 	edx, edx
 13977                              <1> 	; 02/06/2022
 13978 00002DB9 31C9                <1> 	xor	ecx, ecx
 13979 00002DBB 31DB                <1> 	xor	ebx, ebx
 13980                              <1> 	;mov 	ecx, 60
 13981 00002DBD B13C                <1> 	mov	cl, 60
 13982 00002DBF F7F1                <1> 	div	ecx
 13983                              <1> 	;mov 	[imin], eax  ; whole minutes
 13984                              <1> 			     ; since 1/1/1970
 13985                              <1> 	;mov 	[second], dx ; leftover seconds
 13986 00002DC1 8815[9A640000]      <1> 	mov	[second], dl ; 02/06/2022
 13987 00002DC7 29D2                <1> 	sub 	edx, edx
 13988 00002DC9 F7F1                <1> 	div	ecx
 13989                              <1> 	;mov 	[ihrs], eax  ; whole hours
 13990                              <1> 	;		     ; since 1/1/1970
 13991                              <1> 	;mov 	[minute], dx ; leftover minutes
 13992 00002DCB 8815[99640000]      <1> 	mov	[minute], dl ; 02/06/2022
 13993 00002DD1 31D2                <1> 	xor	edx, edx
 13994                              <1> 	;mov 	cx, 24
 13995 00002DD3 B118                <1> 	mov 	cl, 24
 13996 00002DD5 F7F1                <1> 	div	ecx
 13997                              <1> 	;mov 	[iday], ax   ; whole days
 13998                              <1> 			     ; since 1/1/1970
 13999                              <1> 	;mov 	[hour], dx   ; leftover hours
 14000 00002DD7 8815[98640000]      <1> 	mov	[hour], dl   ; 02/06/2022
 14001                              <1> 
 14002 00002DDD 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
 14003                              <1> 			     ; 1/1/1968 	
 14004                              <1> 		;mov 	[iday], ax
 14005 00002DE2 50                  <1> 	push 	eax
 14006 00002DE3 29D2                <1> 	sub	edx, edx
 14007 00002DE5 B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
 14008 00002DEA F7F1                <1> 	div	ecx
 14009 00002DEC 59                  <1> 	pop 	ecx
 14010                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
 14011                              <1> 	;push	dx
 14012                              <1> 	; 02/06/2022
 14013 00002DED 52                  <1> 	push 	edx
 14014                              <1> 	;mov 	[qday], dx   ; days since quadyr began
 14015 00002DEE 6683FA3C            <1> 	cmp 	dx, 31+29    ; if past feb 29 then
 14016 00002DF2 F5                  <1> 	cmc		     ; add this quadyr's leap day
 14017 00002DF3 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
 14018                              <1> 	;mov 	[lday], ax   ; since 1968			  
 14019                              <1> 	;mov 	cx, [iday]
 14020 00002DF6 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
 14021 00002DF7 29C8                <1> 	sub 	eax, ecx     ; iday - lday
 14022 00002DF9 B96D010000          <1> 	mov 	ecx, 365
 14023 00002DFE 31D2                <1> 	xor	edx, edx
 14024                              <1> 	; EAX = iday-lday, EDX = 0
 14025 00002E00 F7F1                <1> 	div	ecx
 14026                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
 14027                              <1> 	;jday = iday - (iyrs*365) - lday
 14028                              <1> 	;mov	[jday], dx   ; days since 1/1 of current year
 14029                              <1> 	;add	eax, 1968
 14030 00002E02 6605B007            <1> 	add 	ax, 1968     ; compute year
 14031 00002E06 66A3[94640000]      <1> 	mov 	[year], ax
 14032                              <1> 	;mov 	cx, dx
 14033                              <1> 	; 02/06/2022
 14034 00002E0C 89D1                <1> 	mov	ecx, edx
 14035                              <1> 	;mov 	dx, [qday]
 14036                              <1> 	;pop	dx
 14037                              <1> 	; 02/06/2022
 14038 00002E0E 5A                  <1> 	pop 	edx
 14039 00002E0F 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
 14040 00002E14 7709                <1> 	ja 	short cfe1   ; jday = jday +1
 14041 00002E16 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
 14042 00002E1A F5                  <1>         cmc		     ; add a leap day to the # of whole
 14043 00002E1B 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
 14044                              <1> cfe1:			
 14045                              <1> 	;mov 	[jday], cx
 14046                              <1> 	;mov 	bx, 12       ; estimate month
 14047                              <1> 	;sub	ebx, ebx
 14048                              <1> 	; 02/06/2022
 14049 00002E1F B30C                <1> 	mov	bl, 12
 14050 00002E21 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
 14051 00002E25 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
 14052                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
 14053                              <1> 	;cmp 	cx, dx       ; mday = # of days passed from 1/1
 14054                              <1> 	; 02/06/2022
 14055 00002E29 39D1                <1> 	cmp	ecx, edx 	 		
 14056 00002E2B 7319                <1> 	jnb 	short cfe3
 14057                              <1> 	;dec 	bx           ; month = month - 1
 14058 00002E2D FECB                <1> 	dec	bl			
 14059                              <1> 	;shl 	bx, 1
 14060 00002E2F D0E3                <1> 	shl	bl, 1
 14061 00002E31 668B93[9C640000]    <1> 	mov 	dx, [ebx+DMonth] ; # elapsed days at 1st of month
 14062                              <1> 	;shr 	bx, 1        ; bx = month - 1 (0 to 11)
 14063                              <1> 	; 02/06/2022
 14064 00002E38 D0EB                <1> 	shr	bl, 1
 14065 00002E3A 80FB01              <1> 	cmp	bl, 1
 14066                              <1> 	;cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
 14067 00002E3D 76EA                <1> 	jna 	short cfe2   ; then mday = mday + 1
 14068 00002E3F 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
 14069 00002E41 75E6                <1> 	jnz 	short cfe2   ; add leap day (to mday)
 14070                              <1> 	;inc 	dx           ; mday = mday + 1
 14071 00002E43 42                  <1> 	inc	edx
 14072 00002E44 EBE3                <1> 	jmp 	short cfe2
 14073                              <1> cfe3:
 14074                              <1> 	;inc 	bx	     ; -> bx = month, 1 to 12
 14075                              <1> 	; 02/06/2022
 14076 00002E46 FEC3                <1> 	inc	bl
 14077                              <1> 	;mov 	[month], bx
 14078 00002E48 881D[96640000]      <1> 	mov	[month], bl
 14079                              <1> 	;sub 	cx, dx	     ; day = jday - mday + 1	
 14080 00002E4E 29D1                <1> 	sub	ecx, edx
 14081                              <1> 	;inc 	cx 			  
 14082 00002E50 FEC1                <1> 	inc	cl
 14083                              <1> 	;mov 	[day], cx
 14084 00002E52 880D[97640000]      <1> 	mov	[day], cl    ; 02/06/2022
 14085                              <1> 
 14086                              <1> 	; eax, ebx, ecx, edx is changed at return
 14087                              <1> 	; output ->
 14088                              <1> 	; [year], [month], [day], [hour], [minute], [second]
 14089                              <1> 	
 14090                              <1> 	; 02/06/2022 (BugFix)	
 14091                              <1> _set_date:
 14092 00002E58 66A1[94640000]      <1> 	mov	ax, [year]
 14093 00002E5E B520                <1> 	mov	ch, 20h ; century (bcd)
 14094 00002E60 662DD007            <1> 	sub	ax, 2000
 14095 00002E64 7306                <1> 	jnc	short set_date
 14096 00002E66 B519                <1> 	mov	ch, 19h ; century (bcd) 
 14097 00002E68 6683C064            <1> 	add	ax, 100	
 14098                              <1> 	; 02/06/2022
 14099                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 14100                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 14101                              <1> set_date:
 14102                              <1>         ;mov	al, [year+1]
 14103                              <1> 	;aam 	; ah = al / 10, al = al mod 10
 14104                              <1> 	;db 	0D5h, 10h    ; Undocumented inst. AAD
 14105                              <1> 	;		     ; AL = AH * 10h + AL
 14106                              <1> 	;mov 	ch, al ; century (BCD)
 14107                              <1> 	;mov 	al, [year]
 14108                              <1> 	; al = year (0-99) ; 01/06/2022
 14109 00002E6C D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14110 00002E6E D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
 14111                              <1> 			     ; AL = AH * 10h + AL
 14112 00002E70 88C1                <1> 	mov 	cl, al ; year (BCD)
 14113 00002E72 A0[96640000]        <1>         mov 	al, [month]
 14114 00002E77 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14115 00002E79 D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
 14116                              <1> 			     ; AL = AH * 10h + AL
 14117 00002E7B 88C6                <1> 	mov 	dh, al ; month (BCD)
 14118 00002E7D A0[97640000]        <1> 	mov 	al, [day]
 14119 00002E82 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14120 00002E84 D510                <1> 	db 	0D5h, 10h    ; Undocumented inst. AAD
 14121                              <1> 			     ; AL = AH * 10h + AL
 14122                              <1> 	; 02/06/2022 (BugFix)
 14123 00002E86 88C2                <1> 	mov 	dl, al ; day (BCD)
 14124                              <1> 
 14125                              <1> 	; Set real-time clock date
 14126 00002E88 E879000000          <1> 	call	set_rtc_date
 14127                              <1> set_time:
 14128                              <1>         ; Read real-time clock time 
 14129                              <1> 	; (get day light saving time bit status)
 14130 00002E8D FA                  <1>  	cli
 14131 00002E8E E8A5DCFFFF          <1> 	CALL	UPD_IPR 	; CHECK FOR UPDATE IN PROCESS
 14132                              <1> 	; cf = 1 -> al = 0
 14133 00002E93 7207                <1>         jc      short stime1
 14134 00002E95 B00B                <1> 	MOV	AL, CMOS_REG_B	; ADDRESS ALARM REGISTER
 14135 00002E97 E886DCFFFF          <1> 	CALL	CMOS_READ	; READ CURRENT VALUE OF DSE BIT
 14136                              <1> stime1:
 14137 00002E9C FB                  <1> 	sti
 14138 00002E9D 2401                <1> 	AND	AL, 00000001B	; MASK FOR VALID DSE BIT
 14139 00002E9F 88C2                <1> 	MOV	DL, AL		; SET [DL] TO ZERO FOR NO DSE BIT
 14140                              <1> 	; DL = 1 or 0 (day light saving time)
 14141                              <1> 	;	
 14142 00002EA1 A0[98640000]        <1> 	mov 	al, [hour]
 14143 00002EA6 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14144 00002EA8 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14145                              <1> 			     ; AL = AH * 10h + AL
 14146 00002EAA 88C5                <1> 	mov 	ch, al ; hour (BCD)
 14147 00002EAC A0[99640000]        <1>         mov     al, [minute]
 14148 00002EB1 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14149 00002EB3 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14150                              <1> 			     ; AL = AH * 10h + AL
 14151 00002EB5 88C1                <1> 	mov 	cl, al       ; minute (BCD)
 14152 00002EB7 A0[9A640000]        <1>         mov     al, [second]
 14153 00002EBC D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14154 00002EBE D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14155                              <1> 			     ; AL = AH * 10h + AL
 14156 00002EC0 88C6                <1> 	mov 	dh, al	     ; second (BCD)
 14157                              <1> 
 14158                              <1> 	; Set real-time clock time
 14159                              <1>  	; call	set_rtc_time
 14160                              <1> set_rtc_time:
 14161                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14162                              <1> 	; 15/03/2015
 14163                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14164                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14165                              <1> 	; INT 1Ah
 14166                              <1> 	; (AH) = 03H  SET THE REAL TIME CLOCK USING,			:
 14167                              <1> 	;      (CH) = HOURS IN BCD (00-23)			       	:
 14168                              <1> 	;      (CL) = MINUTES IN BCD (00-59)			       	:
 14169                              <1> 	;      (DH) = SECONDS IN BCD (00-59)			       	:
 14170                              <1> 	;      (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.    :
 14171                              <1> 	;								:
 14172                              <1> 	;  NOTE: (DL)= 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED. :
 14173                              <1> 	;        (DL)= 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN  :
 14174                              <1> 	;         APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN :
 14175                              <1> 	;         OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.	  :
 14176                              <1> 	;
 14177                              <1> RTC_30: 				; SET RTC TIME
 14178 00002EC2 FA                  <1> 	cli
 14179 00002EC3 E870DCFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14180 00002EC8 7305                <1> 	JNC	short RTC_35		; GO AROUND IF CLOCK OPERATING
 14181 00002ECA E886000000          <1> 	CALL	RTC_STA 		; ELSE TRY INITIALIZING CLOCK
 14182                              <1> RTC_35:
 14183 00002ECF 88F4                <1> 	MOV	AH, DH			; GET TIME BYTE - SECONDS
 14184 00002ED1 B000                <1> 	MOV	AL, CMOS_SECONDS 	; ADDRESS SECONDS
 14185 00002ED3 E89D000000          <1> 	CALL	CMOS_WRITE		; UPDATE SECONDS
 14186 00002ED8 88CC                <1> 	MOV	AH, CL			; GET TIME BYTE - MINUTES
 14187 00002EDA B002                <1> 	MOV	AL, CMOS_MINUTES 	; ADDRESS MINUTES
 14188 00002EDC E894000000          <1> 	CALL	CMOS_WRITE		; UPDATE MINUTES
 14189 00002EE1 88EC                <1> 	MOV	AH, CH			; GET TIME BYTE - HOURS
 14190 00002EE3 B004                <1> 	MOV	AL, CMOS_HOURS		; ADDRESS HOURS
 14191 00002EE5 E88B000000          <1> 	CALL	CMOS_WRITE		; UPDATE ADDRESS
 14192                              <1> 	;MOV	AX, X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14193 00002EEA 66B80B0B            <1> 	MOV	AX, 257*CMOS_REG_B 	; 
 14194 00002EEE E82FDCFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT TIME
 14195 00002EF3 2462                <1> 	AND	AL, 01100010B		; MASK FOR VALID BIT POSITIONS
 14196 00002EF5 0C02                <1> 	OR	AL, 00000010B		; TURN ON 24 HOUR MODE
 14197 00002EF7 80E201              <1> 	AND	DL, 00000001B		; USE ONLY THE DSE BIT
 14198 00002EFA 08D0                <1> 	OR	AL, DL			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
 14199 00002EFC 86E0                <1> 	XCHG	AH, AL			; PLACE IN WORK REGISTER AND GET ADDRESS
 14200 00002EFE E872000000          <1> 	CALL	CMOS_WRITE		; SET NEW ALARM BITS
 14201 00002F03 F8                  <1> 	CLC				; SET CY= 0
 14202 00002F04 FB                  <1> 	sti
 14203 00002F05 C3                  <1> 	RETn				; RETURN WITH CY= 0
 14204                              <1> 
 14205                              <1> set_rtc_date:
 14206                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14207                              <1> 	; 15/03/2015
 14208                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14209                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14210                              <1> 	; INT 1Ah
 14211                              <1> 	; (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING, :
 14212                              <1> 	;     (CH) = CENTURY IN BCD (19 OR 20)			   :
 14213                              <1> 	;     (CL) = YEAR IN BCD (00-99)			   :
 14214                              <1> 	;     (DH) = MONTH IN BCD (01-12)			   :
 14215                              <1> 	;     (DL) = DAY IN BCD (01-31).
 14216                              <1> 	;
 14217                              <1> RTC_50: 				; SET RTC DATE
 14218 00002F06 FA                  <1> 	cli
 14219 00002F07 E82CDCFFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14220 00002F0C 7305                <1> 	JNC	short RTC_55		; GO AROUND IF NO ERROR
 14221 00002F0E E842000000          <1> 	CALL	RTC_STA 		; ELSE INITIALIZE CLOCK
 14222                              <1> RTC_55:
 14223 00002F13 66B80600            <1> 	MOV	AX, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
 14224 00002F17 E859000000          <1> 	CALL	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
 14225 00002F1C 88D4                <1> 	MOV	AH, DL			; GET DAY OF MONTH BYTE
 14226 00002F1E B007                <1> 	MOV	AL, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
 14227 00002F20 E850000000          <1> 	CALL	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
 14228 00002F25 88F4                <1> 	MOV	AH, DH			; GET MONTH
 14229 00002F27 B008                <1> 	MOV	AL, CMOS_MONTH		; ADDRESS MONTH BYTE
 14230 00002F29 E847000000          <1> 	CALL	CMOS_WRITE		; WRITE MONTH REGISTER
 14231 00002F2E 88CC                <1> 	MOV	AH, CL			; GET YEAR BYTE
 14232 00002F30 B009                <1> 	MOV	AL, CMOS_YEAR		; ADDRESS YEAR REGISTER
 14233 00002F32 E83E000000          <1> 	CALL	CMOS_WRITE		; WRITE YEAR REGISTER
 14234 00002F37 88EC                <1> 	MOV	AH, CH			; GET CENTURY BYTE
 14235 00002F39 B032                <1> 	MOV	AL, CMOS_CENTURY 	; ADDRESS CENTURY BYTE
 14236 00002F3B E835000000          <1> 	CALL	CMOS_WRITE		; WRITE CENTURY LOCATION
 14237                              <1> 	;MOV	AX, X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14238 00002F40 66B80B0B            <1> 	MOV	AX, 257*CMOS_REG_B 	; 
 14239 00002F44 E8D9DBFFFF          <1> 	CALL	CMOS_READ		; READ CURRENT SETTINGS
 14240 00002F49 247F                <1> 	AND	AL, 07FH 		; CLEAR 'SET BIT'
 14241 00002F4B 86E0                <1> 	XCHG	AH, AL			; MOVE TO WORK REGISTER
 14242 00002F4D E823000000          <1> 	CALL	CMOS_WRITE		; AND START CLOCK UPDATING
 14243 00002F52 F8                  <1> 	CLC				; SET CY= 0
 14244 00002F53 FB                  <1> 	sti
 14245 00002F54 C3                  <1> 	RETn				; RETURN CY=0
 14246                              <1> 
 14247                              <1> 	; 15/03/2015
 14248                              <1> RTC_STA:				; INITIALIZE REAL TIME CLOCK
 14249 00002F55 B426                <1> 	mov	ah, 26h
 14250 00002F57 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK
 14251 00002F59 E817000000          <1> 	CALL	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
 14252 00002F5E B482                <1> 	mov	ah, 82h
 14253 00002F60 B00B                <1> 	mov 	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION
 14254 00002F62 E80E000000          <1> 	CALL	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
 14255 00002F67 B00C                <1> 	MOV	AL, CMOS_REG_C		; ADDRESS REGISTER C
 14256 00002F69 E8B4DBFFFF          <1> 	CALL	CMOS_READ		; READ REGISTER C TO INITIALIZE
 14257 00002F6E B00D                <1> 	MOV	AL, CMOS_REG_D		; ADDRESS REGISTER D
 14258                              <1> 	;CALL	CMOS_READ		; READ REGISTER D TO INITIALIZE
 14259                              <1> 	;RETn
 14260                              <1> 	; 06/02/2022
 14261 00002F70 E9ADDBFFFF          <1> 	jmp	CMOS_READ
 14262                              <1> 
 14263                              <1> 	; 15/03/2015
 14264                              <1> 	; IBM PC/XT Model 286 BIOS source code ----- 10/06/85 (test4.asm)
 14265                              <1> CMOS_WRITE:			; WRITE (AH) TO LOCATION (AL)
 14266 00002F75 9C                  <1> 	pushf			; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 14267                              <1> 	;push	ax		; SAVE WORK REGISTER VALUES
 14268 00002F76 D0C0                <1> 	rol	al, 1		; MOVE NMI BIT TO LOW POSITION
 14269 00002F78 F9                  <1> 	stc			; FORCE NMI BIT ON IN CARRY FLAG
 14270 00002F79 D0D8                <1> 	rcr	al, 1		; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 14271 00002F7B FA                  <1> 	cli			; DISABLE INTERRUPTS
 14272 00002F7C E670                <1> 	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
 14273 00002F7E 88E0                <1> 	mov	al, ah		; GET THE DATA BYTE TO WRITE
 14274 00002F80 E671                <1> 	out	CMOS_DATA, al	; PLACE IN REQUESTED CMOS LOCATION
 14275 00002F82 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
 14276 00002F84 D0D8                <1> 	rcr	al, 1		; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 14277 00002F86 E670                <1> 	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
 14278 00002F88 90                  <1> 	nop			; I/O DELAY
 14279 00002F89 E471                <1> 	in	al, CMOS_DATA	; OPEN STANDBY LATCH
 14280                              <1> 	;pop	ax		; RESTORE WORK REGISTERS
 14281 00002F8B 9D                  <1> 	popf	
 14282 00002F8C C3                  <1> 	RETn
 14283                              <1> 
 14284                              <1> bf_init:
 14285                              <1> 	; 21/03/2022 (Retro UNIX 386 v1.2)
 14286                              <1> 	; 28/11/2021
 14287                              <1> 	; 14/08/2015
 14288                              <1> 	; 02/07/2015
 14289                              <1> 	; 01/07/2015
 14290                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 14291                              <1> 	; Buffer (pointer) initialization !
 14292                              <1> 	; 
 14293                              <1> 	; 17/07/2013 - 24/07/2013
 14294                              <1> 	; Retro UNIX 8086 v1 (U9.ASM)
 14295                              <1> 	; (Retro UNIX 8086 v1 feature only !)
 14296                              <1> 	;
 14297 00002F8D BF[F46B0000]        <1> 	mov	edi, bufp 
 14298 00002F92 B8[A4970000]        <1> 	mov	eax, buffer + (nbuf*520) 
 14299 00002F97 29D2                <1> 	sub	edx, edx
 14300 00002F99 FECA                <1> 	dec	dl
 14301 00002F9B 31C9                <1> 	xor	ecx, ecx
 14302 00002F9D 49                  <1> 	dec	ecx
 14303                              <1> bi0:
 14304 00002F9E 2D08020000          <1> 	sub	eax, 520 ; 8 header + 512 data
 14305 00002FA3 AB                  <1> 	stosd
 14306 00002FA4 89C6                <1> 	mov	esi, eax
 14307 00002FA6 8916                <1> 	mov	[esi], edx ; 000000FFh
 14308                              <1> 			    ; Not a valid device sign
 14309 00002FA8 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14310                              <1> 		      ; Not a valid block number sign 	 	
 14311 00002FAB 3D[24770000]        <1> 	cmp	eax, buffer
 14312 00002FB0 77EC                <1> 	ja	short bi0
 14313 00002FB2 B8[0C6D0000]        <1> 	mov	eax, sb0
 14314 00002FB7 AB                  <1> 	stosd
 14315 00002FB8 B8[146F0000]        <1> 	mov	eax, sb1
 14316 00002FBD AB                  <1> 	stosd
 14317 00002FBE 89C6                <1> 	mov	esi, eax ; offset sb1
 14318 00002FC0 8916                <1> 	mov	[esi], edx ; 000000FFh
 14319                              <1> 			   ; Not a valid device sign
 14320 00002FC2 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14321                              <1> 		      ; Not a valid block number sign 	 
 14322                              <1> 	; 14/08/2015
 14323                              <1> 	;call 	rdev_init
 14324                              <1> 	;retn
 14325                              <1> 
 14326                              <1> ; ----- Root file system initialization
 14327                              <1> 	
 14328                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
 14329                              <1> 	;	(Retro UNIX -runix- v2 file system) 
 14330                              <1> 	; 28/11/2021
 14331                              <1> rdev_init: ; root device, super block buffer initialization
 14332                              <1> 	; 14/08/2015
 14333                              <1> 	; Retro UNIX 386 v1 feature only !
 14334                              <1> 	;
 14335                              <1> 	; NOTE: Disk partitions (file systems), logical
 14336                              <1> 	; drive initialization, partition's start sector etc.
 14337                              <1> 	; will be coded here, later in 'ldrv_init'	
 14338                              <1> 
 14339 00002FC5 0FB605[48620000]    <1> 	movzx	eax, byte [boot_drv]
 14340                              <1> rdi_0:
 14341 00002FCC 3C80                <1> 	cmp	al, 80h
 14342 00002FCE 7202                <1> 	jb	short rdi_1
 14343 00002FD0 2C7E                <1> 	sub	al, 7Eh ; 80h = 2 (hd0), 81h = 3 (hd1)
 14344                              <1> rdi_1:
 14345 00002FD2 A2[426C0000]        <1> 	mov	[rdev], al
 14346                              <1> 	; 21/03/2022
 14347                              <1> 	;cmp	al, 2
 14348                              <1> 	;jnb	short rdi_2
 14349 00002FD7 08C0                <1> 	or	al, al
 14350 00002FD9 7504                <1> 	jnz	short rdi_2 ; hard disk boot
 14351                              <1> 	; floppy disk boot
 14352 00002FDB 31D2                <1> 	xor	edx, edx ; device number = 0
 14353                              <1> 			 ; (& fglags = 0)
 14354                              <1> 	; eax = 0 ; boot sector address = 0
 14355                              <1> 	;jmp	short rdi_5
 14356 00002FDD EB22                <1> 	jmp	short rdi_4
 14357                              <1> rdi_2:
 14358                              <1> 	; load masterboot sector
 14359                              <1> 	; to get runix v2 partition's boot sector address
 14360                              <1> 	;	
 14361 00002FDF BB[1C710000]        <1> 	mov	ebx, mbrbuf ; masterboot buffer header addr
 14362                              <1> 	;mov	[ebx], eax
 14363 00002FE4 8803                <1> 	mov	[ebx], al
 14364                              <1> 	;sub	al, al
 14365                              <1> 	;; eax = 0
 14366                              <1> 	;mov	[ebx+4], eax ; masterboot sector address
 14367 00002FE6 E8E12A0000          <1> 	call	diskio
 14368 00002FEB 730A                <1> 	jnc	short rdi_3
 14369                              <1> rdi_err:
 14370 00002FED BE[14300000]        <1> 	mov	esi, disk_read_err_msg
 14371 00002FF2 E9B9F9FFFF          <1> 	jmp	key_to_reboot
 14372                              <1> 
 14373                              <1> rdi_3:
 14374                              <1> 	; [ebx+8] = masterboot buffer (data) address 
 14375                              <1> 	;cmp	word [ebx+8+510], 0AA55h
 14376                              <1> 	;jc	short rdi_err
 14377                              <1> 
 14378 00002FF7 8D7308              <1> 	lea	esi, [ebx+8] 
 14379 00002FFA E82D000000          <1> 	call	runix_p_bs    ; return start sector address of
 14380                              <1> 			      ; retro unix v2 partition in esi
 14381                              <1> 	;;jc	short rdi_err ; 'retn'
 14382                              <1> 	;jnc	short rdi_4 ; Runix v2 partition not found !?
 14383                              <1> 			    ; 21/03/2022	
 14384                              <1> 			    ; ((Here, if cf is 1, that means,
 14385                              <1> 			    ; runix v2 partition not found
 14386                              <1> 			    ; in the MBR partition table.
 14387                              <1> 			    ; But, at least, there is a valid
 14388                              <1> 			    ; runix v2 boot sector on the disk
 14389                              <1> 			    ; which started the kernel.
 14390                              <1> 			    ; So, runix v2 boot sector code
 14391                              <1> 			    ; may -must- be on physical sector 0
 14392                              <1> 			    ; and then the superblock may be
 14393                              <1> 			    ; -must be- on physical sector 1.)) 
 14394                              <1> 	;sub	eax, eax
 14395                              <1> 	; eax = 0
 14396                              <1> ;rdi_4:
 14397 00002FFF 8B13                <1> 	mov	edx, [ebx] ; restore device number in dl
 14398                              <1> ;rdi_5:
 14399                              <1> rdi_4:
 14400 00003001 BB[0C6D0000]        <1>         mov	ebx, sb0 ; super block buffer (header)
 14401                              <1> 
 14402 00003006 40                  <1> 	inc	eax	; default sector address of the sb
 14403                              <1> 			; (boot sector address + 1)
 14404                              <1> 
 14405                              <1> 	;mov 	[ebx], eax
 14406                              <1> 	;mov	al, 1 ; eax = 1
 14407                              <1> 	;mov	[ebx+4], eax ; super block address on disk
 14408                              <1> 	; 21/03/2022
 14409 00003007 8913                <1> 	mov	[ebx], edx ; device number in DL
 14410                              <1> 			   ; (other bytes -flags- are zero)
 14411 00003009 894304              <1> 	mov	[ebx+4], eax ; superblock address on disk
 14412                              <1> 
 14413                              <1> 	;call 	diskio
 14414                              <1> 	;retn
 14415                              <1> 	; 28/11/2021
 14416                              <1> 	;jmp	diskio
 14417                              <1> 
 14418                              <1> 	; 21/03/2022
 14419 0000300C E8BB2A0000          <1> 	call	diskio
 14420 00003011 72DA                <1> 	jc	short rdi_err
 14421                              <1> 
 14422                              <1> 	; 21/03/2022
 14423                              <1> 	; Note: If superblock is defective or SB sector
 14424                              <1> 	;	address is wrong, "ERROR: /etc/init !?"
 14425                              <1> 	;	message will appear after here.
 14426                              <1> 	;	..because /etc/init inode will not be found..
 14427                              <1> 	;	So, i am not writing SB validation
 14428                              <1> 	;	(check) code here.
 14429                              <1> 	;
 14430                              <1> 	; ((Also, if we are here, everything should be normal!))
 14431                              <1> 
 14432 00003013 C3                  <1> 	retn
 14433                              <1> 
 14434                              <1> disk_read_err_msg:
 14435                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
 14436 00003014 070D0A              <1> 	db 07h, 0Dh, 0Ah
 14437 00003017 4469736B2072656164- <1> 	db "Disk read error ! "
 14438 00003020 206572726F72202120  <1>
 14439 00003029 0D0A00              <1> 	db 0Dh, 0Ah, 0
 14440                              <1> 
 14441                              <1> 	; 21/03/2022 - Retro UNIX 386 v1.2
 14442                              <1> runix_p_bs:
 14443                              <1> 	; get retro unix v2 partition's boot sector address
 14444                              <1> 	
 14445                              <1> 	; 09/05/2021
 14446                              <1> 	; 19/04/2021 - Retro UNIX 386 v2
 14447                              <1> 	; INPUT:
 14448                              <1> 	;	;;Masterboot buffer at offset mbrbuf
 14449                              <1> 	;	; 21/03/2022
 14450                              <1> 	;	esi = Masterboot buffer (data) address
 14451                              <1> 	; OUTPUT:
 14452                              <1> 	;	;;esi = start sector addr of retro unix v2 fs
 14453                              <1> 	;	; 21/03/2022
 14454                              <1> 	;	eax = start sector address of retro unix v2 fs
 14455                              <1> 	;
 14456                              <1> 	;	cf = 1 -> error, retro unix fs not found
 14457                              <1> 	;		(eax = 0)	
 14458                              <1> 	;
 14459                              <1> 	; Modified registers: esi, eax
 14460                              <1> 
 14461                              <1> 	ptBootable       equ 0
 14462                              <1> 	ptBeginHead      equ 1
 14463                              <1> 	ptBeginSector    equ 2
 14464                              <1> 	ptBeginCylinder  equ 3
 14465                              <1> 	ptFileSystemID   equ 4
 14466                              <1> 	ptEndHead        equ 5
 14467                              <1> 	ptEndSector      equ 6
 14468                              <1> 	ptEndCylinder    equ 7
 14469                              <1> 	ptStartSector    equ 8
 14470                              <1> 	ptSectors        equ 12
 14471                              <1> 
 14472                              <1> 	FS_RETROUNIX	 equ 71h ; runix v2 partition ID
 14473                              <1> 
 14474                              <1> 	;cmp	word [mbrbuf+510], 0AA55h
 14475 0000302C 6681BEFE01000055AA  <1> 	cmp	word [esi+510], 0AA55h
 14476 00003035 7515                <1> 	jne	short runix_p_nf
 14477                              <1> 
 14478                              <1> 	; partition table entries are at offset 1BEh
 14479                              <1> 	;mov	esi, mbrbuf+1BEh+ptFileSystemID
 14480 00003037 81C6C2010000        <1> 	add	esi, 1BEh+ptFileSystemID
 14481 0000303D 8D4640              <1> 	lea	eax, [esi+(4*16)] 
 14482                              <1> runix_p_bs_0:
 14483 00003040 803E71              <1> 	cmp	byte [esi], FS_RETROUNIX ; 71h
 14484 00003043 740B                <1> 	je	short runix_p_f ; it is retro unix partition
 14485 00003045 83C610              <1> 	add	esi, 16
 14486                              <1> 	;cmp	esi, mbrbuf+1BEh+ptFileSystemID+(4*16) 
 14487 00003048 39C6                <1> 	cmp	esi, eax
 14488 0000304A 72F4                <1> 	jb	short runix_p_bs_0 	  
 14489                              <1> runix_p_nf:
 14490 0000304C 29C0                <1> 	sub	eax, eax
 14491                              <1> 	; eax = 0
 14492 0000304E F9                  <1> 	stc
 14493 0000304F C3                  <1> 	retn
 14494                              <1> runix_p_f:
 14495                              <1> 	;mov	esi, [esi+ptStartSector-ptFileSystemID]
 14496 00003050 8B4604              <1> 	mov	eax, [esi+ptStartSector-ptFileSystemID]
 14497 00003053 C3                  <1> 	retn
 14498                              <1> 
 14499                              <1> ; 23/10/2015
 14500                              <1> com1_irq4:
 14501 00003054 [5C300000]          <1> 	dd dummy_retn
 14502                              <1> com2_irq3:
 14503 00003058 [5C300000]          <1> 	dd dummy_retn
 14504                              <1> 
 14505                              <1> dummy_retn:
 14506 0000305C C3                  <1> 	retn
 14507                                  %include 'u1.s'      ; 10/05/2015
 14508                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 14509                              <1> ; (re-write kernel for test by using previous version without a major defect)
 14510                              <1> ; ****************************************************************************
 14511                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS1.INC
 14512                              <1> ; Last Modification: 17/07/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.3)
 14513                              <1> ; ----------------------------------------------------------------------------
 14514                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 14515                              <1> ; (v0.1 - Beginning: 11/07/2012)
 14516                              <1> ;
 14517                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 14518                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 14519                              <1> ; <Bell Laboratories (17/3/1972)>
 14520                              <1> ; <Preliminary Release of UNIX Implementation Document>
 14521                              <1> ;
 14522                              <1> ; Retro UNIX 8086 v1 - U1.ASM (12/07/2014) //// UNIX v1 -> u1.s
 14523                              <1> ;
 14524                              <1> ; ****************************************************************************
 14525                              <1> 
 14526                              <1> unkni: ; / used for all system calls
 14527                              <1> sysent: ; < enter to system call >
 14528                              <1> 	; 25/12/2021 (Retro UNIX 386 v1.2)
 14529                              <1> 	; 19/10/2015
 14530                              <1> 	; 21/09/2015
 14531                              <1> 	; 01/07/2015
 14532                              <1> 	; 19/05/2015
 14533                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14534                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 14535                              <1> 	;
 14536                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
 14537                              <1> 	; The trap type is determined and an indirect jump is made to 
 14538                              <1> 	; the appropriate system call handler. If there is a trap inside
 14539                              <1> 	; the system a jump to panic is made. All user registers are saved 
 14540                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
 14541                              <1> 	; instructor is decoded to get the the system code part (see
 14542                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
 14543                              <1> 	; the indirect jump address is calculated. If a bad system call is
 14544                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
 14545                              <1> 	; is called. If the call is legitimate control passes to the
 14546                              <1> 	; appropriate system routine.
 14547                              <1> 	;
 14548                              <1> 	; Calling sequence:
 14549                              <1> 	;	Through a trap caused by any sys call outside the system.
 14550                              <1> 	; Arguments:
 14551                              <1> 	;	Arguments of particular system call.	
 14552                              <1> 	; ...............................................................
 14553                              <1> 	;	
 14554                              <1> 	; Retro UNIX 8086 v1 modification: 
 14555                              <1> 	;       System call number is in EAX register.
 14556                              <1> 	;
 14557                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14558                              <1> 	;	registers depending of function details.
 14559                              <1>   	;
 14560                              <1> 	; 16/04/2015
 14561 0000305D 368925[5C6C0000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
 14562                              <1> 	; save user registers
 14563 00003064 1E                  <1> 	push	ds
 14564 00003065 06                  <1> 	push	es
 14565 00003066 0FA0                <1> 	push	fs
 14566 00003068 0FA8                <1> 	push	gs
 14567 0000306A 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
 14568                              <1> 	;
 14569                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
 14570                              <1> 	; 	(ESPACE is size of space in kernel stack 
 14571                              <1> 	;	for saving/restoring user registers.)
 14572                              <1> 	;
 14573 0000306B 50                  <1> 	push	eax ; 01/07/2015
 14574 0000306C 66B81000            <1> 	mov     ax, KDATA
 14575 00003070 8ED8                <1>         mov     ds, ax
 14576 00003072 8EC0                <1>         mov     es, ax
 14577 00003074 8EE0                <1>         mov     fs, ax
 14578 00003076 8EE8                <1>         mov     gs, ax
 14579 00003078 A1[28670000]        <1> 	mov	eax, [k_page_dir]
 14580 0000307D 0F22D8              <1> 	mov	cr3, eax
 14581 00003080 58                  <1> 	pop	eax ; 01/07/2015
 14582                              <1> 	; 19/10/2015
 14583 00003081 FC                  <1> 	cld
 14584                              <1> 	;
 14585 00003082 FE05[586C0000]      <1> 	inc	byte [sysflg]
 14586                              <1> 		; incb sysflg / indicate a system routine is in progress
 14587 00003088 FB                  <1>         sti 	; 18/01/2014
 14588                              <1> 	;jnz	panic ; 24/05/2013
 14589                              <1> 	; 04/12/2021
 14590 00003089 7405                <1> 	jz	short _1
 14591 0000308B E91BF9FFFF          <1> 	jmp	panic
 14592                              <1> 		; beq 1f
 14593                              <1> 		; jmp panic ; / called if trap inside system
 14594                              <1> ;1:
 14595                              <1> _1:	; 04/12/2021
 14596                              <1> 	; 16/04/2015
 14597 00003090 A3[646C0000]        <1> 	mov	[u.r0], eax
 14598 00003095 8925[606C0000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
 14599                              <1> 	;
 14600                              <1> 		; mov $s.syst+2,clockp
 14601                              <1> 		; mov r0,-(sp) / save user registers 
 14602                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
 14603                              <1> 			   ; / in u.r0
 14604                              <1> 		; mov r1,-(sp)
 14605                              <1> 		; mov r2,-(sp)
 14606                              <1> 		; mov r3,-(sp)
 14607                              <1> 		; mov r4,-(sp)
 14608                              <1> 		; mov r5,-(sp)
 14609                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
 14610                              <1> 		             ; / arithmetic unit
 14611                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
 14612                              <1> 		             ; / extended arithmetic unit
 14613                              <1> 		; mov sc,-(sp) / "step count" register for the extended
 14614                              <1> 		             ; / arithmetic unit
 14615                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
 14616                              <1> 		; mov 18.(sp),r0 / store pc in r0
 14617                              <1> 		; mov -(r0),r0 / sys inst in r0 10400xxx
 14618                              <1> 		; sub $sys,r0 / get xxx code
 14619 0000309B C1E002              <1> 	shl	eax, 2
 14620                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
 14621 0000309E 3DA0000000          <1> 	cmp	eax, end_of_syscalls - syscalls
 14622                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
 14623                              <1> 	;jnb	short badsys
 14624                              <1> 		; bhis badsys / yes, bad system call
 14625                              <1> 	; 25/12/2021
 14626 000030A3 7205                <1> 	jb	short _2
 14627 000030A5 E969010000          <1> 	jmp	badsys
 14628                              <1> _2:
 14629                              <1> 	; 25/12/2021
 14630                              <1> 	;cmc
 14631                              <1> 	;pushf	
 14632                              <1> 	;push	eax
 14633 000030AA 8B2D[5C6C0000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
 14634                              <1> 	;mov	al, 0FEh ; 11111110b
 14635                              <1> 	;;adc	al, 0 ; al = al + cf
 14636                              <1> 	;and	[ebp+8], al ; flags (reset carry flag)
 14637 000030B0 806508FE            <1> 	and	byte [ebp+8], 0FEh ; 11111110b ; 25/12/2021
 14638                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
 14639                              <1> 				 ; / and clear carry bit
 14640                              <1> 	;pop	ebp ; eax
 14641 000030B4 89C5                <1> 	mov	ebp, eax ; 25/12/2021
 14642                              <1> 	;popf
 14643                              <1>         ;;jc	badsys
 14644                              <1> 	;; 04/12/2021
 14645                              <1> 	;jnc	short _3
 14646                              <1> 	;jmp	badsys
 14647                              <1> ;_3:
 14648 000030B6 A1[646C0000]        <1> 	mov	eax, [u.r0]
 14649                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
 14650 000030BB FFA5[C1300000]      <1> 	jmp	dword [ebp+syscalls]
 14651                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
 14652                              <1> 		            ; / to proper system routine.
 14653                              <1> 
 14654                              <1> 	; 09/01/2022
 14655                              <1> 	; 01/01/2022 (/etc/init error, BugFix efforts, test)
 14656                              <1> syscalls: ; 1:
 14657                              <1> 	; 21/09/2015
 14658                              <1> 	; 01/07/2015
 14659                              <1> 	; 16/04/2015 (32 bit address modification) 
 14660 000030C1 [DD310000]          <1> 	dd sysrele	; / 0
 14661 000030C5 [85320000]          <1> 	dd sysexit 	; / 1
 14662 000030C9 [AF330000]          <1> 	dd sysfork 	; / 2
 14663 000030CD [B4340000]          <1> 	dd sysread 	; / 3
 14664 000030D1 [C9340000]          <1> 	dd syswrite 	; / 4
 14665 000030D5 [2C350000]          <1> 	dd sysopen 	; / 5
 14666 000030D9 [55360000]          <1> 	dd sysclose 	; / 6
 14667 000030DD [2A330000]          <1> 	dd syswait 	; / 7
 14668 000030E1 [BD350000]          <1> 	dd syscreat 	; / 8
 14669 000030E5 [0B3A0000]          <1> 	dd syslink 	; / 9
 14670 000030E9 [993A0000]          <1> 	dd sysunlink 	; / 10
 14671 000030ED [B93B0000]          <1> 	dd sysexec 	; / 11
 14672 000030F1 [26420000]          <1> 	dd syschdir 	; / 12
 14673 000030F5 [28430000]          <1> 	dd systime 	; / 13
 14674 000030F9 [04360000]          <1> 	dd sysmkdir 	; / 14
 14675 000030FD [65420000]          <1> 	dd syschmod 	; / 15
 14676 00003101 [94420000]          <1> 	dd syschown 	; / 16
 14677 00003105 [5C430000]          <1> 	dd sysbreak 	; / 17
 14678 00003109 [5C3F0000]          <1> 	dd sysstat 	; / 18
 14679 0000310D [6A440000]          <1> 	dd sysseek 	; / 19
 14680 00003111 [7C440000]          <1> 	dd systell 	; / 20
 14681 00003115 [2A540000]          <1> 	dd sysmount 	; / 21
 14682 00003119 [43550000]          <1> 	dd sysumount 	; / 22
 14683 0000311D [ED440000]          <1> 	dd syssetuid 	; / 23
 14684 00003121 [22450000]          <1> 	dd sysgetuid 	; / 24
 14685 00003125 [37430000]          <1> 	dd sysstime 	; / 25
 14686 00003129 [E1440000]          <1> 	dd sysquit 	; / 26
 14687 0000312D [D5440000]          <1> 	dd sysintr 	; / 27
 14688 00003131 [433F0000]          <1> 	dd sysfstat 	; / 28
 14689 00003135 [70360000]          <1> 	dd sysemt 	; / 29
 14690 00003139 [BE360000]          <1> 	dd sysmdate 	; / 30
 14691 0000313D [1B370000]          <1> 	dd sysstty 	; / 31
 14692 00003141 [05390000]          <1> 	dd sysgtty 	; / 32
 14693 00003145 [B9360000]          <1> 	dd sysilgins 	; / 33
 14694 00003149 [F65C0000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
 14695                              <1> 			     ; 11/06/2014
 14696 0000314D [235D0000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
 14697                              <1> 			     ; 01/07/2015
 14698 00003151 [FB5D0000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
 14699                              <1> 			     ; 21/09/2015 - get last error number
 14700                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 14701                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 14702 00003155 [3B450000]          <1> 	dd syssetgid	; 37
 14703 00003159 [5E450000]          <1> 	dd sysgetgid	; 38
 14704                              <1> 	; 18/06/2021 - Retro UNIX 386 v2 (ref: TRDOS 386 v2)
 14705 0000315D [73450000]          <1> 	dd sysver	; 39 ; (get) Retro Unix 386 version
 14706                              <1> 
 14707                              <1> end_of_syscalls:
 14708                              <1> 
 14709                              <1> error:
 14710                              <1> 	; 11/12/2021 (Retro UNIX 386 v1.2)
 14711                              <1> 	; 17/09/2015
 14712                              <1> 	; 03/09/2015
 14713                              <1> 	; 01/09/2015
 14714                              <1> 	; 09/06/2015
 14715                              <1> 	; 13/05/2015
 14716                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14717                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 14718                              <1> 	;
 14719                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
 14720                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
 14721                              <1> 	;
 14722                              <1> 	; INPUTS -> none
 14723                              <1> 	; OUTPUTS ->
 14724                              <1> 	;	processor status - carry (c) bit is set (means error)
 14725                              <1> 	;
 14726                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
 14727                              <1> 	; 	      Because, jumps to error procedure
 14728                              <1> 	;	      disrupts push-pop nesting balance)
 14729                              <1> 	;
 14730 00003161 8B2D[5C6C0000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
 14731 00003167 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
 14732                              <1> 				 ; (system call will return with cf = 1)
 14733                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
 14734                              <1> 		               ; / users stack
 14735                              <1> 	; 17/09/2015
 14736 0000316B 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
 14737                              <1> 				 ; for saving/restoring user registers	
 14738                              <1> 	;cmp	ebp, [u.usp]
 14739                              <1> 	;je	short err0	
 14740 0000316E 892D[606C0000]      <1> 	mov	[u.usp], ebp
 14741                              <1> ;err0:
 14742                              <1> 	; 01/09/2015
 14743 00003174 8B25[606C0000]      <1> 	mov	esp, [u.usp]	; Retro Unix 8086 v1 modification!
 14744                              <1> 				; 10/04/2013
 14745                              <1> 				; (If an I/O error occurs during disk I/O,
 14746                              <1> 				; related procedures will jump to 'error'
 14747                              <1> 				; procedure directly without returning to 
 14748                              <1> 				; the caller procedure. So, stack pointer
 14749                              <1> 				; must be restored here.)
 14750                              <1> 	; 13/05/2015
 14751                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
 14752                              <1> 	;	'get last error' system call later. 	
 14753                              <1> 
 14754                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
 14755 0000317A C605[D66C0000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
 14756                              <1> 
 14757                              <1> sysret: ; < return from system call>
 14758                              <1> 	; 11/12/2021
 14759                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 14760                              <1> 	; 30/11/2021
 14761                              <1> 	; 10/09/2015
 14762                              <1> 	; 29/07/2015
 14763                              <1> 	; 25/06/2015
 14764                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14765                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 14766                              <1> 	;
 14767                              <1> 	; 'sysret' first checks to see if process is about to be 
 14768                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
 14769                              <1> 	; If not, following happens:	 
 14770                              <1> 	; 	1) The user's stack pointer is restored.
 14771                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
 14772                              <1> 	;	   i-node has been modified. If it has, it is written out
 14773                              <1> 	;	   via 'ppoke'.
 14774                              <1> 	;	3) If the super block has been modified, it is written out
 14775                              <1> 	;	   via 'ppoke'.				
 14776                              <1> 	;	4) If the dismountable file system's super block has been
 14777                              <1> 	;	   modified, it is written out to the specified device
 14778                              <1> 	;	   via 'ppoke'.
 14779                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
 14780                              <1> 	;	   during his execution. If so, 'tswap' is called to give
 14781                              <1> 	;	   another user a chance to run.
 14782                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
 14783                              <1> 	;	    (See 'sysrele' for conclusion.)		
 14784                              <1> 	;
 14785                              <1> 	; Calling sequence:
 14786                              <1> 	;	jump table or 'br sysret'
 14787                              <1> 	; Arguments: 
 14788                              <1> 	;	-	
 14789                              <1> 	; ...............................................................
 14790                              <1> 	;	
 14791                              <1> 	; ((AX=r1 for 'iget' input))
 14792                              <1> 	;	
 14793                              <1> 	;xor	ax, ax ; 04/05/2013
 14794                              <1> 	; 30/11/2021
 14795 00003181 31C0                <1> 	xor	eax, eax
 14796                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
 14797 00003183 FEC0                <1> 	inc	al ; 04/05/2013
 14798 00003185 3805[B46C0000]      <1> 	cmp	[u.bsys], al ; 1
 14799                              <1> 		; tstb u.bsys / is a process about to be terminated because
 14800                              <1> 	;jnb	sysexit ; 04/05/2013
 14801                              <1> 	;	; bne sysexit / of an error? yes, go to sysexit
 14802                              <1> 	; 04/12/2021
 14803 0000318B 720F                <1> 	jb	short _3
 14804                              <1> 	; 11/12/2021
 14805 0000318D C705[D86C0000]0100- <1> 	mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
 14806 00003195 0000                <1>
 14807 00003197 E9E9000000          <1> 	jmp	sysexit
 14808                              <1> _3:
 14809                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
 14810                              <1> 		; mov u.sp,sp / no point stack to users stack
 14811 0000319C FEC8                <1> 	dec 	al ; mov ax, 0
 14812                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
 14813 0000319E E8CE190000          <1> 	call	iget
 14814                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
 14815                              <1> 		            ; / it is written out
 14816                              <1> 	;xor 	ax, ax ; 0
 14817                              <1> 	; 30/11/2021
 14818 000031A3 31C0                <1> 	xor	eax, eax
 14819 000031A5 3805[566C0000]      <1> 	cmp	[smod], al ; 0
 14820                              <1> 		; tstb	smod / has the super block been modified
 14821 000031AB 7614                <1> 	jna	short sysret1
 14822                              <1> 		; beq	1f / no, 1f
 14823 000031AD A2[566C0000]        <1> 	mov	[smod], al ; 0
 14824                              <1> 		; clrb smod / yes, clear smod
 14825 000031B2 BB[0C6D0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
 14826 000031B7 66810B0002          <1>    	or	word [ebx], 200h ;;
 14827                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
 14828                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
 14829                              <1> 		      	      ; / output
 14830                              <1> 	; AX = 0
 14831 000031BC E86F280000          <1> 	call 	poke ; 07/08/2013
 14832                              <1> 	;call	ppoke
 14833                              <1> 	; AX = 0
 14834                              <1> 		; jsr r0,ppoke / write out modified super block to disk
 14835                              <1> sysret1: ;1:
 14836 000031C1 3805[576C0000]      <1> 	cmp	[mmod], al ; 0
 14837                              <1> 		; tstb	mmod / has the super block for the dismountable file
 14838                              <1> 		           ; / system
 14839 000031C7 7614                <1> 	jna	short sysrel0
 14840                              <1> 		; beq 1f / been modified?  no, 1f
 14841 000031C9 A2[576C0000]        <1> 	mov	[mmod], al ; 0	
 14842                              <1> 		; clrb	mmod / yes, clear mmod
 14843                              <1>         ;mov    ax, [mntd]
 14844                              <1>         ;;mov   al, [mdev] ; 26/04/2013
 14845 000031CE BB[146F0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
 14846                              <1>         ;;mov	[ebx], al
 14847                              <1> 	;mov    [sb1], al
 14848                              <1> 		; movb	mntd,sb1 / set the I/O queue
 14849 000031D3 66810B0002          <1> 	or	word [ebx], 200h
 14850                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
 14851                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
 14852 000031D8 E853280000          <1> 	call	poke ; 07/08/2013
 14853                              <1> 	;call	ppoke 
 14854                              <1> 		; jsr r0,ppoke / write it out to its device
 14855                              <1>         ;xor    al, al ; 26/04/2013       
 14856                              <1> ;1:
 14857                              <1> 		; tstb uquant / is the time quantum 0?
 14858                              <1> 		; bne 1f / no, don't swap it out
 14859                              <1> 
 14860                              <1> sysrele: ; < release >
 14861                              <1> 	; 14/10/2015
 14862                              <1> 	; 01/09/2015
 14863                              <1> 	; 24/07/2015
 14864                              <1> 	; 14/05/2015
 14865                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14866                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
 14867                              <1> 	;
 14868                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
 14869                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
 14870                              <1> 	; turns off the system flag. It then checked to see if there is
 14871                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
 14872                              <1> 	; the output gets flashed (see isintr) and interrupt action is
 14873                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
 14874                              <1> 	; the user, a rti is made.
 14875                              <1> 	;
 14876                              <1> 	; Calling sequence:
 14877                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
 14878                              <1> 	; Arguments:
 14879                              <1> 	;	-	
 14880                              <1> 	; ...............................................................
 14881                              <1> 	;	
 14882                              <1> 	; 23/02/2014 (swapret)
 14883                              <1> 	; 22/09/2013
 14884                              <1> sysrel0: ;1:
 14885 000031DD 803D[AC6C0000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
 14886                              <1> 		; tstb uquant / is the time quantum 0?
 14887 000031E4 7705                <1>         ja      short swapret
 14888                              <1> 		; bne 1f / no, don't swap it out
 14889                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
 14890 000031E6 E808140000          <1> 	call	tswap
 14891                              <1> 		; jsr r0,tswap / yes, swap it out
 14892                              <1> ;
 14893                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
 14894                              <1> swapret: ;1:
 14895                              <1> 	; 10/09/2015
 14896                              <1> 	; 01/09/2015
 14897                              <1> 	; 14/05/2015
 14898                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
 14899                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
 14900                              <1> 	; cli
 14901                              <1> 	; 24/07/2015
 14902                              <1> 	;
 14903                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
 14904                              <1> 	;; mov	esp, [u.usp]
 14905                              <1> 
 14906                              <1> 	; 22/09/2013
 14907 000031EB E8DA150000          <1> 	call	isintr
 14908                              <1> 	; 20/10/2013
 14909 000031F0 7405                <1> 	jz	short sysrel1
 14910 000031F2 E877000000          <1> 	call	intract
 14911                              <1> 		; jsr r0,isintr / is there an interrupt from the user
 14912                              <1> 		;     br intract / yes, output gets flushed, take interrupt
 14913                              <1> 		               ; / action
 14914                              <1> sysrel1:
 14915 000031F7 FA                  <1> 	cli ; 14/10/2015
 14916 000031F8 FE0D[586C0000]      <1> 	dec	byte [sysflg]
 14917                              <1> 		; decb sysflg / turn system flag off
 14918 000031FE A1[C46C0000]        <1> 	mov     eax, [u.pgdir]
 14919 00003203 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
 14920                              <1> 			  ; (others are different than kernel page tables) 
 14921                              <1> 	; 10/09/2015
 14922 00003206 61                  <1> 	popad ; edi, esi, ebp, temp (increment esp by 4), ebx, edx, ecx, eax
 14923                              <1> 		; mov (sp)+,sc / restore user registers
 14924                              <1> 		; mov (sp)+,mq
 14925                              <1> 		; mov (sp)+,ac
 14926                              <1> 		; mov (sp)+,r5
 14927                              <1> 		; mov (sp)+,r4
 14928                              <1> 		; mov (sp)+,r3
 14929                              <1> 		; mov (sp)+,r2
 14930                              <1> 	;
 14931 00003207 A1[646C0000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
 14932 0000320C 0FA9                <1> 	pop	gs
 14933 0000320E 0FA1                <1> 	pop	fs
 14934 00003210 07                  <1> 	pop	es
 14935 00003211 1F                  <1> 	pop	ds
 14936 00003212 CF                  <1> 	iretd	
 14937                              <1> 		; rti / no, return from interrupt
 14938                              <1> 
 14939                              <1> badsys:
 14940                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14941                              <1> 	; (Major Modification: 'core' dumping procedure in
 14942                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
 14943                              <1> 	;	has been changed to print 'Invalid System Call !'
 14944                              <1> 	;	message on the user's console tty.)
 14945                              <1> 	; (EIP, EAX values will be shown on screen with error message)
 14946                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
 14947                              <1> 	; (EAX = Function number)  
 14948                              <1> 	;
 14949 00003213 FE05[B46C0000]      <1> 	inc	byte [u.bsys]
 14950                              <1> 	;
 14951 00003219 8B1D[5C6C0000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
 14952 0000321F 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
 14953 00003221 E8BCE3FFFF          <1> 	call	dwordtohex
 14954 00003226 8915[88640000]      <1> 	mov	[bsys_msg_eip], edx
 14955 0000322C A3[8C640000]        <1> 	mov	[bsys_msg_eip+4], eax
 14956 00003231 A1[646C0000]        <1> 	mov	eax, [u.r0]
 14957 00003236 E8A7E3FFFF          <1> 	call	dwordtohex
 14958 0000323B 8915[78640000]      <1> 	mov	[bsys_msg_eax], edx
 14959 00003241 A3[7C640000]        <1> 	mov	[bsys_msg_eax+4], eax
 14960                              <1> 	; 11/12/2021
 14961                              <1> 	;xor	eax, eax
 14962                              <1> 	;mov	dword [u.base], badsys_msg ; "Invalid System Call !"
 14963                              <1> 	;mov	ebx, [u.fofp]
 14964                              <1> 	;mov	[ebx], eax
 14965                              <1> 	;;mov	eax, 1 ; inode number of console tty (for user)	
 14966                              <1> 	;inc	eax
 14967                              <1> 	; 11/12/2021 - Retro UNIX 386 v2 fs compatibility 
 14968                              <1> 	; (Retro UNIX 386 v1.2)
 14969                              <1> 	;mov	al, 8 ; /dev/tty inode number (runix v2 fs)
 14970                              <1> 	;; eax = 8 ; inode number of console tty (for user)	
 14971                              <1> 	;mov	dword [u.count], BSYS_M_SIZE
 14972                              <1> 		; writei
 14973                              <1> 		; INPUTS ->
 14974                              <1> 		;    r1 - inode number
 14975                              <1> 		;    u.count - byte count to be written
 14976                              <1> 		;    u.base - points to user buffer
 14977                              <1> 		;    u.fofp - points to word with current file offset
 14978                              <1> 		; OUTPUTS ->
 14979                              <1> 		;    u.count - cleared
 14980                              <1> 		;    u.nread - accumulates total bytes passed back	
 14981                              <1> 		;
 14982                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
 14983                              <1> 	;call	writei
 14984                              <1> 	;;mov	eax, 1
 14985                              <1> 	;jmp	sysexit
 14986                              <1> 
 14987                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 14988 00003246 BE[59640000]        <1> 	mov	esi, badsys_msg ; "Invalid System Call !"
 14989 0000324B 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 14990 00003252 8A83[63680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 14991 00003258 C605[57670000]0F    <1> 	mov	byte [ccolor], 0Fh ; white (message) color
 14992 0000325F A2[996C0000]        <1> 	mov 	[u.ttyn], al ; current (active) tty (for user)
 14993 00003264 E8772B0000          <1> 	call	print_cmsg
 14994                              <1> 	;mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
 14995 00003269 E9F3FEFFFF          <1> 	jmp	error
 14996                              <1> 
 14997                              <1> 		; incb u.bsys / turn on the user's bad-system flag
 14998                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
 14999                              <1> 		; jsr r0,namei / get the i-number for the core image file
 15000                              <1> 		; br 1f / error
 15001                              <1> 		; neg r1 / negate the i-number to open the core image file
 15002                              <1> 		       ; / for writing
 15003                              <1> 		; jsr r0,iopen / open the core image file
 15004                              <1> 		; jsr r0,itrunc / free all associated blocks
 15005                              <1> 		; br 2f
 15006                              <1> ;1:
 15007                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
 15008                              <1> 		; jsr r0,maknod / make an i-node
 15009                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
 15010                              <1> ;2:
 15011                              <1> 		; mov $core,u.base / move address core to u.base
 15012                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
 15013                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
 15014                              <1> 		; clr u.off / clear user offset
 15015                              <1> 		; jsr r0,writei / write out the core image to the user
 15016                              <1> 		; mov $user,u.base / pt. u.base to user
 15017                              <1> 		; mov $64.,u.count / u.count = 64
 15018                              <1> 		; jsr r0,writei / write out all the user parameters
 15019                              <1> 		; neg r1 / make i-number positive
 15020                              <1> 		; jsr r0,iclose / close the core image file
 15021                              <1> 		; br sysexit /
 15022                              <1> ;3:
 15023                              <1> 		; <core\0\0>
 15024                              <1> 
 15025                              <1> intract: ; / interrupt action
 15026                              <1> 	; 14/10/2015
 15027                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15028                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
 15029                              <1> 	;
 15030                              <1> 	; Retro UNIX 8086 v1 modification !
 15031                              <1> 	; (Process/task switching and quit routine by using
 15032                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 15033                              <1> 	;
 15034                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
 15035                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
 15036                              <1> 	;		'intract' will jump to 'sysexit'.
 15037                              <1> 	;	    Intract will return to the caller 
 15038                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
 15039                              <1> 	; 14/10/2015
 15040 0000326E FB                  <1> 	sti
 15041                              <1> 	; 07/12/2013	
 15042 0000326F 66FF05[B26C0000]    <1> 	inc 	word [u.quit]
 15043 00003276 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
 15044 00003278 66FF0D[B26C0000]    <1> 	dec	word [u.quit]
 15045                              <1> 	; 16/04/2015
 15046 0000327F C3                  <1> 	retn
 15047                              <1> intrct0:	
 15048 00003280 58                  <1> 	pop	eax ; call intract -> retn
 15049                              <1> 	;
 15050 00003281 31C0                <1> 	xor 	eax, eax
 15051 00003283 FEC0                <1> 	inc	al  ; mov ax, 1
 15052                              <1> ;;;
 15053                              <1> 	; UNIX v1 original 'intract' routine... 
 15054                              <1> 	; / interrupt action
 15055                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
 15056                              <1> 		; bne 1f / no, 1f
 15057                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
 15058                              <1> 	; 1: / now in user area
 15059                              <1> 		; mov r1,-(sp) / save r1
 15060                              <1> 		; mov u.ttyp,r1 
 15061                              <1> 			; / pointer to tty buffer in control-to r1
 15062                              <1> 		; cmpb 6(r1),$177
 15063                              <1> 			; / is the interrupt char equal to "del"
 15064                              <1> 		; beq 1f / yes, 1f
 15065                              <1> 		; clrb 6(r1) 
 15066                              <1> 		        ; / no, clear the byte 
 15067                              <1> 			; / (must be a quit character)
 15068                              <1> 		; mov (sp)+,r1 / restore r1
 15069                              <1> 		; clr u.quit / clear quit flag
 15070                              <1> 		; bis $20,2(sp) 
 15071                              <1> 		    	; / set trace for quit (sets t bit of 
 15072                              <1> 			; / ps-trace trap)
 15073                              <1> 		; rti   ;  / return from interrupt
 15074                              <1> 	; 1: / interrupt char = del
 15075                              <1> 		; clrb 6(r1) / clear the interrupt byte 
 15076                              <1> 			   ; / in the buffer
 15077                              <1> 		; mov (sp)+,r1 / restore r1
 15078                              <1> 		; cmp u.intr,$core / should control be 
 15079                              <1> 				; / transferred to loc core?
 15080                              <1> 		; blo 1f
 15081                              <1> 		; jmp *u.intr / user to do rti yes, 
 15082                              <1> 				; / transfer to loc core
 15083                              <1> 	; 1:
 15084                              <1> 		; sys 1 / exit
 15085                              <1> 
 15086                              <1> sysexit: ; <terminate process>
 15087                              <1> 	; 17/07/2022
 15088                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
 15089                              <1> 	; 01/09/2015
 15090                              <1> 	; 31/08/2015
 15091                              <1> 	; 14/05/2015
 15092                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15093                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 15094                              <1> 	;
 15095                              <1> 	; 'sysexit' terminates a process. First each file that
 15096                              <1> 	; the process has opened is closed by 'flose'. The process
 15097                              <1> 	; status is then set to unused. The 'p.pid' table is then
 15098                              <1> 	; searched to find children of the dying process. If any of
 15099                              <1> 	; children are zombies (died by not waited for), they are
 15100                              <1> 	; set free. The 'p.pid' table is then searched to find the
 15101                              <1> 	; dying process's parent. When the parent is found, it is
 15102                              <1> 	; checked to see if it is free or it is a zombie. If it is
 15103                              <1> 	; one of these, the dying process just dies. If it is waiting
 15104                              <1> 	; for a child process to die, it notified that it doesn't 
 15105                              <1> 	; have to wait anymore by setting it's status from 2 to 1
 15106                              <1> 	; (waiting to active). It is awakened and put on runq by
 15107                              <1> 	; 'putlu'. The dying process enters a zombie state in which
 15108                              <1> 	; it will never be run again but stays around until a 'wait'
 15109                              <1> 	; is completed by it's parent process. If the parent is not
 15110                              <1> 	; found, process just dies. This means 'swap' is called with
 15111                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
 15112                              <1> 	; to write out the process and 'rswap' reads the new process
 15113                              <1> 	; over the one that dies..i.e., the dying process is 
 15114                              <1> 	; overwritten and destroyed.	
 15115                              <1>  	;
 15116                              <1> 	; Calling sequence:
 15117                              <1> 	;	sysexit or conditional branch.
 15118                              <1> 	; Arguments:
 15119                              <1> 	;	-	
 15120                              <1> 	; ...............................................................
 15121                              <1> 	;	
 15122                              <1> 	; Retro UNIX 8086 v1 modification: 
 15123                              <1> 	;       System call number (=1) is in EAX register.
 15124                              <1> 	;
 15125                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 15126                              <1> 	;       registers depending of function details.
 15127                              <1> 	;
 15128                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
 15129                              <1> 	;
 15130                              <1> ; / terminate process
 15131                              <1> 	; AX = 1
 15132                              <1> 	;dec 	ax ; 0
 15133                              <1> 	; 30/11/2021
 15134 00003285 48                  <1> 	dec	eax ; 0
 15135 00003286 66A3[B06C0000]      <1> 	mov	[u.intr], ax ; 0
 15136                              <1> 		; clr u.intr / clear interrupt control word
 15137                              <1> 		; clr r1 / clear r1
 15138                              <1> 	; AX = 0
 15139                              <1> sysexit_1: ; 1:
 15140                              <1> 	; AX = File descriptor
 15141                              <1> 		; / r1 has file descriptor (index to u.fp list)
 15142                              <1> 		; / Search the whole list
 15143 0000328C E8690D0000          <1> 	call	fclose
 15144                              <1> 		; jsr r0,fclose / close all files the process opened
 15145                              <1> 	;; ignore error return
 15146                              <1> 		; br .+2 / ignore error return
 15147                              <1> 	;inc	ax
 15148 00003291 FEC0                <1> 	inc	al
 15149                              <1> 		; inc r1 / increment file descriptor
 15150                              <1> 	;cmp	ax, 10
 15151 00003293 3C0A                <1> 	cmp	al, 10
 15152                              <1> 		; cmp r1,$10. / end of u.fp list?
 15153 00003295 72F5                <1> 	jb	short sysexit_1
 15154                              <1> 		; blt 1b / no, go back
 15155 00003297 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 15156                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
 15157 0000329E 88A3[83680000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 15158                              <1> 		; clrb p.stat-1(r1) / free the process
 15159                              <1> 	;shl	bx, 1
 15160 000032A4 D0E3                <1> 	shl	bl, 1
 15161                              <1> 		; asl r1 / use r1 for index into the below tables
 15162 000032A6 668B8B[22680000]    <1> 	mov	cx, [ebx+p.pid-2]
 15163                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
 15164 000032AD 668B93[42680000]    <1> 	mov	dx, [ebx+p.ppid-2]
 15165                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
 15166                              <1> 	; xor 	bx, bx ; 0
 15167 000032B4 30DB                <1> 	xor	bl, bl ; 0
 15168                              <1> 		; clr r2
 15169 000032B6 31F6                <1> 	xor	esi, esi ; 0
 15170                              <1> 		; clr r5 / initialize reg
 15171                              <1> sysexit_2: ; 1:
 15172                              <1> 	        ; / find children of this dying process, 
 15173                              <1> 		; / if they are zombies, free them
 15174                              <1> 	;add	bx, 2
 15175 000032B8 80C302              <1> 	add	bl, 2
 15176                              <1> 		; add $2,r2 / search parent process table 
 15177                              <1> 		          ; / for dying process's name
 15178 000032BB 66398B[42680000]    <1> 	cmp	[ebx+p.ppid-2], cx
 15179                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
 15180 000032C2 7513                <1> 	jne	short sysexit_4
 15181                              <1> 		; bne 3f / no
 15182                              <1> 	;shr	bx, 1
 15183 000032C4 D0EB                <1> 	shr	bl, 1
 15184                              <1> 		; asr r2 / yes, it is a parent
 15185 000032C6 80BB[83680000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
 15186                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
 15187                              <1> 				     ; / dying process a zombie
 15188 000032CD 7506                <1> 	jne	short sysexit_3 
 15189                              <1> 		; bne 2f / no
 15190 000032CF 88A3[83680000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 15191                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
 15192                              <1> sysexit_3: ; 2:
 15193                              <1> 	;shr	bx, 1
 15194 000032D5 D0E3                <1> 	shl	bl, 1
 15195                              <1> 		; asl r2
 15196                              <1> sysexit_4: ; 3:
 15197                              <1> 		; / search the process name table 
 15198                              <1> 		; / for the dying process's parent
 15199 000032D7 663993[22680000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
 15200                              <1> 		; cmp p.pid-2(r2),r4 / found it?
 15201 000032DE 7502                <1> 	jne	short sysexit_5
 15202                              <1> 		; bne 3f / no
 15203 000032E0 89DE                <1> 	mov	esi, ebx
 15204                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
 15205                              <1> 		          ; / process # x2) in r5
 15206                              <1> sysexit_5: ; 3:
 15207                              <1> 	;cmp	bx, nproc + nproc
 15208 000032E2 80FB20              <1> 	cmp	bl, nproc + nproc
 15209                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
 15210 000032E5 72D1                <1> 	jb	short sysexit_2
 15211                              <1> 		; blt 1b / no, go back
 15212                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
 15213 000032E7 21F6                <1> 	and	esi, esi ; r5=r1
 15214 000032E9 7430                <1> 	jz	short sysexit_6
 15215                              <1> 		; beq 2f / no parent has been found. 
 15216                              <1> 		       ; / The process just dies
 15217                              <1> 	;shr	si, 1
 15218                              <1> 	; 17/07/2022
 15219 000032EB D1EE                <1> 	shr	esi, 1
 15220                              <1> 		; asr r1 / set up index to p.stat
 15221 000032ED 8A86[83680000]      <1> 	mov	al, [esi+p.stat-1]
 15222                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
 15223 000032F3 20C0                <1> 	and	al, al
 15224 000032F5 7424                <1> 	jz	short sysexit_6
 15225                              <1> 		; beq 2f / if its been freed, 2f
 15226 000032F7 3C03                <1> 	cmp	al, 3
 15227                              <1> 		; cmp r2,$3 / is parent a zombie?
 15228 000032F9 7420                <1> 	je	short sysexit_6
 15229                              <1> 		; beq 2f / yes, 2f
 15230                              <1> 	; BH = 0
 15231 000032FB 8A1D[B56C0000]      <1> 	mov	bl, [u.uno]
 15232                              <1> 		; movb u.uno,r3 / move dying process's number to r3
 15233 00003301 C683[83680000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
 15234                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
 15235                              <1> 	; 05/02/2014
 15236 00003308 3C01                <1> 	cmp	al, 1 ; SRUN
 15237 0000330A 740F                <1> 	je	short sysexit_6
 15238                              <1> 	;cmp	al, 2
 15239                              <1> 		; cmp r2,$2 / is the parent waiting for 
 15240                              <1> 			  ; / this child to die
 15241                              <1> 	;jne	short sysexit_6	
 15242                              <1> 		; bne 2f / yes, notify parent not to wait any more
 15243                              <1> 	; 05/02/2014
 15244                              <1> 	; p.stat = 2 --> waiting
 15245                              <1> 	; p.stat = 4 --> sleeping
 15246 0000330C C686[83680000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
 15247                              <1> 	;dec	byte [esi+p.stat-1]
 15248                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
 15249 00003313 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
 15250                              <1> 	; 
 15251                              <1> 	;mov	ebx, runq + 4
 15252                              <1> 		; mov $runq+4,r2 / on the runq
 15253 00003316 E8AF130000          <1> 	call	putlu
 15254                              <1> 		; jsr r0, putlu
 15255                              <1> sysexit_6: ; 2:
 15256                              <1> 	; 31/08/2015
 15257                              <1> 		; / the process dies
 15258 0000331B C605[B56C0000]00    <1> 	mov	byte [u.uno], 0
 15259                              <1> 		; clrb u.uno / put zero as the process number, 
 15260                              <1> 	           ; / so "swap" will
 15261 00003322 E8D6120000          <1> 	call	swap
 15262                              <1> 		; jsr r0,swap / overwrite process with another process
 15263                              <1> hlt_sys:
 15264                              <1> 	;sti ; 18/01/2014
 15265                              <1> hlts0:
 15266 00003327 F4                  <1> 	hlt
 15267 00003328 EBFD                <1> 	jmp	short hlts0
 15268                              <1> 		; 0 / and thereby kill it; halt?
 15269                              <1> 
 15270                              <1> syswait: ; < wait for a processs to die >
 15271                              <1> 	; 09/02/2022
 15272                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 15273                              <1> 	; 17/09/2015
 15274                              <1> 	; 02/09/2015
 15275                              <1> 	; 01/09/2015
 15276                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15277                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
 15278                              <1> 	;
 15279                              <1> 	; 'syswait' waits for a process die. 
 15280                              <1> 	; It works in following way:
 15281                              <1> 	;    1) From the parent process number, the parent's 
 15282                              <1> 	; 	process name is found. The p.ppid table of parent
 15283                              <1> 	;	names is then searched for this process name.
 15284                              <1> 	;	If a match occurs, r2 contains child's process
 15285                              <1> 	;	number. The child status is checked to see if it is
 15286                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
 15287                              <1> 	;	If it is, the child process is freed and it's name
 15288                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
 15289                              <1> 	;	If the child is not a zombie, nothing happens and
 15290                              <1> 	;	the search goes on through the p.ppid table until
 15291                              <1> 	;	all processes are checked or a zombie is found.
 15292                              <1> 	;    2) If no zombies are found, a check is made to see if
 15293                              <1> 	;	there are any children at all. If there are none,
 15294                              <1> 	;	an error return is made. If there are, the parent's
 15295                              <1> 	;	status is set to 2 (waiting for child to die),
 15296                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
 15297                              <1> 	;	is made to wait on the next process.
 15298                              <1> 	;
 15299                              <1> 	; Calling sequence:
 15300                              <1> 	;	?
 15301                              <1> 	; Arguments:
 15302                              <1> 	;	-
 15303                              <1> 	; Inputs: - 
 15304                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
 15305                              <1> 	; ...............................................................
 15306                              <1> 	;				
 15307                              <1> 	
 15308                              <1> ; / wait for a process to die
 15309                              <1> 
 15310                              <1> syswait_0:
 15311 0000332A 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 15312                              <1> 		; movb u.uno,r1 / put parents process number in r1
 15313 00003331 D0E3                <1> 	shl	bl, 1
 15314                              <1> 	;shl	bx, 1
 15315                              <1> 		; asl r1 / x2 to get index into p.pid table
 15316 00003333 668B83[22680000]    <1> 	mov	ax, [ebx+p.pid-2]
 15317                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
 15318 0000333A 31F6                <1> 	xor	esi, esi
 15319                              <1> 		; clr r2
 15320 0000333C 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
 15321                              <1> 	;xor 	cl, cl
 15322                              <1> 		; clr r3 / initialize reg 3
 15323                              <1> syswait_1: ; 1:
 15324                              <1> 	; 09/02/2022
 15325 0000333E 46                  <1> 	inc	esi
 15326 0000333F 46                  <1> 	inc	esi
 15327                              <1> 	;add	si, 2
 15328                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
 15329                              <1> 			  ; / search table of parent processes 
 15330                              <1> 			  ; / for this process name
 15331 00003340 663B86[42680000]    <1> 	cmp	ax, [esi+p.ppid-2]
 15332                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
 15333                              <1> 			            ; / process number
 15334 00003347 7531                <1> 	jne	short syswait_3
 15335                              <1> 		; bne 3f / branch if no match of parent process name
 15336                              <1> 	;inc	cx
 15337 00003349 FEC1                <1> 	inc	cl
 15338                              <1> 		; inc r3 / yes, a match, r3 indicates number of children
 15339                              <1> 	; 09/02/2022
 15340 0000334B D1EE                <1> 	shr	esi, 1
 15341                              <1> 	;shr	si, 1
 15342                              <1> 		; asr r2 / r2/2 to get index to p.stat table
 15343                              <1> 	; The possible states ('p.stat' values) of a process are:
 15344                              <1> 	;	0 = free or unused
 15345                              <1> 	;	1 = active
 15346                              <1> 	;	2 = waiting for a child process to die
 15347                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
 15348 0000334D 80BE[83680000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
 15349                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
 15350 00003354 7522                <1> 	jne	short syswait_2
 15351                              <1> 		; bne 2f / no, skip it
 15352 00003356 88BE[83680000]      <1> 	mov	[esi+p.stat-1], bh ; 0
 15353                              <1> 		; clrb p.stat-1(r2) / yes, free it
 15354                              <1> 	; 09/02/2022
 15355 0000335C D1E6                <1> 	shl	esi, 1
 15356                              <1> 	;shl	si, 1
 15357                              <1> 		; asl r2 / r2x2 to get index into p.pid table
 15358 0000335E 0FB786[22680000]    <1> 	movzx	eax, word [esi+p.pid-2]
 15359 00003365 A3[646C0000]        <1> 	mov	[u.r0], eax
 15360                              <1> 		; mov p.pid-2(r2),*u.r0 
 15361                              <1> 			      ; / put childs process name in (u.r0)
 15362                              <1> 	;
 15363                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
 15364                              <1> 	;
 15365                              <1> 	; Parent process ID -p.ppid- field (of the child process)
 15366                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
 15367                              <1> 	; system call loop from the application/program if it calls
 15368                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
 15369                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
 15370                              <1> 	;
 15371                              <1> 	; Note: syswait will return with error if there is not a
 15372                              <1> 	;       zombie or running process to wait.	
 15373                              <1> 	;
 15374                              <1> 	;sub	ax, ax
 15375                              <1> 	; 08/01/2022
 15376 0000336A 29C0                <1> 	sub	eax, eax
 15377 0000336C 668986[42680000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
 15378 00003373 E90BFEFFFF          <1> 	jmp	sysret0 ; ax = 0
 15379                              <1> 	;
 15380                              <1> 	;jmp	sysret
 15381                              <1> 		; br sysret1 / return cause child is dead
 15382                              <1> syswait_2: ; 2:
 15383                              <1> 	; 09/02/2022
 15384 00003378 D1E6                <1> 	shl	esi, 1
 15385                              <1> 	;shl	si, 1
 15386                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
 15387                              <1> syswait_3: ; 3:
 15388 0000337A 6683FE20            <1> 	cmp	si, nproc+nproc
 15389                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
 15390 0000337E 72BE                <1> 	jb	short syswait_1
 15391                              <1> 		; blt 1b / no, continue search
 15392                              <1> 	;and	cx, cx
 15393 00003380 20C9                <1> 	and	cl, cl
 15394                              <1> 		; tst r3 / one gets here if there are no children 
 15395                              <1> 		       ; / or children that are still active
 15396                              <1> 	; 30/10/2013
 15397 00003382 7515                <1> 	jnz	short syswait_4
 15398                              <1> 	;jz	error
 15399                              <1> 		; beq error1 / there are no children, error
 15400 00003384 890D[646C0000]      <1> 	mov	[u.r0], ecx ; 0
 15401                              <1> 	; 09/02/2022
 15402 0000338A C705[D86C0000]1B00- <1> 	mov	dword [u.error], ERR_MISC ; 27
 15403 00003392 0000                <1>
 15404                              <1> 			; miscellaneous/other errors
 15405 00003394 E9C8FDFFFF          <1> 	jmp	error
 15406                              <1> syswait_4:
 15407 00003399 8A1D[B56C0000]      <1> 	mov	bl, [u.uno]
 15408                              <1> 		; movb u.uno,r1 / there are children so put 
 15409                              <1> 			      ; / parent process number in r1
 15410 0000339F FE83[83680000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
 15411                              <1> 		; incb p.stat-1(r1) / it is waiting for 
 15412                              <1> 				  ; / other children to die
 15413                              <1> 	; 04/11/2013
 15414 000033A5 E853120000          <1> 	call	swap
 15415                              <1> 		; jsr r0,swap / swap it out, because it's waiting
 15416 000033AA E97BFFFFFF          <1> 	jmp	syswait_0
 15417                              <1> 		; br syswait / wait on next process
 15418                              <1> 
 15419                              <1> sysfork: ; < create a new process >
 15420                              <1> 	; 27/02/2022
 15421                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 15422                              <1> 	; 18/09/2015
 15423                              <1> 	; 04/09/2015
 15424                              <1> 	; 02/09/2015
 15425                              <1> 	; 01/09/2015
 15426                              <1> 	; 28/08/2015
 15427                              <1> 	; 14/05/2015
 15428                              <1> 	; 10/05/2015
 15429                              <1> 	; 09/05/2015
 15430                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
 15431                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 15432                              <1> 	;
 15433                              <1> 	; 'sysfork' creates a new process. This process is referred
 15434                              <1> 	; to as the child process. This new process core image is
 15435                              <1> 	; a copy of that of the caller of 'sysfork'. The only
 15436                              <1> 	; distinction is the return location and the fact that (u.r0)
 15437                              <1> 	; in the old process (parent) contains the process id (p.pid)
 15438                              <1> 	; of the new process (child). This id is used by 'syswait'.
 15439                              <1> 	; 'sysfork' works in the following manner: 	
 15440                              <1> 	;    1) The process status table (p.stat) is searched to find
 15441                              <1> 	;	a process number that is unused. If none are found
 15442                              <1> 	;	an error occurs.
 15443                              <1> 	;    2) when one is found, it becomes the child process number
 15444                              <1> 	;	and it's status (p.stat) is set to active.
 15445                              <1> 	;    3) If the parent had a control tty, the interrupt 
 15446                              <1> 	;	character in that tty buffer is cleared.
 15447                              <1> 	;    4) The child process is put on the lowest priority run 
 15448                              <1> 	;	queue via 'putlu'.
 15449                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
 15450                              <1> 	;	it is a unique number) and is put in the child's unique
 15451                              <1> 	;	identifier; process id (p.pid).
 15452                              <1> 	;    6) The process name of the parent is then obtained and
 15453                              <1> 	;	placed in the unique identifier of the parent process
 15454                              <1> 	;	name is then put in 'u.r0'.	
 15455                              <1> 	;    7) The child process is then written out on disk by
 15456                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
 15457                              <1> 	;	and the child is born. (The child process is written 
 15458                              <1> 	;	out on disk/drum with 'u.uno' being the child process
 15459                              <1> 	;	number.)
 15460                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
 15461                              <1> 	;    9) The child process name is put in 'u.r0'.
 15462                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
 15463                              <1> 	;	create the return address for the parent process.
 15464                              <1> 	;   11) The 'u.fp' list as then searched to see what files
 15465                              <1> 	;	the parent has opened. For each file the parent has
 15466                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
 15467                              <1> 	;	to indicate that the child process also has opened
 15468                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
 15469                              <1> 	;
 15470                              <1> 	; Calling sequence:
 15471                              <1> 	;	from shell ?
 15472                              <1> 	; Arguments:
 15473                              <1> 	;	-
 15474                              <1> 	; Inputs: -
 15475                              <1> 	; Outputs: *u.r0 - child process name
 15476                              <1> 	; ...............................................................
 15477                              <1> 	;	
 15478                              <1> 	; Retro UNIX 8086 v1 modification: 
 15479                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
 15480                              <1> 	;	= process id of child a parent process returns
 15481                              <1> 	;	= process id of parent when a child process returns
 15482                              <1> 	;
 15483                              <1> 	;       In original UNIX v1, sysfork is called and returns as
 15484                              <1> 	;	in following manner: (with an example: c library, fork)
 15485                              <1> 	;	
 15486                              <1> 	;	1:
 15487                              <1> 	;		sys	fork
 15488                              <1> 	;			br 1f  / child process returns here
 15489                              <1> 	;		bes	2f     / parent process returns here
 15490                              <1> 	;		/ pid of new process in r0
 15491                              <1> 	;		rts	pc
 15492                              <1> 	;	2: / parent process condionally branches here
 15493                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
 15494                              <1> 	;		rts	pc
 15495                              <1> 	;
 15496                              <1> 	;	1: / child process brances here
 15497                              <1> 	;		clr	r0   / pid = 0 in child process
 15498                              <1> 	;		rts	pc
 15499                              <1> 	;
 15500                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
 15501                              <1> 	;		// pid = fork();
 15502                              <1> 	;		//
 15503                              <1> 	;		// pid == 0 in child process; 
 15504                              <1> 	;		// pid == -1 means error return
 15505                              <1> 	;		// in child, 
 15506                              <1> 	;		//	parents id is in par_uid if needed
 15507                              <1> 	;		
 15508                              <1> 	;		_fork:
 15509                              <1> 	;			mov	$.fork,eax
 15510                              <1> 	;			int	$0x30
 15511                              <1> 	;			jmp	1f
 15512                              <1> 	;			jnc	2f
 15513                              <1> 	;			jmp	cerror
 15514                              <1> 	;		1:
 15515                              <1> 	;			mov	eax,_par_uid
 15516                              <1> 	;			xor	eax,eax
 15517                              <1> 	;		2:
 15518                              <1> 	;			ret
 15519                              <1> 	;
 15520                              <1> 	;	In Retro UNIX 8086 v1,
 15521                              <1> 	;	'sysfork' returns in following manner:
 15522                              <1> 	;	
 15523                              <1> 	;		mov	ax, sys_fork
 15524                              <1> 	;		mov	bx, offset @f ; routine for child
 15525                              <1> 	;		int	20h
 15526                              <1> 	;		jc	error
 15527                              <1> 	;		
 15528                              <1> 	;	; Routine for parent process here (just after 'jc')
 15529                              <1> 	;		mov	word ptr [pid_of_child], ax
 15530                              <1> 	;		jmp	next_routine_for_parent	
 15531                              <1> 	;
 15532                              <1> 	;	@@: ; routine for child process here				
 15533                              <1> 	;		....	
 15534                              <1> 	;	NOTE: 'sysfork' returns to specified offset
 15535                              <1> 	;	       for child process by using BX input.
 15536                              <1> 	;	      (at first, parent process will return then 
 15537                              <1> 	;	      child process will return -after swapped in-
 15538                              <1> 	;	      'syswait' is needed in parent process
 15539                              <1> 	;	      if return from child process will be waited for.)
 15540                              <1> 	;	  				
 15541                              <1> 	
 15542                              <1> ; / create a new process
 15543                              <1> 	; EBX = return address for child process 
 15544                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
 15545 000033AF 31F6                <1> 	xor 	esi, esi
 15546                              <1> 		; clr r1
 15547                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
 15548 000033B1 46                  <1> 	inc	esi
 15549                              <1> 		; inc r1
 15550 000033B2 80BE[83680000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
 15551                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
 15552 000033B9 760B                <1> 	jna	short sysfork_2	
 15553                              <1> 		; beq 1f / it's unused so branch
 15554 000033BB 6683FE10            <1> 	cmp	si, nproc
 15555                              <1> 		; cmp r1,$nproc / all processes checked
 15556 000033BF 72F0                <1> 	jb	short sysfork_1
 15557                              <1> 		; blt 1b / no, branch back
 15558                              <1> 	;
 15559                              <1> 	; Retro UNIX 8086 v1. modification:
 15560                              <1> 	;	Parent process returns from 'sysfork' to address 
 15561                              <1> 	;	which is just after 'sysfork' system call in parent
 15562                              <1> 	;	process. Child process returns to address which is put
 15563                              <1> 	;	in BX register by parent process for 'sysfork'. 
 15564                              <1> 	;
 15565                              <1> 		; add $2,18.(sp) / add 2 to pc when trap occured, points
 15566                              <1> 		             ; / to old process return
 15567                              <1> 		; br error1 / no room for a new process
 15568                              <1> sysfork_0:
 15569 000033C1 E99BFDFFFF          <1> 	jmp	error
 15570                              <1> sysfork_2: ; 1:
 15571 000033C6 E814F0FFFF          <1> 	call	allocate_page
 15572                              <1> 	;jc	error
 15573                              <1> 	; 08/01/2022
 15574 000033CB 72F4                <1> 	jc	short sysfork_0
 15575                              <1> 
 15576 000033CD 50                  <1> 	push	eax   ; UPAGE (user structure page) address
 15577                              <1> 	; Retro UNIX 386 v1 modification!
 15578 000033CE E803F2FFFF          <1> 	call	duplicate_page_dir
 15579                              <1> 		; EAX = New page directory 
 15580 000033D3 7308                <1> 	jnc	short sysfork_3
 15581 000033D5 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15582 000033D6 E8CAF1FFFF          <1> 	call 	deallocate_page
 15583                              <1> 	;jmp	error
 15584                              <1> 	; 08/01/2022
 15585 000033DB EBE4                <1> 	jmp	short sysfork_0  ; error
 15586                              <1> sysfork_3:
 15587                              <1> 	; Retro UNIX 386 v1 modification !
 15588 000033DD 56                  <1> 	push	esi
 15589 000033DE E891120000          <1> 	call	wswap ; save current user (u) structure, user registers
 15590                              <1> 		      ; and interrupt return components (for IRET)
 15591 000033E3 8705[C46C0000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
 15592 000033E9 A3[C86C0000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
 15593 000033EE 5E                  <1> 	pop	esi
 15594 000033EF 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15595                              <1> 		; [u.usp] = esp
 15596 000033F0 89F7                <1> 	mov	edi, esi
 15597                              <1> 	;shl	di, 2
 15598                              <1> 	; 08/01/2022
 15599 000033F2 C1E702              <1> 	shl	edi, 2
 15600 000033F5 8987[90680000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
 15601 000033FB A3[C06C0000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
 15602                              <1> 	; 28/08/2015
 15603 00003400 0FB605[B56C0000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
 15604                              <1> 		; movb u.uno,-(sp) / save parent process number
 15605 00003407 89C7                <1> 	mov	edi, eax
 15606 00003409 50                  <1>         push	eax ; ** 
 15607 0000340A 8A87[63680000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
 15608                              <1> 	; 18/09/2015 (27/02/2022)
 15609 00003410 8886[63680000]      <1> 	mov	[esi+p.ttyc-1], al ; set child's console tty
 15610                              <1> 	; 27/02/2022 (p.waitc is not used)
 15611                              <1> 	;mov	[esi+p.waitc-1], ah ; 0 ; reset child's wait channel
 15612                              <1> 	; 27/02/2022 (BugFix)
 15613                              <1> 	;mov	[esi+p.ttyc-1], ax ; al - set child's console tty
 15614                              <1> 	;			   ; ah - reset child's wait channel
 15615 00003416 89F0                <1> 	mov	eax, esi
 15616 00003418 A2[B56C0000]        <1> 	mov	[u.uno], al ; child process number
 15617                              <1> 		;movb r1,u.uno / set child process number to r1
 15618 0000341D FE86[83680000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
 15619                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
 15620                              <1> 				; / process to active status
 15621                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
 15622                              <1> 			      ; / control tty buffer in r2
 15623                              <1>                 ; beq 2f / branch, if no such tty assigned
 15624                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
 15625                              <1> 	; 2:
 15626 00003423 53                  <1> 	push	ebx  ; * return address for the child process
 15627                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15628                              <1> 	; (Retro UNIX 8086 v1 modification!)
 15629                              <1> 		; mov $runq+4,r2
 15630 00003424 E8A1120000          <1> 	call	putlu 
 15631                              <1>  		; jsr r0,putlu / put child process on lowest priority 
 15632                              <1> 			   ; / run queue
 15633                              <1> 	; 08/01/2022
 15634 00003429 D1E6                <1> 	shl	esi, 1
 15635                              <1> 	;shl	si, 1
 15636                              <1> 		; asl r1 / multiply r1 by 2 to get index 
 15637                              <1> 		       ; / into p.pid table
 15638 0000342B 66FF05[446C0000]    <1> 	inc	word [mpid]
 15639                              <1> 		; inc mpid / increment m.pid; get a new process name
 15640 00003432 66A1[446C0000]      <1> 	mov	ax, [mpid]
 15641 00003438 668986[22680000]    <1> 	mov	[esi+p.pid-2], ax
 15642                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
 15643                              <1> 				    ; / in child process' name slot
 15644 0000343F 5A                  <1> 	pop	edx  ; * return address for the child process
 15645                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15646 00003440 5B                  <1>   	pop	ebx  ; **
 15647                              <1> 	;mov	ebx, [esp] ; ** parent process number
 15648                              <1> 		; movb (sp),r2 / put parent process number in r2
 15649                              <1> 	; 08/01/2022
 15650 00003441 D1E3                <1> 	shl	ebx, 1
 15651                              <1> 	;shl 	bx, 1
 15652                              <1> 		; asl r2 / multiply by 2 to get index into below tables
 15653                              <1> 	;movzx eax, word [ebx+p.pid-2]
 15654 00003443 668B83[22680000]    <1> 	mov	ax, [ebx+p.pid-2]
 15655                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
 15656                              <1> 				   ; / process
 15657 0000344A 668986[42680000]    <1> 	mov	[esi+p.ppid-2], ax
 15658                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
 15659                              <1> 			  ; / in parent process slot for child
 15660 00003451 A3[646C0000]        <1> 	mov	[u.r0], eax	
 15661                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
 15662                              <1> 			     ; / at location where r0 was saved
 15663 00003456 8B2D[5C6C0000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
 15664 0000345C 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
 15665                              <1> 			   ; * return address for the child process
 15666                              <1> 		; mov $sysret1,-(sp) /
 15667                              <1> 		; mov sp,u.usp / contents of sp at the time when 
 15668                              <1> 			      ; / user is swapped out
 15669                              <1> 		; mov $sstack,sp / point sp to swapping stack space
 15670                              <1> 	; 04/09/2015 - 01/09/2015
 15671                              <1> 	; [u.usp] = esp
 15672 0000345F 68[81310000]        <1> 	push	sysret ; ***
 15673 00003464 8925[606C0000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
 15674                              <1> 			     ; (for child process)	
 15675 0000346A 31C0                <1> 	xor 	eax, eax
 15676 0000346C 66A3[9A6C0000]      <1> 	mov 	[u.ttyp], ax ; 0
 15677                              <1> 	;
 15678 00003472 E8FD110000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
 15679                              <1> 		;jsr r0,wswap / put child process out on drum
 15680                              <1> 		;jsr r0,unpack / unpack user stack
 15681                              <1> 		;mov u.usp,sp / restore user stack pointer
 15682                              <1> 		; tst (sp)+ / bump stack pointer
 15683                              <1> 	; Retro UNIX 386 v1 modification !
 15684 00003477 58                  <1> 	pop	eax ; ***
 15685                              <1> 	; 08/01/2022
 15686 00003478 D1E3                <1> 	shl	ebx, 1
 15687                              <1> 	;shl 	bx, 1
 15688 0000347A 8B83[90680000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
 15689 00003480 E818120000          <1> 	call	rswap ; restore parent process 'u' structure, 
 15690                              <1> 		      ; registers and return address (for IRET)
 15691                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
 15692 00003485 0FB705[446C0000]    <1>         movzx   eax, word [mpid]
 15693 0000348C A3[646C0000]        <1> 	mov	[u.r0], eax
 15694                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
 15695                              <1> 			       ; / where r0 was saved
 15696                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
 15697                              <1> 			          ; / process return
 15698                              <1> 	;xor	ebx, ebx
 15699 00003491 31F6                <1> 	xor     esi, esi
 15700                              <1> 		;clr r1
 15701                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
 15702                              <1> 	      ; / opened by the parent process
 15703                              <1> 	; 08/01/2022
 15704                              <1> 	; 01/09/2015
 15705 00003493 30FF                <1> 	xor	bh, bh
 15706 00003495 8A9E[6E6C0000]      <1> 	mov 	bl, [esi+u.fp]
 15707                              <1> 	; 08/01/2022
 15708                              <1> 	;mov 	al, [esi+u.fp]
 15709                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
 15710 0000349B 08DB                <1> 	or	bl, bl
 15711                              <1> 	; 08/01/2022
 15712                              <1> 	;or	al, al
 15713 0000349D 7409                <1> 	jz	short sysfork_5	
 15714                              <1> 		; beq 2f / file has not been opened by parent, 
 15715                              <1> 		       ; / so branch
 15716                              <1> 	;mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
 15717                              <1> 	; 08/01/2022
 15718                              <1> 	;mov	ah, 16 ; Retro UNIX 386 v2 fsp structure size = 16 bytes
 15719                              <1> 	;mul	ah
 15720                              <1> 	;;movzx	ebx, ax
 15721                              <1> 	;mov	bx, ax
 15722                              <1> 	;mov	ebx, eax ; 08/01/2022
 15723                              <1> 	;shl	bx, 3
 15724                              <1> 		; asl r2 / multiply by 8
 15725                              <1>        		; asl r2 / to get index into fsp table
 15726                              <1>        		; asl r2
 15727                              <1> 	; 08/01/2022
 15728 0000349F C1E304              <1> 	shl	ebx, 4 ; multiply by 16
 15729                              <1> 	; 08/01/2022
 15730 000034A2 FE83[CA680000]      <1> 	inc	byte [ebx+fsp-10] ; Retro UNIX 386 v2 fs fsp structure
 15731                              <1>   	;inc	byte [ebx+fsp-2]
 15732                              <1> 		; incb fsp-2(r2) / increment number of processes
 15733                              <1> 			     ; / using file, because child will now be
 15734                              <1> 			     ; / using this file
 15735                              <1> sysfork_5: ; 2:
 15736 000034A8 46                  <1>         inc     esi
 15737                              <1> 		; inc r1 / get next open file
 15738 000034A9 6683FE0A            <1>         cmp     si, 10
 15739                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
 15740                              <1> 			  ; / can be opened
 15741 000034AD 72E4                <1> 	jb	short sysfork_4	
 15742                              <1> 		; blt 1b / check next entry
 15743 000034AF E9CDFCFFFF          <1> 	jmp	sysret
 15744                              <1> 		; br sysret1
 15745                              <1> 
 15746                              <1> sysread: ; < read from file >
 15747                              <1> 	; 24/12/2021
 15748                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 15749                              <1> 	; 27/03/2020
 15750                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15751                              <1> 	; 13/05/2015
 15752                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15753                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15754                              <1> 	;
 15755                              <1> 	; 'sysread' is given a buffer to read into and the number of
 15756                              <1> 	; characters to be read. If finds the file from the file
 15757                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
 15758                              <1> 	; is returned from a successful open call (sysopen).
 15759                              <1> 	; The i-number of file is obtained via 'rw1' and the data
 15760                              <1> 	; is read into core via 'readi'.
 15761                              <1> 	;
 15762                              <1> 	; Calling sequence:
 15763                              <1> 	;	sysread; buffer; nchars
 15764                              <1> 	; Arguments:
 15765                              <1> 	;	buffer - location of contiguous bytes where 
 15766                              <1> 	;		 input will be placed.
 15767                              <1> 	;	nchars - number of bytes or characters to be read.
 15768                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15769                              <1> 	; Outputs: *u.r0 - number of bytes read.	
 15770                              <1> 	; ...............................................................
 15771                              <1> 	;				
 15772                              <1> 	; Retro UNIX 8086 v1 modification: 
 15773                              <1> 	;       'sysread' system call has three arguments; so,
 15774                              <1> 	;	* 1st argument, file descriptor is in BX register
 15775                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15776                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15777                              <1> 	;
 15778                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15779                              <1> 	;	to the user with number of bytes read. 
 15780                              <1> 	;
 15781                              <1> 
 15782 000034B4 E839000000          <1> 	call	rw1
 15783                              <1> 	;jc	error ; 13/05/2015, ax < 1
 15784                              <1> 	;	; jsr r0,rw1 / get i-number of file to be read into r1
 15785                              <1>        	; 04/12/2021
 15786 000034B9 7209                <1> 	jc	short sysread_err
 15787 000034BB 7529                <1> 	jnz	short rw3 ; error ! (permission denied)
 15788                              <1> 	;		; read a file while it is open for write!
 15789                              <1> 
 15790                              <1> 	; eax = inode number
 15791                              <1> 
 15792                              <1> 	; 04/12/2021
 15793                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
 15794                              <1> 	;test	ah, 80h
 15795                              <1> 	;	; tst r1 / negative i-number?
 15796                              <1> 	;;jnz	error
 15797                              <1> 	;;	; ble error1 / yes, error 1 to read
 15798                              <1> 	;;		   ; / it should be positive
 15799                              <1> 	;; 04/12/2021
 15800                              <1> 	;jnz	short sysread_err
 15801                              <1> 
 15802 000034BD E81B1A0000          <1> 	call	readi
 15803                              <1> 		; jsr r0,readi / read data into core
 15804 000034C2 EB13                <1> 	jmp	short rw0
 15805                              <1> 		; br 1f
 15806                              <1> sysread_err:
 15807                              <1> syswrite_err:
 15808                              <1> 	; 04/12/2021
 15809 000034C4 E998FCFFFF          <1> 	jmp	error
 15810                              <1> 
 15811                              <1> syswrite: ; < write to file >
 15812                              <1> 	; 24/12/2021
 15813                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 15814                              <1> 	; 27/03/2020
 15815                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15816                              <1> 	; 13/05/2015
 15817                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15818                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15819                              <1> 	;
 15820                              <1> 	; 'syswrite' is given a buffer to write onto an output file
 15821                              <1> 	; and the number of characters to write. If finds the file
 15822                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
 15823                              <1> 	; descriptor is returned from a successful open or create call
 15824                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
 15825                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
 15826                              <1> 	;
 15827                              <1> 	; Calling sequence:
 15828                              <1> 	;	syswrite; buffer; nchars
 15829                              <1> 	; Arguments:
 15830                              <1> 	;	buffer - location of contiguous bytes to be writtten.
 15831                              <1> 	;	nchars - number of characters to be written.
 15832                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15833                              <1> 	; Outputs: *u.r0 - number of bytes written.	
 15834                              <1> 	; ...............................................................
 15835                              <1> 	;				
 15836                              <1> 	; Retro UNIX 8086 v1 modification: 
 15837                              <1> 	;       'syswrite' system call has three arguments; so,
 15838                              <1> 	;	* 1st argument, file descriptor is in BX register
 15839                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15840                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15841                              <1> 	;
 15842                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15843                              <1> 	;	to the user with number of bytes written. 
 15844                              <1> 	;
 15845                              <1> 
 15846 000034C9 E824000000          <1> 	call	rw1
 15847                              <1> 	;jc	error ; 13/05/2015, ax < 1
 15848                              <1> 	;	; jsr r0,rw1 / get i-number in r1 of file to write
 15849                              <1>        	; 04/12/2021
 15850 000034CE 72F4                <1> 	jc	short syswrite_err
 15851 000034D0 7414                <1> 	jz	short rw3 ; error ! (permission denied)
 15852                              <1> 			; write to a file while it is open for read
 15853                              <1> 	; eax = inode number
 15854                              <1> 	
 15855                              <1> 	; 04/12/2021
 15856                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
 15857                              <1> 	;test	ah, 80h
 15858                              <1> 	;	; tst r1 / positive i-number ?
 15859                              <1>         ;jz	short rw3 ; 13/05/2015
 15860                              <1> 	;;jz	error
 15861                              <1> 	;	; bge error1 / yes, error 1 
 15862                              <1> 	;		   ; / negative i-number means write
 15863                              <1>         ;neg	ax
 15864                              <1> 	;	; neg r1 / make it positive
 15865                              <1> 	
 15866 000034D2 E81A1C0000          <1> 	call	writei
 15867                              <1>         	; jsr r0,writei / write data
 15868                              <1> rw0: ; 1:
 15869 000034D7 A1[906C0000]        <1>         mov	eax, [u.nread]
 15870 000034DC A3[646C0000]        <1> 	mov	[u.r0], eax
 15871                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
 15872                              <1> 				  ; / into (u.r0)
 15873 000034E1 E99BFCFFFF          <1> 	jmp	sysret
 15874                              <1>         	; br sysret1
 15875                              <1> rw3: 
 15876                              <1> 	; 13/05/2015
 15877 000034E6 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 15878 000034EE 0000                <1>
 15879                              <1> 	;stc
 15880                              <1> 	;retn
 15881                              <1> 	; 24/12/2021 - Retro UNIX 386 v1.2
 15882 000034F0 EBD2                <1> 	jmp	short syswrite_err
 15883                              <1> 
 15884                              <1> rw1:	
 15885                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 15886                              <1> 	; 27/03/2020
 15887                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15888                              <1> 	; 14/05/2015
 15889                              <1> 	; 13/05/2015
 15890                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15891                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
 15892                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
 15893                              <1> 	;
 15894                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
 15895                              <1> 				;(in the user's virtual memory space)
 15896                              <1> 	;mov	[u.count], edx 
 15897                              <1> 		; jsr r0,arg; u.base / get buffer pointer
 15898                              <1>         	; jsr r0,arg; u.count / get no. of characters
 15899                              <1> 	;;mov	eax, ebx ; file descriptor
 15900                              <1> 		; mov *u.r0,r1 / put file descriptor 
 15901                              <1> 		             ; / (index to u.fp table) in r1
 15902                              <1> 	; 13/05/2015
 15903 000034F2 C705[646C0000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
 15904 000034FA 0000                <1>
 15905                              <1> 	;
 15906                              <1> 	;; call	getf
 15907                              <1>         ; ebx = File descriptor
 15908 000034FC E8410B0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
 15909                              <1> 		; jsr r0,getf / get i-number of the file in r1
 15910                              <1> 	; AX = I-number of the file ; negative i-number means write
 15911                              <1> 
 15912                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 15913                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15914                              <1> 	; BL = open mode & status flag (0 = read, 1 = write)
 15915                              <1> 	; eax = inode number (ax)
 15916                              <1> 	; 27/03/2020
 15917                              <1> 	; [cdev] = logical drive number 	
 15918                              <1> 
 15919                              <1> 	; 13/05/2015
 15920 00003501 6683F801            <1> 	cmp 	ax, 1
 15921 00003505 721A                <1> 	jb	short rw2
 15922                              <1> 	;
 15923 00003507 890D[886C0000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
 15924                              <1> 				;(in the user's virtual memory space)
 15925 0000350D 8915[8C6C0000]      <1> 	mov	[u.count], edx 
 15926                              <1> 	; 14/05/2015
 15927 00003513 C705[D86C0000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
 15928 0000351B 0000                <1>
 15929                              <1> 
 15930                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 15931                              <1> 	; 27/03/2020 - Retro UNIX 386 v2
 15932 0000351D 80E301              <1> 	and	bl, 1
 15933                              <1> 		; zf = 0 -> open for write	
 15934                              <1> 		; zf = 1 -> open for read
 15935 00003520 C3                  <1> 	retn
 15936                              <1>         	; rts r0
 15937                              <1> rw2:
 15938                              <1> 	; 13/05/2015
 15939 00003521 C705[D86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 15940 00003529 0000                <1>
 15941 0000352B C3                  <1> 	retn
 15942                              <1> 
 15943                              <1> 	; 18/04/2022
 15944                              <1> 	; 08/01/2022
 15945                              <1> 	; 02/01/2022
 15946                              <1> 	; 01/01/2022
 15947                              <1> 	; 27/12/2021
 15948                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility code
 15949                              <1> sysopen: ;<open file>
 15950                              <1> 	; 04/12/2021
 15951                              <1> 	; 07/08/2020 (Retro UNIX 386 v2)
 15952                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 15953                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
 15954                              <1> 	;
 15955                              <1> 	; 'sysopen' opens a file in following manner:
 15956                              <1> 	;    1) The second argument in a sysopen says whether to
 15957                              <1> 	;	open the file ro read (0) or write (>0).
 15958                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
 15959                              <1> 	;    3) The file is opened by 'iopen'.
 15960                              <1> 	;    4) Next housekeeping is performed on the fsp table
 15961                              <1> 	;	and the user's open file list - u.fp.
 15962                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
 15963                              <1> 	;	b) An entry for the file is created in the fsp table.
 15964                              <1> 	;	c) The number of this entry is put on u.fp list.
 15965                              <1> 	;	d) The file descriptor index to u.fp list is pointed
 15966                              <1> 	;	   to by u.r0.
 15967                              <1> 	;
 15968                              <1> 	; Calling sequence:
 15969                              <1> 	;	sysopen; name; mode
 15970                              <1> 	; Arguments:
 15971                              <1> 	;	name - file name or path name
 15972                              <1> 	;	mode - 0 to open for reading
 15973                              <1> 	;	       1 to open for writing
 15974                              <1> 	; Inputs: (arguments)
 15975                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
 15976                              <1> 	;		  is put into r0's location on the stack.	
 15977                              <1> 	; ...............................................................
 15978                              <1> 	;				
 15979                              <1> 	; Retro UNIX 8086 v1 modification: 
 15980                              <1> 	;       'sysopen' system call has two arguments; so,
 15981                              <1> 	;	* 1st argument, name is pointed to by BX register
 15982                              <1> 	;	* 2nd argument, mode is in CX register
 15983                              <1> 	;
 15984                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15985                              <1> 	;	to the user with the file descriptor/number 
 15986                              <1> 	;	(index to u.fp list).
 15987                              <1> 	;
 15988                              <1> 	;call	arg2
 15989                              <1> 	; * name - 'u.namep' points to address of file/path name
 15990                              <1> 	;          in the user's program segment ('u.segmnt')
 15991                              <1> 	;          with offset in BX register (as sysopen argument 1).
 15992                              <1> 	; * mode - sysopen argument 2 is in CX register 
 15993                              <1> 	;          which is on top of stack.
 15994                              <1> 	;
 15995                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
 15996                              <1> 	;
 15997                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
 15998                              <1> 
 15999 0000352C 891D[806C0000]      <1> 	mov	[u.namep], ebx
 16000 00003532 51                  <1> 	push	ecx ; * ; 04/12/2021 (cx -> ecx)
 16001 00003533 E8400B0000          <1> 	call	namei
 16002                              <1> 		; jsr r0,namei / i-number of file in r1
 16003                              <1>      	;and	ax, ax
 16004                              <1> 	;jz	error ; File not found
 16005 00003538 722B                <1> 	jc	short fnotfound ; 14/05/2015
 16006                              <1> 	;jc	error ; 27/05/2013
 16007                              <1> 		; br  error2 / file not found
 16008                              <1>    	;pop	edx ; * ; mode ; 04/12/2021
 16009                              <1> 	;push	edx ; *
 16010                              <1> 	;;or	dx, dx
 16011                              <1> 	;or	dl, dl
 16012                              <1> 	;	; tst (sp) / is mode = 0 (2nd arg of call;
 16013                              <1> 	;	         ; / 0 means, open for read)
 16014                              <1> 	;;jz	short sysopen_0
 16015                              <1> 	;;	; beq 1f / yes, leave i-number positive
 16016                              <1> 	
 16017 0000353A 8B1424              <1> 	mov	edx, [esp] ; *
 16018                              <1> 	; edx = open mode (0 or 1)
 16019                              <1> 
 16020                              <1> ;syscreat_0: ;op0: ; 27/12/2015
 16021                              <1> ;	neg	ax
 16022                              <1> ;        	; neg r1 / open for writing so make i-number negative
 16023                              <1> 
 16024                              <1> sysopen_0: ;1:
 16025 0000353D E8A0200000          <1> 	call	iopen
 16026                              <1> 		; jsr r0,iopen / open file whose i-number is in r1
 16027 00003542 5A                  <1> 	pop	edx ; * ; mode ; 04/12/2021
 16028                              <1> 	;;and	dx, dx
 16029                              <1> 	;and	dl, dl
 16030                              <1>         ;	; tst (sp)+ / pop the stack and test the mode
 16031                              <1> 	;jz	short sysopen_2
 16032                              <1>         ;	; beq op1 / is open for read op1
 16033                              <1> ;sysopen_1: ;op0:
 16034                              <1> 	;neg	ax
 16035                              <1>         ;	; neg r1 
 16036                              <1> 	;	     ;/ make i-number positive if open for writing [???]
 16037                              <1> 
 16038                              <1> 	;; NOTE: iopen always make i-number positive.
 16039                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
 16040                              <1> sysopen_1: ; 04/12/2021
 16041                              <1> sysopen_2: ;op1:
 16042 00003543 31F6                <1>         xor     esi, esi
 16043                              <1>         	; clr r2 / clear registers
 16044 00003545 31DB                <1>         xor     ebx, ebx
 16045                              <1> 		; clr r3
 16046                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
 16047 00003547 389E[6E6C0000]      <1>         cmp     [esi+u.fp], bl ; 0
 16048                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
 16049 0000354D 7625                <1> 	jna	short sysopen_4
 16050                              <1> 		; beq 1f / if byte in list is 0 branch
 16051 0000354F 46                  <1>         inc     esi
 16052                              <1> 		; inc r2 / bump r2 so next byte can be checked
 16053                              <1> 	; 02/01/2022
 16054                              <1> 	;cmp	si, OPENFILES ; 04/12/2021
 16055 00003550 6683FE0A            <1> 	cmp	si, 10
 16056                              <1> 		; cmp r2,$10. / reached end of list?
 16057 00003554 72F1                <1> 	jb	short sysopen_3
 16058                              <1> 		; blt 1b / no, go back
 16059                              <1> toomanyf:
 16060                              <1> 	; 14/05/2015
 16061 00003556 C705[D86C0000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
 16062 0000355E 0000                <1>
 16063 00003560 E9FCFBFFFF          <1> 	jmp	error
 16064                              <1>         	; br error2 / yes, error (no files open)
 16065                              <1> fnotfound: 
 16066                              <1> 	; 14/05/2015
 16067 00003565 C705[D86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
 16068 0000356D 0000                <1>
 16069 0000356F E9EDFBFFFF          <1> 	jmp	error
 16070                              <1> 
 16071                              <1> sysopen_4: ; 1:
 16072 00003574 6683BB[D4680000]00  <1>         cmp     word [ebx+fsp], 0
 16073                              <1> 		; tst fsp(r3) / scan fsp entries
 16074 0000357C 760D                <1>         jna     short sysopen_5
 16075                              <1> 		; beq 1f / if 0 branch
 16076                              <1> 	;; 14/05/2015 - Retro UNIX 386 v1 modification !
 16077                              <1> 	;add	bx, 10 ; fsp structure size = 10 bytes/entry
 16078                              <1> 		; add $8.,r3 / add 8 to r3 
 16079                              <1> 			; / to bump it to next entry mfsp table
 16080                              <1> 	; 01/01/2022
 16081                              <1> 	; 07/08/2020 - Retro UNIX 386 v2
 16082 0000357E 6683C310            <1> 	add	bx, 16 ; fsp structure size = 16 bytes/entry ; runix v2
 16083                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 16084                              <1> 	;add	bx, fp.size
 16085                              <1> 
 16086                              <1> 	; 22/11/2021
 16087                              <1> 	;cmp	bx, NFILES*fp.size ; NFILES*16
 16088                              <1> 	; 02/01/2022
 16089 00003582 6681FB2003          <1> 	cmp	bx, nfiles*16
 16090                              <1> 	; 01/01/2022
 16091                              <1> 	;cmp	bx, NFILES*16 ; NFILES*fp.size
 16092                              <1> 	;;cmp	bx, nfiles*10
 16093                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
 16094 00003587 72EB                <1> 	jb	short sysopen_4
 16095                              <1>        		; blt 1b / no, back
 16096                              <1> 	;jmp	error
 16097                              <1>         ;	; br error2 / yes, error
 16098                              <1> 	; 04/12/2021
 16099                              <1> 	; 07/08/2020
 16100 00003589 EBCB                <1> 	jmp	short toomanyf
 16101                              <1> 
 16102                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
 16103 0000358B 668983[D4680000]    <1>         mov     [ebx+fsp], ax
 16104                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
 16105                              <1> 			; / into next available entry in fsp table,
 16106                              <1> 	;mov	di, [cdev] ; word ? byte ?
 16107                              <1>         ;mov	[ebx+fsp+2], di ; device number
 16108                              <1> 	;	; mov cdev,fsp+2(r3) / put # of device in next word
 16109                              <1> 
 16110                              <1> 	; 18/04/2022
 16111                              <1> 	; 04/12/2021        
 16112                              <1> 	;mov	al, [cdev]
 16113                              <1> 	;mov	ah, dl ; open mode, 0 = read, 1 = write
 16114                              <1> 	;mov	[ebx+fsp+4], ax ; device number & open mode
 16115                              <1> 
 16116                              <1> 	;xor	edi, edi
 16117                              <1>         ;mov	[ebx+fsp+4], edi ; offset pointer (0)
 16118                              <1> 	;	; clr fsp+4(r3)
 16119                              <1>         ;mov	[ebx+fsp+8], di ; open count (0), deleted flag (0)
 16120                              <1>        	;	; clr fsp+6(r3) / clear the next two words
 16121                              <1> 
 16122                              <1> 	; 04/12/2021 
 16123 00003592 31C0                <1> 	xor	eax, eax
 16124 00003594 8983[DC680000]      <1>   	mov	[ebx+fsp+8], eax ; offset pointer = 0
 16125                              <1> 
 16126                              <1> 	;;inc	word [ebx+fsp+6]
 16127                              <1> 	;inc	byte [ebx+fsp+6] ; open count = open count + 1	
 16128                              <1> 	; 18/04/2022
 16129                              <1> 	;mov	word [ebx+fsp+6], ax ; open count = 0 
 16130                              <1> 				     ; (sysfork increases open count)
 16131                              <1> 	; 18/04/2022		     ; reserved (mnt) flag = 0
 16132 0000359A A0[416C0000]        <1> 	mov	al, [cdev]
 16133 0000359F 88D4                <1> 	mov	ah, dl ; open mode, 0 = read, 1 = write
 16134 000035A1 8983[D8680000]      <1> 	mov	[ebx+fsp+4], eax ; device number (al)
 16135                              <1> 				 ; & open mode (ah)
 16136                              <1> 				 ; (& open count = 0)
 16137                              <1>   	;mov	eax, ebx
 16138                              <1> 	;mov	bl, 10
 16139                              <1> 	;div	bl 
 16140                              <1> 	;	; asr r3
 16141                              <1> 	;	; asr r3 / divide by 8 
 16142                              <1> 	;	; asr r3 ; / to get number of the fsp entry-1
 16143                              <1> 	;inc	al
 16144                              <1>         ;	; inc r3 / add 1 to get fsp entry number
 16145                              <1>         ;mov	[esi+u.fp], al
 16146                              <1> 	;	; movb r3,u.fp(r2) / move entry number into 
 16147                              <1> 			; / next available slot in u.fp list
 16148                              <1> 	; 04/12/2021
 16149 000035A7 C1EB04              <1> 	shr	ebx, 4	; / 16
 16150                              <1> 	;shr	bx, 4	; bx = fsp entry number (index)	
 16151                              <1> 			; bx <= 49 for current runix 386 version
 16152 000035AA FEC3                <1> 	inc 	bl	; bl = 1 to 50
 16153 000035AC 889E[6E6C0000]      <1> 	mov	[esi+u.fp], bl 	
 16154                              <1> 
 16155 000035B2 8935[646C0000]      <1>         mov     [u.r0], esi
 16156                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
 16157                              <1> 			     ; / into r0 loc on stack
 16158 000035B8 E9C4FBFFFF          <1>         jmp	sysret
 16159                              <1> 		; br sysret2
 16160                              <1> 
 16161                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
 16162                              <1> ;
 16163                              <1> ;         15                    7                   0
 16164                              <1> ;  1     |-------------------------------------------|
 16165                              <1> ;        |   	     i-number of open file           |
 16166                              <1> ;        |-------------------------------------------| 
 16167                              <1> ;        |        high word of 32 bit i-number       |
 16168                              <1> ;        |-------------------------------------------|
 16169                              <1> ;        | open mode & status  |   device number     |
 16170                              <1> ;        |-------------------------------------------|			
 16171                              <1> ;        |    reserved byte    |     open count      |
 16172                              <1> ;        |-------------------------------------------| 
 16173                              <1> ;        | offset pointer, i.e., r/w pointer to file |
 16174                              <1> ;        |-------------------------------------------|
 16175                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
 16176                              <1> ;        |-------------------------------------------|
 16177                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
 16178                              <1> ;        |-------------------------------------------|
 16179                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
 16180                              <1> ;        |-------------------------------------------|
 16181                              <1> ;  2     |                                           |
 16182                              <1> ;        |-------------------------------------------| 
 16183                              <1> ;        |                                           |
 16184                              <1> ;        |-------------------------------------------|
 16185                              <1> ;        |                                           |
 16186                              <1> ;        |-------------------------------------------|
 16187                              <1> ;        |                                           |
 16188                              <1> ;        |-------------------------------------------| 
 16189                              <1> ;        |                                           | 
 16190                              <1> 
 16191                              <1> 	;
 16192                              <1> 	; 'fsp' table (10 bytes/entry)
 16193                              <1> 	; bit 15				   bit 0
 16194                              <1> 	; ---|-------------------------------------------
 16195                              <1> 	; r/w|		i-number of open file
 16196                              <1> 	; ---|-------------------------------------------
 16197                              <1> 	;		   device number
 16198                              <1> 	; -----------------------------------------------
 16199                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 16200                              <1> 	; -----------------------------------------------
 16201                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 16202                              <1> 	; ----------------------|------------------------
 16203                              <1> 	;  flag that says file 	| number of processes
 16204                              <1> 	;   has been deleted	| that have file open 
 16205                              <1> 	; ----------------------|------------------------
 16206                              <1> 	;
 16207                              <1> 
 16208                              <1> 	; 12/03/2022
 16209                              <1> 	; 11/02/2022
 16210                              <1> 	; 01/01/2022
 16211                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16212                              <1> syscreat: ; < create file >
 16213                              <1> 	; 12/03/2022
 16214                              <1> 	; 11/02/2022
 16215                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16216                              <1> 	; 04/04/2021
 16217                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
 16218                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
 16219                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16220                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
 16221                              <1> 	;
 16222                              <1> 	; 'syscreat' called with two arguments; name and mode.
 16223                              <1> 	; u.namep points to name of the file and mode is put
 16224                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
 16225                              <1> 	; If the file aready exists, it's mode and owner remain 
 16226                              <1> 	; unchanged, but it is truncated to zero length. If the file
 16227                              <1> 	; did not exist, an i-node is created with the new mode via
 16228                              <1> 	; 'maknod' whether or not the file already existed, it is
 16229                              <1> 	; open for writing. The fsp table is then searched for a free
 16230                              <1> 	; entry. When a free entry is found, proper data is placed
 16231                              <1> 	; in it and the number of this entry is put in the u.fp list.
 16232                              <1> 	; The index to the u.fp (also know as the file descriptor)
 16233                              <1> 	; is put in the user's r0. 			
 16234                              <1> 	;
 16235                              <1> 	; Calling sequence:
 16236                              <1> 	;	syscreate; name; mode
 16237                              <1> 	; Arguments:
 16238                              <1> 	;	name - name of the file to be created
 16239                              <1> 	;	mode - mode of the file to be created
 16240                              <1> 	; Inputs: (arguments)
 16241                              <1> 	; Outputs: *u.r0 - index to u.fp list 
 16242                              <1> 	;		   (the file descriptor of new file)
 16243                              <1> 	; ...............................................................
 16244                              <1> 	;				
 16245                              <1> 	; Retro UNIX 8086 v1 modification: 
 16246                              <1> 	;       'syscreate' system call has two arguments; so,
 16247                              <1> 	;	* 1st argument, name is pointed to by BX register
 16248                              <1> 	;	* 2nd argument, mode is in CX register
 16249                              <1> 	;
 16250                              <1> 	;	AX register (will be restored via 'u.r0') will return
 16251                              <1> 	;	to the user with the file descriptor/number 
 16252                              <1> 	;	(index to u.fp list).
 16253                              <1> 	;
 16254                              <1> 	;call	arg2
 16255                              <1> 	; * name - 'u.namep' points to address of file/path name
 16256                              <1> 	;          in the user's program segment ('u.segmnt')
 16257                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16258                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16259                              <1> 	;          which is on top of stack.
 16260                              <1> 	;
 16261                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
 16262                              <1> 			    ; / on stack
 16263 000035BD 891D[806C0000]      <1> 	mov	[u.namep], ebx ; file name address
 16264                              <1> 	;push	cx ; mode
 16265                              <1> 	; 04/12/2021
 16266 000035C3 51                  <1> 	push	ecx ; cx = mode (permission flags)
 16267 000035C4 E8AF0A0000          <1> 	call 	namei        	
 16268                              <1> 		; jsr r0,namei / get the i-number
 16269                              <1>         ;and	ax, ax
 16270                              <1> 	;jz	short syscreat_1	       	
 16271 000035C9 7216                <1> 	jc	short syscreat_1
 16272                              <1> 		; br 2f / if file doesn't exist 2f
 16273                              <1> 	; 27/12/2015
 16274                              <1> 	;cmp	ax, 41 ; device inode ?
 16275                              <1>         ;jb	syscreat_0 ; yes
 16276                              <1> 	;
 16277                              <1> 	;neg 	ax
 16278                              <1>         ;	; neg r1 / if file already exists make i-number 
 16279                              <1> 		       ; / negative (open for writing)
 16280                              <1> 	; 11/02/2022
 16281                              <1> 	; Truncate existing file
 16282                              <1> ;syscreate_2:
 16283                              <1> 	;; 27/03/2021
 16284                              <1> 	;;xor	edx, edx ; 0
 16285                              <1> 	;;inc	dl ; DL = 1 ; create/truncate (open for write)
 16286                              <1> 	;mov	dl, 1
 16287                              <1> 	; 11/02/2022
 16288 000035CB B202                <1> 	mov	dl, 2 ; create file (call from syscreat)
 16289 000035CD E810200000          <1> 	call	iopen
 16290                              <1>          	; jsr r0,iopen
 16291                              <1> 	; 11/02/2022
 16292                              <1> 	; cpu will return here if inode in eax is regular file inode
 16293                              <1> 	; (if it is device or dir inode, cpu will jumpt to 'error')
 16294                              <1> 	;
 16295                              <1> 	; 12/03/2022
 16296 000035D2 50                  <1> 	push	eax ; * ; save inode number
 16297                              <1> 	; 
 16298                              <1> 	; truncate file to zero length
 16299                              <1> 	;call	itrunc
 16300                              <1>         	; jsr r0,itrunc / truncate to 0 length
 16301                              <1> 	; 11/02/2022
 16302                              <1> 	; (iget and regular file check -in 'itrunc'- is not needed) 
 16303 000035D3 E891170000          <1> 	call	itrunc_1
 16304                              <1> 	; 12/03/2022
 16305 000035D8 58                  <1> 	pop	eax ; * ; restore inode number in eax
 16306                              <1> 	;
 16307                              <1> 	;pop	cx ; pop mode (did not exist in original Unix v1 !?)
 16308                              <1> 	; 04/12/2021
 16309 000035D9 59                  <1> 	pop	ecx
 16310                              <1> syscreat_2:
 16311 000035DA B201                <1> 	mov	dl, 1 ; open for writing
 16312 000035DC E962FFFFFF          <1>         jmp     sysopen_1
 16313                              <1>         	; br op0
 16314                              <1> syscreat_1: ; 2: / file doesn't exist
 16315                              <1> 	;pop	ax
 16316                              <1>         ;	; mov (sp)+,r1 / put the mode in r1
 16317                              <1> 	; 27/03/2021
 16318 000035E1 58                  <1> 	pop	eax  ; ax = mode (permission flags)
 16319                              <1> 	;xor	ah, ah	
 16320                              <1>         ;	; bic $!377,r1 / clear upper byte
 16321                              <1> 	; 27/03/2021
 16322                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
 16323                              <1> 	; clear bits 15,14,13,12,9 of mode (input from user)
 16324 000035E2 80E40D              <1> 	and	ah, 0Dh ; ISUID (800h) & ISGID (400h) & IREAD (100h)
 16325                              <1> 	; 11/02/2022
 16326 000035E5 80CC80              <1> 	or	ah, 80h	; IFREG (8000h) ; Regular file
 16327 000035E8 E8B40D0000          <1> 	call 	maknod
 16328                              <1>         	; jsr r0,maknod / make an i-node for this file
 16329                              <1> 	;sub	eax, eax ; 04/12/2021
 16330 000035ED 66A1[9C6C0000]      <1> 	mov	ax, [u.dirbuf]
 16331                              <1>         	; mov u.dirbuf,r1 / put i-number 
 16332                              <1> 			        ; / for this new file in r1
 16333                              <1> 	; 04/04/2021
 16334                              <1> 	;mov	dl, 1 ; open for writing
 16335                              <1>         ;
 16336                              <1> 	;jmp	sysopen_1
 16337                              <1>         ;	; br op0 / open the file
 16338                              <1> 	; 04/04/2021
 16339 000035F3 EBE5                <1> 	jmp	short syscreat_2
 16340                              <1> 
 16341                              <1> 	; 11/02/2022
 16342                              <1> 	; 04/12/2021
 16343                              <1> dir_access_err:	; 13/03/2022
 16344                              <1> ;	; 14/05/2015
 16345                              <1> ;	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 16346                              <1> ;f_create_error:
 16347                              <1> 	; 27/03/2021
 16348 000035F5 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; permission denied !	
 16349 000035FD 0000                <1>
 16350 000035FF E95DFBFFFF          <1> 	jmp	error
 16351                              <1> 
 16352                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16353                              <1> sysmkdir: ; < make directory >
 16354                              <1> 	; 13/03/2022
 16355                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16356                              <1> 	; 02/04/2021
 16357                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
 16358                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16359                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16360                              <1> 	;
 16361                              <1> 	; 'sysmkdir' creates an empty directory whose name is
 16362                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
 16363                              <1> 	; The special entries '.' and '..' are not present.
 16364                              <1> 	; Errors are indicated if the directory already exists or		
 16365                              <1> 	; user is not the super user. 
 16366                              <1> 	;
 16367                              <1> 	; Calling sequence:
 16368                              <1> 	;	sysmkdir; name; mode
 16369                              <1> 	; Arguments:
 16370                              <1> 	;	name - points to the name of the directory
 16371                              <1> 	;	mode - mode of the directory
 16372                              <1> 	; Inputs: (arguments)
 16373                              <1> 	; Outputs: -
 16374                              <1> 	;    (sets 'directory' flag to 1; 
 16375                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
 16376                              <1> 	; ...............................................................
 16377                              <1> 	;				
 16378                              <1> 	; Retro UNIX 8086 v1 modification: 
 16379                              <1> 	;       'sysmkdir' system call has two arguments; so,
 16380                              <1> 	;	* 1st argument, name is pointed to by BX register
 16381                              <1> 	;	* 2nd argument, mode is in CX register
 16382                              <1> 	;
 16383                              <1> 		
 16384                              <1> ; / make a directory
 16385                              <1> 
 16386                              <1> 	;call	arg2
 16387                              <1> 	; * name - 'u.namep' points to address of file/path name
 16388                              <1> 	;          in the user's program segment ('u.segmnt')
 16389                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16390                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16391                              <1> 	;          which is on top of stack.
 16392                              <1> 
 16393                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
 16394                              <1> 			    ; / on stack
 16395 00003604 891D[806C0000]      <1> 	mov	[u.namep], ebx
 16396                              <1> 	;push	cx ; mode
 16397                              <1> 	; 27/03/2021
 16398 0000360A 51                  <1> 	push	ecx ; cx = mode
 16399 0000360B E8680A0000          <1> 	call	namei
 16400                              <1>         	; jsr r0,namei / get the i-number
 16401                              <1>         	;     br .+4 / if file not found branch around error
 16402                              <1>         ;xor 	ax, ax
 16403                              <1> 	;jnz	error
 16404 00003610 7334                <1> 	jnc	short dir_exists ; 14/05/2015
 16405                              <1> 	;jnc	error	
 16406                              <1> 		; br error2 / directory already exists (error)
 16407                              <1> 
 16408                              <1> 	;cmp	byte [u.uid], 0 ; 02/08/2013
 16409                              <1>         ;	;tstb u.uid / is user the super user
 16410                              <1> 	;jna	short dir_access_err ; 14/05/2015
 16411                              <1> 	;;jna	error
 16412                              <1>         ;	;bne error2 / no, not allowed
 16413                              <1> 	;pop	ax
 16414                              <1>         ;	;mov (sp)+,r1 / put the mode in r1
 16415                              <1> 	;and	ax, 0FFCFh ; 1111111111001111b
 16416                              <1>         ;	;bic $!317,r1 / all but su and ex
 16417                              <1> 	;;or	ax, 4000h ; 1011111111111111b
 16418                              <1> 	;or	ah, 40h ; Set bit 14 to 1
 16419                              <1>         ; 	;bis $40000,r1 / directory flag
 16420                              <1> 
 16421                              <1> 	; 02/04/2021
 16422                              <1> 	;cmp	word [u.uid], 0
 16423                              <1> 	;;ja	error
 16424                              <1> 	;ja	short dir_access_err
 16425                              <1> 
 16426                              <1> 	; 13/03/2022
 16427                              <1> 	; NOTE:
 16428                              <1> 	; Unix v5-v7 kernels do not allow (ordinary) users
 16429                              <1> 	; (except root/superuser) --if [u.uid] > 0--
 16430                              <1> 	; to make a sub directory. (ref: sys2.c, 'mknod')
 16431                              <1> 	;
 16432                              <1> 	; But, Retro UNIX 386 v1.2 will allow the owner of
 16433                              <1> 	; the parent directory to make a sub directory, here.
 16434                              <1> 
 16435                              <1> 	; 13/03/2022
 16436 00003612 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0
 16437 0000361A 7618                <1> 	jna	short sysmkdir1 ; root (superuser)
 16438                              <1> 
 16439                              <1> 	; Here..
 16440                              <1> 	; (current) inode buffer contains inode structure
 16441                              <1> 	; of the parent directory (at the return of 'namei').
 16442                              <1> 
 16443 0000361C 66A1[E8670000]      <1> 	mov	ax, [i.uid] ; owner ID of the parent dir
 16444 00003622 663B05[B66C0000]    <1> 	cmp	ax, [u.uid] ; user ID of current user/process
 16445 00003629 75CA                <1> 	jne	short dir_access_err
 16446                              <1> 	; 13/03/2022
 16447                              <1> 	; additional checking (may or may not be necessary!?)
 16448 0000362B 663B05[B86C0000]    <1> 	cmp	ax, [u.ruid] 
 16449                              <1> 			; real (login) user ID must be same
 16450 00003632 75C1                <1> 	jne	short dir_access_err
 16451                              <1> 
 16452                              <1> 	; 02/04/2021
 16453                              <1> 	; ('mkdir' procedure will be called from 'maknod'
 16454                              <1> 	; and then 'mkdir' will check write access permission) 
 16455                              <1> 	; ((so, 'access_w' call is not needed here.))
 16456                              <1> 
 16457                              <1> 	;; 02/04/2021
 16458                              <1> 	;; ('make directory' user permission check)
 16459                              <1> 	;; ((current directory's write permission flags
 16460                              <1> 	;;  will be checked against user's 'uid' & gid'))
 16461                              <1> 	;mov	dx, 80h ; IWRITE
 16462                              <1> 	;call	access_w  ; (in 'access', 'u5.s')
 16463                              <1> 	;; (If cpu will return here, the user has write permission)
 16464                              <1> 
 16465                              <1> sysmkdir1:
 16466                              <1> 	; 27/03/2021
 16467 00003634 58                  <1> 	pop	eax  ; ax = mode
 16468                              <1> 	; [ii] = current directory's inode number
 16469                              <1> 
 16470                              <1> 	; 27/03/2021
 16471                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
 16472                              <1> 	; clear bits 13,12,11,10,9,6,3,0 of mode (input from user)
 16473                              <1> 	;and	ax, 0C1B6h ; bits 15,14,8,7,5,4,2,1
 16474 00003635 6625B601            <1> 	and	ax, 01B6h
 16475 00003639 80CCC0              <1> 	or	ah, 0C0h ; IFREG (8000h) + IFDIR (4000h) 
 16476                              <1> 			 ; Directory
 16477 0000363C E8600D0000          <1> 	call	maknod
 16478                              <1>         	;jsr r0,maknod / make the i-node for the directory
 16479 00003641 E93BFBFFFF          <1> 	jmp	sysret
 16480                              <1>         	;br sysret2 /
 16481                              <1> dir_exists:
 16482                              <1> 	; 27/03/2021
 16483                              <1> 	; (same error number for files and directories)
 16484                              <1> 	; Error Number: 14 (ERR_DIR_EXISTS)
 16485 00003646 C705[D86C0000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS
 16486 0000364E 0000                <1>
 16487                              <1> 				; 'file already exists !' error
 16488                              <1> 	; 04/12/2021
 16489 00003650 E90CFBFFFF          <1> 	jmp	error
 16490                              <1> ;dir_access_err:
 16491                              <1> ;	; 14/05/2015
 16492                              <1> ;	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 16493                              <1> ;	jmp	error
 16494                              <1> 
 16495                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16496                              <1> sysclose: ;<close file>
 16497                              <1> 	; 02/03/2022
 16498                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16499                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16500                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
 16501                              <1> 	;
 16502                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
 16503                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
 16504                              <1> 	; is put in r1 and 'fclose' is called.
 16505                              <1> 	;
 16506                              <1> 	; Calling sequence:
 16507                              <1> 	;	sysclose
 16508                              <1> 	; Arguments:
 16509                              <1> 	;	-  
 16510                              <1> 	; Inputs: *u.r0 - file descriptor
 16511                              <1> 	; Outputs: -
 16512                              <1> 	; ...............................................................
 16513                              <1> 	;				
 16514                              <1> 	; Retro UNIX 8086 v1 modification:
 16515                              <1> 	;	 The user/application program puts file descriptor
 16516                              <1> 	;        in BX register as 'sysclose' system call argument.
 16517                              <1> 	; 	 (argument transfer method 1)
 16518                              <1> 
 16519                              <1> 	; / close the file
 16520                              <1> 	
 16521                              <1> 	;mov 	eax, ebx
 16522                              <1> 	; 04/12/2021
 16523                              <1> 	; ebx = file descriptor/number
 16524                              <1> 	;call 	fclose
 16525                              <1> 	; 02/03/2022
 16526 00003655 E8A2090000          <1> 	call	_fclose
 16527                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
 16528                              <1> 		; jsr r0,fclose / close the file
 16529                              <1>                	; br error2 / unknown file descriptor
 16530                              <1> 		; br sysret2
 16531                              <1> 	;; 14/05/2015
 16532                              <1> 	;jnc	sysret
 16533                              <1> 	; 04/12/2021
 16534 0000365A 7205                <1> 	jc	short sysclose_err
 16535 0000365C E920FBFFFF          <1> 	jmp	sysret
 16536                              <1> sysclose_err:
 16537 00003661 C705[D86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 16538 00003669 0000                <1>
 16539 0000366B E9F1FAFFFF          <1> 	jmp	error
 16540                              <1> 
 16541                              <1> 	; 23/02/2022
 16542                              <1> 	; 19/12/2021
 16543                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16544                              <1> sysemt:
 16545                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16546                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16547                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
 16548                              <1> 	;
 16549                              <1> 	; Retro UNIX 8086 v1 modification: 
 16550                              <1> 	;	'Enable Multi Tasking' system call instead 
 16551                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
 16552                              <1> 	;
 16553                              <1> 	; Retro UNIX 8086 v1 feature only!
 16554                              <1> 	;	Using purpose: Kernel will start without time-out
 16555                              <1> 	;	(internal clock/timer) functionality.
 16556                              <1> 	;	Then etc/init will enable clock/timer for
 16557                              <1> 	;	multi tasking. (Then it will not be disabled again
 16558                              <1> 	;	except hardware reset/restart.)
 16559                              <1> 	;
 16560                              <1> 	
 16561                              <1> 	;cmp	byte [u.uid], 0 ; root ?
 16562                              <1> 	;;ja	error
 16563                              <1> 	;ja	badsys ; 14/05/2015
 16564                              <1> 	; 04/12/2021
 16565 00003670 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0 ; root ?
 16566 00003678 7605                <1> 	jna	short emt_0 
 16567 0000367A E994FBFFFF          <1> 	jmp	badsys
 16568                              <1> emt_0:
 16569 0000367F FA                  <1> 	cli	; 23/02/2022
 16570 00003680 21DB                <1> 	and	ebx, ebx
 16571 00003682 7429                <1> 	jz	short emt_2
 16572                              <1> 	; Enable multi tasking -time sharing-
 16573 00003684 B8[12470000]        <1> 	mov	eax, clock ; enable multi tasking clock/timer
 16574                              <1> 	; 23/02/2022
 16575 00003689 BA[440A0000]        <1> 	mov	edx, rtci_default ; disable rtc (digital) printing
 16576                              <1> emt_1:
 16577 0000368E A3[09070000]        <1> 	mov	[x_timer], eax
 16578                              <1> 	; 23/02/2022 (Temporary)
 16579 00003693 8915[0D070000]      <1> 	mov	[x_rtci], edx
 16580 00003699 B306                <1> 	mov	bl, 6  ; timer interrupt page, video page 6
 16581 0000369B E855020000          <1> 	call	wttyc  ; clear video page
 16582 000036A0 B307                <1> 	mov	bl, 7  ; rtc interrupt page, video page 7
 16583 000036A2 E84E020000          <1> 	call	wttyc  ; clear video page
 16584                              <1> 	;
 16585 000036A7 FB                  <1> 	sti	; 23/02/2022
 16586 000036A8 E9D4FAFFFF          <1> 	jmp	sysret
 16587                              <1> emt_2:
 16588                              <1> 	; Disable multi tasking -time sharing-
 16589 000036AD B8[15070000]        <1> 	mov	eax, u_timer ; enable timer tick printing
 16590                              <1> 	; 23/02/2022
 16591 000036B2 BA[4B0A0000]        <1> 	mov	edx, rtc_p   ; enable rtc (digital) printing
 16592                              <1> 	;
 16593 000036B7 EBD5                <1> 	jmp	short emt_1
 16594                              <1> 
 16595                              <1> 	; Original UNIX v1 'sysemt' routine
 16596                              <1> ;sysemt:
 16597                              <1>         ;
 16598                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
 16599                              <1> 			 ; / in loc 30
 16600                              <1>         ;cmp    30,$core / was the argument a lower address 
 16601                              <1> 			; / than core
 16602                              <1>         ;blo    1f / yes, rtssym
 16603                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
 16604                              <1> 			; / and less than "ecore"
 16605                              <1>         ;blo    2f / yes, sysret2
 16606                              <1> ;1:
 16607                              <1>         ;mov    $rtssym,30
 16608                              <1> ;2:
 16609                              <1>         ;br     sysret2
 16610                              <1> 
 16611                              <1> sysilgins:
 16612                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16613                              <1> 	; 03/06/2013
 16614                              <1> 	; Retro UNIX 8086 v1 modification: 
 16615                              <1> 	;	not a valid system call ! (not in use)
 16616                              <1> 	;
 16617 000036B9 E955FBFFFF          <1> 	jmp	badsys
 16618                              <1> 	;jmp	error
 16619                              <1> 	;;jmp 	sysret
 16620                              <1> 
 16621                              <1> 	; Original UNIX v1 'sysemt' routine
 16622                              <1> ;sysilgins: / calculate proper illegal instruction trap address
 16623                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
 16624                              <1> 			  ;/ put it in loc 8.,
 16625                              <1>         ;cmp    10,$core / making it the illegal instruction 
 16626                              <1> 		       ; / trap address
 16627                              <1>         ;blo    1f / is the address a user core address?  
 16628                              <1> 		; / yes, go to 2f
 16629                              <1>         ;cmp    10,$ecore
 16630                              <1>         ;blo    2f
 16631                              <1> ;1:
 16632                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
 16633                              <1> 		    ; / instruction trap address for the system
 16634                              <1> ;2:
 16635                              <1>         ;br     sysret2 / return to the caller via 'sysret'
 16636                              <1> 
 16637                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16638                              <1> sysmdate: ; < change the modification time of a file >
 16639                              <1> 	; 23/02/2022 (Retro UNIX 386 v1 feature/modification)
 16640                              <1> 	;	(ECX input)
 16641                              <1> 	; 24/12/2021
 16642                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16643                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 16644                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16645                              <1> 	;
 16646                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
 16647                              <1> 	; file into core. The user is checked if he is the owner 
 16648                              <1> 	; or super user. If he is neither an error occurs.
 16649                              <1> 	; 'setimod' is then called to set the i-node modification
 16650                              <1> 	; byte and the modification time, but the modification time
 16651                              <1> 	; is overwritten by whatever get put on the stack during
 16652                              <1> 	; a 'systime' system call. This calls are restricted to
 16653                              <1> 	; the super user.		
 16654                              <1> 	;
 16655                              <1> 	; Calling sequence:
 16656                              <1> 	;	sysmdate; name
 16657                              <1> 	; Arguments:
 16658                              <1> 	;	name - points to the name of file
 16659                              <1> 	; Inputs: (arguments)
 16660                              <1> 	; Outputs: -
 16661                              <1> 	; ...............................................................
 16662                              <1> 	;				
 16663                              <1> 	; Retro UNIX 8086 v1 modification: 
 16664                              <1> 	;	 The user/application program puts address 
 16665                              <1> 	;	 of the file name in BX register 
 16666                              <1> 	;	 as 'sysmdate' system call argument.
 16667                              <1> 	;
 16668                              <1> ; / change the modification time of a file
 16669                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
 16670 000036BE 891D[806C0000]      <1>         mov	[u.namep], ebx
 16671                              <1> 	; 23/02/2022 - (Retro UNIX 386 v1 modification on unix v1 code)
 16672 000036C4 890D[70670000]      <1> 	mov	[p_time], ecx ; save new modification time to be set 
 16673 000036CA E8A9090000          <1> 	call	namei
 16674                              <1> 		; jsr r0,namei / get its i-number
 16675                              <1> 	;;jc	error       
 16676                              <1> 	;	; br error2 / no, such file
 16677                              <1> 	;jc	fnotfound ; file not found !
 16678                              <1> 	; 24/12/2021
 16679 000036CF 7305                <1> 	jnc	short mdate_0
 16680 000036D1 E98FFEFFFF          <1> 	jmp	fnotfound
 16681                              <1> mdate_0: 
 16682 000036D6 E896140000          <1> 	call	iget
 16683                              <1> 		; jsr r0,iget / get i-node into core
 16684                              <1> 	;mov	al, [u.uid]
 16685                              <1> 	;cmp	al, [i.uid]
 16686                              <1>         ;	; cmpb u.uid,i.uid / is user same as owner
 16687                              <1> 	;je	short mdate_1
 16688                              <1>         ;	; beq 1f / yes
 16689                              <1> 	;and	al, al
 16690                              <1> 	;	; tstb u.uid / no, is user the super user
 16691                              <1> 	;;jnz	error
 16692                              <1> 	;	; bne error2 / no, error
 16693                              <1> 	;jz	short mdate_1
 16694                              <1> 	; 04/12/2021
 16695 000036DB 66A1[B66C0000]      <1> 	mov	ax, [u.uid]
 16696 000036E1 663B05[E8670000]    <1> 	cmp	ax, [i.uid]
 16697 000036E8 7414                <1> 	je	short mdate_1	
 16698 000036EA 6621C0              <1> 	and	ax, ax
 16699 000036ED 740F                <1> 	jz	short mdate_1
 16700                              <1> 
 16701 000036EF C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 16702 000036F7 0000                <1>
 16703                              <1> sysstty_err:	; 06/02/2022
 16704 000036F9 E963FAFFFF          <1> 	jmp	error
 16705                              <1> mdate_1: ;1:
 16706 000036FE E8FF150000          <1> 	call	setimod
 16707                              <1>         	; jsr r0,setimod / fill in modification data,
 16708                              <1> 		               ; / time etc.
 16709 00003703 BE[70670000]        <1> 	mov	esi, p_time
 16710 00003708 BF[1C680000]        <1> 	mov	edi, i.mtim
 16711 0000370D A5                  <1> 	movsd
 16712                              <1> 		; mov 4(sp),i.mtim / move present time to
 16713                              <1>         	; mov 2(sp),i.mtim+2 / modification time
 16714 0000370E E96EFAFFFF          <1>         jmp	sysret
 16715                              <1> 		; br sysret2
 16716                              <1> 
 16717                              <1> 	; 06/02/2022
 16718                              <1> sysstty_err_s:
 16719 00003713 880D[646C0000]      <1> 	mov	byte [u.r0], cl ; serial port's tty number
 16720 00003719 EBDE                <1> 	jmp	short sysstty_err
 16721                              <1> 
 16722                              <1> sysstty: ; < set tty status and mode >
 16723                              <1> 	; 22/02/2022
 16724                              <1> 	; 21/02/2022
 16725                              <1> 	; 06/02/2022 (Retro UNIX 286 v1.2)
 16726                              <1> 	; 04/02/2022 (Retro UNIX 386 v1.1, Kernel v0.2.1.2)
 16727                              <1> 	; 02/02/2022 (Retro UNIX 386 v1, Kernel v0.2.0.18)
 16728                              <1> 	; 01/02/2022 (Retro UNIX 386 v1) -clear screen-
 16729                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
 16730                              <1> 	;	    ((32 bit reg push/pop))
 16731                              <1> 	; 17/11/2015
 16732                              <1> 	; 12/11/2015
 16733                              <1> 	; 29/10/2015
 16734                              <1> 	; 17/10/2015
 16735                              <1> 	; 13/10/2015
 16736                              <1> 	; 29/06/2015
 16737                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
 16738                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 16739                              <1> 	;
 16740                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
 16741                              <1> 	; whose file descriptor is in (u.r0).
 16742                              <1> 	;
 16743                              <1> 	; Calling sequence:
 16744                              <1> 	;	sysstty; arg
 16745                              <1> 	; Arguments:
 16746                              <1> 	;	arg - address of 3 consequitive words that contain
 16747                              <1> 	;	      the source of status data	
 16748                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
 16749                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 16750                              <1> 	; ...............................................................
 16751                              <1> 	;	
 16752                              <1> 	; Retro UNIX 8086 v1 modification: 
 16753                              <1> 	;	'sysstty' system call will set the tty
 16754                              <1> 	;	(clear keyboard buffer and set cursor position)
 16755                              <1> 	;	 in following manner:
 16756                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
 16757                              <1> 	;
 16758                              <1> 	; Inputs:
 16759                              <1> 	;	BX = 0 --> means
 16760                              <1> 	;	   If CL = FFh (& DX <> 0FFFFh) ; 01/02/2022
 16761                              <1> 	;	      set cursor position for console tty, only 
 16762                              <1> 	;	      CH will be ignored (char. will not be written)
 16763                              <1> 	;	   If CH = 0 (& DX <> 0FFFFh & CL < FFh) ; 01/02/20222
 16764                              <1> 	;	      set console tty for (current) process
 16765                              <1> 	;	      CL = tty number (0 to 9)
 16766                              <1> 	;	      (If CH = 0, character will not be written)
 16767                              <1> 	;          If CH > 0 (CL < FFh)	
 16768                              <1> 	;             CL = tty number (0 to 9)
 16769                              <1> 	;	      CH = character will be written
 16770                              <1> 	;	        at requested cursor position (in DX)
 16771                              <1> 	;	   DX = cursor position for tty number 0 to 7.
 16772                              <1>   	;		(only tty number 0 to 7) 
 16773                              <1> 	;          DL = communication parameters (for serial ports)
 16774                              <1> 	;	        (only for COM1 and COM2 serial ports)
 16775                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
 16776                              <1> 	;			or set cursor position	
 16777                              <1> 	;	   DH = 0FFh -> DL is not valid
 16778                              <1> 	;		do not set serial port parameters 
 16779                              <1> 	;		or do not set cursor position
 16780                              <1> 	;
 16781                              <1> 	;	BX > 0 --> points to name of tty
 16782                              <1> 	;    	   CH > 0 -->
 16783                              <1> 	;		CH = character will be written in current 
 16784                              <1> 	;            	cursor position (for tty number from 0 to 7)
 16785                              <1> 	;	     	or character will be sent to serial port
 16786                              <1> 	;	     	(for tty number 8 or 9)
 16787                              <1> 	;		CL = color of the character if tty number < 8.
 16788                              <1> 	;    	   CH = 0 --> Do not write a character, 
 16789                              <1> 	;		set mode (tty 8 to 9) or 
 16790                              <1> 	;		set current cursor positions (tty 0 to 7) only.
 16791                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
 16792                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
 16793                              <1> 	;		(DL is not valid)
 16794                              <1> 	;	   DL = communication parameters 
 16795                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
 16796                              <1> 	;
 16797                              <1> 	;	01/02/2022 - Retro UNIX 386 v1 - 2022 modification
 16798                              <1> 	;	(30/01/2022 - Retro UNIX 8086 - 2022 modification)
 16799                              <1> 	;	If CH = 0 & DX = 0FFFFh -> 
 16800                              <1> 	;	   clear screen (video page) & set cursor pos to 0,0.
 16801                              <1> 	;	   (for tty number 0 to 7, CL <= 7)
 16802                              <1> 	;	   (if CL = 0FFh -> clear console tty)	
 16803                              <1> 	;
 16804                              <1> 	; Outputs:
 16805                              <1> 	;	cf = 0 -> OK
 16806                              <1> 	;	     AL = tty number (0 to 9)
 16807                              <1> 	;	     AH = line status if tty number is 8 or 9
 16808                              <1> 	;	     AH = process number (of the caller)
 16809                              <1> 	;	cf = 1 means error (requested tty is not ready)
 16810                              <1> 	;	     AH = FFh if the tty is locked 
 16811                              <1> 	;		  (owned by another process)
 16812                              <1> 	;	        = process number (of the caller) 
 16813                              <1> 	;		  (if < FFh and tty number < 8)
 16814                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 16815                              <1> 	;	     AH = line status if tty number is 8 or 9
 16816                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
 16817                              <1> 	;	
 16818                              <1> 
 16819                              <1> 	; 27/06/2015 (32 bit modifications)
 16820                              <1> 	; 14/01/2014
 16821 0000371B 31C0                <1> 	xor 	eax, eax
 16822 0000371D 6648                <1> 	dec	ax ; 17/10/2015
 16823 0000371F A3[646C0000]        <1> 	mov	[u.r0], eax ; 0FFFFh
 16824                              <1> 	;;;
 16825                              <1> 	; 01/02/2022
 16826 00003724 FEC1                <1> 	inc	cl  ; 0FFh -> 0, 7 -> 8
 16827 00003726 39C2                <1> 	cmp	edx, eax
 16828                              <1> 	;cmp	dx, ax ; 0FFFFh
 16829 00003728 7521                <1> 	jne	short sysstty_18
 16830                              <1> 	; clear video page
 16831                              <1> 	; (CH must be 0)
 16832 0000372A 08ED                <1> 	or	ch, ch
 16833 0000372C 75CB                <1> 	jnz	short sysstty_err ; invalid parameters
 16834 0000372E 80F908              <1> 	cmp	cl, 8 ; > tty7 (serial port?)
 16835 00003731 77C6                <1> 	ja	short sysstty_err ; invalid parameters
 16836 00003733 20C9                <1> 	and	cl, cl
 16837 00003735 7514                <1> 	jnz	short sysstty_18 ; actual tty (video page) num + 1
 16838 00003737 0FB635[B56C0000]    <1> 	movzx	esi, byte [u.uno]
 16839 0000373E 8A8E[63680000]      <1> 	mov	cl, byte [esi+p.ttyc-1] ; current/console tty
 16840 00003744 80F907              <1> 	cmp	cl, 7
 16841 00003747 77CA                <1> 	ja	short sysstty_err_s ; serial port !	 
 16842                              <1> 	; here CL contains (actual) tty number (tty0 to tty7) 
 16843 00003749 FEC1                <1> 	inc	cl  ; 0 -> 1, 7 -> 8 
 16844                              <1> sysstty_18:
 16845 0000374B FEC9                <1> 	dec	cl  ; 8 -> 7, 1 -> 0
 16846                              <1> 	; cl = video page (tty) number
 16847                              <1> 	;;;
 16848 0000374D 21DB                <1> 	and	ebx, ebx
 16849                              <1> 	;jnz	sysstty_6
 16850                              <1> 	; 01/02/2022
 16851 0000374F 7405                <1> 	jz	short sysstty_19
 16852 00003751 E9C2000000          <1> 	jmp	sysstty_6
 16853                              <1> sysstty_19:
 16854                              <1> 	; set console tty
 16855                              <1> 	; 29/10/2015
 16856                              <1> 	; 17/01/2014 
 16857 00003756 80F909              <1> 	cmp	cl, 9
 16858 00003759 7613                <1> 	jna	short sysstty_0
 16859                              <1> 	; 17/11/2015
 16860 0000375B 80F9FF              <1> 	cmp	cl, 0FFh
 16861 0000375E 7202                <1> 	jb	short sysstty_13
 16862 00003760 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
 16863                              <1> sysstty_13:
 16864 00003762 8A1D[B56C0000]      <1> 	mov	bl, [u.uno] ; process number
 16865 00003768 8A8B[63680000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
 16866                              <1> sysstty_0:
 16867                              <1> 	; 29/06/2015
 16868 0000376E 52                  <1> 	push	edx ; 24/12/2021
 16869 0000376F 51                  <1> 	push	ecx
 16870 00003770 30D2                <1> 	xor 	dl, dl	; sysstty call sign
 16871 00003772 88C8                <1> 	mov	al, cl
 16872 00003774 A2[646C0000]        <1> 	mov	[u.r0], al ; tty number (0 to 9)
 16873 00003779 E8311F0000          <1> 	call	ottyp
 16874 0000377E 59                  <1> 	pop	ecx
 16875 0000377F 5A                  <1> 	pop	edx
 16876                              <1> 	;
 16877 00003780 7220                <1> 	jc	short sysstty_pd_err
 16878                              <1> 	;
 16879                              <1> 	; 22/02/2022 (Bug!, BugFix)
 16880                              <1> 	; (ebx = ?, modified in ottyp, it may be > 255)
 16881                              <1> 	;
 16882 00003782 80F908              <1> 	cmp	cl, 8
 16883 00003785 720C                <1> 	jb	short sysstty_2
 16884                              <1> 	;
 16885 00003787 80FEFF              <1> 	cmp	dh, 0FFh
 16886 0000378A 7407                <1> 	je	short sysstty_2
 16887                              <1> 
 16888                              <1> ; 01/02/2022
 16889                              <1> ;	; 29/10/2015
 16890                              <1> ;	mov	ah, dl ; communication parameters
 16891                              <1> ;		; ah = 0E3h = 11100011b = 115200 baud,
 16892                              <1> ;		;			 THRE int + RDA int 
 16893                              <1> ;		; ah = 23h = 00100011b = 9600 baud,
 16894                              <1> ;		;			 THRE int + RDA int 
 16895                              <1> ;	sub	al, al ; 0
 16896                              <1> ;	; 12/07/2014
 16897                              <1> ;	cmp	cl, 9
 16898                              <1> ;	jb	short sysstty_1
 16899                              <1> ;	inc	al
 16900                              <1> ;sysstty_1:
 16901                              <1> ;	; 01/02/2022
 16902                              <1> ;	push	ecx
 16903                              <1> ;	; 29/06/2015	
 16904                              <1> ;	call 	sp_setp ; Set serial port communication parameters
 16905                              <1> ;	mov	[u.r0+1], cx ; Line status (ah)
 16906                              <1> ;			     ; Modem status (EAX bits 16 to 23)
 16907                              <1> ;	; 01/02/2022
 16908                              <1> ;	pop	ecx	
 16909                              <1> ;       jc      short sysstty_tmout_err ; 29/10/2015
 16910                              <1> 
 16911                              <1> 	; 01/02/2022
 16912 0000378C E831010000          <1> 	call	sysstty_scp
 16913 00003791 7276                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 16914                              <1> 
 16915                              <1> sysstty_2:
 16916                              <1> 	; 17/01/2014
 16917 00003793 20ED                <1> 	and	ch, ch 	; set cursor position 
 16918                              <1> 			; or comm. parameters ONLY
 16919 00003795 7527                <1> 	jnz	short sysstty_3
 16920                              <1> 	; 01/02/2022
 16921 00003797 6683FAFF            <1> 	cmp	dx, 0FFFFh
 16922 0000379B 7214                <1> 	jb	short sysstty_20
 16923                              <1> 	; clear screen (video page)
 16924 0000379D E93C010000          <1> 	jmp	sysstty_14
 16925                              <1> 
 16926                              <1> sysstty_pd_err: ; 29/06/2015
 16927                              <1> 	; 'permission denied !' error
 16928 000037A2 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
 16929 000037AA 0000                <1>
 16930 000037AC E9B0F9FFFF          <1> 	jmp	error
 16931                              <1> 
 16932                              <1> sysstty_20:
 16933 000037B1 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16934 000037B8 888B[63680000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
 16935                              <1> sysstty_3:
 16936                              <1> 	; 16/01/2014
 16937 000037BE 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
 16938                              <1> 	; 17/11/2015
 16939 000037C0 B507                <1> 	mov 	ch, 7  ; Default color (light gray)
 16940 000037C2 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
 16941                              <1>         ;jna	sysstty_9
 16942                              <1> 	; 24/12/2021
 16943 000037C4 7705                <1> 	ja	short sysstty_12
 16944 000037C6 E9C6000000          <1> 	jmp	sysstty_9
 16945                              <1> 
 16946                              <1> sysstty_12:
 16947                              <1> 	;; BX = 0, CL = 8 or CL = 9
 16948                              <1> 	; (Set specified serial port as console tty port)
 16949                              <1> 	; CH = character to be written
 16950                              <1> 	; 15/04/2014
 16951                              <1> 	; CH = 0 --> initialization only
 16952                              <1> 	; AL = character
 16953                              <1> 	; 26/06/2014
 16954 000037CB 880D[996C0000]      <1> 	mov	[u.ttyn], cl
 16955                              <1> 	; 12/07/2014
 16956 000037D1 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
 16957                              <1> 	; 02/02/2022
 16958 000037D3 FEC0                <1> 	inc	al  ; 0FFh -> 0, 0 -> 1
 16959 000037D5 740B                <1> 	jz	short sysstty_4 ; al = ch = 0
 16960 000037D7 FEC8                <1> 	dec	al  ; 1 -> 0	
 16961                              <1> 	;and	al, al
 16962 000037D9 7407                <1> 	jz	short sysstty_4 ; al = ch = 0
 16963                              <1>  	; 04/07/2014
 16964 000037DB E802240000          <1> 	call 	sndc
 16965                              <1> 	; 12/07/2014
 16966 000037E0 EB0C                <1> 	jmp	short sysstty_5
 16967                              <1> 
 16968                              <1> sysstty_4:
 16969                              <1> 	; 12/07/2014
 16970                              <1> 	;xchg 	ah, al ; al = 0 -> al = ah, ah = 0
 16971 000037E2 88E0                <1> 	mov	al, ah ; 29/06/2015
 16972 000037E4 2C08                <1> 	sub	al, 8
 16973                              <1> 	; 27/06/2015
 16974 000037E6 E8B4F3FFFF          <1> 	call	sp_status ; get serial port status
 16975                              <1> 	; AL = Line status, AH = Modem status
 16976                              <1> 	; 12/11/2015
 16977 000037EB 3C80                <1> 	cmp	al, 80h
 16978 000037ED F5                  <1> 	cmc
 16979                              <1> sysstty_5:
 16980 000037EE 66A3[656C0000]      <1> 	mov	[u.r0+1], ax ; ah = line status
 16981                              <1> 		; EAX bits 16-23 = modem status	
 16982 000037F4 9C                  <1> 	pushf
 16983 000037F5 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16984 000037F7 A0[996C0000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
 16985 000037FC E8E11F0000          <1> 	call	cttyp
 16986 00003801 9D                  <1> 	popf
 16987                              <1> 	;jnc	sysret ; time out error 
 16988                              <1> 	; 01/02/2022
 16989 00003802 7205                <1> 	jc	short sysstty_tmout_err
 16990 00003804 E978F9FFFF          <1> 	jmp	sysret
 16991                              <1> 
 16992                              <1> 	; time out error 
 16993                              <1> sysstty_tmout_err:
 16994 00003809 C705[D86C0000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
 16995 00003811 0000                <1>
 16996 00003813 E949F9FFFF          <1> 	jmp	error
 16997                              <1> 
 16998                              <1> sysstty_6:
 16999 00003818 52                  <1> 	push	edx ; 24/12/2021
 17000 00003819 51                  <1> 	push	ecx
 17001 0000381A 891D[806C0000]      <1> 	mov	[u.namep], ebx
 17002 00003820 E853080000          <1> 	call	namei
 17003 00003825 59                  <1> 	pop	ecx
 17004 00003826 5A                  <1> 	pop	edx
 17005 00003827 7259                <1> 	jc	short sysstty_inv_dn
 17006                              <1> 	;
 17007                              <1> 	; 21/02/2022
 17008                              <1> 	;cmp	ax, 19  ; inode number of /dev/COM2
 17009                              <1> 	;ja	short sysstty_inv_dn ; 27/06/2015
 17010                              <1> 	;;
 17011                              <1> 	;cmp	al, 10 ; /dev/tty0 .. /dev/tty7
 17012                              <1> 	;	       ; /dev/COM1, /dev/COM2
 17013                              <1> 	;jb	short sysstty_7
 17014                              <1> 	;sub	al, 10
 17015                              <1> 	;jmp	short sysstty_8
 17016                              <1> 	;
 17017                              <1> 	; 21/02/2022
 17018                              <1> 	; (Retro UNIX 386 v2 file system inode numbers)
 17019 00003829 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 17020 0000382C 7754                <1> 	ja	short sysstty_inv_dn
 17021                              <1> 	;cmp	al, 8	; /dev/tty inode number is 8
 17022                              <1> 	;jb	short sysstty_inv_dn
 17023 0000382E 2C08                <1> 	sub	al, 8
 17024 00003830 7250                <1> 	jb	short sysstty_inv_dn
 17025 00003832 7408                <1> 	jz	short sysstty_7 ; /dev/tty inode number is 8
 17026                              <1> 	; convert inode number to tty number (tty0 to tty9)
 17027 00003834 2C09                <1> 	sub	al, 9
 17028 00003836 724A                <1> 	jb	short sysstty_inv_dn
 17029                              <1> 	; al = 0 to 9
 17030 00003838 29DB                <1> 	sub	ebx, ebx ; 22/02/2022
 17031 0000383A EB0D                <1> 	jmp	short sysstty_8 
 17032                              <1> sysstty_7:
 17033                              <1> 	; 21/02/2022
 17034                              <1> 	;cmp	al, 1 ; /dev/tty
 17035                              <1> 	;jne	short sysstty_inv_dn ; 27/06/2015
 17036 0000383C 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 17037 00003843 8A83[63680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
 17038                              <1> sysstty_8:
 17039                              <1> 	; 22/02/2022
 17040                              <1> 	; (ebx < 256)	
 17041 00003849 A2[646C0000]        <1> 	mov	[u.r0], al
 17042 0000384E 52                  <1> 	push	edx ; 24/12/2021
 17043 0000384F 50                  <1> 	push	eax
 17044 00003850 51                  <1> 	push	ecx	
 17045 00003851 E8591E0000          <1> 	call	ottyp
 17046 00003856 59                  <1> 	pop	ecx
 17047 00003857 58                  <1> 	pop	eax
 17048 00003858 5A                  <1> 	pop	edx
 17049                              <1>         ;jc	sysstty_pd_err ; 'permission denied !'
 17050                              <1> 	; 06/02/2022
 17051 00003859 7305                <1> 	jnc	short sysstty_21
 17052                              <1> 	; 'permission denied !'
 17053 0000385B E942FFFFFF          <1> 	jmp	sysstty_pd_err
 17054                              <1> sysstty_21:
 17055                              <1> 	; 29/10/2015
 17056 00003860 86E9                <1> 	xchg 	ch, cl
 17057                              <1> 		; cl = character, ch = color code
 17058 00003862 86C1                <1> 	xchg	al, cl
 17059                              <1> 		; al = character, cl = tty number
 17060 00003864 80F907              <1> 	cmp	cl, 7
 17061                              <1> 	;ja	sysstty_12
 17062                              <1> 	; 06/02/2022
 17063 00003867 7628                <1> 	jna	short sysstty_16
 17064                              <1> ;;
 17065 00003869 80FEFF              <1> 	cmp	dh, 0FFh
 17066 0000386C 740B                <1> 	je	short sysstty_22 ; do not set comm. parameters
 17067                              <1> 
 17068                              <1> ; 01/02/2022
 17069                              <1> ;	; 29/10/2015
 17070                              <1> ;	mov	ah, dl ; communication parameters
 17071                              <1> ;		; ah = 0E3h = 11100011b = 115200 baud,
 17072                              <1> ;		;			 THRE int + RDA int 
 17073                              <1> ;		; ah = 23h = 00100011b = 9600 baud,
 17074                              <1> ;		;			 THRE int + RDA int 
 17075                              <1> ;	sub	al, al ; 0
 17076                              <1> ;	; 12/07/2014
 17077                              <1> ;	cmp	cl, 9
 17078                              <1> ;	jb	short sysstty_1
 17079                              <1> ;	inc	al
 17080                              <1> ;sysstty_1:
 17081                              <1> ;	; 01/02/2022
 17082                              <1> ;	push	ecx
 17083                              <1> ;	; 29/06/2015	
 17084                              <1> ;	call 	sp_setp ; Set serial port communication parameters
 17085                              <1> ;	mov	[u.r0+1], cx ; Line status (ah)
 17086                              <1> ;			     ; Modem status (EAX bits 16 to 23)
 17087                              <1> ;	; 01/02/2022
 17088                              <1> ;	pop	ecx	
 17089                              <1> ;       jc      short sysstty_tmout_err ; 29/10/2015
 17090                              <1> 
 17091                              <1> 	; 02/02/2022
 17092 0000386E 88C5                <1> 	mov	ch, al ; save char
 17093                              <1> 	; 01/02/2022
 17094 00003870 E84D000000          <1> 	call	sysstty_scp
 17095 00003875 7292                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 17096                              <1> 	; 02/02/2022
 17097 00003877 88E8                <1> 	mov	al, ch ; restore char
 17098                              <1> sysstty_22:
 17099                              <1> 	; 01/02/2022
 17100 00003879 08ED                <1> 	or	ch, ch
 17101 0000387B 7437                <1> 	jz	short sysstty_11 ; do not send char to terminal
 17102                              <1> 	; send char to (serial port) terminal
 17103                              <1> 	; al = character
 17104                              <1> 	; cl = tty number (8 or 9)
 17105 0000387D E949FFFFFF          <1> 	jmp	sysstty_12 ; (tty8 or tty9)
 17106                              <1> 
 17107                              <1> sysstty_inv_dn: 
 17108                              <1> 	; 27/06/2015
 17109                              <1> 	; Invalid device name (not a tty) ! error
 17110                              <1> 	; (Device is not a tty or device name not found)
 17111 00003882 C705[D86C0000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 17112 0000388A 0000                <1>
 17113 0000388C E9D0F8FFFF          <1> 	jmp	error
 17114                              <1> 
 17115                              <1> sysstty_16:
 17116                              <1> 	; 22/02/2022
 17117                              <1> 	; 16/01/2014
 17118                              <1> 	;xor	bh, bh
 17119                              <1> sysstty_9: 	; tty 0 to tty 7
 17120                              <1> 	; al = character
 17121                              <1> 	; ch = color/attribute ; 01/02/2022
 17122                              <1> 	;
 17123                              <1>  	; 22/02/2022 (BugFix)
 17124                              <1> 	; (ebx may be > 255 here!? due to 'ottyp')
 17125 00003891 29DB                <1> 	sub	ebx, ebx ; *
 17126 00003893 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
 17127                              <1> 	;
 17128 00003895 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
 17129 00003898 7409                <1> 	je	short sysstty_10
 17130                              <1> 	; 24/12/2021
 17131 0000389A 51                  <1> 	push	ecx
 17132 0000389B 50                  <1> 	push	eax
 17133                              <1> 	; 22/02/2022	
 17134                              <1> 	;;movzx	ebx, cl ; *
 17135                              <1> 	;mov	bl, cl ; (tty number = video page number)
 17136 0000389C E81DDBFFFF          <1> 	call	set_cpos
 17137 000038A1 58                  <1> 	pop	eax
 17138 000038A2 59                  <1> 	pop	ecx
 17139                              <1> sysstty_10: 
 17140                              <1> 	; 22/02/2022
 17141                              <1> 	; bl = video page (tty) number 
 17142                              <1> 	;
 17143                              <1> 	; 29/10/2015
 17144 000038A3 08C0                <1> 	or	al, al ; character
 17145 000038A5 740D                <1> 	jz      short sysstty_11 ; al = 0
 17146                              <1> 	; 17/11/2015
 17147 000038A7 3CFF                <1> 	cmp	al, 0FFh
 17148 000038A9 7309                <1> 	jnb	short sysstty_11
 17149                              <1> 		; ch > 0 and ch < FFh
 17150                              <1> 	; write a character at current cursor position
 17151 000038AB 88EC                <1> 	mov	ah, ch ; color/attribute
 17152                              <1> 	; 12/07/2014
 17153 000038AD 51                  <1> 	push	ecx ; 24/12/2021
 17154 000038AE E8F3DBFFFF          <1> 	call	write_c_current
 17155 000038B3 59                  <1> 	pop	ecx
 17156                              <1> sysstty_11:
 17157                              <1> 	; 14/01/2014
 17158 000038B4 30D2                <1> 	xor	dl, dl ; sysstty call sign
 17159                              <1> 	; 18/01/2014
 17160                              <1> 	;movzx	eax, cl ; 27/06/2015
 17161 000038B6 88C8                <1> 	mov	al, cl
 17162 000038B8 E8251F0000          <1> 	call	cttyp
 17163 000038BD E9BFF8FFFF          <1> 	jmp	sysret
 17164                              <1> 
 17165                              <1> 	; 06/02/2022 (Retro UNIX 386 v1.2)
 17166                              <1> sysstty_scp:
 17167                              <1> 	; 02/02/2022
 17168                              <1> 	; set communication parameters (for COM1 or COM2)
 17169                              <1> 	; 01/02/2022
 17170                              <1> 	;
 17171                              <1> 	; 29/10/2015
 17172 000038C2 88D4                <1> 	mov	ah, dl ; communication parameters
 17173                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
 17174                              <1> 		;			 THRE int + RDA int 
 17175                              <1> 		; ah = 23h = 00100011b = 9600 baud,
 17176                              <1> 		;			 THRE int + RDA int 
 17177 000038C4 28C0                <1> 	sub	al, al ; 0
 17178                              <1> 	; 12/07/2014
 17179 000038C6 80F909              <1> 	cmp	cl, 9
 17180 000038C9 7202                <1> 	jb	short sysstty_1
 17181 000038CB FEC0                <1> 	inc	al
 17182                              <1> sysstty_1:
 17183                              <1> 	; 02/02/2022
 17184 000038CD 52                  <1> 	push	edx
 17185                              <1> 	; 01/02/2022
 17186 000038CE 51                  <1> 	push	ecx
 17187                              <1> 	; 29/06/2015	
 17188 000038CF E8D3F2FFFF          <1> 	call 	sp_setp ; Set serial port communication parameters
 17189 000038D4 66890D[656C0000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
 17190                              <1> 			     ; Modem status (EAX bits 16 to 23)
 17191                              <1> 	; 01/02/2022
 17192 000038DB 59                  <1> 	pop	ecx	
 17193 000038DC 5A                  <1> 	pop	edx ; 02/02/2022
 17194                              <1> 	; 01/02/2022
 17195                              <1> 	; if cf = 1 -> sysstty_tmout_err
 17196 000038DD C3                  <1> 	retn
 17197                              <1> 
 17198                              <1> 	; 06/02/2022 (Retro UNIX 386 v1.2)
 17199                              <1> sysstty_14:
 17200                              <1> 	; 23/02/2022
 17201                              <1> 	; 02/02/2022
 17202                              <1> 	; ch = 0
 17203                              <1> 	; cl = video page
 17204                              <1> 	;
 17205                              <1> 	; dx = 0FFFFh
 17206                              <1> 	; clear screen (video page)
 17207                              <1> 	;
 17208                              <1> 
 17209                              <1> 	; 02/02/2022
 17210                              <1> 	; clear screen
 17211                              <1> 	;
 17212                              <1> 	; (modified registers: eax, ebx, ecx, edx, esi, edi)
 17213                              <1> 
 17214                              <1> 	; 23/02/2022
 17215 000038DE 88CB                <1> 	mov 	bl, cl ; CL = tty number (0 to 7)
 17216                              <1> 
 17217                              <1> 	; clear video page
 17218 000038E0 E810000000          <1> 	call	wttyc ; 23/02/2022
 17219                              <1> 
 17220                              <1> 	; 23/02/2022
 17221 000038E5 88D8                <1> 	mov	al, bl
 17222 000038E7 8A25[B56C0000]      <1> 	mov	ah, [u.uno]
 17223 000038ED 66A3[646C0000]      <1> 	mov	[u.r0], ax
 17224 000038F3 EBBF                <1> 	jmp	short sysstty_11
 17225                              <1> 
 17226                              <1> wttyc:
 17227                              <1> 	; 23/02/2022
 17228                              <1> 	; (clear video page)
 17229                              <1> 	; INPUT:
 17230                              <1> 	;  bl = video page (0 to 7)
 17231                              <1> 	;
 17232                              <1> 	; Modified registers: eax, ecx, edx, esi, edi
 17233                              <1> 
 17234                              <1> 	;xor	dx, dx ; column 0, row 0
 17235                              <1> 	;;inc	dx ; 0 ; 23/02/2022
 17236                              <1> 	;
 17237                              <1> ;	movzx	ebx, cl
 17238                              <1> ;	mov 	bl, cl ; CL = tty number (0 to 7) ; 23/02/2022
 17239                              <1> 
 17240                              <1> ;	shl 	bl, 1 
 17241                              <1> ;	mov 	al, byte ptr [ebx+ttyl]
 17242                              <1> ;		; AL = lock value (0 or process number)
 17243                              <1> ;	or	al, al
 17244                              <1> ;	jz	short @f
 17245                              <1> ;	cmp	al, byte ptr [u.uno] ; process number
 17246                              <1> ;	jne	short sysstty_15
 17247                              <1> ;		; only the owner can clear its video page
 17248                              <1> ;	xor	al, al ; 0
 17249                              <1> ;@@:
 17250                              <1> ;	;mov	bl, cl		
 17251                              <1> ;	shr	bl, 1 
 17252                              <1> 
 17253 000038F5 30C0                <1> 	xor	al, al	; 0
 17254 000038F7 B407                <1> 	mov 	ah, 07h	; attribute/color (default)
 17255                              <1> 
 17256                              <1> 	; scroll_up input:
 17257                              <1> 	;
 17258                              <1> 	; al = line count (0 or 1) ((0 == clear video page))
 17259                              <1> 	; 	((al = 1 for write_tty (putc) procedure))
 17260                              <1> 	; ah = attribute to be used on blanked line
 17261                              <1> 	; bl = video page number (0 to 7)
 17262                              <1> 
 17263 000038F9 E846DBFFFF          <1> 	call	scroll_up ; clear video page (al=0)
 17264                              <1> 
 17265                              <1> 	; (modified registers: eax, ecx, edx, esi, edi)
 17266                              <1> 
 17267                              <1> 	; bl = video page number (0 to 7)
 17268                              <1> 	;xor	dx, dx ; column 0, row 0
 17269                              <1> 	; 02/02/2022
 17270 000038FE 31D2                <1> 	xor	edx, edx
 17271                              <1> 	; 23/02/2022
 17272                              <1> 	;call	set_cpos
 17273                              <1> 	;retn
 17274 00003900 E9B9DAFFFF          <1> 	jmp	set_cpos
 17275                              <1> 
 17276                              <1> 	;mov	al, bl
 17277                              <1> 	;mov	ah, [u.uno]
 17278                              <1> 	;mov	[u.r0], ax
 17279                              <1> 	;jmp	short sysstty_11
 17280                              <1> 
 17281                              <1> ;sysstty_15:
 17282                              <1> ;	; 30/01/2022
 17283                              <1> ;	; permission (denied) error
 17284                              <1> ;	;xor	dl, dl ; sysstty call sign
 17285                              <1> ;	mov	al, cl
 17286                              <1> ;	sub	ah, ah ; 0
 17287                              <1> ;	call	cttyp
 17288                              <1> ;	jmp	error
 17289                              <1> 
 17290                              <1> ; Original UNIX v1 'sysstty' routine:
 17291                              <1> ; gtty:
 17292                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
 17293                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
 17294                              <1> 	; 		/ r2 has source
 17295                              <1>         ;mov    r2,-(sp)
 17296                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
 17297                              <1> ;1: / flush the clist wait till typewriter is quiescent
 17298                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
 17299                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
 17300                              <1>         ;mov    $240,*$ps / set processor priority to 5
 17301                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
 17302                              <1>         ;       br .+4 / list empty, skip branch
 17303                              <1>         ;br     1b / get another character until list is empty
 17304                              <1>         ;mov    0b,r1 / move cc offset to r1
 17305                              <1>         ;inc    r1 / bump it for output clist
 17306                              <1>         ;tstb   cc(r1) / is it 0
 17307                              <1>         ;beq    1f / yes, no characters to output
 17308                              <1>  	;mov    r1,0f / no, put offset in sleep arg
 17309                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
 17310                              <1>         ;br     1b / try to calm it down again
 17311                              <1> ;1:
 17312                              <1>         ;mov    (sp)+,r1
 17313                              <1>         ;mov    (sp)+,r2 / restore registers
 17314                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
 17315                              <1>         ;beq    1f / if 0, 1f
 17316                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
 17317                              <1>         ;                   / control status register
 17318                              <1> ;1:
 17319                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
 17320                              <1>         ;beq    1f / if 0 1f
 17321                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
 17322                              <1> 	;		    / control status reg
 17323                              <1> ;1:
 17324                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
 17325                              <1>         ;jmp     sysret2 / return to user
 17326                              <1> 
 17327                              <1> sysgtty: ; < get tty status >
 17328                              <1> 	; 22/02/2022
 17329                              <1> 	; 21/02/2022 
 17330                              <1> 	;	(Retro UNIX 386 v1.2, inode number modifications)
 17331                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
 17332                              <1> 	;	    ((32 bit reg push/pop))
 17333                              <1> 	; 23/11/2015
 17334                              <1> 	; 29/10/2015
 17335                              <1> 	; 17/10/2015
 17336                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
 17337                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 17338                              <1> 	;
 17339                              <1> 	; 'sysgtty' gets the status of tty in question. 
 17340                              <1> 	; It stores in the three words addressed by it's argument
 17341                              <1> 	; the status of the typewriter whose file descriptor
 17342                              <1> 	; in (u.r0).
 17343                              <1> 	;
 17344                              <1> 	; Calling sequence:
 17345                              <1> 	;	sysgtty; arg
 17346                              <1> 	; Arguments:
 17347                              <1> 	;	arg - address of 3 words destination of the status
 17348                              <1> 	; Inputs: ((*u.r0 - file descriptor))
 17349                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 17350                              <1> 	; ...............................................................
 17351                              <1> 	;	
 17352                              <1> 	; Retro UNIX 8086 v1 modification: 
 17353                              <1> 	;	'sysgtty' system call will return status of tty
 17354                              <1> 	;	(keyboard, serial port and video page status)
 17355                              <1> 	;	 in following manner:
 17356                              <1> 	;
 17357                              <1> 	; Inputs:
 17358                              <1> 	;	BX = 0 --> means 
 17359                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
 17360                              <1> 	;	                 for (current) process
 17361                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
 17362                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
 17363                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
 17364                              <1> 	;	     CH > 0 -->	tty number + 1
 17365                              <1> 	;
 17366                              <1> 	;	BX > 0 --> points to name of tty
 17367                              <1> 	;	     CL = 0 --> return keyboard status
 17368                              <1> 	;	     CL = 1 --> return video page status
 17369                              <1> 	;	     CH = undefined		 
 17370                              <1> 	;
 17371                              <1> 	; Outputs:
 17372                              <1> 	;	cf = 0 ->
 17373                              <1> 	;
 17374                              <1> 	;	     AL = tty number from 0 to 9
 17375                              <1> 	;		  (0 to 7 is also the video page of the tty)	
 17376                              <1> 	;	     AH = 0 if the tty is free/unused
 17377                              <1> 	;	     AH = the process number of the caller 
 17378                              <1>  	;	     AH = FFh if the tty is locked by another process
 17379                              <1> 	;
 17380                              <1> 	;	  (if calling is for serial port status)
 17381                              <1> 	;	     BX = serial port status if tty number is 8 or 9
 17382                              <1> 	;		  (BH = modem status, BL = Line status)
 17383                              <1> 	;	     CX = 0FFFFh (if data is ready)
 17384                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
 17385                              <1> 	;
 17386                              <1> 	;	  (if calling is for keyboard status)
 17387                              <1> 	;	     BX = current character in tty/keyboard buffer
 17388                              <1> 	;		  (BH = scan code, BL = ascii code)
 17389                              <1> 	;		  (BX=0 if there is not a waiting character)
 17390                              <1> 	;	     CX  is undefined
 17391                              <1> 	;
 17392                              <1> 	;	  (if calling is for video page status)	
 17393                              <1> 	;	     BX = cursor position on the video page
 17394                              <1> 	;		  if tty number < 8
 17395                              <1> 	;		  (BH = row, BL = column)
 17396                              <1> 	;	     CX = current character (in cursor position)
 17397                              <1> 	;		  on the video page of the tty 
 17398                              <1> 	;		  if tty number < 8
 17399                              <1> 	;		  (CH = color, CL = character)
 17400                              <1> 	;	
 17401                              <1> 	;	cf = 1 means error (requested tty is not ready)
 17402                              <1> 	;
 17403                              <1> 	;	     AH = FFh if the caller is not owner of
 17404                              <1> 	;		  specified tty or console tty
 17405                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 17406                              <1> 	;	     BX, CX are undefined if cf = 1
 17407                              <1> 	;
 17408                              <1> 	;	  (If tty number is 8 or 9)
 17409                              <1> 	;	     AL = tty number 
 17410                              <1> 	;	     AH = the process number of the caller 
 17411                              <1> 	;	     BX = serial port status
 17412                              <1> 	;  		 (BH = modem status, BL = Line status)
 17413                              <1> 	;	     CX = 0
 17414                              <1> 	;
 17415                              <1> 		
 17416                              <1> gtty:   ; get (requested) tty number
 17417                              <1> 	; 22/02/2022
 17418                              <1> 	; 21/02/2022 (Retro UNIX 386 v1.2, inode number modifications)
 17419                              <1> 	; 17/10/2015
 17420                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 17421                              <1> 	; 30/05/2013 - 12/07/2014
 17422                              <1> 	; Retro UNIX 8086 v1 modification ! 
 17423                              <1> 	;
 17424                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
 17425                              <1> 	;
 17426                              <1> 	; 28/06/2015 (32 bit modifications)
 17427                              <1> 	; 16/01/2014
 17428 00003905 31C0                <1> 	xor 	eax, eax
 17429 00003907 6648                <1> 	dec	ax ; 17/10/2015
 17430 00003909 A3[646C0000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
 17431 0000390E 80F901              <1> 	cmp	cl, 1
 17432 00003911 760F                <1> 	jna	short sysgtty_0
 17433                              <1> sysgtty_invp:
 17434                              <1> 	; 28/06/2015
 17435 00003913 C705[D86C0000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 17436 0000391B 0000                <1>
 17437 0000391D E93FF8FFFF          <1> 	jmp	error
 17438                              <1> sysgtty_0:	
 17439 00003922 21DB                <1> 	and	ebx, ebx
 17440 00003924 7427                <1> 	jz	short sysgtty_1
 17441                              <1> 	;
 17442 00003926 891D[806C0000]      <1> 	mov	[u.namep], ebx
 17443                              <1> 	;push	cx ; 23/11/2015
 17444 0000392C 51                  <1> 	push	ecx ; 24/12/2021
 17445 0000392D E846070000          <1> 	call	namei
 17446 00003932 59                  <1> 	pop	ecx
 17447                              <1> 	;pop	cx ; 23/11/2015
 17448 00003933 7213                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
 17449                              <1> 	;
 17450                              <1> 	; 21/02/2022
 17451                              <1> 	;cmp	ax, 1
 17452                              <1> 	;jna	short sysgtty_2
 17453                              <1> 	;sub	ax, 10
 17454                              <1> 	;cmp	ax, 9
 17455                              <1> 	;;ja	short sysgtty_inv_dn
 17456                              <1> 	;;mov	ch, al
 17457                              <1> 	;;jmp	short sysgtty_4
 17458                              <1> 	;; 23/11/2015
 17459                              <1> 	;jna	short sysgtty_4
 17460                              <1> 	;
 17461                              <1> 	; 21/02/2022
 17462                              <1> 	; (Retro UNIX 386 v2 file system inode numbers)
 17463 00003935 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 17464 00003938 770E                <1> 	ja	short sysgtty_inv_dn
 17465                              <1> 	;cmp	al, 8	; /dev/tty inode number is 8
 17466                              <1> 	;jb	short sysgtty_inv_dn
 17467 0000393A 2C08                <1> 	sub	al, 8
 17468 0000393C 720A                <1> 	jb	short sysgtty_inv_dn
 17469 0000393E 7416                <1> 	jz	short sysgtty_2 ; /dev/tty inode number is 8
 17470                              <1> 	; convert inode number to tty number (tty0 to tty9)
 17471 00003940 2C09                <1> 	sub	al, 9
 17472 00003942 7204                <1> 	jb	short sysgtty_inv_dn
 17473                              <1> 	; al = 0 to 9
 17474 00003944 29DB                <1> 	sub	ebx, ebx ; 22/02/2022
 17475 00003946 EB1F                <1> 	jmp	short sysgtty_4
 17476                              <1> 	
 17477                              <1> sysgtty_inv_dn: 
 17478                              <1> 	;; 28/06/2015
 17479                              <1> 	;; Invalid device name (not a tty) ! error
 17480                              <1> 	;; (Device is not a tty or device name not found)
 17481                              <1> 	;mov	dword [u.error], ERR_INV_DEV_NAME
 17482                              <1> 	;jmp	error
 17483                              <1> 	; 21/02/2022
 17484 00003948 E935FFFFFF          <1> 	jmp	sysstty_inv_dn
 17485                              <1> 
 17486                              <1> sysgtty_1:
 17487                              <1> 	; 16/01/2014
 17488 0000394D 80FD0A              <1> 	cmp	ch, 10
 17489 00003950 77C1                <1> 	ja	short sysgtty_invp ; 28/06/2015
 17490 00003952 FECD                <1> 	dec	ch ; 0 -> FFh (negative)
 17491 00003954 790F                <1> 	jns	short sysgtty_3 ; not negative
 17492                              <1> sysgtty_2:
 17493                              <1> 	; get tty number of console tty
 17494 00003956 8A25[B56C0000]      <1> 	mov	ah, [u.uno]
 17495                              <1>  	; 28/06/2015
 17496 0000395C 0FB6DC              <1> 	movzx 	ebx, ah
 17497 0000395F 8AAB[63680000]      <1> 	mov	ch, [ebx+p.ttyc-1]
 17498                              <1> sysgtty_3:
 17499 00003965 88E8                <1> 	mov	al, ch
 17500                              <1> sysgtty_4:
 17501 00003967 A2[646C0000]        <1> 	mov	[u.r0], al
 17502                              <1>  	; 28/06/2015
 17503                              <1> 	;cmp	al, 9
 17504                              <1> 	;ja	short sysgtty_invp
 17505 0000396C 8B2D[606C0000]      <1> 	mov	ebp, [u.usp]
 17506                              <1> 	; 23/11/2015
 17507 00003972 20C9                <1> 	and	cl, cl
 17508 00003974 7432                <1> 	jz	short sysgtty_6 ; keyboard status
 17509 00003976 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
 17510 00003978 722E                <1> 	jb	short sysgtty_6 ; video page status
 17511                              <1> 	; serial port status
 17512                              <1> 	; 12/07/2014
 17513                              <1> 	;mov	dx, 0
 17514                              <1> 	;je	short sysgtty_5
 17515                              <1> 	;inc	dl
 17516                              <1> ;sysgtty_5:
 17517                              <1> 	; 28/06/2015
 17518 0000397A 2C08                <1> 	sub	al, 8
 17519 0000397C E81EF2FFFF          <1> 	call	sp_status ; serial (COM) port (line) status
 17520                              <1> 	; AL = Line status, AH = Modem status
 17521 00003981 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
 17522 00003985 8A25[B56C0000]      <1> 	mov	ah, [u.uno]
 17523 0000398B 8825[656C0000]      <1>         mov     [u.r0+1], ah
 17524                              <1> 	; 24/12/2021
 17525 00003991 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)
 17526                              <1> 				; (in ECX)
 17527 00003997 A880                <1> 	test	al, 80h
 17528 00003999 7561                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
 17529 0000399B A801                <1> 	test	al, 1
 17530                              <1> 	;jz	sysret
 17531 0000399D 7404                <1> 	jz	short sysgtty_10
 17532 0000399F 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)
 17533                              <1> sysgtty_10:
 17534 000039A3 E9D9F7FFFF          <1> 	jmp	sysret
 17535                              <1> sysgtty_6:
 17536 000039A8 A2[996C0000]        <1> 	mov	[u.ttyn], al ; tty number
 17537                              <1> 	;movzx	ebx, al
 17538 000039AD 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
 17539 000039AF D0E3                <1> 	shl 	bl, 1  ; aligned to word
 17540                              <1> 	; 22/04/2014 - 29/06/2015
 17541 000039B1 81C3[74670000]      <1>         add     ebx, ttyl
 17542 000039B7 8A23                <1>  	mov	ah, [ebx]
 17543 000039B9 3A25[B56C0000]      <1> 	cmp	ah, [u.uno]
 17544 000039BF 7404                <1> 	je	short sysgtty_7
 17545 000039C1 20E4                <1> 	and	ah, ah
 17546                              <1> 	;jz	short sysgtty_7
 17547 000039C3 7506                <1> 	jnz	short sysgtty_8
 17548                              <1> 	;mov	ah, 0FFh
 17549                              <1> sysgtty_7:
 17550 000039C5 8825[656C0000]      <1>         mov     [u.r0+1], ah
 17551                              <1> sysgtty_8:
 17552 000039CB 08C9                <1> 	or	cl, cl
 17553 000039CD 7510                <1> 	jnz	short sysgtty_9
 17554 000039CF B001                <1> 	mov	al, 1  ; test a key is available
 17555 000039D1 E88F210000          <1> 	call	getc
 17556 000039D6 66894510            <1> 	mov	[ebp+16], ax ; bx, character
 17557 000039DA E9A2F7FFFF          <1> 	jmp	sysret
 17558                              <1> sysgtty_9:
 17559 000039DF 8A1D[996C0000]      <1> 	mov	bl, [u.ttyn]
 17560                              <1> 	; bl = video page number
 17561 000039E5 E8EC220000          <1> 	call 	get_cpos
 17562                              <1> 	; dx = cursor position
 17563 000039EA 66895510            <1> 	mov	[ebp+16], dx ; bx
 17564                              <1> 	;mov	bl, [u.ttyn]
 17565                              <1> 	; bl = video page number
 17566 000039EE E8F4220000          <1> 	call	read_ac_current
 17567                              <1> 	; ax = character and attribute/color
 17568 000039F3 66894518            <1> 	mov	[ebp+24], ax ; cx
 17569 000039F7 E985F7FFFF          <1> 	jmp	sysret
 17570                              <1> sysgtty_dnr_err:
 17571                              <1> 	; 'device not responding !' error	
 17572                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
 17573 000039FC C705[D86C0000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ; 25
 17574 00003A04 0000                <1>
 17575 00003A06 E956F7FFFF          <1> 	jmp	error	
 17576                              <1> 
 17577                              <1> ; Original UNIX v1 'sysgtty' routine:
 17578                              <1> ; sysgtty:
 17579                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
 17580                              <1> 	;	       / r2 has destination
 17581                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
 17582                              <1> 	;                     / in 1st word of dest
 17583                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
 17584                              <1> 	;                     / in 2nd word of dest
 17585                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
 17586                              <1>         ;jmp    sysret2 / return to user
 17587                              <1> 	
 17588                              <1> ; Original UNIX v1 'gtty' routine:
 17589                              <1> ; gtty:
 17590                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
 17591                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
 17592                              <1>         ;jsr    r0,getf / get the i-number of the file
 17593                              <1>         ;tst    r1 / is it open for reading
 17594                              <1>         ;bgt    1f / yes
 17595                              <1>         ;neg    r1 / no, i-number is negative, 
 17596                              <1> 	;          / so make it positive
 17597                              <1> ;1:
 17598                              <1>         ;sub    $14.,r1 / get i-number of tty0
 17599                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
 17600                              <1>         ;bhis   error9 / no, error
 17601                              <1>         ;asl    r1 / 0%2
 17602                              <1>         ;asl    r1 / 0%4 / yes
 17603                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
 17604                              <1> 	;	       ; / tty block
 17605                              <1>         ;mov    u.off,r2 / put argument in r2
 17606                              <1>         ;rts    r0 / return
 17607                                  %include 'u2.s'      ; 11/05/2015
 17608                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 17609                              <1> ; (re-write kernel for test by using previous version without a major defect)
 17610                              <1> ; ****************************************************************************
 17611                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS2.INC
 17612                              <1> ; Last Modification: 18/07/2022
 17613                              <1> ; ----------------------------------------------------------------------------
 17614                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 17615                              <1> ; (v0.1 - Beginning: 11/07/2012)
 17616                              <1> ;
 17617                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 17618                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 17619                              <1> ; <Bell Laboratories (17/3/1972)>
 17620                              <1> ; <Preliminary Release of UNIX Implementation Document>
 17621                              <1> ;
 17622                              <1> ; Retro UNIX 8086 v1 - U2.ASM (24/03/2014) //// UNIX v1 -> u2.s
 17623                              <1> ;
 17624                              <1> ; ****************************************************************************
 17625                              <1> 
 17626                              <1> syslink:
 17627                              <1> 	; 12/01/2022
 17628                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 17629                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17630                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17631                              <1> 	;
 17632                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
 17633                              <1> 	; name 1 is a file that already exists. name 2 is the name
 17634                              <1> 	; given to the entry that will go in the current directory.
 17635                              <1> 	; name2 will then be a link to the name 1 file. The i-number
 17636                              <1> 	; in the name 2 entry of current directory is the same
 17637                              <1> 	; i-number for the name 1 file.
 17638                              <1> 	;
 17639                              <1> 	; Calling sequence:
 17640                              <1> 	;	syslink; name 1; name 2
 17641                              <1> 	; Arguments:
 17642                              <1> 	;	name 1 - file name to which link will be created.
 17643                              <1> 	;	name 2 - name of entry in current directory that
 17644                              <1> 	;		 links to name 1.
 17645                              <1> 	; Inputs: -
 17646                              <1> 	; Outputs: -
 17647                              <1> 	; ...............................................................
 17648                              <1> 	;	
 17649                              <1> 	; Retro UNIX 8086 v1 modification: 
 17650                              <1> 	;       'syslink' system call has two arguments; so,
 17651                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
 17652                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
 17653                              <1> 	;
 17654                              <1> 		; / name1, name2
 17655                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
 17656 00003A0B 891D[806C0000]      <1> 	mov	[u.namep], ebx
 17657 00003A11 51                  <1> 	push	ecx
 17658 00003A12 E861060000          <1> 	call	namei
 17659                              <1> 		; jsr r0,namei / find the i-number associated with
 17660                              <1> 			     ; / the 1st path name
 17661                              <1>      	;;and	ax, ax
 17662                              <1> 	;;jz	error ; File not found
 17663                              <1> 	;jc	error 
 17664                              <1> 		; br error9 / cannot be found
 17665 00003A17 730F                <1> 	jnc	short syslink0
 17666                              <1> 	;pop 	ecx
 17667                              <1> 	; 'file not found !' error
 17668 00003A19 C705[D86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17669 00003A21 0000                <1>
 17670 00003A23 E939F7FFFF          <1> 	jmp	error
 17671                              <1> syslink0:
 17672 00003A28 E844110000          <1> 	call	iget
 17673                              <1> 		; jsr r0,iget / get the i-node into core
 17674 00003A2D 8F05[806C0000]      <1> 	pop	dword [u.namep] ; ecx
 17675                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
 17676                              <1> 	; 24/12/2021
 17677 00003A33 50                  <1> 	push	eax ; *
 17678                              <1> 	;push	ax
 17679                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
 17680                              <1> 			    ; / (a link to this file is to be created)
 17681                              <1> 	; 24/12/2021
 17682 00003A34 8A0D[416C0000]      <1> 	mov	cl, [cdev]
 17683 00003A3A 51                  <1> 	push	ecx ; **
 17684                              <1> 	;push	word [cdev]
 17685                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
 17686 00003A3B E8AC000000          <1> 	call	isdir
 17687                              <1> 		; jsr r0,isdir / is it a directory
 17688 00003A40 E833060000          <1> 	call	namei
 17689                              <1> 		; jsr r0,namei / no, get i-number of name2
 17690                              <1> 	;jnc	error
 17691                              <1> 		; br .+4   / not found 
 17692                              <1> 			 ; / so r1 = i-number of current directory
 17693                              <1> 			 ; / ii = i-number of current directory
 17694                              <1> 		; br error9 / file already exists., error
 17695 00003A45 720F                <1> 	jc	short syslink1
 17696                              <1> 	; pop eax ; 24/12/2021
 17697                              <1> 	; pop eax
 17698                              <1> 	; 'file exists !' error
 17699 00003A47 C705[D86C0000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
 17700 00003A4F 0000                <1>
 17701 00003A51 E90BF7FFFF          <1> 	jmp	error
 17702                              <1> syslink1:
 17703                              <1> 	;pop	cx
 17704                              <1> 	; 24/12/2021
 17705 00003A56 59                  <1> 	pop	ecx ; **
 17706                              <1> 	;cmp	cx, [cdev]
 17707 00003A57 3A0D[416C0000]      <1> 	cmp	cl, [cdev]
 17708                              <1> 	;jne	error
 17709                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
 17710                              <1> 			       ; / end of current directory
 17711                              <1> 	        ; bne error9
 17712 00003A5D 740F                <1> 	je	short syslink2
 17713                              <1> 	; 'not same drive !' error
 17714 00003A5F C705[D86C0000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
 17715 00003A67 0000                <1>
 17716 00003A69 E9F3F6FFFF          <1> 	jmp	error
 17717                              <1> syslink2:
 17718                              <1> 	;pop	eax ; 24/12/2021
 17719                              <1> 	;push	eax
 17720                              <1> 	; 24/12/2021
 17721 00003A6E 8B0424              <1> 	mov	eax, [esp] ; *
 17722 00003A71 66A3[9C6C0000]      <1> 	mov	[u.dirbuf], ax
 17723                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
 17724 00003A77 E8C5000000          <1> 	call	mkdir
 17725                              <1> 		; jsr r0,mkdir / make directory entry for name2 
 17726                              <1> 		 	     ; / in current directory
 17727                              <1> 	; 24/12/2021
 17728 00003A7C 58                  <1> 	pop	eax ; *
 17729                              <1> 	;pop	ax
 17730                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
 17731 00003A7D E8EF100000          <1> 	call	iget
 17732                              <1> 		; jsr r0,iget / get i-node into core
 17733 00003A82 FE05[E6670000]      <1> 	inc	byte [i.nlks]
 17734                              <1> 		; incb i.nlks / add 1 to its number of links
 17735                              <1> sysunlink_2:
 17736                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 17737 00003A88 C605[556C0000]01    <1> 	mov	byte [imodx], 1	; (flag means file data is same
 17738                              <1> 				;  but inode's itself has been modified)
 17739 00003A8F E86E120000          <1> 	call	setimod
 17740                              <1> 		; jsr r0,setimod / set the i-node modified flag
 17741 00003A94 E9E8F6FFFF          <1> 	jmp	sysret
 17742                              <1> 
 17743                              <1> sysunlink:
 17744                              <1> 	; 12/01/2022
 17745                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 17746                              <1> 	; 04/12/2015 (14 byte file names)
 17747                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17748                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17749                              <1> 	;
 17750                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
 17751                              <1> 	; name from its directory. If this entry was the last link
 17752                              <1> 	; to the file, the contents of the file are freed and the
 17753                              <1> 	; file is destroyed. If, however, the file was open in any
 17754                              <1> 	; process, the actual destruction is delayed until it is 
 17755                              <1> 	; closed, even though the directory entry has disappeared.
 17756                              <1> 	; 
 17757                              <1> 	; The error bit (e-bit) is set to indicate that the file	
 17758                              <1> 	; does not exist or that its directory can not be written.
 17759                              <1> 	; Write permission is not required on the file itself.
 17760                              <1> 	; It is also illegal to unlink a directory (except for
 17761                              <1> 	; the superuser).
 17762                              <1> 	;
 17763                              <1> 	; Calling sequence:
 17764                              <1> 	;	sysunlink; name
 17765                              <1> 	; Arguments:
 17766                              <1> 	;	name - name of directory entry to be removed 
 17767                              <1> 	; Inputs: -
 17768                              <1> 	; Outputs: -
 17769                              <1> 	; ...............................................................
 17770                              <1> 	;				
 17771                              <1> 	; Retro UNIX 8086 v1 modification:
 17772                              <1> 	;	 The user/application program puts address of the name
 17773                              <1> 	;        in BX register as 'sysunlink' system call argument.
 17774                              <1> 
 17775                              <1> 	; / name - remove link name
 17776 00003A99 891D[806C0000]      <1> 	mov	[u.namep], ebx
 17777                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
 17778 00003A9F E8D4050000          <1> 	call	namei
 17779                              <1> 		; jsr r0,namei / find the i-number associated 
 17780                              <1> 			     ; / with the path name
 17781                              <1> 	;jc	error
 17782                              <1> 		; br error9 / not found
 17783 00003AA4 730F                <1> 	jnc	short sysunlink1
 17784                              <1> 	; 'file not found !' error
 17785 00003AA6 C705[D86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17786 00003AAE 0000                <1>
 17787 00003AB0 E9ACF6FFFF          <1> 	jmp	error
 17788                              <1> sysunlink1:
 17789 00003AB5 50                  <1> 	push	eax ; 24/12/2021
 17790                              <1> 	;push	ax
 17791                              <1> 		; mov r1,-(sp) / put its i-number on the stack
 17792 00003AB6 E831000000          <1> 	call	isdir
 17793                              <1> 		; jsr r0,isdir / is it a directory
 17794                              <1> 	;xor 	ax, ax
 17795                              <1> 	; 24/12/2021
 17796 00003ABB 31C0                <1> 	xor	eax, eax
 17797 00003ABD 66A3[9C6C0000]      <1> 	mov	[u.dirbuf], ax ; 0
 17798                              <1> 		; clr u.dirbuf / no, clear the location that will
 17799                              <1> 			   ; / get written into the i-number portion
 17800                              <1> 			 ; / of the entry
 17801 00003AC3 832D[846C0000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
 17802                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
 17803 00003ACA E8BD000000          <1> 	call	wdir
 17804                              <1> 		; jsr r0,wdir / free the directory entry
 17805 00003ACF 58                  <1> 	pop	eax ; 24/12/2021
 17806                              <1> 	;pop	ax
 17807                              <1> 		; mov (sp)+,r1 / get i-number back
 17808 00003AD0 E89C100000          <1> 	call	iget
 17809                              <1> 		; jsr r0,iget / get i-node
 17810                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 17811                              <1> 	;call	setimod
 17812                              <1> 	;	; jsr r0,setimod / set modified flag
 17813                              <1> 	;	
 17814 00003AD5 FE0D[E6670000]      <1> 	dec	byte [i.nlks]
 17815                              <1> 		; decb i.nlks / decrement the number of links
 17816                              <1> 	; 24/12/2021
 17817 00003ADB 75AB                <1> 	jnz	short sysunlink_2
 17818                              <1> 	;jnz	sysret
 17819                              <1> 		; bgt sysret9 / if this was not the last link
 17820                              <1> 			    ; / to file return
 17821                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 17822 00003ADD E820120000          <1> 	call	setimod
 17823                              <1> 		; jsr r0,setimod / set modified flag
 17824                              <1> 	; AX = r1 = i-number
 17825 00003AE2 E89B0A0000          <1> 	call	anyi
 17826                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
 17827                              <1> 			 ; / Then free contents of file and destroy it.
 17828 00003AE7 E995F6FFFF          <1> 	jmp	sysret
 17829                              <1> 		; br sysret9
 17830                              <1> ;sysunlink_2:
 17831                              <1> 	;; 12/01/2022 - Retro UNIX 386 v1.2
 17832                              <1> 	;mov	byte [imodx], 1	; (flag means file data is same
 17833                              <1> 	;			;  but inode's itself has been modified)
 17834                              <1> 	;call	setimod
 17835                              <1> 	;	; jsr r0,setimod / set the i-node modified flag
 17836                              <1> 	;jmp	sysret
 17837                              <1> 
 17838                              <1> isdir:
 17839                              <1> 	; 13/03/2022
 17840                              <1> 	; 08/01/2022
 17841                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode)
 17842                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 17843                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 17844                              <1> 	;
 17845                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
 17846                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
 17847                              <1> 	;  called by syslink and sysunlink to make sure directories
 17848                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
 17849                              <1> 	; 'isdir' does not bother checking. The current i-node
 17850                              <1> 	;  is not disturbed.			
 17851                              <1> 	;		
 17852                              <1> 	; INPUTS ->
 17853                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
 17854                              <1> 	;    u.uid - user id
 17855                              <1> 	; OUTPUTS ->
 17856                              <1> 	;    r1 - contains current i-number upon exit
 17857                              <1> 	;    	 (current i-node back in core) 
 17858                              <1> 	;	
 17859                              <1> 	; ((AX = R1))
 17860                              <1> 	;
 17861                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 17862                              <1> 	;
 17863                              <1> 
 17864                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
 17865                              <1> 	; / there is an error unless super user made the call
 17866                              <1> 	
 17867                              <1> 	; 01/01/2022
 17868 00003AEC 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0 ; 16 bit uid (runix v2 fs inode)
 17869                              <1> 	;cmp	byte [u.uid], 0 
 17870                              <1> 		; tstb u.uid / super user
 17871 00003AF4 764A                <1> 	jna	short isdir1
 17872                              <1> 		; beq 1f / yes, don't care
 17873                              <1> 	; 08/01/2022
 17874 00003AF6 FF35[3C6C0000]      <1> 	push	dword [ii]
 17875                              <1> 	;push	word [ii]
 17876                              <1> 		; mov ii,-(sp) / put current i-number on stack
 17877 00003AFC E870100000          <1> 	call	iget
 17878                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
 17879                              <1> 	; 01/01/2022 (runix v2 fs inode flags)
 17880 00003B01 F605[E5670000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file ?
 17881 00003B08 7421                <1> 	jz	short isdir2 ; no, error!
 17882 00003B0A F605[E5670000]40    <1> 	test	byte [i.flgs+1], 40h ; directory flag
 17883                              <1> 	;test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
 17884                              <1> 		; bit $40000,i.flgs / is it a directory
 17885                              <1> 	;jnz	error
 17886                              <1> 		; bne error9 / yes, error
 17887 00003B11 7427                <1> 	jz	short isdir0
 17888                              <1> 
 17889                              <1> 	; 13/03/2022
 17890                              <1> 	; NOTE:
 17891                              <1> 	; Unix v5-v7 kernels do not allow (ordinary) users
 17892                              <1> 	; (except root/superuser) --if [u.uid] > 0--
 17893                              <1> 	; to link a directory. (ref: sys2.c, 'link')
 17894                              <1> 	;
 17895                              <1> 	; But, Retro UNIX 386 v1.2 will allow the owner of
 17896                              <1> 	; the directory to link it.
 17897                              <1> 
 17898 00003B13 66A1[E8670000]      <1> 	mov	ax, [i.uid] ; owner ID of the parent dir
 17899 00003B19 663B05[B66C0000]    <1> 	cmp	ax, [u.uid] ; user ID of current user/process
 17900 00003B20 7509                <1> 	jne	short isdir2
 17901                              <1> 	; 13/03/2022
 17902                              <1> 	; additional checking (may or may not be necessary!?)
 17903 00003B22 663B05[B86C0000]    <1> 	cmp	ax, [u.ruid] 
 17904                              <1> 			; real (login) user ID must be same
 17905 00003B29 740F                <1> 	je	short isdir0
 17906                              <1> 
 17907                              <1> isdir2:
 17908 00003B2B C705[D86C0000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
 17909 00003B33 0000                <1>
 17910                              <1> 				; 'permission denied !' error
 17911                              <1> 	;pop	ax
 17912 00003B35 E927F6FFFF          <1> 	jmp	error	
 17913                              <1> isdir0:	
 17914                              <1> 	; 08/01/2022
 17915 00003B3A 58                  <1> 	pop	eax
 17916                              <1> 	;pop	ax
 17917                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
 17918 00003B3B E831100000          <1> 	call	iget
 17919                              <1> 		; jsr r0,iget / get it back in
 17920                              <1> isdir1: ; 1:
 17921 00003B40 C3                  <1> 	retn
 17922                              <1> 		; rts r0
 17923                              <1> 
 17924                              <1> mkdir:
 17925                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 17926                              <1> 	; 04/12/2015 (14 byte directory names)
 17927                              <1> 	; 12/10/2015
 17928                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
 17929                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 17930                              <1> 	;
 17931                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
 17932                              <1> 	; by u.namep into the current directory.
 17933                              <1> 	;
 17934                              <1> 	; INPUTS ->
 17935                              <1> 	;    u.namep - points to a file name 
 17936                              <1> 	;	           that is about to be a directory entry.
 17937                              <1> 	;    ii - current directory's i-number.	
 17938                              <1> 	; OUTPUTS ->
 17939                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
 17940                              <1> 	;    u.off - points to entry to be filled 
 17941                              <1> 	;	     in the current directory		
 17942                              <1> 	;    u.base - points to start of u.dirbuf.
 17943                              <1> 	;    r1 - contains i-number of current directory 
 17944                              <1> 	;	
 17945                              <1> 	; ((AX = R1)) output
 17946                              <1> 	;
 17947                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
 17948                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 17949                              <1> 	;
 17950                              <1> 
 17951                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 17952 00003B41 31C0                <1> 	xor 	eax, eax
 17953 00003B43 BF[9E6C0000]        <1> 	mov     edi, u.dirbuf+2
 17954 00003B48 89FE                <1> 	mov	esi, edi
 17955 00003B4A AB                  <1> 	stosd
 17956 00003B4B AB                  <1> 	stosd
 17957                              <1> 	; 04/12/2015 (14 byte directory names)
 17958 00003B4C AB                  <1> 	stosd
 17959 00003B4D 66AB                <1> 	stosw
 17960                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
 17961 00003B4F 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
 17962                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 17963                              <1> 	;mov 	ebp, [u.namep]
 17964 00003B51 E881060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 17965                              <1> 		; esi = physical address (page start + offset)
 17966                              <1> 		; ecx = byte count in the page (1 - 4096)
 17967                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 17968                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
 17969                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
 17970                              <1> mkdir_1: ; 1: 
 17971 00003B56 45                  <1> 	inc	ebp ; 12/10/2015
 17972                              <1> 	;
 17973                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
 17974                              <1> 	; 01/08/2013
 17975 00003B57 AC                  <1> 	lodsb
 17976                              <1> 		; movb (r2)+,r1 / move character in name to r1
 17977 00003B58 20C0                <1> 	and 	al, al
 17978 00003B5A 7426                <1> 	jz 	short mkdir_3 	  
 17979                              <1> 		; beq 1f / if null, done
 17980 00003B5C 3C2F                <1> 	cmp	al, '/'
 17981                              <1> 		; cmp r1,$'/ / is it a "/"?
 17982 00003B5E 7413                <1> 	je	short mkdir_err
 17983                              <1> 	;je	error
 17984                              <1> 		; beq error9 / yes, error
 17985                              <1> 	; 12/10/2015
 17986                              <1> 	;dec	cx
 17987 00003B60 49                  <1> 	dec	ecx ; 24/12/2021
 17988 00003B61 7505                <1> 	jnz	short mkdir_2
 17989                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 17990 00003B63 E875060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 17991                              <1> 		; esi = physical address (page start + offset)
 17992                              <1> 		; ecx = byte count in the page
 17993                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 17994                              <1> mkdir_2:
 17995 00003B68 81FF[AC6C0000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
 17996                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
 17997                              <1> 				     ; / a char?
 17998 00003B6E 74E6                <1> 	je	short mkdir_1
 17999                              <1> 		; beq 1b / yes, go back
 18000 00003B70 AA                  <1> 	stosb
 18001                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
 18002 00003B71 EBE3                <1> 	jmp 	short mkdir_1
 18003                              <1> 		; br 1b / get next char
 18004                              <1> mkdir_err:
 18005                              <1> 	; 17/06/2015
 18006 00003B73 C705[D86C0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 18007 00003B7B 0000                <1>
 18008 00003B7D E9DFF5FFFF          <1> 	jmp	error
 18009                              <1> 
 18010                              <1> mkdir_3: ; 1:
 18011 00003B82 A1[7C6C0000]        <1> 	mov	eax, [u.dirp]
 18012 00003B87 A3[846C0000]        <1> 	mov	[u.off], eax
 18013                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
 18014                              <1> 				 ; / slot to u.off
 18015                              <1> 	; 08/01/2022
 18016                              <1> wdir:	; 24/12/2021 (Retro UNIX 386 v1.2)
 18017                              <1> 	; 29/04/2013
 18018 00003B8C C705[886C0000]-     <1>         mov     dword [u.base], u.dirbuf
 18019 00003B92 [9C6C0000]          <1>
 18020                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
 18021 00003B96 C705[8C6C0000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
 18022 00003B9E 0000                <1>
 18023                              <1> 		; mov $10.,u.count / u.count = 10
 18024                              <1> 	; 08/01/2022
 18025 00003BA0 A1[3C6C0000]        <1> 	mov	eax, [ii]
 18026                              <1> 	;mov	ax, [ii] 
 18027                              <1> 		; mov ii,r1 / r1 has i-number of current directory
 18028                              <1> 	;mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
 18029                              <1> 	; 08/01/2022 (Retro UNIX 386 v2 file system inode)
 18030 00003BA5 66BA8000            <1> 	mov	dx, 80h	; mov dx, IWRITE
 18031 00003BA9 E8AD100000          <1> 	call 	access
 18032                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
 18033                              <1> 				 ; / for writing
 18034                              <1> 	; AX = i-number of current directory
 18035                              <1> 	; 01/08/2013
 18036 00003BAE FE05[D66C0000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
 18037                              <1> 	;call	writei
 18038                              <1> 	;	; jsr r0,writei / write into directory
 18039                              <1> 	;retn	
 18040                              <1> 	;	; rts r0
 18041                              <1> 	; 24/12/2021
 18042 00003BB4 E938150000          <1> 	jmp	writei
 18043                              <1> 
 18044                              <1> 
 18045                              <1> 	; 09/05/2022 
 18046                              <1> 	;	(Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 18047                              <1> 	; 06/02/2022
 18048                              <1> 	; 12/01/2022
 18049                              <1> 	; 01/01/2022
 18050                              <1> 	; 24/12/2021
 18051                              <1> 	; 11/12/2021
 18052                              <1> 	; 04/12/2021
 18053                              <1> 	; 30/11/2021
 18054                              <1> 	; 28/11/2021 - Retro UNIX 386 v1.2
 18055                              <1> 	;	(Retro UNIX 386 v2 fs compatibility modification)
 18056                              <1> sysexec:
 18057                              <1> 	; 02/05/2021
 18058                              <1> 	; 27/03/2021
 18059                              <1> 	; 26/03/2021
 18060                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 18061                              <1> 	; 23/10/2015
 18062                              <1> 	; 10/10/2015, 18/10/2015, 19/10/2015
 18063                              <1> 	; 29/07/2015, 05/08/2015, 05/08/2015
 18064                              <1> 	; 21/07/2015, 24/07/2015, 25/07/2015
 18065                              <1> 	; 01/07/2015, 02/07/2015, 20/07,2015
 18066                              <1> 	; 24/06/2015, 25/06/2021
 18067                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18068                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 18069                              <1> 	;
 18070                              <1> 	; 'sysexec' initiates execution of a file whose path name if
 18071                              <1> 	; pointed to by 'name' in the sysexec call. 
 18072                              <1> 	; 'sysexec' performs the following operations:
 18073                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
 18074                              <1> 	;    2. obtains i-node of file to be executed via 'iget'.
 18075                              <1> 	;    3. sets trap vectors to system routines.
 18076                              <1> 	;    4. loads arguments to be passed to executing file into
 18077                              <1> 	;	highest locations of user's core
 18078                              <1> 	;    5. puts pointers to arguments in locations immediately
 18079                              <1> 	;	following arguments.
 18080                              <1> 	;    6.	saves number of arguments in next location.
 18081                              <1> 	;    7. initializes user's stack area so that all registers
 18082                              <1> 	;	will be zeroed and the PS is cleared and the PC set
 18083                              <1> 	;	to core when 'sysret' restores registers 
 18084                              <1> 	;	and does an rti.
 18085                              <1> 	;    8. inializes u.r0 and u.sp
 18086                              <1> 	;    9. zeros user's core down to u.r0
 18087                              <1> 	;   10.	reads executable file from storage device into core
 18088                              <1> 	;	starting at location 'core'.
 18089                              <1> 	;   11.	sets u.break to point to end of user's code with
 18090                              <1> 	;	data area appended.
 18091                              <1> 	;   12.	calls 'sysret' which returns control at location
 18092                              <1> 	;	'core' via 'rti' instruction.
 18093                              <1> 	;
 18094                              <1> 	; Calling sequence:
 18095                              <1> 	;	sysexec; namep; argp
 18096                              <1> 	; Arguments:
 18097                              <1> 	;	namep - points to pathname of file to be executed
 18098                              <1> 	;	argp  - address of table of argument pointers
 18099                              <1> 	;	argp1... argpn - table of argument pointers
 18100                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
 18101                              <1> 	; Inputs: (arguments)
 18102                              <1> 	; Outputs: -	
 18103                              <1> 	; ...............................................................
 18104                              <1> 	;
 18105                              <1> 	; Retro UNIX 386 v1 modification: 
 18106                              <1> 	;	User application runs in it's own virtual space 
 18107                              <1> 	;	which is izolated from kernel memory (and other
 18108                              <1> 	;	memory pages) via 80386	paging in ring 3 
 18109                              <1> 	;	privilige mode. Virtual start address is always 0.
 18110                              <1> 	;	User's core memory starts at linear address 400000h
 18111                              <1> 	;	(the end of the 1st 4MB).
 18112                              <1> 	;
 18113                              <1> 	; Retro UNIX 8086 v1 modification: 
 18114                              <1> 	;	user/application segment and system/kernel segment
 18115                              <1> 	;	are different and sysenter/sysret/sysrele routines
 18116                              <1> 	;	are different (user's registers are saved to 
 18117                              <1> 	;	and then restored from system's stack.)
 18118                              <1> 	;
 18119                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 18120                              <1> 	;	      arguments which were in these registers;
 18121                              <1> 	;	      but, it returns by putting the 1st argument
 18122                              <1> 	;	      in 'u.namep' and the 2nd argument
 18123                              <1> 	;	      on top of stack. (1st argument is offset of the
 18124                              <1> 	;	      file/path name in the user's program segment.)
 18125                              <1> 	
 18126                              <1> 	;call	arg2
 18127                              <1> 	; * name - 'u.namep' points to address of file/path name
 18128                              <1> 	;          in the user's program segment ('u.segmnt')
 18129                              <1> 	;          with offset in BX register (as sysopen argument 1).
 18130                              <1> 	; * argp - sysexec argument 2 is in CX register 
 18131                              <1> 	;          which is on top of stack.
 18132                              <1> 	;
 18133                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
 18134                              <1> 
 18135                              <1> 	; 23/06/2015 (32 bit modifications)
 18136                              <1> 
 18137 00003BB9 891D[806C0000]      <1> 	mov	[u.namep], ebx ; argument 1
 18138                              <1>         ; 18/10/2015
 18139 00003BBF 890D[F46C0000]      <1> 	mov     [argv], ecx  ; * ; argument 2
 18140 00003BC5 E8AE040000          <1> 	call	namei
 18141                              <1> 		; jsr r0,namei / namei returns i-number of file 
 18142                              <1> 			     ; / named in sysexec call in r1
 18143                              <1> 	;jc	error
 18144                              <1> 		; br error9
 18145 00003BCA 730F                <1> 	jnc	short sysexec_0
 18146                              <1> 	;
 18147                              <1> 	; 'file not found !' error
 18148 00003BCC C705[D86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
 18149 00003BD4 0000                <1>
 18150 00003BD6 E986F5FFFF          <1> 	jmp	error
 18151                              <1> 
 18152                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 18153                              <1> 	; (executable file flag is checked in 'access')
 18154                              <1> 	; (following error message is in 'access' subroutine)
 18155                              <1> ;sysexec_not_exf:
 18156                              <1> 	;; 'not executable file !' error
 18157                              <1> 	;mov	dword [u.error], ERR_NOT_EXECUTABLE
 18158                              <1> 	;jmp	error 
 18159                              <1> sysexec_0:
 18160                              <1> 	; 26/03/2021 ('iget' will be called in 'access')
 18161                              <1> 	;call	iget
 18162                              <1> 	;	; jsr r0,iget / get i-node for file to be executed
 18163                              <1> 	;
 18164                              <1> 	;test	byte [i.flgs], 10h
 18165                              <1> 	;;test	word [i.flgs], 10h
 18166                              <1> 	;	; bit $20,i.flgs / is file executable
 18167                              <1> 	;jz	short sysexec_not_exf
 18168                              <1> 	;;jz	error
 18169                              <1> 	;	; beq error9
 18170                              <1> 	; 26/03/2021
 18171 00003BDB 66BA4000            <1> 	mov	dx, 40h ; IEXEC - execute, owner
 18172 00003BDF E877100000          <1> 	call	access
 18173                              <1> 	; ! we are here because there is execute permission !
 18174                              <1> 	; ('iopen' is not needed for regular files, from now on)
 18175                              <1> 
 18176                              <1> 	; 26/03/2021
 18177                              <1> 	;; 25/03/2021
 18178                              <1> 	;; (ref: Retro UNIX 386 v2, 'ux.s')
 18179                              <1> 	;mov	dx, 40h ; IEXEC - execute, owner
 18180                              <1> 	;;
 18181                              <1> 	;call	iopen
 18182                              <1> 	;	; jsr r0,iopen / gets i-node for file with i-number
 18183                              <1> 	;		     ; / given in r1 (opens file)
 18184                              <1> 	
 18185                              <1> 	; 26/03/2021
 18186                              <1> 	; AX = i-number of the file
 18187                              <1> 	;test	byte [i.flgs], 20h
 18188                              <1> 	;;test	word [i.flgs], 20h
 18189                              <1> 	;	; bit $40,i.flgs / test user id on execution bit
 18190                              <1> 	;jz	short sysexec_1
 18191                              <1> 	;	; beq 1f
 18192                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013
 18193                              <1> 	;	; tstb u.uid / test user id
 18194                              <1> 	;jna	short sysexec_1
 18195                              <1> 	;	; beq 1f / super user
 18196                              <1> 
 18197                              <1> 	;mov	cl, [i.uid]
 18198                              <1> 	;mov	[u.uid], cl ; 02/08/2013
 18199                              <1> 	;	; movb i.uid,u.uid / put user id of owner of file
 18200                              <1> 				 ; / as process user id
 18201                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 18202                              <1> 	;mov	al, [i.flgs+1]
 18203 00003BE4 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0	; super user (root) ?
 18204                              <1> 	;jna	short sysexec_19 ; yes, super user
 18205                              <1> 	;; 02/05/2021
 18206 00003BEC 7625                <1> 	jna	short sysexec_1	; don't set UID or GID
 18207                              <1> 
 18208                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2
 18209 00003BEE A0[E5670000]        <1> 	mov	al, [i.flgs+1]
 18210                              <1> 
 18211                              <1> 	; test set user id on execution bit 
 18212 00003BF3 A808                <1> 	test	al, 08h ; ISUID flag (800h)
 18213                              <1> 	;jz	short sysexec_19
 18214                              <1> 	; 02/05/2021
 18215 00003BF5 741C                <1> 	jz	short sysexec_1 ; do not set group ID
 18216                              <1> 				; (if user ID will not be set)
 18217                              <1> 				; (02/05/2021)	
 18218                              <1> 	; set user id on exec (800h)
 18219                              <1> 	; 26/03/2021
 18220                              <1> sysexec_setuid:
 18221                              <1> 	;; 27/03/2021
 18222                              <1> 	;cmp	word [u.uid], 0
 18223                              <1> 	;;jna	short sysexec_19 ; super user
 18224                              <1> 	;; 02/05/2021
 18225                              <1> 	;jna	short sysexec_1 ; do not set group ID
 18226                              <1> 	;			; (if user ID will not be set)
 18227                              <1> 	;			; (02/05/2021)
 18228 00003BF7 668B0D[E8670000]    <1> 	mov	cx, [i.uid]
 18229 00003BFE 66890D[B66C0000]    <1> 	mov	[u.uid], cx
 18230                              <1> sysexec_19:
 18231                              <1> 	; test set group id on execution bit 
 18232 00003C05 A804                <1> 	test	al, 04h ; ISGID flag (400h)
 18233 00003C07 740A                <1> 	jz	short sysexec_1
 18234                              <1> sysexec_setgid:
 18235                              <1> 	; set group id on exec (400h)
 18236 00003C09 A0[EA670000]        <1> 	mov	al, [i.gid]
 18237 00003C0E A2[BA6C0000]        <1> 	mov	[u.gid], al
 18238                              <1> 	;
 18239                              <1> sysexec_1:
 18240                              <1> 	; 06/02/2022
 18241                              <1> 	; 12/01/2022
 18242                              <1> 	; 24/12/2021
 18243                              <1> 	; 11/12/2021
 18244                              <1> 	; 04/12/2021
 18245                              <1> 	; 10/10/2015, 18/10/2015
 18246                              <1> 	; 21/07/2015, 24/07/2015
 18247                              <1> 	; 24/06/2015, 25/06/2015
 18248                              <1>         ; Moving arguments to the end of [u.upage]
 18249                              <1> 	; (by regarding page borders in user's memory space)
 18250                              <1> 	;
 18251                              <1> 	; 10/10/2015
 18252                              <1> 	; 21/07/2015
 18253 00003C13 89E5                <1> 	mov	ebp, esp ; (**)
 18254                              <1> 	; 18/10/2015
 18255 00003C15 89EF                <1> 	mov 	edi, ebp
 18256 00003C17 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
 18257                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
 18258 00003C1C 29CF                <1> 	sub	edi, ecx
 18259 00003C1E 89FC                <1> 	mov	esp, edi
 18260 00003C20 31C0                <1> 	xor	eax, eax
 18261 00003C22 A3[906C0000]        <1> 	mov 	[u.nread], eax ; 0
 18262                              <1> 	; 12/01/2022
 18263                              <1> 	; ([argc] must be cleared because previous 'sysexec'
 18264                              <1> 	; may leave it with any value after an error))
 18265 00003C27 A3[F06C0000]        <1> 	mov	[argc], eax ; 0
 18266                              <1> 	;
 18267 00003C2C 49                  <1> 	dec	ecx ; 256 - 1
 18268 00003C2D 890D[8C6C0000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
 18269                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
 18270                              <1> 	; 24/12/2021
 18271                              <1> sysexec_2:
 18272 00003C33 8B35[F46C0000]      <1> 	mov	esi, [argv] ; 18/10/2015
 18273 00003C39 E85C020000          <1> 	call	get_argp
 18274                              <1> 	;mov	ecx, 4 
 18275                              <1> 	; 06/02/2022
 18276 00003C3E 31C9                <1> 	xor	ecx, ecx
 18277 00003C40 B104                <1> 	mov	cl, 4
 18278                              <1> sysexec_3:
 18279 00003C42 21C0                <1> 	and	eax, eax
 18280 00003C44 7454                <1> 	jz	short sysexec_6
 18281                              <1> 	; 18/10/2015
 18282 00003C46 010D[F46C0000]      <1> 	add	[argv], ecx ; 4
 18283                              <1> 	;;inc	word [argc]
 18284                              <1> 	; 11/12/2021
 18285                              <1> 	;inc	dword [argc]
 18286                              <1> 	; 12/01/2022
 18287 00003C4C FE05[F06C0000]      <1> 	inc	byte [argc]
 18288                              <1> 	;
 18289 00003C52 A3[886C0000]        <1> 	mov	[u.base], eax
 18290                              <1>  	; 23/10/2015
 18291 00003C57 66C705[D06C0000]00- <1> 	mov	word [u.pcount], 0
 18292 00003C5F 00                  <1>
 18293                              <1> sysexec_4:
 18294 00003C60 E8C4160000          <1> 	call	cpass ; get a character from user's core memory
 18295 00003C65 750B                <1>         jnz	short sysexec_5
 18296                              <1> 		; (max. 255 chars + null)
 18297                              <1> 	; 18/10/2015
 18298 00003C67 28C0                <1> 	sub 	al, al
 18299 00003C69 AA                  <1> 	stosb
 18300 00003C6A FF05[906C0000]      <1> 	inc	dword [u.nread]
 18301 00003C70 EB28                <1> 	jmp	short sysexec_6
 18302                              <1> sysexec_5:
 18303 00003C72 AA                  <1> 	stosb
 18304 00003C73 20C0                <1> 	and 	al, al
 18305 00003C75 75E9                <1> 	jnz	short sysexec_4
 18306 00003C77 B904000000          <1> 	mov	ecx, 4
 18307 00003C7C 390D[EC6C0000]      <1> 	cmp	[ncount], ecx ; 4
 18308 00003C82 72AF                <1> 	jb	short sysexec_2
 18309 00003C84 8B35[E86C0000]      <1> 	mov	esi, [nbase]
 18310 00003C8A 010D[E86C0000]      <1> 	add	[nbase], ecx ; 4	
 18311                              <1> 	;sub	[ncount], cx 
 18312                              <1> 	; 11/12/2021
 18313 00003C90 290D[EC6C0000]      <1> 	sub	[ncount], ecx
 18314 00003C96 8B06                <1> 	mov	eax, [esi]
 18315 00003C98 EBA8                <1> 	jmp	short sysexec_3
 18316                              <1> sysexec_6:
 18317                              <1> 	; 24/12/2021
 18318                              <1> 	; 18/10/2015
 18319                              <1> 	; argument list transfer from user's core memory to
 18320                              <1> 	; kernel stack frame is OK here.
 18321                              <1> 	; [u.nread] = argument list length
 18322                              <1> 	;mov	[argv], esp ; start address of argument list
 18323                              <1> 	;
 18324                              <1> 	; 18/10/2015
 18325                              <1> 	; 24/07/2015
 18326                              <1>         ; 21/07/2015
 18327                              <1> 	; 02/07/2015
 18328                              <1> 	; 25/06/2015
 18329                              <1> 	; 24/06/2015
 18330                              <1> 	; 23/06/2015
 18331                              <1> 	;
 18332 00003C9A 8B1D[C86C0000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
 18333 00003CA0 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
 18334 00003CA2 740A                <1> 	jz	short sysexec_7
 18335 00003CA4 A1[C46C0000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
 18336 00003CA9 E861E8FFFF          <1> 	call	deallocate_page_dir
 18337                              <1> sysexec_7:
 18338 00003CAE E891E7FFFF          <1> 	call	make_page_dir
 18339                              <1> 	;jc	short sysexec_14
 18340                              <1> 	;jc	panic  ; allocation error 
 18341                              <1> 	;	       ; after a deallocation would be nonsence !?
 18342                              <1> 	; 26/03/2021
 18343 00003CB3 7243                <1> 	jc	short sysexec_panic
 18344                              <1> 	
 18345                              <1> 	; 24/07/2015
 18346                              <1> 	; map kernel pages (1st 4MB) to PDE 0
 18347                              <1> 	;     of the user's page directory
 18348                              <1> 	;     (It is needed for interrupts!)
 18349                              <1> 	; 18/10/2015
 18350 00003CB5 8B15[28670000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
 18351 00003CBB 8B02                <1> 	mov	eax, [edx] ; physical address of
 18352                              <1> 			   ; kernel's first page table (1st 4 MB)
 18353                              <1> 			   ; (PDE 0 of kernel's page directory)
 18354 00003CBD 8B15[C46C0000]      <1> 	mov 	edx, [u.pgdir]
 18355 00003CC3 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
 18356                              <1> 	;
 18357                              <1> 	; 20/07/2015
 18358 00003CC5 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
 18359                              <1> 	; 18/10/2015
 18360 00003CCA BE[E06C0000]        <1> 	mov	esi, pcore ; physical start address
 18361                              <1> sysexec_8:	
 18362 00003CCF B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
 18363 00003CD4 E889E7FFFF          <1> 	call	make_page_table
 18364                              <1> 	;jc	panic
 18365                              <1> 	; 26/03/2021
 18366 00003CD9 721D                <1> 	jc	short sysexec_panic
 18367                              <1> 	;
 18368                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
 18369 00003CDB E890E7FFFF          <1> 	call	make_page ; make new page, clear and set the pte
 18370                              <1> 	;jc	panic
 18371                              <1> 	; 26/03/2021
 18372 00003CE0 7216                <1> 	jc	short sysexec_panic
 18373                              <1> 	;
 18374 00003CE2 8906                <1> 	mov	[esi], eax ; 24/06/2015
 18375                              <1> 	; ebx = virtual address (24/07/2015)
 18376                              <1> 	; 30/11/2021
 18377                              <1> 	;call 	add_to_swap_queue
 18378                              <1> 	; 18/10/2015
 18379 00003CE4 81FE[E46C0000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
 18380 00003CEA 7411                <1> 	je	short sysexec_9 ; yes
 18381 00003CEC BE[E46C0000]        <1> 	mov	esi, ecore  ; physical address of the last page
 18382                              <1> 	; 20/07/2015
 18383 00003CF1 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
 18384                              <1> 	; ebx = virtual end address + segment base address - 4K
 18385 00003CF6 EBD7                <1>         jmp     short sysexec_8
 18386                              <1> sysexec_panic:
 18387                              <1> 	; 26/03/2021
 18388 00003CF8 E9AEECFFFF          <1> 	jmp	panic
 18389                              <1> 
 18390                              <1> sysexec_9:
 18391                              <1> 	; 12/01/2022
 18392                              <1> 	; 11/12/2021
 18393                              <1> 	; 18/10/2015
 18394                              <1> 	; 26/08/2015
 18395                              <1> 	; 25/06/2015
 18396                              <1> 	; move arguments from kernel stack to [ecore]
 18397                              <1> 	; (argument list/line will be copied from kernel stack
 18398                              <1> 	; frame to the last (stack) page of user's core memory)
 18399                              <1> 	; 18/10/2015
 18400 00003CFD 8B3D[E46C0000]      <1> 	mov	edi, [ecore]
 18401 00003D03 81C700100000        <1> 	add	edi, PAGE_SIZE
 18402                              <1> 	;movzx	eax, word [argc]
 18403                              <1> 	; 12/01/2022
 18404                              <1> 	;xor	eax, eax
 18405                              <1> 	;mov	al, [argc]
 18406                              <1> 	; [argc] < 32
 18407                              <1> 	; 11/12/2021
 18408 00003D09 A1[F06C0000]        <1> 	mov	eax, [argc]
 18409 00003D0E 09C0                <1> 	or	eax, eax
 18410 00003D10 7509                <1> 	jnz	short sysexec_10
 18411 00003D12 89FB                <1> 	mov 	ebx, edi
 18412 00003D14 83EB04              <1> 	sub	ebx, 4 
 18413 00003D17 8903                <1> 	mov	[ebx], eax ; 0
 18414 00003D19 EB43                <1> 	jmp 	short sysexec_13
 18415                              <1> sysexec_10:
 18416 00003D1B 8B0D[906C0000]      <1> 	mov	ecx, [u.nread]
 18417                              <1> 	;mov 	esi, [argv]
 18418 00003D21 89E6                <1> 	mov	esi, esp ; start address of argument list
 18419 00003D23 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
 18420                              <1> 
 18421                              <1> 	;;;;
 18422                              <1> 	; 09/05/2022
 18423                              <1> 	; (move edi -backward- to dword boundary)
 18424                              <1> 	; ((this will prevent 'general protection fault' error
 18425                              <1> 	;  as result of a lodsd or dword move instruction
 18426                              <1> 	;  at the end of argument list))
 18427 00003D25 83EF03              <1> 	sub	edi, 3
 18428 00003D28 83E7FC              <1> 	and	edi, ~3 ; (*)
 18429                              <1> 	;;;
 18430                              <1> 
 18431 00003D2B 89C2                <1> 	mov	edx, eax
 18432                              <1> 	; 03/02/2022 ; ([argc] < 32)
 18433 00003D2D FEC2                <1> 	inc	dl ; argument count + 1 for argc value
 18434 00003D2F C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
 18435                              <1> 	; edx <= 128
 18436 00003D32 89FB                <1> 	mov	ebx, edi
 18437                              <1> 	; 09/05/2022 (*) - edi is already dword aligned -
 18438                              <1> 	;and	bl, 0FCh ; 32 bit (dword) alignment
 18439 00003D34 29D3                <1> 	sub 	ebx, edx
 18440 00003D36 89FA                <1> 	mov	edx, edi
 18441 00003D38 F3A4                <1> 	rep	movsb
 18442 00003D3A 89D6                <1> 	mov 	esi, edx
 18443 00003D3C 89DF                <1> 	mov 	edi, ebx
 18444 00003D3E BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
 18445 00003D43 2B15[E46C0000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
 18446 00003D49 AB                  <1> 	stosd	; eax = argument count
 18447                              <1> sysexec_11:
 18448 00003D4A 89F0                <1> 	mov	eax, esi
 18449 00003D4C 01D0                <1> 	add	eax, edx
 18450 00003D4E AB                  <1> 	stosd  ; eax = virtual address
 18451 00003D4F FE0D[F06C0000]      <1> 	dec	byte [argc]
 18452 00003D55 7407                <1> 	jz	short sysexec_13
 18453                              <1> sysexec_12:
 18454 00003D57 AC                  <1> 	lodsb
 18455 00003D58 20C0                <1> 	and	al, al
 18456 00003D5A 75FB                <1> 	jnz	short sysexec_12
 18457 00003D5C EBEC                <1> 	jmp	short sysexec_11
 18458                              <1> 	;
 18459                              <1> 	; 1:
 18460                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
 18461                              <1> 			     ; / pointers to arguments to be passed
 18462                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
 18463                              <1> 			      ; / u.quit = 1 take quit
 18464                              <1> 		; mov $1,u.intr / u.intr determines handling of 
 18465                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
 18466                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
 18467                              <1> 			       ; / system routine
 18468                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector
 18469                              <1> 			       ; / set to take system routine
 18470                              <1> 		; mov $sstack,sp / stack space used during swapping
 18471                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
 18472                              <1> 		; mov $ecore,r5 / r5 has end of core
 18473                              <1> 		; mov $core,r4 / r4 has start of users core
 18474                              <1> 		; mov r4,u.base / u.base has start of users core
 18475                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
 18476                              <1> 	; 1:
 18477                              <1> 		; tst (r2)+ / argument char = "nul"
 18478                              <1> 		; bne 1b
 18479                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of
 18480                              <1> 			  ; / end of argument pointer list
 18481                              <1> 	; 1:
 18482                              <1> 	     ; / move arguments to bottom of users core
 18483                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 18484                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
 18485                              <1> 			    ; / ptr list
 18486                              <1> 		; blo 1f / branch to 1f when all arguments
 18487                              <1> 		       ; / are moved
 18488                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 18489                              <1> 	; 2:
 18490                              <1> 		; tstb (r3)+
 18491                              <1> 		; bne 2b / scan argument for \0 (nul)
 18492                              <1> 
 18493                              <1> 	; 2:
 18494                              <1> 		; movb -(r3),-(r5) / move argument char 
 18495                              <1> 				 ; / by char starting at "ecore"
 18496                              <1> 		; cmp r3,(r2) / moved all characters in 
 18497                              <1> 			    ; / this argument
 18498                              <1> 		; bhi 2b / branch 2b if not
 18499                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
 18500                              <1> 			     ; / r5 has pointer to nth arg
 18501                              <1> 		; br 1b / string
 18502                              <1> 	; 1:
 18503                              <1> 		; clrb -(r5)
 18504                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
 18505                              <1> 			; / last word of argument strings
 18506                              <1> 		; mov $core,r2
 18507                              <1> 	
 18508                              <1> 	; 1: / move argument pointers into core following 
 18509                              <1> 	      ; / argument strings
 18510                              <1> 		; cmp r2,r4
 18511                              <1> 		; bhis 1f / branch to 1f when all pointers
 18512                              <1> 			; / are moved
 18513                              <1> 		; mov (r2)+,-(r5)
 18514                              <1> 		; br 1b
 18515                              <1> 	; 1:
 18516                              <1> 		; sub $core,r4 / gives number of arguments *2
 18517                              <1> 		; asr r4 / divide r4 by 2 to calculate 
 18518                              <1> 		       ; / the number of args stored
 18519                              <1> 		; mov r4,-(r5) / save number of arguments ahead
 18520                              <1> 			     ; / of the argument pointers
 18521                              <1> sysexec_13:
 18522                              <1> 	; 30/11/2021
 18523                              <1> 	; 28/11/2021
 18524                              <1> 	; 19/10/2015
 18525                              <1> 	; 18/10/2015
 18526                              <1> 	; 29/07/2015
 18527                              <1> 	; 25/07/2015
 18528                              <1> 	; 24/07/2015
 18529                              <1> 	; 20/07/2015
 18530                              <1> 	; 25/06/2015
 18531                              <1> 	; 24/06/2015
 18532                              <1> 	; 23/06/2015
 18533                              <1> 	;
 18534                              <1> 	; moving arguments to [ecore] is OK here..
 18535                              <1> 	; 18/10/2015
 18536 00003D5E 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
 18537                              <1> 	; ebx = beginning address of argument list pointers
 18538                              <1> 	;	in user's stack
 18539                              <1> 	; 19/10/2015
 18540 00003D60 2B1D[E46C0000]      <1> 	sub 	ebx, [ecore]
 18541 00003D66 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
 18542                              <1> 			; end of core - 4096 (last page)
 18543                              <1> 			; (virtual address)
 18544 00003D6C 891D[F46C0000]      <1> 	mov	[argv], ebx
 18545 00003D72 891D[946C0000]      <1> 	mov	[u.break], ebx ; available user memory
 18546                              <1> 	;
 18547 00003D78 29C0                <1> 	sub	eax, eax
 18548 00003D7A C705[8C6C0000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
 18549 00003D82 0000                <1>
 18550                              <1> 		; mov $14,u.count
 18551 00003D84 C705[786C0000]-     <1> 	mov	dword [u.fofp], u.off
 18552 00003D8A [846C0000]          <1>
 18553                              <1> 		; mov $u.off,u.fofp
 18554 00003D8E A3[846C0000]        <1> 	mov	[u.off], eax ; 0
 18555                              <1> 		; clr u.off / set offset in file to be read to zero
 18556                              <1> 	; 25/07/2015
 18557 00003D93 A3[886C0000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
 18558                              <1> 	; 25/06/2015 
 18559 00003D98 A1[3C6C0000]        <1> 	mov	eax, [ii] ; 28/11/2021 (32 bit inode number)
 18560                              <1> 	; AX = i-number of the executable file
 18561 00003D9D E83B110000          <1> 	call	readi
 18562                              <1> 		; jsr r0,readi / read in first six words of 
 18563                              <1> 			; / user's file, starting at $core
 18564                              <1> 		; mov sp,r5 / put users stack address in r5
 18565                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
 18566                              <1> 				; / from r5 (leaves number of words
 18567                              <1> 				; / less 26 available for
 18568                              <1> 			     	; / program in user core
 18569                              <1> 		; mov r5,u.count /
 18570                              <1> 	; 25/06/2015
 18571 00003DA2 8B0D[946C0000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
 18572 00003DA8 890D[8C6C0000]      <1> 	mov	[u.count], ecx ; save for overrun check
 18573                              <1> 	;
 18574 00003DAE 8B0D[906C0000]      <1> 	mov	ecx, [u.nread]
 18575 00003DB4 890D[946C0000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
 18576 00003DBA 80F920              <1> 	cmp	cl, 32
 18577 00003DBD 7540                <1>         jne     short sysexec_15
 18578                              <1> 	;:
 18579                              <1> 	; 25/06/2015
 18580                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
 18581                              <1> 	; 18/10/2015
 18582 00003DBF 8B35[E06C0000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
 18583                              <1> 		             ; (phys. start addr. of the exec. file)
 18584 00003DC5 AD                  <1> 	lodsd
 18585 00003DC6 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBh, 1Eh -> jump to +32
 18586 00003DCA 7533                <1> 	jne	short sysexec_15
 18587                              <1> 		; cmp core,$405 / br .+14 is first instruction 
 18588                              <1> 			      ; / if file is standard a.out format
 18589                              <1> 		; bne 1f / branch, if not standard format
 18590 00003DCC AD                  <1> 	lodsd
 18591 00003DCD 89C1                <1> 	mov	ecx, eax ; text (code) section size
 18592 00003DCF AD                  <1> 	lodsd
 18593 00003DD0 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
 18594                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
 18595                              <1> 		              ; / number of bytes in program text
 18596                              <1> 		; sub $14,r5 / subtract 12
 18597 00003DD2 89CB                <1> 	mov	ebx, ecx
 18598                              <1> 	;
 18599                              <1> 	; 25/06/2015
 18600                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
 18601                              <1> 	;	and SINGLIX operating systems (as code template).
 18602                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
 18603                              <1> 	;	due to RUFS (floppy disk file system) restriction...
 18604                              <1> 	;	Overrun is not possible for current version.
 18605                              <1> 	;
 18606 00003DD4 AD                  <1> 	lodsd	
 18607 00003DD5 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
 18608 00003DD7 3B1D[8C6C0000]      <1> 	cmp	ebx, [u.count]
 18609 00003DDD 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
 18610                              <1> 	;
 18611                              <1> 	; 24/07/2015
 18612                              <1> 	; add bss section size to [u.break]
 18613 00003DDF 0105[946C0000]      <1> 	add 	[u.break], eax
 18614                              <1> 	;
 18615 00003DE5 83E920              <1> 	sub	ecx, 32 ; header size (already loaded)
 18616                              <1> 	;cmp	ecx, [u.count]
 18617                              <1> 	;jnb	short sysexec_16
 18618                              <1> 		; cmp r5,u.count /
 18619                              <1> 		; bgt 1f / branch if r5 greater than u.count
 18620 00003DE8 890D[8C6C0000]      <1> 	mov	[u.count], ecx ; required read count
 18621                              <1> 		; mov r5,u.count
 18622                              <1> 	;
 18623 00003DEE EB29                <1> 	jmp	short sysexec_16
 18624                              <1> 	;
 18625                              <1> sysexec_14:
 18626                              <1> 	; 23/06/2015
 18627                              <1> 	; insufficient (out of) memory
 18628 00003DF0 C705[D86C0000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
 18629 00003DF8 0000                <1>
 18630 00003DFA E962F3FFFF          <1> 	jmp	error
 18631                              <1> 	;
 18632                              <1> sysexec_15:
 18633                              <1> 	; 25/06/2015
 18634                              <1>         ;movzx   edx, word [i.size] ; file size
 18635                              <1> 	; 30/11/2021
 18636 00003DFF 8B15[EC670000]      <1> 	mov	edx, [i.size] ; file size
 18637 00003E05 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
 18638 00003E07 7626                <1> 	jna	short sysexec_17 ; no need to next read
 18639 00003E09 01D1                <1> 	add	ecx, edx ; [i.size]
 18640 00003E0B 3B0D[8C6C0000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
 18641 00003E11 77DD                <1> 	ja	short sysexec_14
 18642 00003E13 8915[8C6C0000]      <1> 	mov	[u.count], edx
 18643                              <1> sysexec_16:
 18644                              <1> 	;mov	ax, [ii] ; i-number
 18645                              <1> 	; 28/11/2021
 18646 00003E19 A1[3C6C0000]        <1> 	mov	eax, [ii] ; 32 bit inode number
 18647 00003E1E E8BA100000          <1> 	call	readi
 18648                              <1> 		; add core+10,u.nread / add size of user data area
 18649                              <1> 		                    ; / to u.nread
 18650                              <1> 		; br 2f
 18651                              <1> 	; 1:
 18652                              <1> 		; jsr r0,readi / read in rest of file
 18653                              <1> 	; 2:
 18654 00003E23 8B0D[906C0000]      <1> 	mov	ecx, [u.nread]
 18655 00003E29 010D[946C0000]      <1> 	add	[u.break], ecx
 18656                              <1> 		; mov u.nread,u.break / set users program break to end of
 18657                              <1> 				    ; / user code
 18658                              <1> 		; add $core+14,u.break / plus data area
 18659                              <1> 	; 20/07/2015
 18660                              <1> sysexec_17:
 18661                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 18662                              <1> 	; ('iclose' is not needed for regular files, from now on)
 18663                              <1> 	;;mov	ax, [ii] ; i-number
 18664                              <1> 	;call	iclose
 18665                              <1> 	;	; jsr r0,iclose / does nothing
 18666 00003E2F 31C0                <1>         xor     eax, eax
 18667 00003E31 FEC0                <1> 	inc	al
 18668 00003E33 66A3[B06C0000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
 18669 00003E39 66A3[B26C0000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
 18670                              <1> 	; 30/11/2021
 18671 00003E3F FEC8                <1> 	dec	al  ; eax = 0
 18672                              <1> 	; 02/07/2015
 18673                              <1>         ;cmp	dword [u.ppgdir], 0 ; is the caller sys_init (kernel) ?
 18674 00003E41 3905[C86C0000]      <1> 	cmp	[u.ppgdir], eax ; 0 ; is the caller sys_init (kernel) ?
 18675 00003E47 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
 18676                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
 18677 00003E49 8B15[28670000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
 18678 00003E4F 8915[C86C0000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here
 18679                              <1> sysexec_18:
 18680                              <1> 	; 18/10/2015
 18681                              <1> 	; 05/08/2015
 18682                              <1> 	; 29/07/2015
 18683 00003E55 8B2D[F46C0000]      <1> 	mov	ebp, [argv] ; user's stack pointer must points to argument
 18684                              <1> 			    ; list pointers (argument count)
 18685 00003E5B FA                  <1> 	cli
 18686 00003E5C 8B25[C4660000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
 18687                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
 18688                              <1> 			    ; for this process	 
 18689                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
 18690                              <1> 	;;xor	eax, eax ; 0
 18691                              <1> 	;dec	al ; eax = 0
 18692                              <1> 	; eax = 0 ; 30/11/2021 
 18693 00003E62 66BA2300            <1> 	mov	dx, UDATA
 18694 00003E66 6652                <1> 	push	dx  ; user's stack segment
 18695 00003E68 55                  <1> 	push	ebp ; user's stack pointer
 18696                              <1> 		    ; (points to number of arguments)
 18697 00003E69 FB                  <1> 	sti
 18698 00003E6A 9C                  <1> 	pushfd	; EFLAGS
 18699                              <1> 		; Set IF for enabling interrupts in user mode
 18700                              <1> 	;or	dword [esp], 200h 
 18701                              <1> 	;
 18702                              <1> 	;mov	bx, UCODE
 18703                              <1> 	;push	bx ; user's code segment
 18704 00003E6B 6A1B                <1> 	push	UCODE
 18705                              <1> 	;push	0
 18706 00003E6D 50                  <1> 	push	eax ; EIP (=0) - start address -
 18707                              <1> 		; clr -(r5) / popped into ps when rti in 
 18708                              <1> 			  ; / sysrele is executed
 18709                              <1> 		; mov $core,-(r5) / popped into pc when rti 
 18710                              <1> 		                ; / in sysrele is executed
 18711                              <1> 		;mov r5,0f / load second copyz argument
 18712                              <1> 		;tst -(r5) / decrement r5
 18713 00003E6E 8925[5C6C0000]      <1> 	mov	[u.sp], esp ; 29/07/2015
 18714                              <1> 	; 05/08/2015
 18715                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
 18716                              <1> 	; ('push dx' would cause to general protection fault, 
 18717                              <1> 	; after 'pop ds' etc.)
 18718                              <1> 	;
 18719                              <1> 	;; push dx ; ds (UDATA)
 18720                              <1> 	;; push dx ; es (UDATA)
 18721                              <1> 	;; push dx ; fs (UDATA)
 18722                              <1> 	;; push dx ; gs (UDATA)
 18723                              <1> 	;
 18724                              <1> 	; This is a trick to prevent general protection fault
 18725                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
 18726 00003E74 8EC2                <1> 	mov 	es, dx ; UDATA
 18727 00003E76 06                  <1> 	push 	es ; ds (UDATA)
 18728 00003E77 06                  <1> 	push 	es ; es (UDATA)
 18729 00003E78 06                  <1> 	push 	es ; fs (UDATA)
 18730 00003E79 06                  <1> 	push	es ; gs (UDATA)
 18731 00003E7A 66BA1000            <1> 	mov	dx, KDATA
 18732 00003E7E 8EC2                <1> 	mov	es, dx
 18733                              <1> 	;
 18734                              <1> 	;; pushad simulation
 18735 00003E80 89E5                <1> 	mov	ebp, esp ; esp before pushad
 18736 00003E82 50                  <1> 	push	eax ; eax (0)
 18737 00003E83 50                  <1> 	push	eax ; ecx (0)
 18738 00003E84 50                  <1> 	push	eax ; edx (0)
 18739 00003E85 50                  <1> 	push	eax ; ebx (0)
 18740 00003E86 55                  <1> 	push	ebp ; esp before pushad
 18741 00003E87 50                  <1> 	push	eax ; ebp (0)
 18742 00003E88 50                  <1> 	push	eax ; esi (0)		
 18743 00003E89 50                  <1> 	push	eax ; edi (0)	
 18744                              <1> 	;
 18745 00003E8A A3[646C0000]        <1> 	mov	[u.r0], eax ; eax = 0
 18746 00003E8F 8925[606C0000]      <1> 	mov	[u.usp], esp
 18747                              <1> 		; mov r5,u.r0 /
 18748                              <1> 		; sub $16.,r5 / skip 8 words
 18749                              <1> 		; mov r5,u.sp / assign user stack pointer value,
 18750                              <1> 		;             / effectively zeroes all regs
 18751                              <1> 			    ; / when sysrele is executed
 18752                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
 18753                              <1> 		; clr u.break
 18754                              <1> 		; mov r5,sp / point sp to user's stack
 18755                              <1> 	;
 18756 00003E95 E9E9F2FFFF          <1> 	jmp	sysret0
 18757                              <1> 	;jmp	sysret
 18758                              <1> 		; br sysret3 / return to core image at $core
 18759                              <1> 
 18760                              <1> get_argp:
 18761                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 18762                              <1> 	; 18/10/2015 (nbase, ncount)
 18763                              <1> 	; 21/07/2015
 18764                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
 18765                              <1> 	; Get (virtual) address of argument from user's core memory
 18766                              <1> 	;
 18767                              <1> 	; INPUT:
 18768                              <1> 	;	esi = virtual address of argument pointer
 18769                              <1> 	; OUTPUT:
 18770                              <1> 	;	eax = virtual address of argument
 18771                              <1> 	;
 18772                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
 18773                              <1> 	;
 18774 00003E9A 833D[C86C0000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
 18775                              <1> 				    ; (the caller is kernel)
 18776 00003EA1 767C                <1>         jna     short get_argpk 
 18777                              <1> 	;
 18778 00003EA3 89F3                <1>      	mov	ebx, esi
 18779 00003EA5 E81DE9FFFF          <1> 	call	get_physical_addr ; get physical address
 18780 00003EAA 7254                <1>         jc	short get_argp_err ; 11/12/2021
 18781 00003EAC A3[E86C0000]        <1> 	mov 	[nbase], eax ; physical address	
 18782                              <1> 	;mov	[ncount], cx ; remain byte count in page (1-4096)
 18783                              <1> 	; 11/12/2021
 18784 00003EB1 890D[EC6C0000]      <1> 	mov	[ncount], ecx
 18785 00003EB7 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
 18786                              <1> 	;cmp	cx, ax ; 4
 18787                              <1> 	; 11/12/2021
 18788 00003EBC 39C1                <1> 	cmp	ecx, eax ; 4
 18789 00003EBE 734A                <1> 	jnb	short get_argp2
 18790 00003EC0 89F3                <1> 	mov	ebx, esi
 18791 00003EC2 01CB                <1> 	add	ebx, ecx
 18792 00003EC4 E8FEE8FFFF          <1> 	call	get_physical_addr ; get physical address
 18793 00003EC9 7235                <1> 	jc	short get_argp_err
 18794                              <1> 	;push	esi
 18795 00003ECB 89C6                <1> 	mov	esi, eax
 18796                              <1> 	;xchg	cx, [ncount]
 18797                              <1> 	; 11/12/2021
 18798 00003ECD 870D[EC6C0000]      <1> 	xchg	ecx, [ncount]
 18799 00003ED3 8735[E86C0000]      <1> 	xchg	esi, [nbase]
 18800 00003ED9 B504                <1> 	mov	ch, 4
 18801 00003EDB 28CD                <1> 	sub	ch, cl
 18802                              <1> get_argp0:
 18803 00003EDD AC                  <1> 	lodsb
 18804                              <1> 	;push	ax
 18805                              <1> 	; 11/12/2021
 18806 00003EDE 50                  <1> 	push	eax
 18807 00003EDF FEC9                <1> 	dec	cl
 18808 00003EE1 75FA                <1>         jnz     short get_argp0
 18809 00003EE3 8B35[E86C0000]      <1> 	mov	esi, [nbase]
 18810                              <1> 	; 21/07/2015
 18811 00003EE9 0FB6C5              <1> 	movzx	eax, ch
 18812 00003EEC 0105[E86C0000]      <1> 	add	[nbase], eax
 18813                              <1> 	;sub	[ncount], ax
 18814                              <1> 	; 11/12/2021
 18815 00003EF2 2905[EC6C0000]      <1> 	sub	[ncount], eax
 18816                              <1> get_argp1:
 18817 00003EF8 AC                  <1> 	lodsb
 18818 00003EF9 FECD                <1> 	dec	ch
 18819 00003EFB 743B                <1>         jz      short get_argp3
 18820                              <1>         ;push	ax
 18821                              <1> 	; 11/12/2021
 18822 00003EFD 50                  <1> 	push	eax
 18823 00003EFE EBF8                <1> 	jmp     short get_argp1
 18824                              <1> get_argp_err:
 18825 00003F00 A3[D86C0000]        <1> 	mov	[u.error], eax
 18826 00003F05 E957F2FFFF          <1> 	jmp	error
 18827                              <1> get_argp2:
 18828                              <1> 	; 21/07/2015
 18829                              <1> 	;mov	eax, 4
 18830 00003F0A 8B15[E86C0000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
 18831 00003F10 0105[E86C0000]      <1> 	add	[nbase], eax
 18832                              <1> 	;sub	[ncount], ax
 18833                              <1> 	; 11/12/2021
 18834 00003F16 2905[EC6C0000]      <1> 	sub	[ncount], eax
 18835                              <1> 	;
 18836 00003F1C 8B02                <1> 	mov	eax, [edx]
 18837 00003F1E C3                  <1> 	retn
 18838                              <1> get_argpk:
 18839                              <1> 	; Argument is in kernel's memory space
 18840 00003F1F 66C705[EC6C0000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
 18841 00003F27 10                  <1>
 18842 00003F28 8935[E86C0000]      <1> 	mov	[nbase], esi
 18843 00003F2E 8305[E86C0000]04    <1> 	add	dword [nbase], 4
 18844 00003F35 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physical addr.
 18845 00003F37 C3                  <1> 	retn
 18846                              <1> get_argp3:
 18847 00003F38 B103                <1> 	mov	cl, 3
 18848                              <1> get_argp4:
 18849 00003F3A C1E008              <1> 	shl	eax, 8
 18850                              <1> 	;pop	dx
 18851                              <1> 	; 11/12/2021
 18852 00003F3D 5A                  <1> 	pop	edx
 18853 00003F3E 88D0                <1> 	mov 	al, dl
 18854 00003F40 E2F8                <1>         loop    get_argp4
 18855                              <1> 	;pop	esi
 18856 00003F42 C3                  <1> 	retn	
 18857                              <1> 
 18858                              <1> sysfstat:
 18859                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 18860                              <1> 	;	([idev] return in eax)
 18861                              <1> 	;	0 = root device
 18862                              <1> 	;	1 = mounted device (>0)
 18863                              <1> 	; 06/02/2022 
 18864                              <1> 	; 08/01/2022
 18865                              <1> 	; 26/12/2021 (Retro UNIX 386 v1.2) 
 18866                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18867                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18868                              <1> 	;
 18869                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
 18870                              <1> 	; on open files instead of files given by name. It puts the
 18871                              <1> 	; buffer address on the stack, gets the i-number and
 18872                              <1> 	; checks to see if the file is open for reading or writing.
 18873                              <1> 	; If the file is open for writing (i-number is negative)
 18874                              <1> 	; the i-number is set positive and a branch into 'sysstat'
 18875                              <1> 	; is made.	
 18876                              <1> 	;
 18877                              <1> 	; Calling sequence:
 18878                              <1> 	;	sysfstat; buf
 18879                              <1> 	; Arguments:
 18880                              <1> 	;	buf - buffer address
 18881                              <1> 	;
 18882                              <1> 	; Inputs: *u.r0 - file descriptor
 18883                              <1> 	; Outputs: buffer is loaded with file information
 18884                              <1> 	; ...............................................................
 18885                              <1> 	;				
 18886                              <1> 	; Retro UNIX 8086 v1 modification:
 18887                              <1> 	;       'sysfstat' system call has two arguments; so,
 18888                              <1> 	;	* 1st argument, file descriptor is in BX register
 18889                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 18890                              <1> 
 18891                              <1> 	; / set status of open file
 18892                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
 18893 00003F43 51                  <1> 	push	ecx ; *
 18894                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
 18895                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
 18896                              <1> 		; jsr r0,getf / get the files i-number
 18897                              <1> 	; BX = file descriptor (file number)
 18898 00003F44 E8F9000000          <1> 	call	getf1
 18899                              <1> 	; 06/02/2022
 18900 00003F49 21C0                <1> 	and	eax, eax
 18901                              <1> 	;and	ax, ax ; i-number of the file
 18902                              <1> 		; tst	r1 / is it 0?
 18903                              <1> 	;jz	error
 18904                              <1> 		; beq error3 / yes, error
 18905                              <1> 	;jnz	short sysfstat1
 18906                              <1> 	; 26/12/2021 - Retro UNIX 386 v1.2 (runix v2 file system)
 18907 00003F4B 752C                <1> 	jnz	short sysstat1
 18908 00003F4D C705[D86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 18909 00003F55 0000                <1>
 18910 00003F57 E905F2FFFF          <1> 	jmp	error
 18911                              <1> 	; 26/12/2021
 18912                              <1> ;sysfstat1:
 18913                              <1> 	;cmp	ah, 80h
 18914                              <1>         ;jb      short sysstat1
 18915                              <1> 	;	; bgt 1f / if i-number is negative (open for writing)
 18916                              <1> 	;neg	ax
 18917                              <1> 	;	; neg r1 / make it positive, then branch
 18918                              <1> 	; 08/01/2022
 18919                              <1> 	;jmp	short sysstat1
 18920                              <1> 		; br 1f / to 1f
 18921                              <1> sysstat:
 18922                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.1, Kernel v0.2.1.3)
 18923                              <1> 	;	([idev] return in eax)
 18924                              <1> 	;	0 = root device
 18925                              <1> 	;	1 = mounted device (>0)
 18926                              <1> 	; 26/12/2021 (Retro UNIX 386 v1.2) 
 18927                              <1> 	; 18/10/2015
 18928                              <1> 	; 07/10/2015
 18929                              <1> 	; 02/09/2015
 18930                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18931                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18932                              <1> 	;
 18933                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
 18934                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
 18935                              <1> 	; long and information about the file placed in it.	
 18936                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
 18937                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
 18938                              <1> 	; is then loaded and the results are given in the UNIX
 18939                              <1> 	; Programmers Manual sysstat (II).	
 18940                              <1> 	;
 18941                              <1> 	; Calling sequence:
 18942                              <1> 	;	sysstat; name; buf
 18943                              <1> 	; Arguments:
 18944                              <1> 	;	name - points to the name of the file
 18945                              <1> 	;	buf - address of a 34 bytes buffer
 18946                              <1> 	; Inputs: -
 18947                              <1> 	; Outputs: buffer is loaded with file information
 18948                              <1> 	; ...............................................................
 18949                              <1> 	;				
 18950                              <1> 	; Retro UNIX 8086 v1 modification: 
 18951                              <1> 	;       'sysstat' system call has two arguments; so,
 18952                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 18953                              <1> 	;	to get sysstat system call arguments from the user;
 18954                              <1> 	;	* 1st argument, name is pointed to by BX register
 18955                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 18956                              <1> 	;
 18957                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 18958                              <1> 	;	      arguments which were in these registers;
 18959                              <1> 	;	      but, it returns by putting the 1st argument
 18960                              <1> 	;	      in 'u.namep' and the 2nd argument
 18961                              <1> 	;	      on top of stack. (1st argument is offset of the
 18962                              <1> 	;	      file/path name in the user's program segment.)		 	
 18963                              <1> 	
 18964                              <1> 	; / ; name of file; buffer - get files status
 18965                              <1> 		; jsr r0,arg2 / get the 2 arguments
 18966 00003F5C 891D[806C0000]      <1> 	mov	[u.namep], ebx
 18967 00003F62 51                  <1> 	push	ecx ; *
 18968 00003F63 E810010000          <1> 	call	namei
 18969                              <1> 		; jsr r0,namei / get the i-number for the file
 18970                              <1> 	;jc	error
 18971                              <1> 		; br error3 / no such file, error
 18972 00003F68 730F                <1> 	jnc	short sysstat1
 18973                              <1> 	; pop 	ecx
 18974                              <1> sysstat_err0:
 18975                              <1> 	; 'file not found !' error
 18976 00003F6A C705[D86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 18977 00003F72 0000                <1>
 18978 00003F74 E9E8F1FFFF          <1> 	jmp	error
 18979                              <1> 
 18980                              <1> sysstat1: ; 1:
 18981 00003F79 E8F30B0000          <1> 	call	iget
 18982                              <1> 		; jsr r0,iget / get the i-node into core
 18983                              <1> 	; 07/10/2015 (ax = [ii], inode number)
 18984                              <1> 	; 02/09/2015
 18985 00003F7E 8F05[886C0000]      <1> 	pop	dword [u.base] ; *
 18986                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
 18987 00003F84 E861000000          <1> 	call	sysstat_gpa ; get physical address
 18988 00003F89 730A                <1> 	jnc 	short sysstat2
 18989                              <1> sysstat_err1:
 18990 00003F8B A3[D86C0000]        <1> 	mov	dword [u.error], eax ; error code
 18991 00003F90 E9CCF1FFFF          <1> 	jmp	error
 18992                              <1> sysstat2:
 18993 00003F95 A0[3C6C0000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
 18994 00003F9A AA                  <1> 	stosb
 18995 00003F9B FF05[886C0000]      <1> 	inc 	dword [u.base]
 18996                              <1> 	;dec 	cx
 18997 00003FA1 49                  <1> 	dec	ecx ; 26/12/2021
 18998 00003FA2 7505                <1> 	jnz	short sysstat3
 18999 00003FA4 E841000000          <1> 	call	sysstat_gpa
 19000                              <1> 	;jc	short sysstat_err1
 19001                              <1> sysstat3:
 19002 00003FA9 A0[3D6C0000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
 19003 00003FAE AA                  <1> 	stosb
 19004                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
 19005 00003FAF FF05[886C0000]      <1> 	inc 	dword [u.base]
 19006                              <1> 	;;dec 	word [u.pcount]
 19007                              <1> 	;dec	cx
 19008 00003FB5 49                  <1> 	dec	ecx ; 26/12/2021
 19009 00003FB6 7505                <1> 	jnz	short sysstat4
 19010 00003FB8 E82D000000          <1> 	call	sysstat_gpa
 19011                              <1> 	;jc	short sysstat_err1	
 19012                              <1> sysstat4:
 19013 00003FBD BE[E4670000]        <1> 	mov	esi, inode
 19014                              <1> 		; mov $inode,r2 / r2 points to i-node
 19015                              <1> sysstat5: ; 1:
 19016 00003FC2 A4                  <1> 	movsb
 19017                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
 19018 00003FC3 FF05[886C0000]      <1> 	inc 	dword [u.base]
 19019                              <1> 	;;dec 	word [u.pcount]
 19020                              <1> 	;dec	cx
 19021 00003FC9 49                  <1> 	dec	ecx ; 26/12/2021
 19022 00003FCA 7505                <1> 	jnz	short sysstat6
 19023 00003FCC E819000000          <1> 	call	sysstat_gpa
 19024                              <1> 	;jc	short sysstat_err1
 19025                              <1> sysstat6:
 19026                              <1> 	; 26/12/2021 - Retro UNIX 386 v1.2
 19027 00003FD1 81FE[24680000]      <1> 	cmp	esi, inode + 64 ; Retro UNIX v2 inode		
 19028                              <1> 	;cmp	esi, inode + 32
 19029                              <1> 		; cmp r2,$inode+32 / done?
 19030 00003FD7 75E9                <1> 	jne	short sysstat5
 19031                              <1> 		; bne 1b / no, go back
 19032                              <1> 
 19033                              <1> 	;;;
 19034                              <1> 	; 09/05/2022
 19035                              <1> 	;*** additional feature *** -retro unix only- 
 19036                              <1> 	;
 19037                              <1> 	; !! return device number -of current inode- in eax !!
 19038                              <1> 	;
 19039                              <1> 	; (modification reason/purpose:
 19040                              <1> 	; to improve 'pwd' command's pathname output/result
 19041                              <1> 	; and to correct 'cp' command's 'can not copy file itself'
 19042                              <1> 	; error due to same inode numbers in root file system
 19043                              <1> 	; and mounted file system.)
 19044                              <1> 	;
 19045 00003FD9 29C0                <1> 	sub	eax, eax
 19046 00003FDB A0[406C0000]        <1> 	mov	al, [idev] ; [cdev]
 19047 00003FE0 A3[646C0000]        <1> 	mov	[u.r0], eax
 19048                              <1> 	;;;  
 19049                              <1> 
 19050 00003FE5 E997F1FFFF          <1> 	jmp	sysret
 19051                              <1> 		; br sysret3 / return through sysret
 19052                              <1> 	;
 19053                              <1> sysstat_gpa: ; get physical address of file status buffer
 19054                              <1> 	; 02/09/2015
 19055 00003FEA 8B1D[886C0000]      <1> 	mov 	ebx, [u.base]
 19056                              <1> 	; 07/10/2015
 19057 00003FF0 E8D2E7FFFF          <1> 	call	get_physical_addr ; get physical address
 19058                              <1> 	;jc	short sysstat_gpa1
 19059 00003FF5 7294                <1> 	jc	short sysstat_err1
 19060                              <1> 	; 18/10/2015
 19061 00003FF7 89C7                <1> 	mov	edi, eax ; physical address
 19062                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
 19063                              <1> ;sysstat_gpa1:
 19064 00003FF9 C3                  <1> 	retn
 19065                              <1> 
 19066                              <1> fclose:
 19067                              <1> 	; 12/03/2022
 19068                              <1> 	; 11/02/2022
 19069                              <1> 	; 08/01/2022
 19070                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 19071                              <1> 	; 08/04/2021
 19072                              <1> 	; 04/04/2021
 19073                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
 19074                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
 19075                              <1> 	;            (32 bit offset pointer modification)
 19076                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
 19077                              <1> 	;
 19078                              <1> 	; Given the file descriptor (index to the u.fp list)
 19079                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
 19080                              <1> 	; If i-node is active (i-number > 0) the entry in 
 19081                              <1> 	; u.fp list is cleared. If all the processes that opened
 19082                              <1> 	; that file close it, then fsp etry is freed and the file
 19083                              <1> 	; is closed. If not a return is taken. 
 19084                              <1> 	; If the file has been deleted while open, 'anyi' is called
 19085                              <1> 	; to see anyone else has it open, i.e., see if it is appears
 19086                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
 19087                              <1> 	; a check is made to see if the file is special.	
 19088                              <1> 	;
 19089                              <1> 	; INPUTS ->
 19090                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
 19091                              <1> 	;    u.fp - list of entries in the fsp table
 19092                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
 19093                              <1> 	; OUTPUTS ->
 19094                              <1> 	;    r1 - contains the same file descriptor
 19095                              <1> 	;    r2 - contains i-number
 19096                              <1> 	;
 19097                              <1> 	; ((AX = R1))
 19098                              <1> 	; ((Modified registers: edx, ebx, ecx, esi, edi, ebp))
 19099                              <1> 	;
 19100                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
 19101                              <1> 	;              if i-number of the file is 0. (error)
 19102                              <1> 
 19103                              <1> 	; 08/04/2021
 19104                              <1> 	; INPUT:
 19105                              <1> 	;	eax = file descriptor
 19106                              <1> 	; OUTPUT:
 19107                              <1> 	;	cf = 0 -> eax = file descriptor
 19108                              <1> 	;	cf = 1 -> file not open ; 11/02/2022
 19109                              <1> 
 19110                              <1> 	; 18/08/2020
 19111                              <1> 	;movzx	edx, ax ; **
 19112 00003FFA 89C3                <1> 	mov	ebx, eax
 19113                              <1> 
 19114                              <1> 	; 18/08/2020
 19115                              <1> _fclose:
 19116 00003FFC 53                  <1> 	push	ebx ; ***  ; file descriptor (index to u.fp)
 19117                              <1> 
 19118                              <1> 	;push	ax ; ***
 19119                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
 19120                              <1> 			     ; / the index to u.fp list)
 19121                              <1> 	; ebx = file descriptor/number
 19122 00003FFD E840000000          <1> 	call	getf
 19123                              <1> 		; jsr r0,getf / r1 contains i-number, 
 19124                              <1> 			    ; / cdev has device =, u.fofp 
 19125                              <1> 			    ; / points to 3rd word of fsp entry
 19126                              <1> 	;cmp	eax, 1 ; 18/08/2020
 19127 00004002 6683F801            <1> 	cmp	ax, 1 ; r1
 19128                              <1> 		; tst r1 / is i-number 0?
 19129 00004006 7238                <1> 	jb	short fclose_2
 19130                              <1> 		; beq 1f / yes, i-node not active so return
 19131                              <1> 		; tst (r0)+ / no, jump over error return
 19132                              <1> 	
 19133                              <1> 	;mov	ebx, edx ; **
 19134                              <1>  	; 18/08/2020
 19135 00004008 8B1C24              <1> 	mov	ebx, [esp]
 19136                              <1> 	;mov	edx, eax 
 19137                              <1> 	;;mov 	dx, ax ; *
 19138                              <1> 		; mov r1,r2 / move i-number to r2 ;*
 19139                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
 19140                              <1> 			    ; / which is index to u.fp ; **
 19141 0000400B C683[6E6C0000]00    <1> 	mov	byte [ebx+u.fp], 0
 19142                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
 19143 00004012 8B1D[786C0000]      <1> 	mov	ebx, [u.fofp]
 19144                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
 19145                              <1> 
 19146                              <1> 	; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
 19147                              <1> 	; ebx = 5th word of fsp entry (64 bit file offset)
 19148                              <1> fclose_0:
 19149                              <1> 	; 08/01/2022
 19150 00004018 FE4BFE              <1> 	dec	byte [ebx-2] ; 18/08/2020 - Retro UNIX 386 v2
 19151                              <1> 	;dec	byte [ebx+4] ; 18/06/2015
 19152                              <1> 		; decb 2(r1) / decrement the number of processes 
 19153                              <1> 			   ; / that have opened the file
 19154 0000401B 7923                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
 19155                              <1> 		; bge 1f / if all processes haven't closed the file, return
 19156                              <1> 	;
 19157                              <1> 	;push	dx ; *
 19158                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
 19159                              <1> 	;;xor	ax, ax ; 0
 19160                              <1> 	;xor	eax, eax ; 18/08/2020
 19161                              <1> 		; clear 1st word of fsp entry
 19162                              <1> 	;mov	[ebx-8], ax ; 0 ; 18/08/2020
 19163                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
 19164 0000401D 66C743F80000        <1> 	mov	word [ebx-8], 0 ; clear 1st word of fsp entry ; i-number
 19165                              <1> 			; Note: 32 bit i-node number field is ready but
 19166                              <1> 			;	it is not used in current runix version.	
 19167                              <1> 
 19168                              <1> 	;;mov	[ebx-4], ax ; 0
 19169                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
 19170                              <1> 	;mov	al, [ebx+5] ; 18/06/2015
 19171                              <1> 	;	; tstb	3(r1) / has this file been deleted
 19172                              <1> 	;and	al, al
 19173                              <1> 	;jz	short fclose_1
 19174                              <1> 	;	; beq 2f / no, branch
 19175                              <1> 
 19176                              <1> 	;push	edx ; * ; 18/08/2020
 19177                              <1> 	;mov	eax, edx ; * ; 18/08/2020
 19178                              <1> 
 19179                              <1> 	;; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
 19180                              <1> 	;;test	byte [ebx-3], 80h ; open mode & status flags
 19181                              <1> 	; 04/04/2021 - Retro UNIX 386 v2 (new fsp structure)
 19182                              <1> 	;test	byte [ebx-4], 80h ; open mode & status flags 
 19183                              <1> 	;jz	short fclose_1	; deleted file flag (bit 7)
 19184                              <1> 
 19185                              <1> 	; 04/04/2021
 19186 00004023 31D2                <1> 	xor	edx, edx
 19187                              <1> 	; 08/01/2022
 19188 00004025 8A53FD              <1> 	mov	dl, [ebx-3] ; open mode & status flags
 19189 00004028 F6C280              <1> 	test	dl, 80h	    ; deleted file flag (bit 7)
 19190 0000402B 7409                <1> 	jz	short fclose_1 ; (not deleted -while open-)
 19191 0000402D 52                  <1> 	push	edx
 19192                              <1> 	; 12/03/2022
 19193 0000402E 50                  <1> 	push	eax ; inode number 
 19194                              <1> 
 19195                              <1> 	; deleted file !
 19196                              <1> 
 19197                              <1> 	;mov	ax, dx ; *
 19198                              <1> 		; mov r2,r1 / yes, put i-number back into r1
 19199                              <1> 	; AX = inode number
 19200 0000402F E84E050000          <1> 	call	anyi
 19201                              <1> 		; jsr r0,anyi / free all blocks related to i-number
 19202                              <1> 			    ; / check if file appears in fsp again
 19203                              <1> 	; 12/03/2022
 19204 00004034 58                  <1> 	pop	eax ; inode number
 19205                              <1> 	; 04/04/2021
 19206 00004035 5A                  <1> 	pop	edx
 19207                              <1> 	; 11/02/2022
 19208                              <1> 	;(cpu will come here if anyi returns -without error-)
 19209                              <1> 	;; 08/04/2021
 19210                              <1> 	;jc	short fclose_3 ; error code in eax	
 19211                              <1> 	;; 18/08/2020
 19212                              <1> 	;;jmp	short fclose_2
 19213                              <1> 
 19214                              <1> 	; ax = inode number
 19215                              <1> fclose_1: ; 2:
 19216                              <1> 	; 04/04/2021
 19217 00004036 80E201              <1> 	and	dl, 1
 19218 00004039 FEC2                <1> 	inc	dl ; 0 -> 1 (open for read), 1 -> 2 (open for write)
 19219                              <1> 	
 19220                              <1> 	;pop	eax ; * ; 18/08/2020 
 19221                              <1> 	;;pop	ax ; *
 19222                              <1> 		; mov (sp)+,r1 / put i-number back into r1
 19223 0000403B E814170000          <1> 	call	iclose ; close if it is special file 
 19224                              <1> 		; jsr r0,iclose / check to see if it is a special file
 19225                              <1> 	; 11/02/2022
 19226                              <1> 	;(cpu will come here if iclose returns -without error-)
 19227                              <1> 	;; 08/04/2021
 19228                              <1> 	;jnc	short fclose_2
 19229                              <1> ;fclose_3:
 19230                              <1> ;	pop	ebx ; ***  ; file descriptor
 19231                              <1> ;	; eax = error code
 19232                              <1> ;	retn
 19233                              <1> fclose_2: ; 1:
 19234 00004040 58                  <1> 	pop	eax ; *** ; 18/08/2020
 19235                              <1> 	;pop	ax ; ***
 19236                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
 19237 00004041 C3                  <1> 	retn
 19238                              <1> 		; rts r0
 19239                              <1> 
 19240                              <1> 	; 08/01/2022
 19241                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 19242                              <1> getf:	; / get the device number and the i-number of an open file
 19243                              <1> 	; 13/05/2015
 19244                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 19245                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 19246                              <1> 
 19247                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 19248                              <1> 	;
 19249                              <1> 	; 16/05/2021
 19250                              <1> 	; 27/03/2020 - Retro UNIX 386 v2 
 19251                              <1> 	;	(new open files -fsp- structure)
 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> 	; INPUT: 
 19257                              <1> 	;    ;eax = file descriptor/number
 19258                              <1> 	;     ebx = file descriptor/number ; 18/08/2020 	
 19259                              <1> 	; OUTPUT:
 19260                              <1> 	;     bl = open mode & status flag ; 27/03/2020
 19261                              <1> 	;        (bit 0 open mode flag, 0 = read, 1 = write)  
 19262                              <1> 	;    eax = inode number (in AX)
 19263                              <1> 	;          If eax = 0 -> file not open
 19264                              <1> 	;   byte [cdev] = logical drive number (of inode in eax)
 19265                              <1> 	;	
 19266                              <1> 	; Modified registers: eax, ebx
 19267                              <1> 
 19268                              <1> 	; 16/05/2021 ('getf' procedure, unix v7 x86 'fio.c')
 19269                              <1> 	; /*
 19270                              <1> 	;  * Convert a user supplied
 19271                              <1> 	;  * file descriptor into a pointer
 19272                              <1> 	;  * to a file structure.
 19273                              <1> 	;  * Only task is to check range
 19274                              <1> 	;  * of the descriptor.
 19275                              <1> 	;  */
 19276                              <1> 	; struct file *
 19277                              <1> 	; getf(f)
 19278                              <1> 	;
 19279                              <1> 	; 18/08/2020
 19280                              <1> 	; 	ebx = file descriptor/number
 19281                              <1> 
 19282                              <1> 	; 16/05/2021
 19283                              <1> 	;NOFILE	equ 10 ; 08/01/2022
 19284                              <1> 
 19285                              <1> 	; 18/08/2020
 19286                              <1> 	;mov	ebx, eax
 19287                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
 19288                              <1> 
 19289                              <1> 	; ebx = file descriptor/number
 19290                              <1> 
 19291                              <1> 	; 18/08/2020
 19292 00004042 29C0                <1> 	sub	eax, eax ; eax = 0
 19293                              <1>  
 19294 00004044 83FB0A              <1> 	cmp	ebx, 10 ; cmp ebx, NOFILE ; 16/05/2021
 19295                              <1> 		; cmp r1,$10. / user limited to 10 open files
 19296 00004047 732E                <1>         jnb	short getf2 ; 13/05/2015
 19297                              <1> 	;jnb	error
 19298                              <1> 		; bhis error3 / u.fp is table of users open files,
 19299                              <1> 			    ; / index in fsp table
 19300                              <1> 	; 08/01/2022
 19301 00004049 8A83[6E6C0000]      <1> 	mov	al, [ebx+u.fp]
 19302                              <1> 	;mov	bl, [ebx+u.fp]
 19303                              <1> 		; movb u.fp(r1),r1 / r1 contains number of entry 
 19304                              <1> 		                 ; / in fsp table
 19305 0000404F 08C0                <1> 	or	al, al ; 08/01/2022
 19306                              <1> 	;or	bl, bl
 19307                              <1> 	;jnz	short getf3
 19308 00004051 7424                <1> 	jz	short getf2 ; 18/08/2020
 19309                              <1> 	;;jz	short getf4
 19310                              <1> 		; beq 1f / if its zero return
 19311                              <1> ;getf2:
 19312                              <1> ;	; 'File not open !' error (ax=0)
 19313                              <1> ;	;sub	eax, eax ; 18/08/2020
 19314                              <1> ;	retn
 19315                              <1> ;getf3:	
 19316                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
 19317                              <1> 	;
 19318                              <1> 	; 'fsp' table (10 bytes/entry)
 19319                              <1> 	; bit 15				   bit 0
 19320                              <1> 	; ---|-------------------------------------------
 19321                              <1> 	; r/w|		i-number of open file
 19322                              <1> 	; ---|-------------------------------------------
 19323                              <1> 	;		   device number
 19324                              <1> 	; -----------------------------------------------
 19325                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 19326                              <1> 	; -----------------------------------------------
 19327                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 19328                              <1> 	; ----------------------|------------------------
 19329                              <1> 	;  flag that says file 	| number of processes
 19330                              <1> 	;   has been deleted	| that have file open 
 19331                              <1> 	; ----------------------|------------------------
 19332                              <1> 
 19333                              <1> 	; Retro UNIX 386 v2 modification ! (27/03/2020)
 19334                              <1> 
 19335                              <1> 	; bit 15 				    bit 0
 19336                              <1> 	; ----------------------------------------------- byte 0
 19337                              <1> 	;    	       i-number of open file           
 19338                              <1> 	; ----------------------------------------------- byte 2
 19339                              <1> 	;          high word of 32 bit i-number       
 19340                              <1> 	; ----------------------------------------------- byte 4
 19341                              <1> 	;    open mode & status  |   device number     
 19342                              <1> 	; ----------------------------------------------- byte 6
 19343                              <1> 	;       reserved byte    |    open count  
 19344                              <1> 	; ----------------------------------------------- byte 8
 19345                              <1> 	;   offset pointer, i.e., r/w pointer to file 
 19346                              <1> 	; ----------------------------------------------- byte 10
 19347                              <1> 	;     64 bit file offset pointer (bit 16-31)  
 19348                              <1> 	; ----------------------------------------------- byte 12
 19349                              <1> 	;     64 bit file offset pointer (bit 32-47)   
 19350                              <1> 	; ----------------------------------------------- byte 14
 19351                              <1> 	;     64 bit file offset pointer (bit 48-63)  
 19352                              <1> 	; ----------------------------------------------- byte 16
 19353                              <1> 	
 19354                              <1> 	; 11/05/2015 - Retro UNIX 386 v1
 19355                              <1> 	;mov	eax, 10
 19356                              <1> 
 19357                              <1> 	; 27/03/2020 - Retro UNIX 386 v2	
 19358                              <1> 	;mov	eax, opfls.size ; mov eax, 16
 19359                              <1> 	
 19360                              <1> 	;sub	eax, eax ; 18/08/2020 ; eax = 0
 19361                              <1> 
 19362                              <1> 	;mov	al, opfls.size  ; mov al, 16
 19363                              <1> 	;
 19364                              <1> 	;mul	bl
 19365                              <1> 	;;mov	ebx, fsp-6 ; the 3rd word in the fsp entry
 19366                              <1> 	;; 27/03/2020
 19367                              <1> 	;mov	ebx, fsp-(opfls.size-opfls.offset) ; fsp-8
 19368                              <1> 	
 19369                              <1> 	;add	ebx, eax
 19370                              <1> 		; asl r1
 19371                              <1> 		; asl r1 / multiply by 8 to get index into 
 19372                              <1> 		       ; / fsp table entry
 19373                              <1> 		; asl r1
 19374                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
 19375                              <1> 			      ; / in the fsp entry
 19376                              <1> 	; 08/01/2022
 19377 00004053 88C3                <1> 	mov	bl, al
 19378                              <1> 	; 18/08/2020
 19379 00004055 FECB                <1> 	dec	bl ; zero based fsp table entry number
 19380                              <1> 	;shl	bl, 4 ; * 16 ; opfls.size
 19381                              <1> 	; 08/01/2022
 19382 00004057 C1E304              <1> 	shl	ebx, 4 ; * 16 ; opfls.size
 19383 0000405A 81C3[DC680000]      <1> 	add	ebx, fsp+8 ; opfls.offset	
 19384                              <1> 	; ebx = address of the file offset pointer 
 19385                              <1> 	;	(not file offset! not fsp entry address !)
 19386                              <1> 
 19387 00004060 891D[786C0000]      <1> 	mov	[u.fofp], ebx
 19388                              <1> 		; mov r1,u.fofp / save address of 3rd word 
 19389                              <1> 			     ; / in fsp entry in u.fofp
 19390                              <1> 	; 18/08/2020
 19391 00004066 8A43FD              <1> 	mov	al, [ebx-3]  ; open mode & status flags
 19392                              <1> 
 19393 00004069 50                  <1> 	push	eax
 19394                              <1> 
 19395                              <1> 	;mov	ax, [ebx]
 19396                              <1> 	;;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
 19397                              <1> 	;mov	[cdev], ax ; ;;in fact (!) 
 19398                              <1> 			     ;;dev number is in 1 byte
 19399                              <1> 		; mov -(r1),cdev / remove the device number cdev
 19400                              <1> 
 19401                              <1> 	; 18/08/2020
 19402 0000406A 8A43FC              <1> 	mov	al, [ebx-4]  ; logical drive number
 19403                              <1> 
 19404 0000406D A2[416C0000]        <1> 	mov	[cdev], al
 19405                              <1> 
 19406                              <1> 	;dec	ebx
 19407                              <1> 	;dec	ebx
 19408                              <1> 	; 18/08/2020
 19409 00004072 668B43F8            <1> 	mov	ax, [ebx-8]
 19410                              <1> 		; mov -(r1),r1 / and the i-number r1
 19411                              <1> 
 19412 00004076 5B                  <1> 	pop	ebx ; ebx = bl = open mode and status flag
 19413                              <1> 		; (bit 0 is open mode flag, 0 = read, 1 = write)
 19414                              <1> 	; eax = inode number (in ax)	
 19415                              <1> 
 19416                              <1> getf2:	; 18/08/2020
 19417                              <1> getf4:	; 1: ; 08/01/2022
 19418 00004077 C3                  <1> 	retn
 19419                              <1> 		; rts r0
 19420                              <1> 
 19421                              <1> 	; 15/05/2022
 19422                              <1> 	; 08/01/2022
 19423                              <1> 	; 19/12/2021
 19424                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 19425                              <1> namei:
 19426                              <1> 	; 18/10/2021
 19427                              <1> 	; 12/06/2021
 19428                              <1> 	; 01/05/2021
 19429                              <1> 	; 26/03/2021
 19430                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 19431                              <1> 	; 04/12/2015 (14 byte file names)
 19432                              <1> 	; 18/10/2015 (nbase, ncount)
 19433                              <1> 	; 12/10/2015
 19434                              <1> 	; 21/08/2015
 19435                              <1> 	; 18/07/2015
 19436                              <1> 	; 02/07/2015
 19437                              <1> 	; 17/06/2015
 19438                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
 19439                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 19440                              <1> 	;
 19441                              <1> 	; 'namei' takes a file path name and returns i-number of
 19442                              <1> 	; the file in the current directory or the root directory
 19443                              <1> 	; (if the first character of the pathname is '/').	
 19444                              <1> 	;
 19445                              <1> 	; INPUTS ->
 19446                              <1> 	;    u.namep - points to a file path name
 19447                              <1> 	;    u.cdir - i-number of users directory
 19448                              <1> 	;    u.cdev - device number on which user directory resides	
 19449                              <1> 	; OUTPUTS ->
 19450                              <1> 	;    r1 - i-number of file
 19451                              <1> 	;    cdev
 19452                              <1> 	;    u.dirbuf - points to directory entry where a match 
 19453                              <1> 	;               occurs in the search for file path name.
 19454                              <1> 	;	        If no match u.dirp points to the end of 
 19455                              <1> 	;               the directory and r1 = i-number of the current
 19456                              <1> 	;	        directory.	
 19457                              <1> 	; ((AX = R1))
 19458                              <1> 	;
 19459                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
 19460                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 19461                              <1> 	;
 19462                              <1> 
 19463                              <1> 	;mov	ax, [u.cdir]
 19464                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
 19465                              <1> 			      ; / in r1
 19466                              <1> 	; 01/05/2021
 19467 00004078 A1[686C0000]        <1> 	mov	eax, [u.cdir]	
 19468 0000407D 8A15[6C6C0000]      <1> 	mov	dl, [u.cdrv]
 19469 00004083 8815[416C0000]      <1> 	mov	[cdev], dl
 19470                              <1> 	;mov	dx, [u.cdrv]
 19471                              <1> 	;mov	[cdev], dx	; NOTE: Retro UNIX 8086 v1 
 19472                              <1> 				; device/drive number is in 1 byte, 
 19473                              <1> 				; not in 1 word!
 19474                              <1> 		; mov u.cdev,cdev / device number for users directory 
 19475                              <1> 				; / into cdev
 19476                              <1> 	; 12/10/2015
 19477                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 19478                              <1>       	; convert virtual (pathname) addr to physical address
 19479 00004089 E849010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
 19480                              <1> 		; esi = physical address of [u.namep]
 19481                              <1> 		; ecx = byte count in the page
 19482 0000408E 803E2F              <1> 	cmp	byte [esi], '/'
 19483                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
 19484 00004091 751C                <1> 	jne	short namei_1
 19485                              <1> 		; bne 1f
 19486 00004093 FF05[806C0000]      <1> 	inc	dword [u.namep]
 19487                              <1> 		; inc u.namep / go to next char
 19488                              <1> 	;dec	cx ; remain byte count in the page
 19489 00004099 49                  <1> 	dec	ecx ; 18/10/2021
 19490 0000409A 7506                <1> 	jnz	short namei_0
 19491                              <1> 	; 12/10/2015
 19492 0000409C E836010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 19493                              <1> 		; esi = physical address (page start + offset)
 19494                              <1> 		; ecx = byte count in the page
 19495 000040A1 4E                  <1> 	dec	esi
 19496                              <1> namei_0:
 19497 000040A2 46                  <1> 	inc 	esi  ; go to next char
 19498                              <1> 	;mov	ax, [rootdir] ; 09/07/2013
 19499                              <1> 	; 18/10/2021
 19500 000040A3 A1[466C0000]        <1> 	mov	eax, [rootdir]
 19501                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
 19502 000040A8 C605[416C0000]00    <1> 	mov	byte [cdev], 0
 19503                              <1> 		; clr cdev / clear device number
 19504                              <1> namei_1: ; 1:
 19505 000040AF F606FF              <1> 	test	byte [esi], 0FFh
 19506                              <1> 	;jz	short getf4
 19507                              <1> 	; 26/03/2021
 19508                              <1> 	;jz	short getf2 ; retn
 19509                              <1> 	;;jz	nig
 19510                              <1> 		; tstb *u.namep / is the character in file name a nul
 19511                              <1> 		; beq nig / yes, end of file name reached; 
 19512                              <1> 			; / branch to "nig"
 19513                              <1> 	; 19/12/2021
 19514                              <1> namei_9:
 19515                              <1> 	; 12/06/2021
 19516                              <1> 	;jnz	short namei_2
 19517                              <1> 	;retn
 19518                              <1> 	; 08/01/2022
 19519 000040B2 74C3                <1> 	jz	short getf4
 19520                              <1> namei_2: ; 1:
 19521                              <1> 	; 18/10/2015
 19522 000040B4 8935[E86C0000]      <1> 	mov 	[nbase], esi
 19523                              <1> 	;mov 	[ncount], cx
 19524                              <1> 	; 18/10/2021
 19525 000040BA 890D[EC6C0000]      <1> 	mov	[ncount], ecx
 19526                              <1> 	;
 19527                              <1> 	;;mov	dx, 2
 19528                              <1> 	;mov	dl, 2 ; user flag (read, non-owner)
 19529                              <1> 	; 25/03/2021
 19530                              <1> 	;mov	dx, 100h ; IREAD - read, owner 
 19531                              <1> 	; 18/10/2021
 19532 000040C0 29D2                <1> 	sub	edx, edx
 19533 000040C2 FEC6                <1> 	inc	dh ; dx = 100h ; IREAD - read, owner 
 19534 000040C4 E8920B0000          <1> 	call	access
 19535                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
 19536                              <1> 	; 'access' will not return here if user has not "r" permission !
 19537                              <1> 
 19538                              <1> 	;test 	word [i.flgs], 4000h
 19539                              <1> 	;	; bit $40000,i.flgs / directory i-node?
 19540                              <1>         ;jz	short namei_err
 19541                              <1> 		; beq error3 / no, got an error
 19542                              <1> 	; 26/03/2021 
 19543                              <1> ;	mov	al, [i.flgs+1]
 19544                              <1> ;	;test	al, 80h ; IFREG ; 80h
 19545                              <1> ;	;jz	short namei_err ; not a regular file ! (device!?)
 19546                              <1> ;	;and	al, 40h ; IFDIR ; 40h
 19547                              <1> ;	;jz	short namei_err ; not a sub directory !
 19548                              <1> ;	shl	al, 1 ; 80h (IFREG flag) -> cf = 1
 19549                              <1> ;	jnc	short namei_err ; not a regular file ! (device!?)
 19550                              <1> ;	shl	al, 1 ; 80h (IFDIR flag) -> cf = 1
 19551                              <1> ;	jnc	short namei_err ; not a sub directory !
 19552                              <1> 
 19553                              <1> 	; 27/03/2021
 19554 000040C9 E83A010000          <1> 	call	chk_dir ; check for directory, jump to 'error' if not
 19555                              <1> 	; CPU will be here if the inode is a (valid) directory inode
 19556                              <1> 
 19557                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 19558                              <1> 	;xor	eax, eax
 19559                              <1> 	;mov	[u.off], eax ; 0
 19560                              <1> 	; 01/05/2021 - Retro UNIX 386 v2 inode structure
 19561 000040CE A1[EC670000]        <1> 	mov	eax, [i.size]
 19562                              <1> 	;mov	ax, [i.size]
 19563 000040D3 A3[7C6C0000]        <1> 	mov	[u.dirp], eax
 19564                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
 19565                              <1> 		; clr u.off / u.off is file offset used by user
 19566                              <1> 	; 18/10/2021
 19567 000040D8 31C0                <1> 	xor	eax, eax
 19568                              <1> 	;mov	[u.off], eax ; 0
 19569 000040DA BB[846C0000]        <1> 	mov	ebx, u.off
 19570 000040DF 8903                <1> 	mov	[ebx], eax ; mov dword [u.off], 0
 19571                              <1> 	;
 19572 000040E1 891D[786C0000]      <1> 	mov	[u.fofp], ebx ; u.off ; 18/10/2021
 19573                              <1> 	;mov	dword [u.fofp], u.off
 19574                              <1> 			; mov $u.off,u.fofp / u.fofp is a pointer to 
 19575                              <1> 				  ; / the offset portion of fsp entry
 19576                              <1> namei_3: ; 2:
 19577 000040E7 C705[886C0000]-     <1> 	mov	dword [u.base], u.dirbuf
 19578 000040ED [9C6C0000]          <1>
 19579                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
 19580                              <1> 				    ; / copied from a directory
 19581 000040F1 C705[8C6C0000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
 19582 000040F9 0000                <1>
 19583                              <1>  		; mov $10.,u.count / u.count is byte count 
 19584                              <1> 				 ; / for reads and writes
 19585                              <1> 	;mov 	ax, [ii]
 19586                              <1> 	; 18/10/2021
 19587 000040FB A1[3C6C0000]        <1> 	mov	eax, [ii] ; (32 bit inode number)
 19588                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
 19589 00004100 FE05[D66C0000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
 19590 00004106 E8D20D0000          <1>     	call	readi
 19591                              <1> 		; jsr r0,readi / read 10. bytes of file 
 19592                              <1> 		      ; with i-number (r1); i.e. read a directory entry
 19593                              <1> 
 19594 0000410B 8B0D[906C0000]      <1> 	mov 	ecx, [u.nread]
 19595 00004111 09C9                <1> 	or 	ecx, ecx
 19596                              <1> 		; tst u.nread
 19597 00004113 741A                <1> 	jz	short nib
 19598                              <1> 		; ble nib / gives error return
 19599                              <1> 	;
 19600                              <1> 	;mov 	bx, [u.dirbuf]
 19601                              <1> 	;and 	bx, bx       
 19602                              <1> 	; 18/10/2021
 19603 00004115 66F705[9C6C0000]FF- <1> 	test	word [u.dirbuf], 0FFFFh
 19604 0000411D FF                  <1>
 19605                              <1> 		; tst u.dirbuf /
 19606 0000411E 7513                <1> 	jnz	short namei_4
 19607                              <1> 		; bne 3f / branch when active directory entry 
 19608                              <1> 		       ; / (i-node word in entry non zero)
 19609 00004120 A1[846C0000]        <1> 	mov	eax, [u.off]
 19610 00004125 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
 19611 00004128 A3[7C6C0000]        <1> 	mov	[u.dirp], eax
 19612                              <1> 		; mov u.off,u.dirp
 19613                              <1> 		; sub $10.,u.dirp
 19614 0000412D EBB8                <1> 	jmp	short namei_3
 19615                              <1> 		; br 2b
 19616                              <1> 
 19617                              <1> 	; 18/07/2013
 19618                              <1> nib: 
 19619 0000412F 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
 19620 00004131 F9                  <1> 	stc
 19621                              <1> nig:
 19622 00004132 C3                  <1> 	retn
 19623                              <1> 
 19624                              <1> 	; 27/03/2021
 19625                              <1> ;namei_err:
 19626                              <1> 	; 16/06/2015
 19627                              <1> ;	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
 19628                              <1> ;	jmp	error
 19629                              <1> 
 19630                              <1> namei_4: ; 3:
 19631                              <1> 	; 18/10/2015
 19632                              <1> 	; 12/10/2015
 19633                              <1> 	; 21/08/2015
 19634                              <1> 	; 18/07/2015
 19635 00004133 8B2D[806C0000]      <1> 	mov	ebp, [u.namep]
 19636                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
 19637 00004139 BF[9E6C0000]        <1> 	mov 	edi, u.dirbuf + 2
 19638                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
 19639                              <1> 	; 18/10/2015
 19640 0000413E 8B35[E86C0000]      <1> 	mov	esi, [nbase]
 19641                              <1> 	;mov	cx, [ncount]
 19642                              <1> 	;and	cx, cx
 19643                              <1> 	; 18/10/2021
 19644 00004144 8B0D[EC6C0000]      <1> 	mov	ecx, [ncount]
 19645 0000414A 21C9                <1> 	and	ecx, ecx
 19646 0000414C 7505                <1> 	jnz	short namei_5	
 19647                              <1> 	;
 19648 0000414E E88A000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 19649                              <1> 		; esi = physical address (page start + offset)
 19650                              <1> 		; ecx = byte count in the page
 19651                              <1> namei_5: ; 3:
 19652 00004153 45                  <1> 	inc	ebp ; 18/07/2015
 19653 00004154 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
 19654                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
 19655 00004155 08C0                <1> 	or 	al, al
 19656 00004157 741C                <1> 	jz 	short namei_7
 19657                              <1> 		; beq 3f / if char is nul, then the last char in string
 19658                              <1> 			; / has been moved
 19659 00004159 3C2F                <1> 	cmp	al, '/'
 19660                              <1> 		; cmp r4,$'/ / is char a </>
 19661 0000415B 7418                <1> 	je 	short namei_7
 19662                              <1> 		; beq 3f	
 19663                              <1> 	; 12/10/2015
 19664                              <1> 	;dec	cx ; remain byte count in the page
 19665 0000415D 49                  <1> 	dec	ecx ; 18/10/2021
 19666 0000415E 7505                <1> 	jnz	short namei_6
 19667 00004160 E878000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 19668                              <1> 		; esi = physical address (page start + offset)
 19669                              <1> 		; ecx = byte count in the page
 19670                              <1> namei_6:
 19671 00004165 81FF[AC6C0000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 19672                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
 19673                              <1> 				     ; / all 8 bytes of file name
 19674 0000416B 74E6                <1> 	je	short namei_5
 19675                              <1> 		; beq 3b
 19676 0000416D AE                  <1> 	scasb	
 19677                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
 19678                              <1> 			      ; / char read from directory
 19679 0000416E 74E3                <1> 	je 	short namei_5
 19680                              <1> 		; beq 3b / branch if chars match
 19681                              <1> namei_10:
 19682 00004170 E972FFFFFF          <1>         jmp	namei_3 ; 2b
 19683                              <1> 		; br 2b / file names do not match go to next directory entry
 19684                              <1> namei_7: ; 3:
 19685 00004175 81FF[AC6C0000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 19686                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
 19687 0000417B 7405                <1> 	je	short namei_8
 19688                              <1> 		; beq 3f
 19689                              <1> 	;mov 	ah, [edi]
 19690                              <1> 	;;inc 	edi 
 19691                              <1> 	;and 	ah, ah
 19692                              <1> 	;	; tstb (r3)+ /
 19693                              <1>         ; 18/10/2021
 19694 0000417D F607FF              <1> 	test	byte [edi], 0FFh
 19695                              <1> 	; 08/01/2021
 19696 00004180 75EE                <1> 	jnz	short namei_10 
 19697                              <1> 	;jnz	namei_3
 19698                              <1> 		; bne 2b
 19699                              <1> namei_8: ; 3
 19700 00004182 892D[806C0000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
 19701                              <1> 		; mov r2,u.namep / u.namep points to char 
 19702                              <1> 			       ; / following a / or nul
 19703                              <1> 	;mov	bx, [u.dirbuf]
 19704                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
 19705                              <1> 				; / entry to r1
 19706                              <1> 
 19707                              <1> 	;;;;
 19708                              <1> 	; 15/05/2022 - Retro UNIX (8086/386) feature only !
 19709                              <1> 	; ! 'pwd' utility modification !
 19710                              <1> 	; ((if directory entry name is a dotdot)))
 19711                              <1> 	;; check if it is mounted device's root directory inode
 19712                              <1> 	; and if so, replace it with parent dir inode number
 19713                              <1> 	;  of mounting directory in [mntp].
 19714                              <1> 
 19715 00004188 0FB71D[9C6C0000]    <1> 	movzx	ebx, word [u.dirbuf]
 19716                              <1> 
 19717 0000418F 6683FB01            <1> 	cmp	bx, 1 ; root directory inode number
 19718 00004193 7539                <1> 	jne	short namei_11
 19719                              <1> 
 19720 00004195 3B1D[3C6C0000]      <1> 	cmp	ebx, [ii] ; for root dir, '.' & '..' is 1
 19721 0000419B 7531                <1> 	jne	short namei_11 ; not root dir (of mounted dev)
 19722                              <1> 
 19723                              <1> 	;cmp	[idev], bh ; 0
 19724 0000419D 383D[416C0000]      <1> 	cmp	[cdev], bh ; 0
 19725                              <1> 			; 0 = root fs, dev num in [rdev]
 19726                              <1> 			; 1 = mounted, dev num in [mdev]
 19727 000041A3 7629                <1> 	jna	short namei_11
 19728                              <1> 
 19729                              <1> 	; dotdot (parent directory link) check
 19730 000041A5 66813D[9E6C0000]2E- <1> 	cmp	word [u.dirbuf+2], '..'
 19731 000041AD 2E                  <1>
 19732 000041AE 751E                <1> 	jne	short namei_11
 19733 000041B0 803D[A06C0000]00    <1> 	cmp	byte [u.dirbuf+4], 0
 19734 000041B7 7515                <1> 	jne	short namei_11
 19735                              <1> 	
 19736                              <1> 	; (This may not be necessary because [idev] = 1
 19737                              <1> 	; and [mnti] is expected as a sub dir inode number)
 19738 000041B9 391D[4A6C0000]      <1> 	cmp	[mnti], ebx ; 1
 19739 000041BF 760D                <1> 	jna	short namei_11
 19740                              <1> 	
 19741                              <1> 	; change inumber to parent dir inum of mount directory
 19742 000041C1 8B1D[4E6C0000]      <1> 	mov	ebx, [mntp]
 19743 000041C7 C605[416C0000]00    <1> 	mov	byte [cdev], 0 ; root fs
 19744                              <1> namei_11:
 19745                              <1> 	;;;;
 19746                              <1> 
 19747 000041CE 20C0                <1> 	and 	al, al
 19748                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
 19749                              <1> 		      ;  / if r4 = </> then go to next directory
 19750                              <1> 	; 15/05/2022
 19751 000041D0 89D8                <1> 	mov	eax, ebx
 19752                              <1> 	;;mov	ax, bx
 19753                              <1> 	;;mov 	ax, [u.dirbuf] ; 17/06/2015
 19754                              <1>         ;; 18/10/2021 (16 bit inode number in 32 bit register)
 19755                              <1> 	;movzx	eax, word [u.dirbuf] 
 19756                              <1> 	; 19/12/2021
 19757 000041D2 E9DBFEFFFF          <1> 	jmp	namei_9 ; eax = inode number
 19758                              <1> ;	jnz	namei_2 
 19759                              <1> ;		; bne 1b
 19760                              <1> ;	; AX = i-number of the file
 19761                              <1> ;;;nig:
 19762                              <1> ;	retn
 19763                              <1> 		; tst (r0)+ / gives non-error return
 19764                              <1> ;;nib:
 19765                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
 19766                              <1> 		       ; ax = 0 -> file not found 
 19767                              <1> ;;	stc	; 27/05/2013
 19768                              <1> ;;	retn
 19769                              <1> 		; rts r0
 19770                              <1> 
 19771                              <1> trans_addr_nmbp:
 19772                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 19773                              <1> 	; 18/10/2015
 19774                              <1> 	; 12/10/2015
 19775 000041D7 8B2D[806C0000]      <1> 	mov 	ebp, [u.namep]
 19776                              <1> trans_addr_nm: 
 19777                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 19778                              <1> 	; Convert virtual (pathname) address to physical address
 19779                              <1> 	; (Retro UNIX 386 v1 feature only !)
 19780                              <1> 	; 18/10/2015
 19781                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
 19782                              <1> 	; 02/07/2015
 19783                              <1> 	; 17/06/2015
 19784                              <1> 	; 16/06/2015
 19785                              <1> 	;
 19786                              <1> 	; INPUTS: 
 19787                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
 19788                              <1> 	;	[u.pgdir] = user's page directory
 19789                              <1> 	; OUTPUT:
 19790                              <1> 	;       esi = physical address of the pathname
 19791                              <1> 	;	ecx = remain byte count in the page
 19792                              <1> 	;
 19793                              <1> 	; (Modified registers: EBX, ECX, EDX, ESI) ; 18/10/2021
 19794                              <1> 	;
 19795                              <1> 
 19796                              <1> 	; 18/10/2021
 19797 000041DD 29C9                <1> 	sub	ecx, ecx
 19798                              <1> 	;
 19799                              <1>         ;cmp	dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
 19800 000041DF 390D[C86C0000]      <1> 	cmp	[u.ppgdir], ecx ; 0 ; 18/10/2021
 19801 000041E5 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
 19802                              <1> 				     ; it is already physical address
 19803 000041E7 50                  <1>    	push	eax	
 19804 000041E8 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
 19805 000041EA E8D8E5FFFF          <1>        	call	get_physical_addr ; get physical address
 19806 000041EF 7204                <1> 	jc	short tr_addr_nm_err
 19807                              <1> 	; 18/10/2015
 19808                              <1> 	; eax = physical address 
 19809                              <1> 	; ecx = remain byte count in page (1-4096) ; 18/10/2021
 19810                              <1> 		; 12/10/2015 (cx = [u.pncount])
 19811 000041F1 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
 19812 000041F3 58                  <1> 	pop	eax 
 19813 000041F4 C3                  <1> 	retn
 19814                              <1> 
 19815                              <1> tr_addr_nm_err:
 19816 000041F5 A3[D86C0000]        <1> 	mov	[u.error], eax
 19817                              <1> 	;pop 	eax
 19818 000041FA E962EFFFFF          <1> 	jmp	error
 19819                              <1> 
 19820                              <1> trans_addr_nmk:
 19821                              <1> 	; 12/10/2015
 19822                              <1> 	; 02/07/2015
 19823 000041FF 8B35[806C0000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
 19824                              <1> 	;mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
 19825                              <1> 	; 18/10/2021
 19826 00004205 B510                <1> 	mov	ch, PAGE_SIZE/256
 19827 00004207 C3                  <1> 	retn
 19828                              <1> 
 19829                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 19830                              <1> chk_dir:
 19831                              <1> 	; 12/06/2021
 19832                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
 19833                              <1> 	; Check for directory inode
 19834                              <1> 
 19835 00004208 8A0D[E5670000]      <1> 	mov	cl, [i.flgs+1]
 19836                              <1> 	;test	cl, 80h ; IFREG ; 80h
 19837                              <1> 	;jz	short chk_dir_err ; not a regular file ! (device!?)
 19838                              <1> 	;and	cl, 40h ; IFDIR ; 40h
 19839                              <1> 	;jz	short chk_dir_err ; not a sub directory !
 19840 0000420E D0E1                <1> 	shl	cl, 1 ; 80h (IFREG flag) -> cf = 1
 19841 00004210 7305                <1> 	jnc	short chk_dir_err ; not a regular file ! (device!?)
 19842 00004212 D0E1                <1> 	shl	cl, 1 ; 40h (IFDIR flag) -> cf = 1
 19843 00004214 7301                <1> 	jnc	short chk_dir_err ; not a sub directory !
 19844                              <1> 	; 12/06/2021
 19845 00004216 C3                  <1> 	retn
 19846                              <1> chk_dir_err:
 19847 00004217 C705[D86C0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 19848 0000421F 0000                <1>
 19849 00004221 E93BEFFFFF          <1> 	jmp	error
 19850                              <1> 
 19851                              <1> 	; 06/02/2022
 19852                              <1> 	; 08/01/2022
 19853                              <1> 	; 01/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode)
 19854                              <1> syschdir:
 19855                              <1> 	; / makes the directory specified in the argument
 19856                              <1> 	; / the current directory
 19857                              <1> 	;
 19858                              <1> 	; 08/01/2022 (Retro UNIX 386 v1.2)
 19859                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19860                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 19861                              <1> 	;
 19862                              <1> 	; 'syschdir' makes the directory specified in its argument
 19863                              <1> 	; the current working directory.
 19864                              <1> 	;
 19865                              <1> 	; Calling sequence:
 19866                              <1> 	;	syschdir; name
 19867                              <1> 	; Arguments:
 19868                              <1> 	;	name - address of the path name of a directory
 19869                              <1> 	;	       terminated by nul byte.	
 19870                              <1> 	; Inputs: -
 19871                              <1> 	; Outputs: -
 19872                              <1> 	; ...............................................................
 19873                              <1> 	;				
 19874                              <1> 	; Retro UNIX 8086 v1 modification:
 19875                              <1> 	;	 The user/application program puts address of 
 19876                              <1> 	;	 the path name in BX register as 'syschdir' 
 19877                              <1> 	; 	 system call argument.
 19878                              <1> 
 19879 00004226 891D[806C0000]      <1> 	mov	[u.namep], ebx
 19880                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
 19881 0000422C E847FEFFFF          <1> 	call	namei
 19882                              <1> 		; jsr r0,namei / find its i-number
 19883                              <1> 	;jc	error
 19884                              <1> 		; br error3
 19885 00004231 730F                <1> 	jnc	short syschdir0
 19886                              <1> 	; 'directory not found !' error
 19887 00004233 C705[D86C0000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
 19888 0000423B 0000                <1>
 19889 0000423D E91FEFFFFF          <1> 	jmp	error
 19890                              <1> syschdir0:
 19891                              <1> 	; 08/01/2022
 19892 00004242 66BA0001            <1> 	mov	dx, 100h  ; read access ; IREAD (100h)
 19893 00004246 E8100A0000          <1> 	call	access
 19894                              <1> 		; jsr r0,access; 2 / get i-node into core
 19895                              <1> 	
 19896                              <1> 	; 06/02/2022
 19897                              <1> 	;; 01/01/2022 (runix v2 fs inode flag)
 19898                              <1> 	;test	byte [i.flgs+1], 80h ; regular file ?
 19899                              <1> 	;jz	short syschdir2 ; no, error!
 19900                              <1> 	;test	byte [i.flgs+1], 40h ; directory flag ?
 19901                              <1> 	;;test	word [i.flgs], 4000h
 19902                              <1> 	;	; bit $40000,i.flgs / is it a directory?
 19903                              <1> 	;;jz	error 
 19904                              <1> 	;	; beq error3 / no error
 19905                              <1> 	;jnz	short syschdir1
 19906                              <1> ;syschdir2:
 19907                              <1> 	;mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 19908                              <1> 	;jmp	error
 19909                              <1> 
 19910                              <1> 	; 06/02/2022
 19911                              <1> 	; check for directory, jump to 'error' if not
 19912 0000424B E8B8FFFFFF          <1> 	call	chk_dir
 19913                              <1> 	; (cpu will not return here
 19914                              <1> 	;  if the inode it is not a valid dir inode)
 19915                              <1> 
 19916                              <1> syschdir1:
 19917 00004250 66A3[686C0000]      <1> 	mov	[u.cdir], ax
 19918                              <1> 		; mov r1,u.cdir / move i-number to users 
 19919                              <1> 			      ; / current directory
 19920                              <1> 	;mov	ax, [cdev]
 19921                              <1> 	;mov	[u.cdrv], ax
 19922                              <1> 	; 08/01/2022
 19923 00004256 A0[416C0000]        <1> 	mov	al, [cdev]
 19924 0000425B A2[6C6C0000]        <1> 	mov	[u.cdrv], al
 19925                              <1> 		; mov cdev,u.cdev / move its device to users 
 19926                              <1> 			        ; / current device
 19927 00004260 E91CEFFFFF          <1> 	jmp	sysret
 19928                              <1> 		; br sysret3
 19929                              <1> 
 19930                              <1> syschmod: ; < change mode of file >
 19931                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 19932                              <1> 	; 01/05/2021
 19933                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 19934                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19935                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 19936                              <1> 	;
 19937                              <1> 	; 'syschmod' changes mode of the file whose name is given as
 19938                              <1> 	; null terminated string pointed to by 'name' has it's mode 
 19939                              <1> 	; changed to 'mode'.
 19940                              <1> 	;
 19941                              <1> 	; Calling sequence:
 19942                              <1> 	;	syschmod; name; mode
 19943                              <1> 	; Arguments:
 19944                              <1> 	;	name - address of the file name
 19945                              <1> 	;	       terminated by null byte.
 19946                              <1> 	;	mode - (new) mode/flags < attributes >
 19947                              <1> 	;	
 19948                              <1> 	; Inputs: -
 19949                              <1> 	; Outputs: -
 19950                              <1> 	; ...............................................................
 19951                              <1> 	;				
 19952                              <1> 	; Retro UNIX 8086 v1 modification: 
 19953                              <1> 	;       'syschmod' system call has two arguments; so,
 19954                              <1> 	;	* 1st argument, name is pointed to by BX register
 19955                              <1> 	;	* 2nd argument, mode is in CX register
 19956                              <1> 	;
 19957                              <1> 	; Mode bits (Flags):
 19958                              <1> 	;	bit 15 - 'i-node is allocated' flag (8000h)
 19959                              <1> 	;	bit 14 - directory flag (4000h)
 19960                              <1> 	;	bit 13 - file has modified flag (always on) (2000h)
 19961                              <1> 	;	bit 12 - large file flag (1000h)
 19962                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
 19963                              <1> 	;	bit 5 - set user ID on execution flag (20h) 
 19964                              <1> 	;	bit 4 - executable flag (10h)
 19965                              <1> 	;	bit 3 - read permission for owner (08h)
 19966                              <1> 	;	bit 2 - write permission for owner (04h)
 19967                              <1> 	;	bit 1 - read permission for non-owner (02h)
 19968                              <1> 	;	bit 0 - write permission for non-owner (01h)
 19969                              <1> 
 19970                              <1> 	; 01/05/2021 (07/02/2020)
 19971                              <1> 	; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
 19972                              <1> 	; 	bit 15 - IFREG - regular file (8000h)
 19973                              <1> 	;	bit 14 - IFDIR - directory (4000h)
 19974                              <1> 	;	bit 13 - IRSVD - 0 - reserved/mounted bit (2000h)
 19975                              <1> 	; 	bit 12 - ILARG - large file addressing bit (1000h)
 19976                              <1> 	; 	bit 11 - ISUID - set user id on exec (800h)
 19977                              <1> 	;	bit 10 - ISGID - set group id on exec (400h)
 19978                              <1> 	; 	bit  9 - IEXTT - 0 - use extents (200h)
 19979                              <1> 	;	bit  8 - IREAD - read, owner (100h)
 19980                              <1> 	;	bit  7 - IWRITE - write, owner (80h)
 19981                              <1> 	;	bit  6 - IEXEC - execute, owner (40h)
 19982                              <1> 	; 	bit  5 - read, group (20h)
 19983                              <1> 	; 	bit  4 - write, group (10h)
 19984                              <1> 	; 	bit  3 - execute, group (08h)
 19985                              <1> 	;	bit  2 - read, others (04h)
 19986                              <1> 	; 	bit  1 - write, others (02h)
 19987                              <1> 	; 	bit  0 - execute, others (01h)
 19988                              <1> 	;
 19989                              <1> 	; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
 19990                              <1> 	;	bit 15 - IFREG - 0 - device file (8000h)
 19991                              <1> 	; 	bit 14 - IFBLK - block device (4000h)
 19992                              <1> 	; 	bit 13 - IFCHR - 1 - character special (2000h)
 19993                              <1> 	;	bit 12 - IFIFO - fifo special (1000h)
 19994                              <1> 	; 	bit 11 - IPIPE - pipe special (800h)
 19995                              <1> 	;	bit 10 - IREDIR - redirected (400h)
 19996                              <1> 	;	bit  9 - IEXTR - external device driver (200h)
 19997                              <1> 	;	bit  8 - IREAD - read, owner (100h)
 19998                              <1> 	;	bit  7 - IWRITE - write, owner (80h)
 19999                              <1> 	;	bit  6 - IEXEC - execute, owner (40h)
 20000                              <1> 	; 	bit  5 - read, group (20h)
 20001                              <1> 	; 	bit  4 - write, group (10h)
 20002                              <1> 	; 	bit  3 - execute, group (08h)
 20003                              <1> 	;	bit  2 - read, others (04h)
 20004                              <1> 	; 	bit  1 - write, others (02h)
 20005                              <1> 	; 	bit  0 - execute, others (01h)
 20006                              <1> 
 20007                              <1> 	; / name; mode
 20008 00004265 E877000000          <1> 	call	isown
 20009                              <1> 		; jsr r0,isown / get the i-node and check user status
 20010                              <1> 
 20011                              <1> 	; 25/05/2020
 20012                              <1> 	; AL = new mode (return form 'isown', ecx -> eax)
 20013                              <1> 
 20014                              <1> 	;test	word [i.flgs], 4000h
 20015                              <1> 	;	; bit $40000,i.flgs / directory?
 20016                              <1> 	;jz	short syschmod1
 20017                              <1> 	;	; beq 2f / no
 20018                              <1> 	;; AL = (new) mode
 20019                              <1> 	;and	al, 0CFh ; 11001111b (clears bit 4 & 5)
 20020                              <1> 	;	; bic $60,r2 / su & ex / yes, clear set user id and 
 20021                              <1> 	;		   ; / executable modes
 20022                              <1> 
 20023                              <1> 	; 01/05/2021
 20024                              <1> 	; AX = new mode (9 bits for devices or 12 bits files)
 20025 0000426A 8A15[E5670000]      <1> 	mov	dl, [i.flgs+1]
 20026                              <1> 	; 09/01/2022
 20027 00004270 F6C280              <1> 	test	dl, 80h ; regular file
 20028 00004273 7416                <1> 	jz	short syschmod1 ; device file
 20029 00004275 F6C240              <1> 	test	dl, 40h ; directory
 20030 00004278 7511                <1> 	jnz	short syschmod1
 20031                              <1> 	; regular file
 20032 0000427A 6625FF0D            <1> 	and	ax, 0DFFh ; clear bit 9, 12-15 (of new mode)
 20033                              <1> 	; clear bit 8,10,11 of current mode/flags
 20034 0000427E 80E2F2              <1> 	and	dl, 0F2h ; and dl, 11110010b
 20035                              <1> syschmod0:
 20036 00004281 08D4                <1> 	or	ah, dl
 20037 00004283 66A3[E4670000]      <1> 	mov	[i.flgs], ax	
 20038 00004289 EB45                <1> 	jmp	short syschmod2
 20039                              <1> syschmod1: 
 20040                              <1> 	; device or directory	
 20041 0000428B 6625B601            <1> 	and	ax, 1B6h ; clear bit 9-15 & bit 0,3,6 (EXEC bits)
 20042                              <1> 	; clear bit 8 (IREAD) of current mode/flags
 20043                              <1> 	;	 (dl contains flag bits 8-15)
 20044 0000428F 80E2FE              <1> 	and	dl, ~1 ; and dl, 11111110b 
 20045 00004292 EBED                <1> 	jmp	short syschmod0
 20046                              <1> 
 20047                              <1> ;syschmod1: ; 2:
 20048                              <1> 	;mov	[i.flgs], al	
 20049                              <1> 	;	; movb r2,i.flgs / move remaining mode to i.flgs
 20050                              <1> 
 20051                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 20052                              <1> 	;mov	byte [imodx], 1 ; (flag means file data is same
 20053                              <1> 	;			;  but inode's itself has been modified)
 20054                              <1> 	;call	setimod
 20055                              <1> 	;jmp	sysret
 20056                              <1> 
 20057                              <1> 	; 25/05/2020
 20058                              <1> 	;jmp	short syschmod2
 20059                              <1> 
 20060                              <1> syschown: ; < change owner of file >
 20061                              <1> 	; 13/03/2022
 20062                              <1> 	; 11/03/2022
 20063                              <1> 	; 14/02/2022
 20064                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20065                              <1> 	; 01/05/2021
 20066                              <1> 	;	(change owner and group ID of file)
 20067                              <1> 	; 02/04/2021
 20068                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 20069                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20070                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 20071                              <1> 	;
 20072                              <1> 	; 'syschown' changes the owner of the file whose name is given
 20073                              <1> 	; as null terminated string pointed to by 'name' has it's owner
 20074                              <1> 	; changed to 'owner'
 20075                              <1> 	;
 20076                              <1> 	; Calling sequence:
 20077                              <1> 	;	syschown; name; owner
 20078                              <1> 	; Arguments:
 20079                              <1> 	;	name - address of the file name
 20080                              <1> 	;	       terminated by null byte.
 20081                              <1> 	;	owner - (new) owner (number/ID)
 20082                              <1> 	;	
 20083                              <1> 	; Inputs: -
 20084                              <1> 	; Outputs: -
 20085                              <1> 	; ...............................................................
 20086                              <1> 	;				
 20087                              <1> 	; Retro UNIX 8086 v1 modification: 
 20088                              <1> 	;       'syschown' system call has two arguments; so,
 20089                              <1> 	;	* 1st argument, name is pointed to by BX register
 20090                              <1> 	;	* 2nd argument, owner number is in CX register
 20091                              <1> 	;
 20092                              <1> 	; / name; owner
 20093 00004294 E848000000          <1> 	call	isown
 20094                              <1> 		; jsr r0,isown / get the i-node and check user status
 20095                              <1> 	
 20096                              <1> 	; 25/05/2020
 20097                              <1> 	; AL = owner number (return form 'isown', ecx -> eax)
 20098                              <1> 	; 02/04/2021
 20099                              <1> 	; AX = owner number
 20100                              <1> 	; 01/05/2021
 20101                              <1> 	; byte 2 of EAX is group number
 20102                              <1> 
 20103                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013 
 20104                              <1> 	;	; tstb u.uid / super user
 20105                              <1> 	;jz	short syschown1
 20106                              <1> 	;	; beq 2f / yes, 2f
 20107 00004299 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0
 20108 000042A1 741F                <1> 	jz	short syschown1
 20109                              <1> 
 20110                              <1> 	;test	byte [i.flgs], 20h ; 32
 20111                              <1> 	;	; bit $40,i.flgs / no, set userid on execution?
 20112                              <1> 	;;jnz	error
 20113                              <1> 	;	; bne 3f / yes error, could create Trojan Horses
 20114                              <1> 	;jz	short syschown1
 20115                              <1> 	; 01/05/2021
 20116                              <1> 	; check set user id on execution flag
 20117                              <1> 	; (protection against Trojan Horses)
 20118                              <1> 
 20119                              <1> 	; ((Note: UNIX v7 x86 'chown' source code in 'sys4.c'
 20120                              <1> 	;        does not contain this protection)) 
 20121                              <1> 
 20122                              <1> 	; 14/02/2022
 20123 000042A3 8A15[E5670000]      <1> 	mov	dl, [i.flgs+1]
 20124 000042A9 F6C280              <1> 	test	dl, 80h ; IFREG ; RUNIX v2 inode flags  	
 20125 000042AC 7405                <1> 	jz	short syschown_err ; device file !
 20126                              <1> 	; 09/01/2022
 20127                              <1> 	;test	byte [i.flgs+1], 08h ; ISUID ; RUNIX v2 inode flags  	
 20128                              <1> 	; 14/02/2022
 20129 000042AE F6C208              <1> 	test	dl, 08h	; set user id on execution
 20130 000042B1 740F                <1> 	jz	short syschown1 ; 11/03/2022
 20131                              <1> 		; 11/03/2022
 20132                              <1> 		; bit $40,i.flgs / no, set userid on execution?
 20133                              <1> 		; bne 3f / yes error, could create Trojan Horses
 20134                              <1> syschown_err:
 20135                              <1> 	; 'permission denied !'
 20136 000042B3 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
 20137 000042BB 0000                <1>
 20138 000042BD E99FEEFFFF          <1> 	jmp	error
 20139                              <1> syschown1: ; 2:
 20140                              <1> 	;; AL = owner (number/ID)
 20141                              <1> 	;mov	[i.uid], al ; 23/06/2015
 20142                              <1> 	;	; movb r2,i.uid / no, put the new owners id 
 20143                              <1> 	;		      ; / in the i-node
 20144                              <1> 	; 02/04/2021 (Retro UNIX 386 v2)
 20145                              <1> 	; AX = owner number
 20146 000042C2 66A3[E8670000]      <1> 	mov	[i.uid], ax ; owner
 20147                              <1> 	; 13/03/2022
 20148                              <1> 	;; 14/02/2022 (Retro UNIX 386 v1.2)
 20149                              <1> 	;test	dl, 04h ; ISGID ; set grup id on execution
 20150                              <1> 	;jz	short syschown2
 20151                              <1> 	; 01/05/2021 (Retro UNIX 386 v2)
 20152 000042C8 C1E810              <1> 	shr	eax, 16
 20153 000042CB A2[EA670000]        <1> 	mov	[i.gid], al ; group
 20154                              <1> syschown2:
 20155                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 20156                              <1> syschmod2:
 20157                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20158 000042D0 C605[556C0000]01    <1> 	mov	byte [imodx], 1	; (flag means file data is same
 20159                              <1> 			      ;  but inode's itself has been modified)
 20160 000042D7 E8260A0000          <1> 	call	setimod ; 25/05/2020
 20161                              <1> 	
 20162 000042DC E9A0EEFFFF          <1> 	jmp	sysret
 20163                              <1> 
 20164                              <1> 	; 1: 
 20165                              <1> 		; jmp sysret4
 20166                              <1> 	; 3:
 20167                              <1> 		; jmp	error
 20168                              <1> 
 20169                              <1> isown:
 20170                              <1> 	; 11/03/2022
 20171                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20172                              <1> 	; 06/11/2021
 20173                              <1> 	; 12/06/2021
 20174                              <1> 	; 01/05/2021
 20175                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 20176                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20177                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 20178                              <1> 	;
 20179                              <1> 	; 'isown' is given a file name (the 1st argument).
 20180                              <1> 	;  It find the i-number of that file via 'namei' 
 20181                              <1> 	;  then gets the i-node into core via 'iget'.
 20182                              <1> 	;  It then tests to see if the user is super user. 
 20183                              <1> 	;  If not, it checks to see if the user is owner of 
 20184                              <1> 	;  the file. If he is not an error occurs.
 20185                              <1> 	;  If user is the owner 'setimod' is called to indicate
 20186                              <1> 	;  the inode has been modified and the 2nd argument of
 20187                              <1> 	;  the call is put in r2.
 20188                              <1> 	;
 20189                              <1> 	; INPUTS ->
 20190                              <1> 	;    arguments of syschmod and syschown calls
 20191                              <1> 	; OUTPUTS ->
 20192                              <1> 	;    u.uid - id of user
 20193                              <1> 	;    imod - set to a 1
 20194                              <1> 	;    r2 - contains second argument of the system call
 20195                              <1> 	;
 20196                              <1> 	;   ((AX=R2) output as 2nd argument)
 20197                              <1> 	;
 20198                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))
 20199                              <1> 	;
 20200                              <1> 		; jsr r0,arg2 / u.namep points to file name
 20201                              <1> 	;; ! 2nd argument on top of stack !
 20202                              <1> 	;; 22/06/2015 - 32 bit modifications
 20203                              <1> 	;; 07/07/2013
 20204 000042E1 891D[806C0000]      <1> 	mov	[u.namep], ebx ;; 1st argument
 20205 000042E7 51                  <1> 	push 	ecx ;* ; 2nd argument
 20206                              <1> 	;;
 20207 000042E8 E88BFDFFFF          <1> 	call	namei
 20208                              <1> 		; jsr r0,namei / get its i-number
 20209                              <1>        ; Retro UNIX 8086 v1 modification !
 20210                              <1>        ; ax = 0 -> file not found 
 20211                              <1> 	;and	ax, ax
 20212                              <1> 	;jz	error
 20213                              <1> 	;jc	error ; 27/05/2013
 20214                              <1> 		; br error3
 20215 000042ED 730F                <1> 	jnc	short isown1  ; 25/05/2020 (isown0 -> isown1)
 20216                              <1> 	; 'file not found !' error
 20217 000042EF C705[D86C0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 20218 000042F7 0000                <1>
 20219 000042F9 E963EEFFFF          <1> 	jmp	error
 20220                              <1> isown1:
 20221 000042FE E86E080000          <1> 	call	iget
 20222                              <1> 		; jsr r0,iget / get i-node into core
 20223                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 20224                              <1> 	;; 06/11/2021
 20225                              <1> 	;jnc	short isown3
 20226                              <1> 	;mov	[u.error], eax
 20227                              <1> 	;jmp	error
 20228                              <1> ;isown3:
 20229                              <1> 	; check if it is super user ID
 20230                              <1> 	; 09/01/2022 (Retro UNIX 386 v2 fs inode structure)
 20231 00004303 66A1[B66C0000]      <1> 	mov	ax, [u.uid]
 20232 00004309 6609C0              <1> 	or	ax, ax
 20233                              <1> 	;mov	al, [u.uid] ; 02/08/2013
 20234                              <1> 	;or	al, al
 20235                              <1> 		; tstb u.uid / super user?
 20236                              <1> 	; 12/06/2021
 20237 0000430C 7418                <1> 	jz	short isown2 ; 25/05/2020 (isown1 -> isown2)
 20238                              <1> 		; beq 1f / yes, branch
 20239                              <1> 	
 20240                              <1> 	; check user ID	(if same with file's owner)
 20241 0000430E 663B05[E8670000]    <1> 	cmp	ax, [i.uid] ; 09/01/2022
 20242                              <1> 	;cmp	al, [i.uid]
 20243                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
 20244                              <1> 				 ; / the file
 20245                              <1> 	;jne	error
 20246                              <1> 		; beq 1f / yes
 20247                              <1> 		; jmp error3 / no, error
 20248                              <1> 	; 11/03/2022
 20249 00004315 740F                <1> 	je	short isown2 ; 25/05/2020
 20250                              <1> 	;; 01/05/2021
 20251                              <1> 	;jne	short isown_err
 20252                              <1> 
 20253                              <1> 	; 11/03/2022 (*)
 20254                              <1> 	; Note: It is seen as original unix (v5-v7) kernel
 20255                              <1> 	;	source handles 'u.gid' for group permissions
 20256                              <1> 	;	but kernel uses 'u.uid' as primary and unic
 20257                              <1> 	;	(singular) user id/number; a user group
 20258                              <1> 	;	does/can not contain same user id/number
 20259                              <1> 	;	with anotner group. So, if active/current
 20260                              <1> 	;	user ID is same with file's owner id,
 20261                              <1> 	;	group id check is not needed.
 20262                              <1> 	;	([u.uid] = [i.uid] is enough to confirm)	
 20263                              <1> 
 20264                              <1> 	; 01/05/2021
 20265                              <1> 	;mov	ax, [u.uid]
 20266                              <1> 	;or	ax, ax
 20267                              <1> 	;jz	short isown2 
 20268                              <1> 	;cmp	ax, [i.uid]
 20269                              <1> 	;;je	short isown2
 20270                              <1> 	;jne	short isown_err
 20271                              <1> 
 20272                              <1> 	; 01/05/2021
 20273                              <1> 	; ((Note: UNIX v7 x86 'chown', 'chmod' procedures
 20274                              <1> 	;    and their sub procedures do not check group ID))
 20275                              <1> 	; (('sys4.c', 'fio.c'))
 20276                              <1> 
 20277                              <1> 	; 11/03/2022 (*)
 20278                              <1> 	; 01/05/2021
 20279                              <1> 	; check group ID (if same with group of file's owner)
 20280                              <1> 	;mov	al, [u.gid]
 20281                              <1> 	;cmp	al, [i.gid]
 20282                              <1> 	;je	short isown2
 20283                              <1> isown_err:
 20284 00004317 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER ; 11
 20285 0000431F 0000                <1>
 20286                              <1> 			; 'permission denied !' error
 20287 00004321 E93BEEFFFF          <1> 	jmp	error
 20288                              <1> 
 20289                              <1> 	; 25/05/2020
 20290                              <1> ;isown2: ; 1:
 20291                              <1> ;	call	setimod
 20292                              <1> ;		; jsr r0,setimod / indicates 
 20293                              <1> ;		;	       ; / i-node has been modified
 20294                              <1> isown2: 
 20295                              <1> 	; 25/05/2020
 20296 00004326 58                  <1> 	pop	eax ;* ; 2nd argument
 20297                              <1> 		; mov (sp)+,r2 / mode is put in r2 
 20298                              <1> 		       ; / (u.off put on stack with 2nd arg)
 20299 00004327 C3                  <1> 	retn
 20300                              <1> 
 20301                              <1> ;;arg:  ; < get system call arguments >
 20302                              <1> 	; 'arg' extracts an argument for a routine whose call is 
 20303                              <1> 	; of form:
 20304                              <1> 	;	sys 'routine' ; arg1
 20305                              <1> 	;		or
 20306                              <1> 	;	sys 'routine' ; arg1 ; arg2
 20307                              <1> 	;		or
 20308                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
 20309                              <1> 	;	
 20310                              <1> 	; INPUTS ->
 20311                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
 20312                              <1> 	;	This pointers's value is actually the value of
 20313                              <1> 	;	update pc at the the trap to sysent (unkni) is
 20314                              <1> 	;	made to process the sys instruction
 20315                              <1> 	;    r0 - contains the return address for the routine
 20316                              <1> 	;	that called arg. The data in the word pointer 
 20317                              <1> 	;	to by the return address is used as address
 20318                              <1> 	;	in which the extracted argument is stored
 20319                              <1> 	;    	
 20320                              <1> 	; OUTPUTS ->
 20321                              <1> 	;    'address' - contains the extracted argument 
 20322                              <1> 	;    u.sp+18 - is incremented by 2 
 20323                              <1> 	;    r1 - contains the extracted argument
 20324                              <1> 	;    r0 - points to the next instruction to be
 20325                              <1> 	;	 executed in the calling routine.
 20326                              <1> 	;
 20327                              <1>   
 20328                              <1> 	; mov u.sp,r1
 20329                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
 20330                              <1> 			; / into argument of arg2
 20331                              <1> 	; add $2,18.(r1) / point pc on stack 
 20332                              <1> 			      ; / to next system argument
 20333                              <1> 	; rts r0
 20334                              <1> 
 20335                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
 20336                              <1> 	; 'arg2' takes first argument in system call
 20337                              <1> 	;  (pointer to name of the file) and puts it in location
 20338                              <1> 	;  u.namep; takes second argument and puts it in u.off
 20339                              <1> 	;  and on top of the stack
 20340                              <1> 	;	
 20341                              <1> 	; INPUTS ->
 20342                              <1> 	;    u.sp, r0
 20343                              <1> 	;    	
 20344                              <1> 	; OUTPUTS ->
 20345                              <1> 	;    u.namep
 20346                              <1> 	;    u.off 
 20347                              <1> 	;    u.off pushed on stack
 20348                              <1> 	;    r1
 20349                              <1> 	;
 20350                              <1> 
 20351                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
 20352                              <1> 				; / first arg in sys call
 20353                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
 20354                              <1> 				; / second arg in sys call
 20355                              <1> 	; mov r0,r1 / r0 points to calling routine
 20356                              <1> 	; mov (sp),r0 / put operation code back in r0
 20357                              <1> 	; mov u.off,(sp) / put pointer to second argument 
 20358                              <1> 			; / on stack
 20359                              <1> 	; jmp (r1) / return to calling routine
 20360                              <1> 
 20361                              <1> systime: ; / get time of year
 20362                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20363                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 20364                              <1> 	;
 20365                              <1> 	; 20/06/2013
 20366                              <1> 	; 'systime' gets the time of the year.
 20367                              <1> 	; The present time is put on the stack.
 20368                              <1> 	;
 20369                              <1> 	; Calling sequence:
 20370                              <1> 	;	systime
 20371                              <1> 	; Arguments: -
 20372                              <1> 	;	
 20373                              <1> 	; Inputs: -
 20374                              <1> 	; Outputs: sp+2, sp+4 - present time
 20375                              <1> 	; ...............................................................
 20376                              <1> 	;	
 20377                              <1> 	; Retro UNIX 8086 v1 modification: 
 20378                              <1> 	;       'systime' system call will return to the user
 20379                              <1> 	;	with unix time (epoch) in DX:AX register pair
 20380                              <1> 	;
 20381                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
 20382                              <1> 	;	system call for PC compatibility !!		 	
 20383                              <1> 
 20384 00004328 E80DE9FFFF          <1> 	call 	epoch
 20385 0000432D A3[646C0000]        <1> 	mov 	[u.r0], eax
 20386                              <1> 		; mov s.time,4(sp)
 20387                              <1> 		; mov s.time+2,2(sp) / put the present time 
 20388                              <1> 				   ; / on the stack
 20389                              <1> 		; br sysret4
 20390 00004332 E94AEEFFFF          <1> 	jmp	sysret 
 20391                              <1> 
 20392                              <1> sysstime: ; / set time
 20393                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20394                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20395                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 20396                              <1> 	;
 20397                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
 20398                              <1> 	;
 20399                              <1> 	; Calling sequence:
 20400                              <1> 	;	sysstime
 20401                              <1> 	; Arguments: -
 20402                              <1> 	;	
 20403                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
 20404                              <1> 	; Outputs: -
 20405                              <1> 	; ...............................................................
 20406                              <1> 	;	
 20407                              <1> 	; Retro UNIX 8086 v1 modification: 
 20408                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
 20409                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
 20410                              <1> 	; 
 20411                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 20412                              <1> 	;	to get sysstime system call arguments from the user;
 20413                              <1> 	;	* 1st argument, lowword of unix time is in BX register
 20414                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
 20415                              <1> 	;
 20416                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
 20417                              <1> 	;	system call for PC compatibility !!	
 20418                              <1> 
 20419                              <1> 	; 09/01/2022 (Retro UNIX 386 v2 fs inode structure)
 20420 00004337 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0 ; 16 bit user ID
 20421                              <1> 	;cmp	byte [u.uid], 0
 20422                              <1> 		; tstb u.uid / is user the super user
 20423                              <1> 	;ja	error
 20424                              <1> 		; bne error4 / no, error
 20425 0000433F 760F                <1> 	jna	short systime1
 20426                              <1> 	; 'permission denied !'
 20427 00004341 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
 20428 00004349 0000                <1>
 20429 0000434B E911EEFFFF          <1> 	jmp	error
 20430                              <1> systime1:
 20431                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
 20432                              <1> 	; EBX = unix (epoch) time (from user)
 20433 00004350 89D8                <1> 	mov	eax, ebx
 20434 00004352 E860EAFFFF          <1> 	call 	set_date_time
 20435                              <1> 		; mov 4(sp),s.time
 20436                              <1> 		; mov 2(sp),s.time+2 / set the system time
 20437 00004357 E925EEFFFF          <1> 	jmp	sysret
 20438                              <1> 		; br sysret4
 20439                              <1> 
 20440                              <1> sysbreak:
 20441                              <1> 	; 18/10/2015
 20442                              <1> 	; 07/10/2015
 20443                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 20444                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
 20445                              <1> 	;
 20446                              <1> 	; 'sysbreak' sets the programs break points. 
 20447                              <1> 	; It checks the current break point (u.break) to see if it is
 20448                              <1> 	; between "core" and the stack (sp). If it is, it is made an
 20449                              <1> 	; even address (if it was odd) and the area between u.break
 20450                              <1> 	; and the stack is cleared. The new breakpoint is then put
 20451                              <1> 	; in u.break and control is passed to 'sysret'.
 20452                              <1> 	;
 20453                              <1> 	; Calling sequence:
 20454                              <1> 	;	sysbreak; addr
 20455                              <1> 	; Arguments: -
 20456                              <1> 	;	
 20457                              <1> 	; Inputs: u.break - current breakpoint
 20458                              <1> 	; Outputs: u.break - new breakpoint 
 20459                              <1> 	;	area between old u.break and the stack (sp) is cleared.
 20460                              <1> 	; ...............................................................
 20461                              <1> 	;	
 20462                              <1> 	; Retro UNIX 8086 v1 modification:
 20463                              <1> 	;	The user/application program puts breakpoint address
 20464                              <1> 	;       in BX register as 'sysbreak' system call argument.
 20465                              <1> 	; 	(argument transfer method 1)
 20466                              <1> 	;
 20467                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
 20468                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
 20469                              <1> 	;  NOTE:
 20470                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
 20471                              <1> 	;	'u.break' address) of user's memory for original unix's
 20472                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
 20473                              <1> 
 20474                              <1> 		; mov u.break,r1 / move users break point to r1
 20475                              <1> 		; cmp r1,$core / is it the same or lower than core?
 20476                              <1> 		; blos 1f / yes, 1f
 20477                              <1> 	; 23/06/2015
 20478 0000435C 8B2D[946C0000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
 20479                              <1> 	;and	ebp, ebp
 20480                              <1> 	;jz	short sysbreak_3 
 20481                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
 20482                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
 20483 00004362 8B15[5C6C0000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
 20484 00004368 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
 20485                              <1> 	; 07/10/2015
 20486 0000436B 891D[946C0000]      <1> 	mov	[u.break], ebx ; virtual address !!!
 20487                              <1> 	;
 20488 00004371 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
 20489                              <1> 			   ; with top of user's stack (virtual!)
 20490 00004373 7327                <1> 	jnb	short sysbreak_3
 20491                              <1> 		; cmp r1,sp / is it the same or higher 
 20492                              <1> 			  ; / than the stack?
 20493                              <1> 		; bhis 1f / yes, 1f
 20494 00004375 89DE                <1> 	mov	esi, ebx
 20495 00004377 29EE                <1> 	sub	esi, ebp ; new break point - old break point
 20496 00004379 7621                <1> 	jna	short sysbreak_3 
 20497                              <1> 	;push	ebx
 20498                              <1> sysbreak_1:
 20499 0000437B 89EB                <1> 	mov	ebx, ebp  
 20500 0000437D E845E4FFFF          <1> 	call	get_physical_addr ; get physical address
 20501 00004382 0F826DFEFFFF        <1> 	jc	tr_addr_nm_err
 20502                              <1> 	; 18/10/2015
 20503 00004388 89C7                <1> 	mov	edi, eax 
 20504 0000438A 29C0                <1> 	sub	eax, eax ; 0
 20505                              <1> 		 ; ECX = remain byte count in page (1-4096)
 20506 0000438C 39CE                <1> 	cmp	esi, ecx
 20507 0000438E 7302                <1> 	jnb	short sysbreak_2
 20508 00004390 89F1                <1> 	mov	ecx, esi
 20509                              <1> sysbreak_2:
 20510 00004392 29CE                <1> 	sub	esi, ecx
 20511 00004394 01CD                <1> 	add	ebp, ecx
 20512 00004396 F3AA                <1> 	rep 	stosb
 20513 00004398 09F6                <1> 	or	esi, esi
 20514 0000439A 75DF                <1> 	jnz	short sysbreak_1
 20515                              <1> 	;
 20516                              <1> 		; bit $1,r1 / is it an odd address
 20517                              <1> 		; beq 2f / no, its even
 20518                              <1> 		; clrb (r1)+ / yes, make it even
 20519                              <1> 	; 2: / clear area between the break point and the stack
 20520                              <1> 		; cmp r1,sp / is it higher or same than the stack
 20521                              <1> 		; bhis 1f / yes, quit
 20522                              <1> 		; clr (r1)+ / clear word
 20523                              <1> 		; br 2b / go back
 20524                              <1> 	;pop	ebx
 20525                              <1> sysbreak_3: ; 1:
 20526                              <1> 	;mov	[u.break], ebx ; virtual address !!!
 20527                              <1> 		; jsr r0,arg; u.break / put the "address" 
 20528                              <1> 			; / in u.break (set new break point)
 20529                              <1> 		; br sysret4 / br sysret
 20530 0000439C E9E0EDFFFF          <1> 	jmp	sysret
 20531                              <1> 
 20532                              <1> maknod: 
 20533                              <1> 	; 18/07/2022
 20534                              <1> 	; 12/03/2022
 20535                              <1> 	; 11/03/2022
 20536                              <1> 	; 14/02/2022
 20537                              <1> 	; 10/01/2022
 20538                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20539                              <1> 	; 06/11/2021 (Retro UNIX 386 v2)
 20540                              <1> 	; 15/08/2021
 20541                              <1> 	; 06/05/2021
 20542                              <1> 	; 02/05/2021
 20543                              <1> 	; 01/04/2021
 20544                              <1> 	; 27/03/2021
 20545                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 20546                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20547                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 20548                              <1> 	;
 20549                              <1> 	; 'maknod' creates an i-node and makes a directory entry
 20550                              <1> 	; for this i-node in the current directory.
 20551                              <1> 	;
 20552                              <1> 	; INPUTS ->
 20553                              <1> 	;    r1 - contains mode
 20554                              <1> 	;    ii - current directory's i-number	
 20555                              <1> 	;    	
 20556                              <1> 	; OUTPUTS ->
 20557                              <1> 	;    u.dirbuf - contains i-number of free i-node 
 20558                              <1> 	;    i.flgs - flags in new i-node 
 20559                              <1> 	;    i.uid - filled with u.uid
 20560                              <1> 	;    i.nlks - 1 is put in the number of links
 20561                              <1> 	;    i.ctim - creation time
 20562                              <1> 	;    i.ctim+2 - modification time
 20563                              <1> 	;    imod - set via call to setimod
 20564                              <1> 	;	
 20565                              <1> 	; ((AX = R1)) input
 20566                              <1> 	;
 20567                              <1> 	; (Retro UNIX Prototype : 
 20568                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
 20569                              <1>         ; ((Modified registers: eax, edx, ebx, ecx, esi, edi, ebp))
 20570                              <1> 
 20571                              <1> 	; 27/03/2021
 20572                              <1> 	; INPUT:
 20573                              <1>  	;	AX = mode
 20574                              <1> 	;
 20575                              <1> 	; ('maknod' is called by 'syscreat' and 'sysmkdir')
 20576                              <1> 	; (('syscreat' and 'sysmkdir' will set AX input))
 20577                              <1> 
 20578                              <1> 	; 27/03/2021
 20579                              <1> 	; Retro UNIX 386 v2 inode mode flags (ref: 'ux.s')
 20580                              <1> 	; for File Inode: (high byte)
 20581                              <1> 	;   IFREG - 1 = regular file (8000h)
 20582                              <1> 	;   IFDIR - 1 = directory (4000h)
 20583                              <1> 	;   IRSVD - 0 = reserved bit (2000h) ; Mounted flag for dirs
 20584                              <1> 	;   ILARG - large file addressing bit (1000h)
 20585                              <1> 	;   ISUID - set user id on exec (800h)
 20586                              <1> 	;   ISGID - set group id on exec (400h)
 20587                              <1> 	;   IEXTT - 1 = use extents (200h)
 20588                              <1> 	;   IREAD - read, owner (100h)
 20589                              <1> 	; for Device Inode: (high byte)
 20590                              <1> 	;   IFREG - 0 = device file (8000h)
 20591                              <1> 	;   IFBLK - 1 = block device (4000h)
 20592                              <1> 	;   IFCHR - character special (2000h) -always 1-
 20593                              <1> 	;   IFIFO - fifo special (1000h)
 20594                              <1> 	;   IPIPE - pipe special (800h) ; 07/02/2020
 20595                              <1> 	;   IREDIR - redirected (400h)  ; 07/02/2020
 20596                              <1> 	;   IEXTR - 1 = external device driver (200h)
 20597                              <1> 	;   IREAD - read, owner (100h)
 20598                              <1> 
 20599                              <1> 	;; / r1 contains the mode
 20600                              <1> 	;or 	ah, 80h	; 10000000b
 20601                              <1> 	;	; bis $100000,r1 / allocate flag set
 20602                              <1> 
 20603                              <1> 	; 14/02/2022
 20604                              <1> 	; input ->
 20605                              <1> 	;   [u.namep] points to the file name address
 20606                              <1> 	;	     (in the user's memory space)
 20607                              <1> 	;   [u.dirp] points to empty slot in the directory
 20608                              <1> 
 20609                              <1> 	; high 3 bit will be checked here
 20610                              <1> 	; 	(ref: unix v7 x86 source, iget.c)
 20611                              <1> 
 20612                              <1> ;	; 27/03/2021
 20613                              <1> ;	test	ah, 0E0h ; 80h+40h+20h
 20614                              <1> ;	jnz	short maknod0	
 20615                              <1> ;
 20616                              <1> ;	; ('syscreat' clears ILARG & IEXTT bits)
 20617                              <1> ;	;and	ah, ~0Ch ; clear ILARG & IEXTT bits
 20618                              <1> ;	;	; user can set ISUID & ISGID bits
 20619                              <1> ;
 20620                              <1> ;	or	ah, 80h ; IFREG
 20621                              <1> ;maknod0:
 20622 000043A1 50                  <1> 	push	eax ; ***** ; 27/03/2021 (32 bit push, pop)
 20623                              <1> 		; mov r1,-(sp) / put mode on stack
 20624                              <1> 	; 31/07/2013
 20625                              <1> 	;mov	ax, [ii] ; move current i-number to AX/r1
 20626                              <1> 	;	; mov ii,r1 / move current i-number to r1
 20627                              <1> 	;mov	dl, 1 ; owner flag mask
 20628                              <1> 	; 15/08/2021
 20629                              <1> 	;movzx	eax, word [ii] ; move current i-number to EAX
 20630                              <1> 	; 09/01/2022
 20631 000043A2 A1[3C6C0000]        <1> 	mov	eax, [ii] ; move current i-number to EAX
 20632                              <1> 	; 25/03/2021
 20633 000043A7 66BA8000            <1> 	mov	dx, 80h	; IWRITE - write,owner
 20634 000043AB E8AB080000          <1> 	call	access	
 20635                              <1> 		; jsr r0,access; 1 / get its i-node into core
 20636                              <1> 	; 15/08/2021
 20637                              <1> 	; NOTE: cpu will not return here if there is a permission error
 20638                              <1> 	;	(it will jump to 'error' address from/in 'access')
 20639                              <1> 	
 20640 000043B0 50                  <1> 	push	eax ; **** (parent) ; 27/03/2021 (32 bit push, pop)
 20641                              <1> 		; mov r1,-(sp) / put i-number on stack
 20642                              <1> 	;mov	ax, 40
 20643                              <1> 	;	; mov $40.,r1 / r1 = 40
 20644                              <1> 	; 27/03/2021
 20645 000043B1 31C0                <1> 	xor	eax, eax
 20646                              <1> 	;;dec	ax ; 0FFFFh
 20647                              <1> 	; 15/08/2021
 20648                              <1> 	;dec	eax ; 0FFFFFFFFh
 20649                              <1> 	; 01/04/2021
 20650                              <1> ;maknod1: ; 1: / scan for a free i-node (next 4 instructions)
 20651                              <1> 	;;inc	ax
 20652                              <1> 	;	; inc r1 / r1 = r1 + 1
 20653                              <1> 	; 15/08/2021
 20654                              <1> 	;inc	eax
 20655                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 20656                              <1> 	; eax = 0 -> start from first free inode
 20657                              <1> 	; eax > 0 -> locate this inode on the inode map buffer
 20658                              <1> 	; NOTE:
 20659                              <1> 	; Retro UNIX 386 v2 'imap' is mostly different than v1 'imap'
 20660                              <1> 	; ('imap' will not check inode table)
 20661 000043B3 E8980A0000          <1> 	call	imap
 20662                              <1> 		; jsr r0,imap / get byte address and bit position in 
 20663                              <1> 			    ; /	inode map in r2 & m
 20664                              <1> 	; 09/01/2022
 20665                              <1> 	; (cpu will not return here if there would be an eror in imap)
 20666                              <1> 	; 15/08/2021
 20667                              <1> 	;jc	short maknod_err
 20668                              <1> 
 20669                              <1> 	; DX (MQ) has a 1 in the calculated bit position
 20670                              <1>         ; eBX (R2) has byte address of the byte with allocation bit
 20671                              <1> 
 20672                              <1> 	; 06/11/2021
 20673                              <1> 	; ebp = superblock buffer address
 20674                              <1> 	; eax = inode number
 20675                              <1> 	; 10/01/2022
 20676                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
 20677                              <1> 	;		of current IMAP sector	
 20678                              <1> 
 20679                              <1> 	; 27/03/2021
 20680                              <1> 	; If cpu is here, there is not an error
 20681                              <1> 	; and EBX points to inode map buffer
 20682                              <1> 	; DL has 1 at bit position which is for free inode
 20683                              <1> 	; (E)AX = inode number
 20684                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 20685                              <1> 	; ECX = byte offset from the (start of) inode map buffer
 20686                              <1> 
 20687                              <1> 	; 15/08/2021
 20688                              <1> maknod1:
 20689                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
 20690                              <1> 	;	       Inode count must be checked here
 20691                              <1> 	; (Original UNIX v1 did not check inode count here !?)
 20692 000043B8 8413                <1> 	test	[ebx], dl
 20693                              <1> 		; bitb mq,(r2) / is the i-node active
 20694                              <1> 	;jnz	short maknod1
 20695                              <1> 	;	; bne 1b / yes, try the next one
 20696                              <1> 	; 15/08/2021
 20697 000043BA 7408                <1> 	jz	short maknod3 ; free inode (inactive inode)
 20698                              <1> maknod2:
 20699 000043BC 40                  <1> 	inc	eax
 20700 000043BD E8B20A0000          <1> 	call	imap_x ; next call to imap (bypass 1st call code)
 20701                              <1> 	; 10/01/2022
 20702                              <1> 	; (cpu will/would not return here 
 20703                              <1> 	;  if there is/was an error in 'imap_x')
 20704                              <1> 	;jnc	short maknod1
 20705 000043C2 EBF4                <1> 	jmp	short maknod1
 20706                              <1> 
 20707                              <1> 	; 14/02/2022
 20708                              <1> ;maknod_err:
 20709                              <1> ;	; 15/08/2021
 20710                              <1> ;	;pop	edx  ; two pops for stack alignment
 20711                              <1> ;	;pop	edx  ; (may not be needed while jumping to 'error')
 20712                              <1> ;	mov	[u.error], eax
 20713                              <1> ;	jmp	error
 20714                              <1> maknod3:
 20715                              <1> 	; 10/01/2022
 20716                              <1> 	; ebp = superblock buffer address
 20717                              <1> 	; eax = (free) inode number
 20718                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
 20719                              <1> 	;			of current IMAP sector
 20720                              <1> 	; EBX = buffer address/offset for relevant alloc byte
 20721                              <1> 	;  DL has 1 at bit position which is for free inode
 20722                              <1> 	;
 20723                              <1> 	; ECX = byte offset from the (start of) inode map buffer
 20724                              <1> 
 20725                              <1> 	;mov	[ebp+SB.LastInode], eax ; (free) inode number
 20726                              <1> 
 20727 000043C4 50                  <1> 	push	eax ; ***
 20728 000043C5 51                  <1> 	push	ecx ; **
 20729 000043C6 52                  <1> 	push	edx ; *
 20730                              <1> 	; 18/07/2022
 20731                              <1> 	;push	ebp ; @ ; 11/03/2022
 20732                              <1> 
 20733 000043C7 8B457C              <1> 	mov	eax, [ebp+SB.ImapBuffer]
 20734                              <1> 
 20735 000043CA E821160000          <1> 	call	wslot
 20736                              <1> 	; ebx = buffer data address (write operation bit is set)
 20737                              <1> 	; eax = physical sector number
 20738                              <1> 	; Note: ebx contains addr of the 1st buffer in the buf chain
 20739                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 20740                              <1> 
 20741                              <1> 	; 18/07/2022
 20742                              <1> 	;pop	ebp ; @ ; 11/03/2022
 20743                              <1> 
 20744                              <1> 	;mov	[ebp+SB.ImapBuffer], ebx
 20745                              <1> 			; save inode map buffer address
 20746 000043CF 5A                  <1> 	pop	edx ; *
 20747 000043D0 59                  <1> 	pop	ecx ; **
 20748 000043D1 01CB                <1> 	add	ebx, ecx ; + byte offset (for allocation bit pos)	
 20749                              <1> 
 20750                              <1> 	; set allocation bit (for this new inode) ; 10/01/2022 
 20751 000043D3 0813                <1> 	or	[ebx], dl
 20752                              <1> 		; bisb mq,(r2) / no, make it active 
 20753                              <1> 			     ; / (put a 1 in the bit map)
 20754                              <1> 	;push	ebp ; @
 20755 000043D5 E823160000          <1> 	call	dskwr ; writes the 1st buffer to sector
 20756                              <1> 		      ; (at the beginning/head of the buffer chain)
 20757                              <1> 	;pop	ebp ; @
 20758                              <1> 
 20759                              <1> 	; if we are here, buffer has been written to disk successfully 
 20760                              <1> 	; (otherwise cpu would jump to 'error' address)
 20761                              <1> 
 20762                              <1> 	; set superblock modified flag
 20763 000043DA BA[566C0000]        <1> 	mov	edx, smod
 20764 000043DF F605[416C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 20765 000043E6 7401                <1> 	jz	short maknod4 ; no, root device
 20766                              <1> 	; yes, mounted device
 20767                              <1> 	;mov	edx, mmod
 20768 000043E8 42                  <1> 	inc	edx ; edx = offset mmod
 20769                              <1> maknod4: 
 20770 000043E9 FE02                <1> 	inc	byte [edx] ; superblock modified !
 20771                              <1> 
 20772                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20773                              <1> 	;;
 20774                              <1> 	;; 27/03/2021
 20775                              <1> 	;; (ref: 'UNIXHDCP.ASM', 'mak_nod', 18/01/2020)
 20776                              <1> 	;or	byte [smod], 2 ; inode map modified
 20777                              <1> 	;; 01/04/2021
 20778                              <1> 	;;or	byte [imapbuf_hdr+bufhdr.status], 2
 20779                              <1> 	;or	byte [imapbuf_hdr], 2 ; set modified flag bit
 20780                              <1> 	; 02/05/2021
 20781                              <1> 	;or	byte [esi+ldrv.b_status], 2 ; inode map modified
 20782                              <1> 	; 15/08/2021
 20783                              <1> 	; 06/05/2021
 20784                              <1> 	;or	byte [esi+ldrv.status], 2 ; inode map modified
 20785                              <1> 	;;or	byte [sysbuf_hdr], 2 ; set modified flag bit
 20786                              <1> 	
 20787                              <1> 	;mov	eax, [ebp+SB.LastInode] ; (free) inode number
 20788                              <1> 	;push	eax ; ***
 20789                              <1> 
 20790                              <1> 	; 12/03/2022
 20791                              <1> 	; increase first free inode number
 20792 000043EB 8B0424              <1> 	mov	eax, [esp] ; ***
 20793 000043EE 40                  <1> 	inc	eax ; next inode number 
 20794                              <1> 		    ; (free inode search start value)
 20795 000043EF 894534              <1> 	mov	[ebp+SB.FirstFreeIno], eax
 20796                              <1> 
 20797                              <1> 	; 12/03/2022
 20798                              <1> 	; decrease free inode count
 20799 000043F2 8B5530              <1> 	mov	edx, [ebp+SB.FreeInodes]
 20800                              <1> 	;cmp	edx, 0FFFFFFFFh
 20801                              <1> 	;je	short maknod5 ; invalid
 20802 000043F5 42                  <1> 	inc	edx ; 0FFFFFFFFh -> 0
 20803 000043F6 7405                <1> 	jz	short maknod5 ; invalid
 20804 000043F8 4A                  <1> 	dec	edx
 20805 000043F9 4A                  <1> 	dec	edx
 20806 000043FA 895530              <1> 	mov	[ebp+SB.FreeInodes], edx ; -1
 20807                              <1> maknod5:
 20808 000043FD E851170000          <1> 	call	get_system_time
 20809                              <1> 		; eax = current time (as unix epoch time)
 20810 00004402 89455C              <1> 	mov	[ebp+SB.ModifTime], eax
 20811                              <1> 
 20812 00004405 58                  <1> 	pop	eax ; *** ; inode number
 20813                              <1> 	;;
 20814 00004406 E866070000          <1> 	call	iget
 20815                              <1> 		; jsr r0,iget / get i-node into core
 20816                              <1> 	; 09/01/2022
 20817                              <1> 	;  (If cpu is here, there was/is not an error!)
 20818                              <1> 	; 06/11/2021
 20819                              <1> 	;jc	short maknod_err
 20820                              <1> 	
 20821                              <1> 	;test	word [i.flgs], 8000h 
 20822                              <1> 	;	; tst i.flgs / is i-node already allocated
 20823                              <1> 	;jnz	short maknod1	
 20824                              <1> 	;	; blt 1b / yes, look for another one
 20825                              <1> 	; 27/03/2021
 20826                              <1> 	; (Retro UNIX 386 v2 inode flags) 
 20827 0000440B F605[E5670000]E0    <1> 	test	byte [i.flgs+1], 0E0h ; 80h+40h+20h
 20828                              <1> 	;jnz	short maknod1 ; i-node already allocated
 20829                              <1> 	;		      ; (as it is in inode table)
 20830                              <1> 	; 15/08/2021
 20831 00004412 75A8                <1> 	jnz	short maknod2 ; defective inode map !?
 20832                              <1> 
 20833                              <1> 	; AX = free inode number
 20834 00004414 66A3[9C6C0000]      <1> 	mov	[u.dirbuf], ax
 20835                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
 20836 0000441A 58                  <1> 	pop	eax ; **** (parent) ; 27/03/2021 (32 bit push, pop)
 20837                              <1> 		; mov (sp)+,r1 / get current i-number back
 20838 0000441B E851070000          <1> 	call	iget
 20839                              <1> 		; jsr r0,iget / get i-node in core
 20840                              <1> 	; 09/01/2022
 20841                              <1> 	; 06/11/2021
 20842                              <1> 	;jc	short maknod_err
 20843                              <1> 
 20844                              <1> 	; 14/02/2022
 20845                              <1> 	; here..
 20846                              <1> 	;  [u.namep] points to the file name address
 20847                              <1> 	;	     (in the user's memory space)
 20848                              <1> 	;  [u.dirp] points to empty slot in the directory
 20849                              <1> 
 20850 00004420 E81CF7FFFF          <1> 	call	mkdir
 20851                              <1> 		; jsr r0,mkdir / make a directory entry 
 20852                              <1> 			     ; / in current directory
 20853                              <1> 	; 09/01/2022
 20854                              <1> 	;  (If cpu is here, there was/is not an error in 'mkdir'!)
 20855                              <1> 	; 06/11/2021
 20856                              <1> 	;jc	short maknod_err
 20857                              <1> 	
 20858                              <1> 	; (eax = 0)
 20859                              <1> 	;movzx	eax, [u.difbuf] ; 06/11/2021
 20860 00004425 66A1[9C6C0000]      <1> 	mov	ax, [u.dirbuf]
 20861                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
 20862 0000442B E841070000          <1> 	call	iget
 20863                              <1> 		; jsr r0,iget / get it into core
 20864                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
 20865                              <1> 	; 09/01/2022
 20866                              <1> 	; 06/11/2021
 20867                              <1> 	;jc	short maknod_err
 20868                              <1> 
 20869                              <1> 	;mov	ecx, 8
 20870                              <1> 	; 27/03/2021
 20871 00004430 31C9                <1> 	xor	ecx, ecx 
 20872 00004432 B110                <1> 	mov	cl, 16 ; 64 bit inodes
 20873 00004434 31C0                <1> 	xor	eax, eax ; 0
 20874 00004436 BF[E4670000]        <1> 	mov	edi, inode 
 20875 0000443B F3AB                <1> 	rep	stosd
 20876                              <1> 	;
 20877                              <1> 	;pop	word [i.flgs]
 20878                              <1> 	;	; mov (sp)+,i.flgs / fill flags
 20879                              <1> 	; 27/03/2021 (32 bit push, pop)
 20880 0000443D 58                  <1> 	pop	eax ; *****
 20881 0000443E 66A3[E4670000]      <1> 	mov	[i.flgs], ax
 20882                              <1> 
 20883                              <1> 	;mov 	cl, [u.uid] ; 02/08/2013
 20884                              <1> 	;mov 	[i.uid], cl
 20885                              <1> 	;	; movb u.uid,i.uid / user id
 20886                              <1> 	; 15/08/2021
 20887                              <1> 	; 27/03/2021
 20888 00004444 8A0D[BA6C0000]      <1> 	mov	cl, [u.gid] ; 8 bit group ID ; 15/08/2021
 20889 0000444A 880D[EA670000]      <1> 	mov	[i.gid], cl 	
 20890 00004450 668B0D[B66C0000]    <1> 	mov	cx, [u.uid] ; 16 bit user ID
 20891 00004457 66890D[E8670000]    <1> 	mov	[i.uid], cx	
 20892                              <1> 
 20893 0000445E C605[E6670000]01    <1> 	mov     byte [i.nlks], 1
 20894                              <1> 		; movb $1,i.nlks / 1 link
 20895                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
 20896                              <1> 	;mov	eax, [s.time]
 20897                              <1> 	;mov 	[i.ctim], eax
 20898                              <1> 	 	; mov s.time,i.ctim / time created
 20899                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
 20900                              <1> 	; Retro UNIX 8086 v1 modification !
 20901                              <1> 	; i.ctime=0, i.ctime+2=0 and
 20902                              <1>         ; 'setimod' will set ctime of file via 'epoch'
 20903                              <1> 	;call	setimod
 20904                              <1> 	;	; jsr r0,setimod / set modified flag
 20905                              <1> 	;retn
 20906                              <1> 	;	; rts r0 / return
 20907                              <1> 	; 27/03/2021
 20908 00004465 E998080000          <1> 	jmp	setimod
 20909                              <1> 
 20910                              <1> sysseek: ; / moves read write pointer in an fsp entry
 20911                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20912                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 20913                              <1> 	;
 20914                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
 20915                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
 20916                              <1> 	; The file descriptor refers to a file open for reading or
 20917                              <1> 	; writing. The read (or write) pointer is set as follows:
 20918                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
 20919                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
 20920                              <1> 	;	  current location plus offset.
 20921                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
 20922                              <1> 	;	  size of file plus offset.
 20923                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
 20924                              <1> 	;
 20925                              <1> 	; Calling sequence:
 20926                              <1> 	;	sysseek; offset; ptrname
 20927                              <1> 	; Arguments:
 20928                              <1> 	;	offset - number of bytes desired to move 
 20929                              <1> 	;		 the r/w pointer
 20930                              <1> 	;	ptrname - a switch indicated above
 20931                              <1> 	;
 20932                              <1> 	; Inputs: r0 - file descriptor 
 20933                              <1> 	; Outputs: -
 20934                              <1> 	; ...............................................................
 20935                              <1> 	;	
 20936                              <1> 	; Retro UNIX 8086 v1 modification: 
 20937                              <1> 	;       'sysseek' system call has three arguments; so,
 20938                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
 20939                              <1> 	;	* 2nd argument, offset is in CX register
 20940                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
 20941                              <1> 	;	
 20942                              <1> 
 20943 0000446A E820000000          <1> 	call	seektell
 20944                              <1> 	; AX = u.count
 20945                              <1> 	; BX = *u.fofp
 20946                              <1> 		; jsr r0,seektell / get proper value in u.count
 20947                              <1> 		; add u.base,u.count / add u.base to it
 20948 0000446F 0305[886C0000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
 20949 00004475 8903                <1> 	mov	[ebx], eax
 20950                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
 20951 00004477 E905EDFFFF          <1> 	jmp	sysret
 20952                              <1> 		; br sysret4
 20953                              <1> 
 20954                              <1> systell: ; / get the r/w pointer
 20955                              <1> 	; 01/03/2022
 20956                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20957                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20958                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 20959                              <1> 	;
 20960                              <1> 	; Retro UNIX 8086 v1 modification:
 20961                              <1> 	; ! 'systell' does not work in original UNIX v1,
 20962                              <1> 	; 	    it returns with error !
 20963                              <1> 	; Inputs: r0 - file descriptor 
 20964                              <1> 	; Outputs: r0 - file r/w pointer
 20965                              <1> 
 20966                              <1> 	;xor	ecx, ecx ; 0
 20967                              <1> 	;mov	edx, 1 ; 05/08/2013
 20968                              <1> 	; 09/01/2022
 20969 0000447C 29D2                <1> 	sub	edx, edx
 20970 0000447E FEC2                <1> 	inc	dl
 20971                              <1> 	; edx = 1
 20972                              <1> 	;call 	seektell
 20973 00004480 E810000000          <1> 	call 	seektell0 ; 05/08/2013
 20974                              <1> 	;mov	ebx, [u.fofp]
 20975                              <1> 	; 01/03/2022
 20976                              <1> 	;mov	eax, [ebx]
 20977 00004485 A3[646C0000]        <1> 	mov	[u.r0], eax
 20978 0000448A E9F2ECFFFF          <1> 	jmp	sysret
 20979                              <1> 
 20980                              <1> ; Original unix v1 'systell' system call:
 20981                              <1> 		; jsr r0,seektell
 20982                              <1> 		; br error4
 20983                              <1> 
 20984                              <1> seektell:
 20985                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 20986                              <1> 	; 06/11/2021
 20987                              <1> 	; 12/06/2021
 20988                              <1> 	; 06/05/2021 (Retro UNIX 386 v2)
 20989                              <1> 	; 03/01/2016
 20990                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20991                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 20992                              <1> 	;
 20993                              <1> 	; 'seektell' puts the arguments from sysseek and systell
 20994                              <1> 	; call in u.base and u.count. It then gets the i-number of
 20995                              <1> 	; the file from the file descriptor in u.r0 and by calling
 20996                              <1> 	; getf. The i-node is brought into core and then u.count
 20997                              <1> 	; is checked to see it is a 0, 1, or 2.
 20998                              <1> 	; If it is 0 - u.count stays the same
 20999                              <1> 	;          1 - u.count = offset (u.fofp)
 21000                              <1> 	;	   2 - u.count = i.size (size of file)
 21001                              <1> 	; 	 		
 21002                              <1> 	; !! Retro UNIX 8086 v1 modification:
 21003                              <1> 	;	Argument 1, file descriptor is in BX;
 21004                              <1> 	;	Argument 2, offset is in CX;
 21005                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
 21006                              <1> 	;
 21007                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
 21008                              <1> 	; call 	arg
 21009                              <1> 	;
 21010                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
 21011                              <1> 	;
 21012 0000448F 890D[886C0000]      <1> 	mov 	[u.base], ecx ; offset
 21013                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
 21014                              <1> 	; 09/01/2022
 21015                              <1> 	; ebx = file descriptor (0 to 9)
 21016                              <1> seektell0:
 21017 00004495 8915[8C6C0000]      <1> 	mov 	[u.count], edx
 21018                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
 21019                              <1> 	;mov	ax, bx
 21020                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
 21021                              <1> 			     ; / (index in u.fp list)
 21022                              <1> 	; 12/06/2021
 21023                              <1> 	; BX = file descriptor (file number)
 21024 0000449B E8A2FBFFFF          <1> 	call	getf
 21025                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
 21026                              <1> 	; 09/01/2022
 21027 000044A0 09C0                <1> 	or	eax, eax
 21028                              <1> 	;or	ax, ax ; i-number of the file
 21029                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
 21030                              <1> 		             ; / put it on the stack
 21031                              <1> 	;jz	error
 21032                              <1> 		; beq error4 / if i-number is 0, not active so error
 21033 000044A2 750F                <1> 	jnz	short seektell1
 21034 000044A4 C705[D86C0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 21035 000044AC 0000                <1>
 21036 000044AE E9AEECFFFF          <1> 	jmp	error
 21037                              <1> seektell1:
 21038                              <1> 	; 06/05/2021
 21039                              <1> 	;push	eax
 21040                              <1> 	;cmp	ah, 80h
 21041                              <1> 	;jb	short seektell2
 21042                              <1> 	;	; bgt .+4 / if its positive jump
 21043                              <1> 	;neg	ax
 21044                              <1> 	;	; neg r1 / if not make it positive
 21045                              <1> seektell2:
 21046 000044B3 E8B9060000          <1> 	call	iget
 21047                              <1> 		; jsr r0,iget / get its i-node into core
 21048                              <1> 	; 09/01/2022
 21049                              <1> 	; (if there is/was an error in 'iget', cpu will not come here)
 21050                              <1> 	;; 06/11/2021
 21051                              <1> 	;jnc	short seektell6
 21052                              <1> 	;mov	[u.error], eax
 21053                              <1> 	;jmp	error
 21054                              <1> seektell6:
 21055 000044B8 8B1D[786C0000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
 21056 000044BE 803D[8C6C0000]01    <1> 	cmp	byte [u.count], 1
 21057                              <1> 		; cmp u.count,$1 / is ptr name =1
 21058 000044C5 7705                <1> 	ja	short seektell3
 21059                              <1> 		; blt 2f / no its zero
 21060 000044C7 7409                <1> 	je	short seektell4
 21061                              <1> 		; beq 1f / yes its 1
 21062 000044C9 31C0                <1> 	xor	eax, eax
 21063                              <1> 	;jmp	short seektell5
 21064 000044CB C3                  <1> 	retn
 21065                              <1> seektell3:
 21066                              <1> 	; 03/01/2016
 21067                              <1> 	;;movzx	eax, word [i.size]
 21068                              <1> 	;mov   	ax, [i.size]
 21069                              <1> 	;	; mov i.size,u.count /  put number of bytes 
 21070                              <1> 	;			; / in file in u.count
 21071                              <1> 	;;jmp	short seektell5
 21072                              <1> 	;	; br 2f
 21073                              <1> 	; 06/05/2021 - Retro UNIX 386 v2
 21074 000044CC A1[EC670000]        <1> 	mov	eax, [i.size]
 21075 000044D1 C3                  <1> 	retn
 21076                              <1> seektell4: ; 1: / ptrname =1
 21077                              <1> 	;mov	ebx, [u.fofp]
 21078 000044D2 8B03                <1> 	mov	eax, [ebx]
 21079                              <1> 		; mov *u.fofp,u.count / put offset in u.count
 21080                              <1> ;seektell5: ; 2: / ptrname =0
 21081                              <1> 	;mov	[u.count], eax
 21082                              <1> 	;pop	eax 
 21083                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
 21084 000044D4 C3                  <1> 	retn
 21085                              <1> 		; rts r0
 21086                              <1> 
 21087                              <1> sysintr: ; / set interrupt handling
 21088                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21089                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21090                              <1> 	;
 21091                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
 21092                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
 21093                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
 21094                              <1> 	; If one does the interrupt character in the tty buffer is
 21095                              <1> 	; cleared and 'sysret'is called. If one does not exits
 21096                              <1> 	; 'sysret' is just called.	
 21097                              <1> 	;
 21098                              <1> 	; Calling sequence:
 21099                              <1> 	;	sysintr; arg
 21100                              <1> 	; Argument:
 21101                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
 21102                              <1> 	;	    - if 1, intterupts cause their normal result
 21103                              <1> 	;		 i.e force an exit.
 21104                              <1> 	;	    - if arg is a location within the program,
 21105                              <1> 	;		control is passed to that location when
 21106                              <1> 	;		an interrupt occurs.	
 21107                              <1> 	; Inputs: -
 21108                              <1> 	; Outputs: -
 21109                              <1> 	; ...............................................................
 21110                              <1> 	;	
 21111                              <1> 	; Retro UNIX 8086 v1 modification: 
 21112                              <1> 	;       'sysintr' system call sets u.intr to value of BX
 21113                              <1> 	;	then branches into sysquit.
 21114                              <1> 	;
 21115 000044D5 66891D[B06C0000]    <1> 	mov	[u.intr], bx
 21116                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
 21117                              <1> 		; br 1f / go into quit routine
 21118 000044DC E9A0ECFFFF          <1> 	jmp	sysret
 21119                              <1> 
 21120                              <1> sysquit:
 21121                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21122                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21123                              <1> 	;
 21124                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
 21125                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
 21126                              <1> 	; tty exists. If one does the interrupt character in the tty
 21127                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
 21128                              <1> 	; 'sysret' is just called.	
 21129                              <1> 	;
 21130                              <1> 	; Calling sequence:
 21131                              <1> 	;	sysquit; arg
 21132                              <1> 	; Argument:
 21133                              <1> 	;	arg - if 0, this call disables quit signals from the
 21134                              <1> 	;		typewriter (ASCII FS)
 21135                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
 21136                              <1> 	;		cease and a core image to be produced.
 21137                              <1> 	;		 i.e force an exit.
 21138                              <1> 	;	    - if arg is an address in the program,
 21139                              <1> 	;		a quit causes control to sent to that
 21140                              <1> 	;		location.	
 21141                              <1> 	; Inputs: -
 21142                              <1> 	; Outputs: -
 21143                              <1> 	; ...............................................................
 21144                              <1> 	;	
 21145                              <1> 	; Retro UNIX 8086 v1 modification: 
 21146                              <1> 	;       'sysquit' system call sets u.quit to value of BX
 21147                              <1> 	;	then branches into 'sysret'.
 21148                              <1> 	;
 21149 000044E1 66891D[B26C0000]    <1> 	mov	[u.quit], bx
 21150 000044E8 E994ECFFFF          <1> 	jmp	sysret
 21151                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
 21152                              <1> 	;1:
 21153                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
 21154                              <1> 			      ; / to r1
 21155                              <1> 		; beq sysret4 / return to user
 21156                              <1> 		; clrb 6(r1) / clear the interrupt character 
 21157                              <1> 			   ; / in the tty buffer
 21158                              <1> 		; br sysret4 / return to user
 21159                              <1> 
 21160                              <1> syssetuid: ; / set process id
 21161                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21162                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21163                              <1> 	;		(16 bit uid)
 21164                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21165                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 21166                              <1> 	;
 21167                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
 21168                              <1> 	; to the process id in (u.r0). Both the effective user u.uid
 21169                              <1> 	; and the real user u.ruid are set to this. 
 21170                              <1> 	; Only the super user can make this call.	
 21171                              <1> 	;
 21172                              <1> 	; Calling sequence:
 21173                              <1> 	;	syssetuid
 21174                              <1> 	; Arguments: -
 21175                              <1> 	;
 21176                              <1> 	; Inputs: (u.r0) - contains the process id.
 21177                              <1> 	; Outputs: -
 21178                              <1> 	; ...............................................................
 21179                              <1> 	;	
 21180                              <1> 	; Retro UNIX 8086 v1 modification: 
 21181                              <1> 	;       BL contains the (new) user ID of the current process
 21182                              <1> 
 21183                              <1> 	; 27/03/2021
 21184                              <1> 	; INPUT:
 21185                              <1> 	;    BX = (new) user ID
 21186                              <1> 
 21187                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
 21188                              <1> 	;cmp	bl, [u.ruid] 
 21189                              <1> 	;	; cmpb r1,u.ruid / is it equal to the real user 
 21190                              <1> 			       ; / id number
 21191                              <1> 	; 27/03/2021
 21192 000044ED 663B1D[B86C0000]    <1> 	cmp	bx, [u.ruid]
 21193 000044F4 7420                <1> 	je	short setuid1
 21194                              <1> 		; beq 1f / yes
 21195                              <1> 	;cmp	byte [u.uid], 0 ; 02/08/2013
 21196                              <1> 	;	; tstb u.uid / no, is current user the super user?
 21197                              <1> 	;;ja	error
 21198                              <1> 	;	; bne error4 / no, error
 21199                              <1> 	; 27/03/2021
 21200 000044F6 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0 
 21201 000044FE 760F                <1> 	jna	short setuid0
 21202                              <1> setuid_err:
 21203                              <1> setgid_err:
 21204 00004500 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
 21205 00004508 0000                <1>
 21206                              <1> 				; 'permission denied !' error
 21207 0000450A E952ECFFFF          <1> 	jmp	error
 21208                              <1> setuid0:
 21209                              <1> 	;mov	[u.ruid], bl
 21210                              <1> 	; 27/03/2021
 21211 0000450F 66891D[B86C0000]    <1> 	mov	[u.ruid], bx
 21212                              <1> setuid1: ; 1:
 21213                              <1> 	;mov	[u.uid], bl ; 02/08/2013
 21214                              <1> 	;	; movb r1,u.uid / put process id in u.uid
 21215                              <1> 	;	; movb r1,u.ruid / put process id in u.ruid
 21216                              <1> 	; 27/03/2021
 21217 00004516 66891D[B66C0000]    <1> 	mov	[u.uid], bx
 21218 0000451D E95FECFFFF          <1> 	jmp	sysret
 21219                              <1> 		; br sysret4 / system return
 21220                              <1> 
 21221                              <1> sysgetuid: ; < get user id >
 21222                              <1> 	; 11/03/2022
 21223                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21224                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21225                              <1> 	;		(16 bit uid)
 21226                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21227                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 21228                              <1> 	;
 21229                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
 21230                              <1> 	; The real user ID identifies the person who is logged in,
 21231                              <1> 	; in contradistinction to the effective user ID, which
 21232                              <1> 	; determines his access permission at each moment. It is thus
 21233                              <1> 	; useful to programs which operate using the 'set user ID'
 21234                              <1> 	; mode, to find out who invoked them.	
 21235                              <1> 	;
 21236                              <1> 	; Calling sequence:
 21237                              <1> 	;	syssetuid
 21238                              <1> 	; Arguments: -
 21239                              <1> 	;
 21240                              <1> 	; Inputs: -
 21241                              <1> 	; Outputs: (u.r0) - contains the real user's id.
 21242                              <1> 	; ...............................................................
 21243                              <1> 	;	
 21244                              <1> 	; Retro UNIX 8086 v1 modification: 
 21245                              <1> 	;       AL contains the real user ID at return.
 21246                              <1> 	;
 21247                              <1> 	; 11/03/2022 - Retro UNIX 386 v1.2
 21248                              <1> 	; Input:
 21249                              <1> 	;	none
 21250                              <1> 	; Output/Return:
 21251                              <1> 	;	AX = real user ID
 21252                              <1> 	;	Hig Word of EAX = effective user ID
 21253                              <1> 
 21254                              <1> 	;;movzx eax, byte [u.ruid]
 21255                              <1> 	; 27/03/2021
 21256                              <1> 	;movzx	eax, word [u.ruid]
 21257                              <1> 	; 11/03/2022
 21258                              <1> 	; (return u.uid & u.ruid numbers as it is in unix v5-v7)
 21259 00004522 66A1[B66C0000]      <1> 	mov	ax, [u.uid]
 21260 00004528 C1E010              <1> 	shl	eax, 16	; efective user ID in high word of eax
 21261                              <1> 	; 09/01/2022
 21262 0000452B 66A1[B86C0000]      <1> 	mov	ax, [u.ruid] ; real user ID in low word of eax
 21263 00004531 A3[646C0000]        <1> 	mov	[u.r0], eax 
 21264                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
 21265 00004536 E946ECFFFF          <1> 	jmp	sysret
 21266                              <1> 		; br sysret4 / systerm return, sysret
 21267                              <1> 
 21268                              <1> syssetgid: ; set group id
 21269                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21270                              <1> 	; 02/04/2021
 21271                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21272                              <1> 	;
 21273                              <1> 	; 'syssetgid' sets the user's group id (u.gid) 
 21274                              <1> 	;  of the current process to the process id in (u.r0).
 21275                              <1> 	;  Both the effective user u.gid and the real user
 21276                              <1> 	;  u.rgid are set to this. 
 21277                              <1> 	;  Only the super user can make this call.	
 21278                              <1> 	
 21279                              <1> 	; INPUT:
 21280                              <1> 	;	BL = (new) group ID
 21281                              <1> 	; OUTPUT:
 21282                              <1> 	;	-
 21283                              <1> 
 21284 0000453B 3A1D[BB6C0000]      <1> 	cmp	bl, [u.rgid] 
 21285 00004541 7410                <1> 	je	short setgid1
 21286                              <1> 
 21287                              <1> 	;cmp	byte [u.uid], 0
 21288                              <1> 	; 02/04/2021
 21289 00004543 66833D[B66C0000]00  <1> 	cmp	word [u.uid], 0
 21290 0000454B 77B3                <1> 	ja	short setgid_err
 21291                              <1> setgid0:
 21292 0000454D 881D[BB6C0000]      <1> 	mov	[u.rgid], bl
 21293                              <1> setgid1: ; 1:
 21294 00004553 881D[BA6C0000]      <1> 	mov	[u.gid], bl
 21295 00004559 E923ECFFFF          <1> 	jmp	sysret
 21296                              <1> 
 21297                              <1> sysgetgid: ; < get group id >
 21298                              <1> 	; 11/03/2022
 21299                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21300                              <1> 	; 27/03/2021 - Retro UNIX 386 v2
 21301                              <1> 	;
 21302                              <1> 	; 'sysgetgid' returns the real group ID of the current process.
 21303                              <1> 	; The real group ID identifies the group of the person
 21304                              <1> 	; who is logged in, in contradistinction to the effective
 21305                              <1> 	; group ID, which determines his access permission at each moment.
 21306                              <1> 	; It is thus useful to programs which operate using
 21307                              <1> 	; the 'set group ID' mode, to find out the group of the user
 21308                              <1> 	; who invoked them.
 21309                              <1> 
 21310                              <1> 	; 11/03/2022 - Retro UNIX 386 v1.2
 21311                              <1> 	; Input:
 21312                              <1> 	;	none
 21313                              <1> 	; Output/Return:
 21314                              <1> 	;	AL = real group ID
 21315                              <1> 	;	AH = effective group ID
 21316                              <1> 
 21317                              <1> 	;movzx	eax, word [u.ruid]
 21318                              <1> 	;; 09/01/2022
 21319                              <1> 	;mov	ax, [u.ruid]
 21320                              <1> 	; 11/03/2022
 21321                              <1> 	; (return u.gid & u.rgid numbers as it is in unix v5-v7)
 21322 0000455E 8A25[BA6C0000]      <1> 	mov	ah, [u.gid] ; efective group ID in byte 1
 21323 00004564 A0[BB6C0000]        <1> 	mov	al, [u.rgid] ; real group ID in byte 0
 21324 00004569 A3[646C0000]        <1> 	mov	[u.r0], eax
 21325 0000456E E90EECFFFF          <1> 	jmp	sysret
 21326                              <1> 
 21327                              <1> sysver: ; get operating system version
 21328                              <1> 	; 09/01/2022 - Retro UNIX 386 v1.2
 21329                              <1> 	; 18/06/2021 - Retro UNIX 386 v2
 21330                              <1> 
 21331                              <1> 	;VMAJOR equ 2 ; Retro UNIX 386 v2
 21332                              <1> 	;VMINOR equ 0 ; Retro UNIX 386 v2.0 (v2.0.0)
 21333                              <1> 	;CURRENT_VERSION equ (VMAJOR*256)+VMINOR
 21334                              <1> 
 21335                              <1> 	; 09/01/2022
 21336                              <1> 	VMAJOR equ 1 ; Retro UNIX 386 v1
 21337                              <1> 	VMINOR equ 2 ; Retro UNIX 386 v1.2 (v1.2.0)
 21338                              <1> 	CURRENT_VERSION equ (VMAJOR*256)+VMINOR 		  
 21339                              <1> 
 21340                              <1> 	; 29/04/2016 - TRDOS 386 v2.0
 21341                              <1> 	;mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
 21342                              <1> 	; 18/06/2021
 21343 00004573 C705[646C0000]0201- <1> 	mov	dword [u.r0], CURRENT_VERSION ;	(ah = 2, al = 0)
 21344 0000457B 0000                <1>
 21345 0000457D E9FFEBFFFF          <1> 	jmp	sysret
 21346                              <1> 
 21347                              <1> anyi: 
 21348                              <1> 	; 18/07/2022
 21349                              <1> 	; 26/03/2022
 21350                              <1> 	; 13/03/2022
 21351                              <1> 	; 12/03/2022
 21352                              <1> 	; 09/01/2022
 21353                              <1> 	; 02/01/2022
 21354                              <1> 	; 01/01/2022
 21355                              <1> 	; 27/12/2021 (Retro UNIX 386 v1.2)
 21356                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 21357                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 21358                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
 21359                              <1> 	;
 21360                              <1> 	; 'anyi' is called if a file deleted while open.
 21361                              <1> 	; "anyi" checks to see if someone else has opened this file.
 21362                              <1> 	;
 21363                              <1> 	; INPUTS ->
 21364                              <1> 	;    r1 - contains an i-number
 21365                              <1> 	;    fsp - start of table containing open files
 21366                              <1> 	;
 21367                              <1> 	; OUTPUTS ->
 21368                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
 21369                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
 21370                              <1> 	;    if file not found - bit in i-node map is cleared
 21371                              <1> 	;    			 (i-node is freed)
 21372                              <1> 	;               all blocks related to i-node are freed
 21373                              <1> 	;	        all flags in i-node are cleared
 21374                              <1> 	; ((AX = R1)) input
 21375                              <1> 	;
 21376                              <1> 	;    (Retro UNIX Prototype: 02/12/2012, UNIXCOPY.ASM)
 21377                              <1> 	;	12/03/2022
 21378                              <1>         ;    ((Modified registers: eax, edx, ecx, ebx, esi, edi, ebp))  
 21379                              <1> 	;
 21380                              <1> 		; / r1 contains an i-number
 21381 00004582 BB[D4680000]        <1> 	mov	ebx, fsp
 21382                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
 21383                              <1> anyi_1: ; 1:
 21384                              <1> 	;cmp	eax, [ebx] ; 09/01/2022 (32 bit inode number)
 21385 00004587 663B03              <1> 	cmp	ax, [ebx]
 21386                              <1> 		; cmp r1,(r2) / do i-numbers match?
 21387                              <1> 	;je	short anyi_3
 21388                              <1> 		; beq 1f / yes, 1f
 21389                              <1> 	; 12/03/2022
 21390 0000458A 7505                <1> 	jne	short anyi_0		
 21391                              <1> 
 21392                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21393                              <1> 	;neg	ax
 21394                              <1> 	;	; neg r1 / no complement r1
 21395                              <1> 	;cmp	ax, [ebx]
 21396                              <1> 	;	; cmp r1,(r2) / do they match now?
 21397                              <1> 	;;je	short anyi_3
 21398                              <1> 		; beq 1f / yes, transfer
 21399                              <1> 		; / i-numbers do not match
 21400                              <1> 	; 12/03/2022
 21401                              <1> 	;jne	short ayni_0
 21402                              <1> 
 21403                              <1> anyi_3: ; 1: / i-numbers match
 21404                              <1> 	; 13/03/2022 (BugFix)
 21405                              <1> 	;; 09/01/2022
 21406                              <1> 	;test	byte [ebx+5], 1 ; open for writing flag
 21407                              <1> 	;jz	short anyi_0	
 21408                              <1> 
 21409                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21410 0000458C 804B0580            <1> 	or	byte [ebx+5], 80h ; set deleted file flag (bit 7)
 21411                              <1> 	; 22/06/2015
 21412                              <1> 	;inc 	byte [ebx+9]
 21413                              <1> 		; incb 7(r2) / increment upper byte of the 4th word
 21414                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
 21415 00004590 C3                  <1> 	retn
 21416                              <1> 		; rts r0
 21417                              <1> anyi_0:
 21418                              <1> 	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21419                              <1> 	;add	ebx, fp.size ; runix v2 fsp table size is 16 bytes
 21420                              <1> 	; 01/01/2022
 21421 00004591 83C310              <1> 	add	ebx, 16 ; runix v2 fsp table size is 16 bytes
 21422                              <1> 	;;add	ebx, 10 ; fsp table size is 10 bytes
 21423                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
 21424                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
 21425                              <1> 	; 22/11/2021
 21426                              <1> 	;cmp	ebx, fsp + (NFILES*fp.size) ; fsp+(NFILES*16)
 21427                              <1> 	; 02/01/2022
 21428 00004594 81FB[F46B0000]      <1> 	cmp	ebx, fsp + (nfiles*16)
 21429                              <1> 	; 01/01/2022
 21430                              <1> 	;cmp	ebx, fsp + (NFILES*16) ; fsp+(NFILES*fp.size)
 21431                              <1> 	;;cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
 21432                              <1> 		; cmp r2,$fsp+[nfiles*8] 
 21433                              <1> 			; / are we at last entry in the table
 21434 0000459A 72EB                <1> 	jb	short anyi_1
 21435                              <1> 		; blt 1b / no, check next entries i-number
 21436                              <1> 
 21437                              <1> 	; 27/12/2021
 21438                              <1> 	;;cmp	ax, 32768
 21439                              <1> 	;cmp	ah, 80h ; negative number check
 21440                              <1> 	;	; tst r1 / yes, no match
 21441                              <1> 	;	; bge .+4
 21442                              <1> 	;jb	short anyi_2
 21443                              <1> 	;neg	ax
 21444                              <1> 	;	; neg r1 / make i-number positive
 21445                              <1> ;anyi_2:	
 21446                              <1> 	; 12/03/2022
 21447                              <1> 	;push	eax ; **** ; inode number
 21448                              <1> 	;
 21449 0000459C E8AF080000          <1> 	call	imap
 21450                              <1> 		; jsr r0,imap / get address of allocation bit 
 21451                              <1> 			    ; / in the i-map in r2
 21452                              <1> 
 21453                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
 21454                              <1>         ;; EBX (R2) has address of the byte with allocation bit
 21455                              <1> 
 21456                              <1> 	; 12/03/2022
 21457                              <1> 	; (at return of imap)
 21458                              <1> 	; ebp = superblock buffer address
 21459                              <1> 	; eax = inode number
 21460                              <1> 	; [ebp+SB.ImapBuffer] = physical block/sector number
 21461                              <1> 	;			of current IMAP sector
 21462                              <1> 	; EBX = buffer address/offset for relevant alloc byte
 21463                              <1> 	;  DL has 1 at bit position which is for free inode
 21464                              <1> 	;
 21465                              <1> 	; ECX = byte offset from the (start of) inode map buffer
 21466                              <1> 
 21467                              <1>  	;;not	dx
 21468                              <1> 	;not 	dl ; 0 at calculated bit position, other bits are 1
 21469                              <1>         ;;and	[ebx], dx
 21470                              <1> 	;and 	[ebx], dl 
 21471                              <1> 	;	; bicb mq,(r2) / clear bit for i-node in the imap
 21472                              <1> 
 21473                              <1> 	; 12/03/2022 ; (*)
 21474                              <1> 
 21475                              <1> 	;mov	[ebp+SB.LastInode], eax ; (free) inode number
 21476                              <1> 
 21477 000045A1 50                  <1> 	push	eax ; ***
 21478 000045A2 51                  <1> 	push	ecx ; **
 21479 000045A3 52                  <1> 	push	edx ; *
 21480                              <1> 
 21481                              <1> 	; 18/07/2022
 21482                              <1> 	;push	ebp ; @ ; 11/03/2022
 21483                              <1> 
 21484 000045A4 8B457C              <1> 	mov	eax, [ebp+SB.ImapBuffer]
 21485                              <1> 
 21486 000045A7 E844140000          <1> 	call	wslot
 21487                              <1> 	; ebx = buffer data address (write operation bit is set)
 21488                              <1> 	; eax = physical sector number
 21489                              <1> 	; Note: ebx contains addr of the 1st buffer in the buf chain
 21490                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 21491                              <1> 
 21492                              <1> 	; 18/07/2022
 21493                              <1> 	;pop	ebp ; @ ; 11/03/2022
 21494                              <1> 
 21495                              <1> 	;mov	[ebp+SB.ImapBuffer], ebx
 21496                              <1> 			; save inode map buffer address
 21497 000045AC 5A                  <1> 	pop	edx ; *
 21498 000045AD 59                  <1> 	pop	ecx ; **
 21499 000045AE 01CB                <1> 	add	ebx, ecx ; + byte offset (for allocation bit pos)	
 21500                              <1> 
 21501                              <1> 	;not	dx
 21502 000045B0 F6D2                <1> 	not 	dl ; 0 at calculated bit position, other bits are 1
 21503                              <1>         ;and	[ebx], dx
 21504 000045B2 2013                <1> 	and 	[ebx], dl 
 21505                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
 21506                              <1> 
 21507                              <1> 	;push	ebp ; @
 21508 000045B4 E844140000          <1> 	call	dskwr ; writes the 1st buffer to sector
 21509                              <1> 		      ; (at the beginning/head of the buffer chain)
 21510                              <1> 	;pop	ebp ; @
 21511                              <1> 
 21512                              <1> 	; if we are here, buffer has been written to disk successfully 
 21513                              <1> 	; (otherwise cpu would jump to 'error' address)
 21514                              <1> 
 21515                              <1> 	; 12/03/2022 ; (*)
 21516                              <1> 	; set superblock modified flag
 21517 000045B9 BA[566C0000]        <1> 	mov	edx, smod
 21518 000045BE F605[416C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 21519 000045C5 7401                <1> 	jz	short anyi_2 ; no, root device
 21520                              <1> 	; yes, mounted device
 21521 000045C7 42                  <1> 	inc	edx ; edx = offset mmod
 21522                              <1> anyi_2:
 21523 000045C8 FE02                <1> 	inc	byte [edx] ; superblock modified !
 21524                              <1> 
 21525                              <1> 	; 12/03/2022
 21526                              <1> 	; decrease first free inode number (if it is required)
 21527 000045CA 8B0424              <1> 	mov	eax, [esp] ; ***
 21528                              <1> 	; eax = released/freed inode number 
 21529 000045CD 394534              <1> 	cmp	[ebp+SB.FirstFreeIno], eax
 21530 000045D0 7603                <1> 	jna	short anyi_4
 21531 000045D2 894534              <1> 	mov	[ebp+SB.FirstFreeIno], eax
 21532                              <1> 		    ; (free inode search start value)
 21533                              <1> anyi_4:
 21534                              <1> 	; 12/03/2022
 21535                              <1> 	; increase free inode count
 21536 000045D5 8B5530              <1> 	mov	edx, [ebp+SB.FreeInodes]
 21537                              <1> 	;cmp	edx, 0FFFFFFFFh
 21538                              <1> 	;je	short anyi_5 ; invalid
 21539 000045D8 42                  <1> 	inc	edx ; 0FFFFFFFFh -> 0
 21540 000045D9 7403                <1> 	jz	short anyi_5 ; invalid
 21541 000045DB 895530              <1> 	mov	[ebp+SB.FreeInodes], edx ; +1
 21542                              <1> anyi_5:
 21543 000045DE E870150000          <1> 	call	get_system_time
 21544                              <1> 		; eax = current time (as unix epoch time)
 21545 000045E3 89455C              <1> 	mov	[ebp+SB.ModifTime], eax
 21546                              <1> 
 21547 000045E6 58                  <1> 	pop	eax ; *** ; inode number
 21548                              <1> 
 21549 000045E7 E860070000          <1> 	call	itrunc
 21550                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
 21551                              <1> 
 21552                              <1> 	; 26/03/2022
 21553                              <1> 	; eax = 0 ; (itrunc clears eax at return)
 21554                              <1> 
 21555                              <1> 	; 12/03/2022
 21556                              <1> 	;pop	eax ; **** ; inode number
 21557                              <1> 
 21558                              <1> 	; 26/03/2022
 21559 000045EC 66A3[E4670000]      <1> 	mov	[i.flgs], ax ; (eax should be 0 here)
 21560                              <1> 	;mov 	word [i.flgs], 0
 21561                              <1> 		; clr i.flgs / clear all flags in the i-node
 21562 000045F2 C3                  <1> 	retn
 21563                              <1> 		; rts r0 / return
 21564                              <1> 
 21565                              <1> ;anyi_3: ; 1: / i-numbers match
 21566                              <1> ;	; 09/01/2022
 21567                              <1> ;	test	byte [ebx+5], 1 ; open for writing flag
 21568                              <1> ;	jz	short anyi_0	
 21569                              <1> ;
 21570                              <1> ;	; 27/12/2021 - Retro UNIX 386 v1.2 (runix v2 fs)
 21571                              <1> ;	or	byte [ebx+5], 80h ; set deleted file flag (bit 7)
 21572                              <1> ;	; 22/06/2015
 21573                              <1> ;	;inc 	byte [ebx+9]
 21574                              <1> ;		; incb 7(r2) / increment upper byte of the 4th word
 21575                              <1> ;		   ; / in that fsp entry (deleted flag of fsp entry)
 21576                              <1> ;	retn
 21577                              <1> ;		; rts r0
 21578                                  %include 'u3.s'      ; 10/05/2015
 21579                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 21580                              <1> ; (re-write kernel for test by using previous version without a major defect)
 21581                              <1> ; ****************************************************************************
 21582                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS3.INC
 21583                              <1> ; Last Modification: 24/12/2021
 21584                              <1> ; ----------------------------------------------------------------------------
 21585                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 21586                              <1> ; (v0.1 - Beginning: 11/07/2012)
 21587                              <1> ;
 21588                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 21589                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 21590                              <1> ; <Bell Laboratories (17/3/1972)>
 21591                              <1> ; <Preliminary Release of UNIX Implementation Document>
 21592                              <1> ;
 21593                              <1> ; Retro UNIX 8086 v1 - U3.ASM (08/03/2014) //// UNIX v1 -> u3.s
 21594                              <1> ;
 21595                              <1> ; ****************************************************************************
 21596                              <1> 
 21597                              <1> tswitch: ; Retro UNIX 386 v1
 21598                              <1> tswap:
 21599                              <1> 	; 01/09/2015
 21600                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 21601                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 21602                              <1> 	; time out swap, called when a user times out.
 21603                              <1> 	; the user is put on the low priority queue.
 21604                              <1> 	; This is done by making a link from the last user
 21605                              <1> 	; on the low priority queue to him via a call to 'putlu'.
 21606                              <1> 	; then he is swapped out.
 21607                              <1> 	;
 21608                              <1> 	; Retro UNIX 386 v1 modification ->
 21609                              <1> 	;       swap (software task switch) is performed by changing
 21610                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 21611                              <1> 	;	as in Retro UNIX 8086 v1.
 21612                              <1> 	;
 21613                              <1> 	; RETRO UNIX 8086 v1 modification ->
 21614                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21615                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21616                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21617                              <1> 	;	compatibles was using 1MB segmented memory 
 21618                              <1> 	;	in 8086/8088 times.
 21619                              <1> 	;
 21620                              <1> 	; INPUTS ->
 21621                              <1> 	;    u.uno - users process number
 21622                              <1> 	;    runq+4 - lowest priority queue
 21623                              <1> 	; OUTPUTS ->
 21624                              <1> 	;    r0 - users process number
 21625                              <1> 	;    r2 - lowest priority queue address
 21626                              <1> 	;
 21627                              <1> 	; ((AX = R0, BX = R2)) output
 21628                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
 21629                              <1> 	;
 21630 000045F3 A0[B56C0000]        <1> 	mov 	al, [u.uno]
 21631                              <1> 	       	; movb u.uno,r1 / move users process number to r1
 21632                              <1> 		; mov  $runq+4,r2 
 21633                              <1> 			; / move lowest priority queue address to r2
 21634 000045F8 E8CD000000          <1>         call 	putlu
 21635                              <1> 		; jsr r0,putlu / create link from last user on Q to 
 21636                              <1> 		             ; / u.uno's user
 21637                              <1> 
 21638                              <1> switch: ; Retro UNIX 386 v1
 21639                              <1> swap:
 21640                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 21641                              <1> 	; 02/09/2015
 21642                              <1> 	; 01/09/2015
 21643                              <1> 	; 31/08/2015
 21644                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 21645                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 21646                              <1> 	; 'swap' is routine that controls the swapping of processes
 21647                              <1> 	; in and out of core.
 21648                              <1> 	;
 21649                              <1> 	; Retro UNIX 386 v1 modification ->
 21650                              <1> 	;       swap (software task switch) is performed by changing
 21651                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 21652                              <1> 	;	as in Retro UNIX 8086 v1.
 21653                              <1> 	;
 21654                              <1> 	; RETRO UNIX 8086 v1 modification ->
 21655                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21656                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21657                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21658                              <1> 	;	compatibles was using 1MB segmented memory 
 21659                              <1> 	;	in 8086/8088 times.
 21660                              <1> 	;
 21661                              <1> 	; INPUTS ->
 21662                              <1> 	;    runq table - contains processes to run.
 21663                              <1> 	;    p.link - contains next process in line to be run.
 21664                              <1> 	;    u.uno - process number of process in core	
 21665                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
 21666                              <1> 	; OUTPUTS ->
 21667                              <1> 	;    (original unix v1 -> present process to its disk block)
 21668                              <1> 	;    (original unix v1 -> new process into core -> 
 21669                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
 21670                              <1> 	;	   for new process)
 21671                              <1> 	;    u.quant = 3 (Time quantum for a process)
 21672                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
 21673                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
 21674                              <1> 	;	 for now, it will swap the process if there is not
 21675                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
 21676                              <1> 	;	 or will count down from 3 to 0 even if there is a
 21677                              <1> 	;        keyboard event locking due to repetitive key strokes.
 21678                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
 21679                              <1> 	;
 21680                              <1> 	;    u.pri -points to highest priority run Q.
 21681                              <1> 	;    r2 - points to the run queue.
 21682                              <1> 	;    r1 - contains new process number
 21683                              <1> 	;    r0 - points to place in routine or process that called
 21684                              <1> 	;	  swap all user parameters
 21685                              <1> 	;				
 21686                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
 21687                              <1> 	;
 21688                              <1> swap_0:
 21689                              <1> 		;mov $300,*$ps / processor priority = 6
 21690 000045FD BE[526C0000]        <1> 	mov	esi, runq
 21691                              <1> 		; mov $runq,r2 / r2 points to runq table
 21692                              <1> swap_1: ; 1: / search runq table for highest priority process
 21693 00004602 668B06              <1> 	mov	ax, [esi]
 21694 00004605 6621C0              <1> 	and 	ax, ax
 21695                              <1>        		; tst (r2)+ / are there any processes to run 
 21696                              <1> 			  ; / in this Q entry
 21697 00004608 7507                <1> 	jnz	short swap_2
 21698                              <1>        		; bne 1f / yes, process 1f
 21699                              <1> 		; cmp r2,$runq+6 / if zero compare address 
 21700                              <1> 			       ; / to end of table
 21701                              <1> 		; bne 1b / if not at end, go back
 21702 0000460A E8E0000000          <1> 	call	idle
 21703                              <1> 		; jsr r0,idle; s.idlet+2 / wait for interrupt; 
 21704                              <1> 				       ; / all queues are empty
 21705 0000460F EBF1                <1> 	jmp	short swap_1
 21706                              <1> 		; br swap
 21707                              <1> swap_2: ; 1:
 21708 00004611 0FB6D8              <1> 	movzx	ebx, al ; 02/09/2015
 21709                              <1> 		; tst -(r2) / restore pointer to right Q entry
 21710                              <1>  		; mov r2,u.pri / set present user to this run queue
 21711                              <1> 	        ; movb (r2)+,r1 / move 1st process in queue to r1
 21712 00004614 38E0                <1> 	cmp	al, ah
 21713                              <1> 		; cmpb r1,(r2)+ / is there only 1 process 
 21714                              <1> 			      ; / in this Q to be run
 21715 00004616 740A                <1> 	je	short swap_3
 21716                              <1>        		; beq 1f / yes
 21717                              <1> 		; tst -(r2) / no, pt r2 back to this Q entry
 21718                              <1> 	;movzx	ebx, al
 21719 00004618 8AA3[73680000]      <1> 	mov	ah, [ebx+p.link-1] 
 21720 0000461E 8826                <1>        	mov	[esi], ah
 21721                              <1> 		; movb p.link-1(r1),(r2) / move next process 
 21722                              <1> 				       ; / in line into run queue
 21723 00004620 EB05                <1> 	jmp	short swap_4
 21724                              <1>        		; br 2f
 21725                              <1> swap_3: ; 1:
 21726                              <1> 	;xor	dx, dx
 21727                              <1> 	; 24/12/2021
 21728 00004622 31D2                <1> 	xor	edx, edx
 21729 00004624 668916              <1> 	mov	[esi], dx
 21730                              <1> 		; clr -(r2) / zero the entry; no processes on the Q
 21731                              <1> swap_4: ; / write out core to appropriate disk area and read 
 21732                              <1>       ; / in new process if required
 21733                              <1>        		; clr *$ps / clear processor status
 21734 00004627 8A25[B56C0000]      <1> 	mov 	ah, [u.uno]
 21735 0000462D 38C4                <1> 	cmp	ah, al
 21736                              <1> 		; cmpb r1,u.uno / is this process the same as 
 21737                              <1> 			      ; / the process in core?
 21738 0000462F 743B                <1>        	je	short swap_8
 21739                              <1>        		; beq 2f / yes, don't have to swap
 21740                              <1>        		; mov r0,-(sp) / no, write out core; save r0 
 21741                              <1> 			   ; / (address in routine that called swap)
 21742                              <1> 		; mov r1,-(sp) / put r1 (new process #) on the stack
 21743                              <1> 	; 01/09/2015
 21744                              <1> 	;mov	[u.usp], esp
 21745                              <1>        		; mov sp,u.usp / save stack pointer
 21746                              <1> 		; mov $sstack,sp / move swap stack pointer 
 21747                              <1> 			       ; / to the stack pointer
 21748 00004631 08E4                <1> 	or	ah, ah
 21749                              <1>        		; tstb u.uno / is the process # = 0
 21750 00004633 740D                <1>        	jz	short swap_6 ; 'sysexit'
 21751                              <1> 		; beq  1f / yes, kill process by overwriting
 21752                              <1> 	; 02/09/2015
 21753 00004635 8925[606C0000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
 21754                              <1> 	;
 21755 0000463B E834000000          <1> 	call	wswap
 21756                              <1> 		;jsr r0,wswap / write out core to disk
 21757                              <1> 	 ; 31/08/2015
 21758                              <1> 	;movzx	ebx, al ; New (running) process number
 21759 00004640 EB1C                <1> 	jmp 	short swap_7
 21760                              <1> swap_6:
 21761                              <1> 	; 31/08/2015
 21762                              <1> 	; Deallocate memory pages belong to the process
 21763                              <1> 	; which is being terminated
 21764                              <1> 	; 14/05/2015 ('sysexit')
 21765                              <1>  	; Deallocate memory pages of the process
 21766                              <1> 	; (Retro UNIX 386 v1 modification !)
 21767                              <1> 	;
 21768                              <1> 	; movzx ebx, al
 21769 00004642 53                  <1> 	push	ebx
 21770 00004643 A1[C46C0000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
 21771 00004648 8B1D[C86C0000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
 21772 0000464E E8BCDEFFFF          <1> 	call	deallocate_page_dir
 21773 00004653 A1[C06C0000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
 21774 00004658 E848DFFFFF          <1> 	call	deallocate_page
 21775 0000465D 5B                  <1> 	pop	ebx
 21776                              <1> swap_7: ;1: 
 21777                              <1> 	; 02/09/2015
 21778                              <1> 	; 31/08/2015
 21779                              <1> 	; 14/05/2015
 21780 0000465E C0E302              <1> 	shl	bl, 2 ; * 4 
 21781 00004661 8B83[90680000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
 21782                              <1> 	;cli
 21783 00004667 E831000000          <1> 	call	rswap
 21784                              <1>  		; mov (sp)+,r1 / restore r1 to new process number
 21785                              <1> 		; jsr r0,rswap / read new process into core
 21786                              <1>        		; jsr r0,unpack / unpack the users stack from next
 21787                              <1> 			      ; / to his program to its normal
 21788                              <1> 	; 01/09/2015
 21789                              <1> 	;mov	esp, [u.usp]	
 21790                              <1> 		; mov u.usp,sp / location; restore stack pointer to
 21791                              <1> 			     ; / new process stack
 21792                              <1> 		; mov (sp)+,r0 / put address of where the process 
 21793                              <1> 			     ; / that just got swapped in, left off.,
 21794                              <1> 			     ; / i.e., transfer control to new process
 21795                              <1> 	;sti
 21796                              <1> swap_8: ;2:
 21797                              <1> 	; RETRO UNIX 8086 v1 modification !
 21798 0000466C C605[AC6C0000]04    <1> 	mov	byte [u.quant], time_count 
 21799                              <1> 		; movb $30.,uquant / initialize process time quantum
 21800 00004673 C3                  <1> 	retn
 21801                              <1> 		; rts r0 / return
 21802                              <1> 
 21803                              <1> wswap:  ; < swap out, swap to disk >
 21804                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 21805                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 21806                              <1> 	; 'wswap' writes out the process that is in core onto its 
 21807                              <1> 	; appropriate disk area.
 21808                              <1> 	;
 21809                              <1> 	; Retro UNIX 386 v1 modification ->
 21810                              <1> 	;       User (u) structure content and the user's register content
 21811                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
 21812                              <1> 	;	saving 'u' structure and user registers for task switching).
 21813                              <1> 	;	u.usp - points to kernel stack address which contains
 21814                              <1> 	;		user's registers while entering system call.  
 21815                              <1> 	;	u.sp  - points to kernel stack address 
 21816                              <1> 	;		to return from system call -for IRET-.
 21817                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 21818                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 21819                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 21820                              <1> 	;
 21821                              <1> 	; Retro UNIX 8086 v1 modification ->
 21822                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21823                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21824                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21825                              <1> 	;	compatibles was using 1MB segmented memory 
 21826                              <1> 	;	in 8086/8088 times.
 21827                              <1> 	;
 21828                              <1> 	; INPUTS ->
 21829                              <1> 	;    u.break - points to end of program
 21830                              <1> 	;    u.usp - stack pointer at the moment of swap
 21831                              <1> 	;    core - beginning of process program		
 21832                              <1> 	;    ecore - end of core 	
 21833                              <1> 	;    user - start of user parameter area		
 21834                              <1> 	;    u.uno - user process number	
 21835                              <1> 	;    p.dska - holds block number of process	
 21836                              <1> 	; OUTPUTS ->
 21837                              <1> 	;    swp I/O queue
 21838                              <1> 	;    p.break - negative word count of process 
 21839                              <1> 	;    r1 - process disk address	
 21840                              <1> 	;    r2 - negative word count
 21841                              <1> 	;
 21842                              <1> 	; RETRO UNIX 8086 v1 input/output:
 21843                              <1> 	;
 21844                              <1> 	; INPUTS ->
 21845                              <1> 	;    u.uno - process number (to be swapped out)
 21846                              <1> 	; OUTPUTS ->
 21847                              <1> 	;    none
 21848                              <1> 	;
 21849                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
 21850                              <1> 	;
 21851 00004674 8B3D[C06C0000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
 21852 0000467A B921000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 21853 0000467F BE[5C6C0000]        <1> 	mov	esi, user ; active user (u) structure	
 21854 00004684 F3A5                <1> 	rep	movsd
 21855                              <1> 	;
 21856 00004686 8B35[606C0000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
 21857                              <1> 			     ;      points to user registers)
 21858 0000468C 8B0D[5C6C0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 21859                              <1> 			     ; (for IRET)
 21860                              <1> 			     ; [u.sp] -> EIP (user)
 21861                              <1> 			     ; [u.sp+4]-> CS (user)
 21862                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 21863                              <1> 			     ; [u.sp+12] -> ESP (user)
 21864                              <1> 			     ; [u.sp+16] -> SS (user)	
 21865 00004692 29F1                <1> 	sub	ecx, esi     ; required space for user registers
 21866 00004694 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 21867                              <1> 			     ; (for IRET) 	
 21868 00004697 C1E902              <1> 	shr	ecx, 2	     		
 21869 0000469A F3A5                <1> 	rep	movsd
 21870 0000469C C3                  <1> 	retn
 21871                              <1> 
 21872                              <1> 	; Original UNIX v1 'wswap' routine:
 21873                              <1> 	; wswap:
 21874                              <1> 		; mov *$30,u.emt / determines handling of emts
 21875                              <1>         	; mov *$10,u.ilgins / determines handling of 
 21876                              <1> 				; / illegal instructions
 21877                              <1> 		; mov u.break,r2 / put process program break address in r2
 21878                              <1> 		; inc r2 / add 1 to it 
 21879                              <1> 		; bic $1,r2 / make it even
 21880                              <1> 		; mov r2,u.break / set break to an even location
 21881                              <1> 		; mov u.usp,r3 / put users stack pointer 
 21882                              <1> 			     ; / at moment of swap in r3
 21883                              <1> 		; cmp r2,$core / is u.break less than $core
 21884                              <1> 		; blos 2f / yes
 21885                              <1> 		; cmp r2,r3 / no, is (u.break) greater than stack ptr.
 21886                              <1>        		; bhis 2f / yes
 21887                              <1> 	; 1:
 21888                              <1>        		; mov (r3)+,(r2)+ / no, pack stack next to users program
 21889                              <1> 		; cmp r3,$ecore / has stack reached end of core
 21890                              <1> 		; bne 1b / no, keep packing
 21891                              <1> 	 	; br 1f / yes
 21892                              <1> 	; 2:
 21893                              <1>        		; mov $ecore,r2 / put end of core in r2 
 21894                              <1> 	; 1:
 21895                              <1>        		; sub  $user,r2 / get number of bytes to write out 
 21896                              <1> 			   ; / (user up to end of stack gets written out)
 21897                              <1> 		; neg r2 / make it negative
 21898                              <1> 		; asr r2 / change bytes to words (divide by 2)
 21899                              <1> 		; mov r2,swp+4 / word count
 21900                              <1> 		; movb u.uno,r1 / move user process number to r1
 21901                              <1> 		; asl r1 / x2 for index
 21902                              <1>       		; mov r2,p.break-2(r1) / put negative of word count 
 21903                              <1> 				     ; / into the p.break table
 21904                              <1>        		; mov p.dska-2(r1),r1 / move disk address of swap area 
 21905                              <1> 				    ; /	for process to r1
 21906                              <1>        		; mov r1,swp+2 / put processes dska address in swp+2 
 21907                              <1> 			     ; / (block number)
 21908                              <1> 		; bis $1000,swp / set it up to write (set bit 9)
 21909                              <1>        		; jsr r0,ppoke / write process out on swap area of disk
 21910                              <1> 	; 1:
 21911                              <1>        		; tstb swp+1 / is lt done writing?
 21912                              <1>        		; bne 1b / no, wait
 21913                              <1> 		; rts r0 / yes, return to swap
 21914                              <1> 
 21915                              <1> rswap:  ; < swap in, swap from disk >
 21916                              <1> 	; 15/09/2015
 21917                              <1> 	; 28/08/2015
 21918                              <1> 	; 14/05/2015
 21919                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 21920                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 21921                              <1> 	; 'rswap' reads a process whose number is in r1, 
 21922                              <1> 	; from disk into core.
 21923                              <1> 	;
 21924                              <1> 	; Retro UNIX 386 v1 modification ->
 21925                              <1> 	;       User (u) structure content and the user's register content
 21926                              <1> 	;	will be restored from process's/user's UPAGE (a page for
 21927                              <1> 	;	saving 'u' structure and user registers for task switching).
 21928                              <1> 	;	u.usp - points to kernel stack address which contains
 21929                              <1> 	;		user's registers while entering system call.  
 21930                              <1> 	;	u.sp  - points to kernel stack address 
 21931                              <1> 	;		to return from system call -for IRET-.
 21932                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 21933                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 21934                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 21935                              <1> 	;
 21936                              <1> 	; RETRO UNIX 8086 v1 modification ->
 21937                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 21938                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 21939                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 21940                              <1> 	;	compatibles was using 1MB segmented memory 
 21941                              <1> 	;	in 8086/8088 times.
 21942                              <1> 	;
 21943                              <1> 	; INPUTS ->
 21944                              <1> 	;    r1 - process number of process to be read in
 21945                              <1> 	;    p.break - negative of word count of process 
 21946                              <1> 	;    p.dska - disk address of the process		
 21947                              <1> 	;    u.emt - determines handling of emt's 	
 21948                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 21949                              <1> 	; OUTPUTS ->
 21950                              <1> 	;    8 = (u.ilgins)
 21951                              <1> 	;    24 = (u.emt)
 21952                              <1> 	;    swp - bit 10 is set to indicate read 
 21953                              <1> 	;		(bit 15=0 when reading is done)	
 21954                              <1> 	;    swp+2 - disk block address
 21955                              <1> 	;    swp+4 - negative word count 	
 21956                              <1> 	;      ((swp+6 - address of user structure)) 
 21957                              <1> 	;
 21958                              <1> 	; RETRO UNIX 8086 v1 input/output:
 21959                              <1> 	;
 21960                              <1> 	; INPUTS ->
 21961                              <1> 	;    AL	- new process number (to be swapped in)	 
 21962                              <1> 	; OUTPUTS ->
 21963                              <1> 	;    none
 21964                              <1> 	;
 21965                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
 21966                              <1> 	;
 21967                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
 21968 0000469D 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
 21969 0000469F B921000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 21970 000046A4 BF[5C6C0000]        <1> 	mov	edi, user ; active user (u) structure	
 21971 000046A9 F3A5                <1> 	rep	movsd
 21972 000046AB 58                  <1> 	pop	eax ; 15/09/2015, 'rswap' return address 
 21973 000046AC 8B3D[606C0000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
 21974                              <1> 			     ;      points to user registers)
 21975 000046B2 8B0D[5C6C0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 21976                              <1> 			     ; (for IRET)
 21977                              <1> 			     ; [u.sp] -> EIP (user)
 21978                              <1> 			     ; [u.sp+4]-> CS (user)
 21979                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 21980                              <1> 			     ; [u.sp+12] -> ESP (user)
 21981                              <1> 			     ; [u.sp+16] -> SS (user)		
 21982                              <1> 	; 28/08/2015
 21983 000046B8 29F9                <1> 	sub	ecx, edi     ; required space for user registers
 21984 000046BA 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 21985                              <1> 			     ; (for IRET) 	
 21986 000046BD C1E902              <1> 	shr	ecx, 2	       		
 21987 000046C0 F3A5                <1> 	rep	movsd
 21988 000046C2 8B25[606C0000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
 21989 000046C8 50                  <1> 	push	eax ; 15/09/2015 'rswap' return address
 21990 000046C9 C3                  <1> 	retn
 21991                              <1> 
 21992                              <1> 	; Original UNIX v1 'rswap'  and 'unpack' routines:
 21993                              <1> 	;rswap:
 21994                              <1>        		; asl r1 / process number x2 for index
 21995                              <1>        		; mov p.break-2(r1), swp+4 / word count
 21996                              <1>        		; mov p.dska-2(r1),swp+2 / disk address
 21997                              <1>        		; bis $2000,swp / read
 21998                              <1>        		; jsr r0,ppoke / read it in 
 21999                              <1> 	; 1:
 22000                              <1>        		; tstb swp+1 / done
 22001                              <1>        		; bne 1b / no, wait for bit 15 to clear (inhibit bit)
 22002                              <1>        		; mov u.emt,*$30 / yes move these
 22003                              <1>        		; mov u.ilgins,*$10 / back
 22004                              <1>        		; rts r0 / return
 22005                              <1> 
 22006                              <1> 	;unpack: ; / move stack back to its normal place
 22007                              <1> 		; mov u.break,r2 / r2 points to end of user program
 22008                              <1>        		; cmp r2,$core / at beginning of user program yet?
 22009                              <1> 		; blos 2f / yes, return
 22010                              <1> 		; cmp r2,u.usp / is break_above the stack pointer 
 22011                              <1> 			     ; / before swapping
 22012                              <1> 		; bhis 2f / yes, return
 22013                              <1> 		; mov $ecore,r3 / r3 points to end of core
 22014                              <1> 		; add r3,r2
 22015                              <1> 		; sub u.usp,r2 / end of users stack is in r2
 22016                              <1> 	; 1:
 22017                              <1> 		; mov -(r2),-(r3) / move stack back to its normal place
 22018                              <1> 		; cmp r2,u.break / in core
 22019                              <1> 		; bne 1b
 22020                              <1> 	; 2:
 22021                              <1>        		; rts r0
 22022                              <1> 
 22023                              <1> putlu: 
 22024                              <1> 	; 12/09/2015
 22025                              <1> 	; 02/09/2015
 22026                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 22027                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 22028                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
 22029                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
 22030                              <1> 	; the last process on the queue to process in r1 by putting
 22031                              <1> 	; the process number in r1 into the last process's link.
 22032                              <1> 	;
 22033                              <1> 	; INPUTS ->
 22034                              <1> 	;    r1 - user process number
 22035                              <1> 	;    r2 - points to lowest priority queue 
 22036                              <1> 	;    p.dska - disk address of the process		
 22037                              <1> 	;    u.emt - determines handling of emt's 	
 22038                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 22039                              <1> 	; OUTPUTS ->
 22040                              <1> 	;    r3 - process number of last process on the queue upon
 22041                              <1> 	;	  entering putlu
 22042                              <1> 	;    p.link-1 + r3 - process number in r1
 22043                              <1> 	;    r2 - points to lowest priority queue
 22044                              <1> 	;
 22045                              <1> 	; ((Modified registers: EDX, EBX)) 
 22046                              <1> 	;
 22047                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
 22048                              <1> 
 22049                              <1> 	; eBX = r2
 22050                              <1> 	; eAX = r1 (AL=r1b)
 22051                              <1> 
 22052 000046CA BB[526C0000]        <1> 	mov	ebx, runq
 22053 000046CF 0FB613              <1> 	movzx  	edx, byte [ebx]
 22054 000046D2 43                  <1> 	inc	ebx
 22055 000046D3 20D2                <1> 	and	dl, dl
 22056                              <1> 		; tstb (r2)+ / is queue empty?
 22057 000046D5 740A                <1>        	jz	short putlu_1
 22058                              <1> 		; beq 1f / yes, branch
 22059 000046D7 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
 22060                              <1> 		; movb (r2),r3 / no, save the "last user" process number
 22061                              <1> 			     ; / in r3
 22062 000046D9 8882[73680000]      <1>        	mov	[edx+p.link-1], al
 22063                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
 22064                              <1> 			     ; / "last users" link
 22065 000046DF EB03                <1> 	jmp	short putlu_2
 22066                              <1> 		; br 2f /
 22067                              <1> putlu_1: ; 1:
 22068 000046E1 8843FF              <1> 	mov	[ebx-1], al
 22069                              <1>        		; movb r1,-1(r2) / user is only user; 
 22070                              <1> 			    ; / put process no. at beginning and at end
 22071                              <1> putlu_2: ; 2: 
 22072 000046E4 8803                <1> 	mov	[ebx], al
 22073                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
 22074                              <1> 			     ; / on the queue
 22075 000046E6 88C2                <1> 	mov	dl, al
 22076 000046E8 88B2[73680000]      <1>         mov     [edx+p.link-1], dh ; 0
 22077                              <1> 		; dec r2 / restore r2
 22078 000046EE C3                  <1>         retn
 22079                              <1> 		; rts r0
 22080                              <1> 
 22081                              <1> ;copyz:
 22082                              <1> ;       mov     r1,-(sp) / put r1 on stack
 22083                              <1> ;       mov     r2,-(sp) / put r2 on stack
 22084                              <1> ;       mov     (r0)+,r1
 22085                              <1> ;       mov     (r0)+,r2
 22086                              <1> ;1:
 22087                              <1> ;       clr     (r1)+ / clear all locations between r1 and r2
 22088                              <1> ;       cmp     r1,r2 
 22089                              <1> ;       blo     1b
 22090                              <1> ;       mov     (sp)+,r2 / restore r2
 22091                              <1> ;       mov     (sp)+,r1 / restore r1
 22092                              <1> ;       rts     r0 
 22093                              <1> 
 22094                              <1> idle:
 22095                              <1> 	; 01/09/2015
 22096                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 22097                              <1> 	; 10/04/2013 - 23/10/2013 (Retro UNIX 8086 v1)
 22098                              <1> 	; (idle & wait loop)
 22099                              <1> 	; Retro Unix 8086 v1 modification on original UNIX v1
 22100                              <1> 	; idle procedure!
 22101                              <1>       	;
 22102                              <1>   	; 01/09/2015
 22103 000046EF FB                  <1> 	sti
 22104                              <1>       	; 29/07/2013
 22105 000046F0 F4                  <1>       	hlt
 22106 000046F1 90                  <1>       	nop ; 10/10/2013
 22107 000046F2 90                  <1>       	nop
 22108 000046F3 90                  <1>       	nop
 22109                              <1>       	; 23/10/2013
 22110 000046F4 90                  <1>       	nop
 22111 000046F5 90                  <1>       	nop
 22112 000046F6 90                  <1>       	nop
 22113 000046F7 90                  <1>       	nop
 22114 000046F8 C3                  <1>       	retn      
 22115                              <1> 
 22116                              <1> 	;mov *$ps,-(sp) / save ps on stack
 22117                              <1> 	;clr *$ps / clear ps
 22118                              <1> 	;mov clockp,-(sp) / save clockp on stack
 22119                              <1> 	;mov (r0)+,clockp / arg to idle in clockp
 22120                              <1> 	;1 / wait for interrupt
 22121                              <1> 	;mov (sp)+,clockp / restore clockp, ps
 22122                              <1> 	;mov (sp)+,*$ps
 22123                              <1> 	;rts r0
 22124                              <1> 
 22125                              <1> clear:
 22126                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.1)
 22127                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 22128                              <1> 	; 09/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 22129                              <1> 	; 'clear' zero's out of a block (whose block number is in r1)
 22130                              <1> 	; on the current device (cdev)
 22131                              <1> 	;	
 22132                              <1> 	; INPUTS ->
 22133                              <1> 	;    r1 - block number of block to be zeroed
 22134                              <1> 	;    cdev - current device number 
 22135                              <1> 	; OUTPUTS ->
 22136                              <1> 	;    a zeroed I/O buffer onto the current device
 22137                              <1> 	;    r1 - points to last entry in the I/O buffer
 22138                              <1> 	;
 22139                              <1> 	; ((AX = R1)) input/output
 22140                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 14/11/2012, UNIXCOPY.ASM)
 22141                              <1>         ;    ((Modified registers: EDX, ECX, EBX, ESI, EDI, EBP))  
 22142                              <1> 
 22143 000046F9 E8F2120000          <1> 	call 	wslot
 22144                              <1> 		; jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
 22145                              <1>                    ; / word of I/O queue r5 points to first data word in buffer
 22146 000046FE 89DF                <1> 	mov	edi, ebx ; r5
 22147 00004700 89C2                <1> 	mov	edx, eax
 22148 00004702 B980000000          <1> 	mov	ecx, 128
 22149                              <1> 		; mov $256.,r3
 22150 00004707 31C0                <1> 	xor	eax, eax
 22151 00004709 F3AB                <1> 	rep	stosd
 22152 0000470B 89D0                <1> 	mov	eax, edx
 22153                              <1> ; 1: 
 22154                              <1>        		; clr (r5)+ / zero data word in buffer
 22155                              <1>        		; dec r3
 22156                              <1>        		; bgt 1b / branch until all data words in buffer are zero
 22157                              <1> 	;call	dskwr
 22158                              <1> 		; jsr r0,dskwr / write zeroed buffer area out onto physical
 22159                              <1>                              ; / block specified in r1
 22160                              <1> 	; eAX (r1) = block number
 22161                              <1> 	;retn
 22162                              <1> 		; rts r0
 22163                              <1> 	; 24/12/2021
 22164 0000470D E9EB120000          <1> 	jmp	dskwr
 22165                                  %include 'u4.s'      ; 15/04/2015
 22166                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 22167                              <1> ; (re-write kernel for test by using previous version without a major defect)
 22168                              <1> ; ****************************************************************************
 22169                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS4.INC
 22170                              <1> ; Last Modification: 27/02/2022 (Retro UNIX 386 v1.2)
 22171                              <1> ; ----------------------------------------------------------------------------
 22172                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22173                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22174                              <1> ;
 22175                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22176                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22177                              <1> ; <Bell Laboratories (17/3/1972)>
 22178                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22179                              <1> ;
 22180                              <1> ; Retro UNIX 8086 v1 - U4.ASM (04/07/2014) //// UNIX v1 -> u4.s
 22181                              <1> ;
 22182                              <1> ; ****************************************************************************
 22183                              <1> 
 22184                              <1> ;setisp:
 22185                              <1>        ;mov     r1,-(sp)
 22186                              <1>        ;mov     r2,-(sp)
 22187                              <1>        ;mov     r3,-(sp)
 22188                              <1>        ;mov     clockp,-(sp)
 22189                              <1>        ;mov     $s.syst+2,clockp
 22190                              <1>        ;jmp     (r0)
 22191                              <1> 
 22192                              <1> clock: ; / interrupt from 60 cycle clock
 22193                              <1> 	
 22194                              <1> 	; 14/10/2015
 22195                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 22196                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
 22197                              <1> 
 22198                              <1>        ;mov     r0,-(sp) / save r0
 22199                              <1>        ;tst     *$lks / restart clock?
 22200                              <1>        ;mov     $s.time+2,r0 / increment the time of day
 22201                              <1>        ;inc     (r0)
 22202                              <1>        ;bne     1f
 22203                              <1>        ;inc     -(r0)
 22204                              <1> ;1:
 22205                              <1>        ;mov     clockp,r0 / increment appropriate time category
 22206                              <1>        ;inc     (r0)
 22207                              <1>        ;bne     1f
 22208                              <1>        ;inc     -(r0)
 22209                              <1> ;1:
 22210                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 22211                              <1> 
 22212 00004712 803D[AC6C0000]00    <1> 	cmp	byte [u.quant], 0
 22213 00004719 772C                <1> 	ja	short clk_1
 22214                              <1> 	;
 22215 0000471B 803D[586C0000]FF    <1>         cmp     byte [sysflg], 0FFh ; user or system space ?
 22216 00004722 7529                <1> 	jne	short clk_2 ; system space (sysflg <> 0FFh)
 22217 00004724 803D[B56C0000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ?
 22218 0000472B 761A                <1> 	jna	short clk_1 ; yes, do not swap out
 22219 0000472D 66833D[B06C0000]00  <1> 	cmp	word [u.intr], 0
 22220 00004735 7616                <1> 	jna	short clk_2
 22221                              <1> clk_0:
 22222                              <1> 	; 14/10/2015
 22223 00004737 FE05[586C0000]      <1> 	inc	byte [sysflg] ; Now, we are in system space
 22224 0000473D 58                  <1> 	pop	eax ; return address to the timer interrupt
 22225                              <1> 	;
 22226 0000473E B020                <1> 	MOV	AL,EOI			; GET END OF INTERRUPT MASK
 22227                              <1> 	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
 22228 00004740 E620                <1> 	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
 22229                              <1> 	;
 22230 00004742 E99FEAFFFF          <1> 	jmp     sysrelease ; 'sys release' by clock/timer
 22231                              <1> clk_1:
 22232 00004747 FE0D[AC6C0000]      <1> 	dec	byte [u.quant]
 22233                              <1> clk_2:
 22234 0000474D C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
 22235                              <1> 
 22236                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 22237                              <1> 
 22238                              <1>        ;mov     $uquant,r0 / decrement user time quantum
 22239                              <1>        ;decb    (r0)
 22240                              <1>        ;bge     1f / if less than 0
 22241                              <1>        ;clrb    (r0) / make it 0
 22242                              <1> ;1: / decrement time out counts return now if priority was not 0
 22243                              <1>        ;cmp     4(sp),$200 / ps greater than or equal to 200
 22244                              <1>        ;bge     2f / yes, check time outs
 22245                              <1>        ;tstb    (r0) / no, user timed out?
 22246                              <1>        ;bne     1f / no
 22247                              <1>        ;cmpb    sysflg,$-1 / yes, are we outside the system?
 22248                              <1>        ;bne     1f / no, 1f
 22249                              <1>        ;mov     (sp)+,r0 / yes, put users r0 in r0
 22250                              <1>        ;sys     0 / sysrele
 22251                              <1>        ;rti
 22252                              <1> ;2: / priority is high so just decrement time out counts
 22253                              <1>        ;mov     $toutt,r0 / r0 points to beginning of time out table
 22254                              <1> ;2:
 22255                              <1>        ;tstb    (r0) / is the time out?
 22256                              <1>        ;beq     3f / yes, 3f (get next entry)
 22257                              <1>        ;decb    (r0) / no, decrement the time
 22258                              <1>        ;bne     3f / isit zero now?
 22259                              <1>        ;incb    (r0) / yes, increment the time
 22260                              <1> ;3:
 22261                              <1>        ;inc     r0 / next entry
 22262                              <1>        ;cmp     r0,$touts / end of toutt table?
 22263                              <1>        ;blo     2b / no, check this entry
 22264                              <1>        ;mov     (sp)+,r0 / yes, restore r0
 22265                              <1>        ;rti / return from interrupt
 22266                              <1> ;1: / decrement time out counts; if 0 call subroutine
 22267                              <1>        ;mov     (sp)+,r0 / restore r0
 22268                              <1>        ;mov     $240,*$ps / set processor priority to 5
 22269                              <1>        ;jsr     r0,setisp / save registers
 22270                              <1>        ;mov     $touts-toutt-1,r0 / set up r0 as index to decrement thru
 22271                              <1>                                ;  / the table
 22272                              <1> ;1:
 22273                              <1>        ;tstb    toutt(r0) / is the time out for this entry
 22274                              <1>        ;beq     2f / yes
 22275                              <1>        ;decb    toutt(r0) / no, decrement the time
 22276                              <1>        ;bne     2f / is the time 0, now
 22277                              <1>        ;asl     r0 / yes, 2 x r0 to get word index for tout entry
 22278                              <1>        ;jsr     r0,*touts(r0) / go to appropriate routine specified in this
 22279                              <1>        ;asr     r0 / touts entry; set r0 back to toutt index
 22280                              <1> ;2:
 22281                              <1>        ;dec     r0 / set up r0 for next entry
 22282                              <1>        ;bge     1b / finished? , no, go back
 22283                              <1>        ;br      retisp / yes, restore registers and do a rti
 22284                              <1> 
 22285                              <1> ;retisp:
 22286                              <1>        ;mov     (sp)+,clockp / pop values before interrupt off the stack
 22287                              <1>        ;mov     (sp)+,r3
 22288                              <1>        ;mov     (sp)+,r2
 22289                              <1>        ;mov     (sp)+,r1
 22290                              <1>        ;mov     (sp)+,r0
 22291                              <1>        ;rti     / return from interrupt
 22292                              <1> 
 22293                              <1> 
 22294                              <1> wakeup: ; / wakeup processes waiting for an event 
 22295                              <1> 	; / by linking them to the queue
 22296                              <1> 	;
 22297                              <1> 	; 27/02/2022
 22298                              <1> 	; 15/09/2015
 22299                              <1> 	; 29/06/2015
 22300                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 22301                              <1> 	;
 22302                              <1> 	; 15/05/2013 - 02/06/2014
 22303                              <1> 	; Retro UNIX 8086 v1 modification !
 22304                              <1> 	; (Process/task switching routine by using
 22305                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.)
 22306                              <1> 	;
 22307                              <1> 	; In original UNIX v1, 'wakeup' is called to wake the process
 22308                              <1> 	; sleeping in the specified wait channel by creating a link 
 22309                              <1> 	; to it from the last user process on the run queue.
 22310                              <1> 	; If there is no process to wake up, nothing happens.
 22311                              <1> 	;
 22312                              <1> 	; In Retro UNIX 8086 v1, Int 09h keyboard interrupt will set
 22313                              <1> 	; 'switching' status of the current process (owns current tty)
 22314                              <1> 	; (via alt + function keys) to a process which has highest
 22315                              <1> 	; priority (on run queue) on the requested tty (0 to 7, except
 22316                              <1> 	; 8 and 9 which are tty identifiers of COM1, COM2 serial ports)
 22317                              <1> 	; as it's console tty. (NOTE: 'p.ttyc' is used to set console
 22318                              <1> 	; tty for tty switching by keyboard.)	 
 22319                              <1> 	; 
 22320                              <1> 	; INPUT -> 
 22321                              <1> 	;	   AL = wait channel (r3) ('tty number' for now)
 22322                              <1> 	;	   ;;EBX = Run queue (r2) offset
 22323                              <1> 	;
 22324                              <1> 	; ((modified registers: EAX, EBX))
 22325                              <1> 	;
 22326 0000474E 0FB6D8              <1> 	movzx	ebx, al ; 29/06/2015
 22327 00004751 81C3[88670000]      <1> 	add	ebx, wlist
 22328 00004757 8A03                <1> 	mov	al, [ebx] ; waiting list (waiting process number)
 22329 00004759 20C0                <1> 	and	al, al
 22330 0000475B 741E                <1> 	jz	short wa0 ; nothing to wakeup
 22331                              <1> 	;
 22332 0000475D 30E4                <1> 	xor	ah, ah
 22333 0000475F 8825[AC6C0000]      <1> 	mov 	[u.quant], ah ; 0 ; time quantum = 0	
 22334 00004765 8823                <1> 	mov	[ebx], ah ; 0 ; zero wait channel entry
 22335                              <1> 	; 15/09/2015
 22336 00004767 0FB6D8              <1> 	movzx	ebx, al
 22337                              <1> 	; 27/02/2022 (p.waitc is not used)
 22338                              <1> 	;mov	[ebx+p.waitc-1], ah ; 0
 22339 0000476A FEC4                <1> 	inc	ah
 22340 0000476C 88A3[83680000]      <1> 	mov	byte [ebx+p.stat-1], ah ; 1 ; SRUN
 22341                              <1> 	;
 22342 00004772 57                  <1> 	push	edi
 22343 00004773 52                  <1> 	push	edx
 22344 00004774 E851FFFFFF          <1> 	call	putlu
 22345 00004779 5A                  <1> 	pop	edx
 22346 0000477A 5F                  <1> 	pop	edi
 22347                              <1> wa0:
 22348 0000477B C3                  <1> 	retn
 22349                              <1> 
 22350                              <1> 	; 27/02/2022
 22351                              <1> 	; 05/12/2021
 22352                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
 22353                              <1> sleep: 
 22354                              <1> 	; 15/09/2015
 22355                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 22356                              <1> 	;
 22357                              <1> 	; 09/05/2013 - 20/03/2014
 22358                              <1> 	;
 22359                              <1> 	; Retro UNIX 8086 v1 modification !
 22360                              <1> 	; (Process/task switching and quit routine by using
 22361                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 22362                              <1> 	;
 22363                              <1> 	; In original UNIX v1, 'sleep' is called to wait for
 22364                              <1> 	; tty and tape output or input becomes available
 22365                              <1> 	; and process is put on waiting channel and swapped out,
 22366                              <1> 	; then -when the tty or tape is ready to write or read-
 22367                              <1> 	; 'wakeup' gets process back to active swapped-in status.)
 22368                              <1> 	;
 22369                              <1> 	; In Retro UNIX 8086 v1, Int 1Bh ctrl+brk interrupt and
 22370                              <1> 	; Int 09h keyboard interrupt will set 'quit' or 'switching'		
 22371                              <1> 	; status of the current process also INT 1Ch will count down
 22372                              <1> 	; 'uquant' value and INT 09h will redirect scancode of keystroke
 22373                              <1> 	; to tty buffer of the current process and kernel will get
 22374                              <1> 	; user input by using tty buffer of the current process
 22375                              <1> 	; (instead of standard INT 16h interrupt).
 22376                              <1> 	; TTY output will be redirected to related video page of text mode
 22377                              <1> 	; (INT 10h will be called with different video page depending
 22378                              <1> 	; on tty assignment of the active process: 0 to 7 for
 22379                              <1> 	; pseudo screens.)
 22380                              <1> 	;
 22381                              <1> 	; In Retro UNIX 8086 v1, 'sleep' will be called to wait for
 22382                              <1> 	; a keystroke from keyboard or wait for reading or writing
 22383                              <1> 	; characters/data on serial port(s).
 22384                              <1> 	;
 22385                              <1> 	; Character/Terminal input/output through COM1 and COM2 will be
 22386                              <1> 	; performed by related routines in addition to pseudo TTY routines.
 22387                              <1> 	; 
 22388                              <1> 	; R1 = AH = wait channel (0-9 for TTYs) ; 05/10/2013 (22/09/2013)
 22389                              <1> 	;
 22390                              <1> 	;; 05/10/2013
 22391                              <1>         ;10/12/2013
 22392                              <1> 	;cmp   byte [u.uno], 1
 22393                              <1>         ;ja    short sleep0
 22394                              <1> 	;retn
 22395                              <1> 
 22396                              <1> 	; 20/03/2014
 22397                              <1> 	;mov	bx, [runq]
 22398                              <1> 	;cmp	bl, bh
 22399                              <1> 	;jne	short sleep0	
 22400                              <1> 	; 25/02/2014
 22401                              <1> 	;cmp	word ptr [runq], 0
 22402                              <1> 	;ja	short sleep0	
 22403                              <1> 	;retn
 22404                              <1> sleep0:
 22405                              <1> 	;
 22406 0000477C E849000000          <1> 	call	isintr
 22407                              <1> 	;jnz	sysret
 22408                              <1> 		; / wait for event
 22409                              <1>        		; jsr r0,isintr / check to see if interrupt 
 22410                              <1> 			      ; / or quit from user
 22411                              <1>                		; br 2f / something happened
 22412                              <1> 			      ; / yes, his interrupt so return
 22413                              <1>                      	      ;	/ to user
 22414                              <1> 	; 05/12/2021
 22415 00004781 7405                <1> 	jz	short sleep_2
 22416                              <1> sleep_3:
 22417 00004783 E9F9E9FFFF          <1> 	jmp	sysret
 22418                              <1> sleep_2:
 22419                              <1> 	; 30/06/2015
 22420 00004788 0FB6DC              <1>     	movzx	ebx, ah ; 30/06/2015
 22421 0000478B 81C3[88670000]      <1> 	add	ebx, wlist
 22422 00004791 8A03                <1> 	mov	al, [ebx]
 22423 00004793 20C0                <1> 	and	al, al
 22424 00004795 7407                <1> 	jz	short sleep1
 22425 00004797 53                  <1> 	push	ebx
 22426 00004798 E82DFFFFFF          <1> 	call	putlu
 22427 0000479D 5B                  <1> 	pop	ebx
 22428                              <1> sleep1:
 22429 0000479E A0[B56C0000]        <1> 	mov	al, [u.uno]    
 22430 000047A3 8803                <1>   	mov	[ebx], al 	; put the process number
 22431                              <1> 				; in the wait channel
 22432                              <1> 		; mov (r0)+,r1 / put number of wait channel in r1
 22433                              <1> 		; movb wlist(r1),-(sp) / put old process number in there,
 22434                              <1> 				     ; / on the stack
 22435                              <1>        		; movb u.uno,wlist(r1) / put process number of process
 22436                              <1> 				     ; / to put to sleep in there
 22437                              <1> 	; 30/11/2021
 22438 000047A5 31DB                <1> 	xor	ebx, ebx
 22439 000047A7 8A1D[416C0000]      <1> 	mov	bl, [cdev]
 22440 000047AD 53                  <1> 	push	ebx
 22441                              <1>         ; 15/09/2015
 22442                              <1> 	;movzx	ebx, al
 22443 000047AE 88C3                <1> 	mov	bl, al
 22444 000047B0 C683[83680000]04    <1>         mov     byte [ebx+p.stat-1], 4 ; SSLEEP
 22445                              <1> 	; 27/02/2022 (p.waitc is not used)
 22446                              <1> 	;inc	ah
 22447                              <1> 	;mov	[ebx+p.waitc-1], ah ; wait channel + 1
 22448                              <1> 	;
 22449                              <1> 	;
 22450                              <1> 	;push	word [cdev]
 22451                              <1> 	;	; mov cdev,-(sp) / nothing happened in isintr so
 22452 000047B7 E841FEFFFF          <1> 	call	swap
 22453                              <1>        		; jsr r0,swap / swap out process that needs to sleep
 22454                              <1>         ;pop	word [cdev]
 22455                              <1> 	;	; mov (sp)+,cdev / restore device
 22456                              <1> 	; 30/11/2021
 22457 000047BC 58                  <1> 	pop	eax
 22458 000047BD A2[416C0000]        <1> 	mov	[cdev], al
 22459 000047C2 E803000000          <1> 	call	isintr
 22460                              <1> 	; 22/09/2013
 22461                              <1> 	;jnz	sysret         
 22462                              <1> 		; jsr r0,isintr / check for interrupt of new process
 22463                              <1>                		; br 2f / yes, return to new user
 22464                              <1> 		; movb (sp)+,r1 / no, r1 = old process number that was 
 22465                              <1> 				; / originally on the wait channel
 22466                              <1>        		; beq 1f / if 0 branch
 22467                              <1>   		; mov $runq+4,r2 / r2 points to lowest priority queue
 22468                              <1>        		; mov $300,*$ps / processor priority = 6
 22469                              <1> 		; jsr r0,putlu / create link to old process number
 22470                              <1>        		; clr *$ps / clear the status; process priority = 0
 22471                              <1> 	; 05/12/2021
 22472 000047C7 75BA                <1> 	jnz	short sleep_3 ; jump to sysret
 22473                              <1>      ;1:
 22474 000047C9 C3                  <1> 	retn
 22475                              <1> 		; rts r0 / return
 22476                              <1>      ;2:
 22477                              <1>         ;;jmp	sysret
 22478                              <1> 		; jmp sysret / return to user
 22479                              <1> 
 22480                              <1> isintr:
 22481                              <1> 	; 30/11/2021	
 22482                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 22483                              <1> 	;
 22484                              <1> 	; 09/05/2013 - 30/05/2014
 22485                              <1> 	;
 22486                              <1> 	; Retro UNIX 8086 v1 modification !
 22487                              <1> 	; (Process/task switching and quit routine by using
 22488                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 22489                              <1> 	;
 22490                              <1> 	; Retro UNIX 8086 v1 modification:
 22491                              <1> 	; 'isintr' checks if user interrupt request is enabled
 22492                              <1> 	;  and there is a 'quit' request by user;
 22493                              <1> 	;  otherwise, 'isintr' will return with zf=1 that means
 22494                              <1> 	;  "nothing to do". (20/10/2013)
 22495                              <1> 	;
 22496                              <1> 	; 20/10/2013
 22497 000047CA 66833D[9A6C0000]00  <1> 	cmp 	word [u.ttyp], 0 ; has process got a tty ?
 22498 000047D2 761F                <1> 	jna	short isintr2 ; retn
 22499                              <1> 	; 03/09/2013
 22500                              <1> 	; (nothing to do)
 22501                              <1> 	;retn
 22502                              <1> 	; 22/09/2013
 22503 000047D4 66833D[B06C0000]00  <1> 	cmp	word [u.intr], 0
 22504 000047DC 7615                <1> 	jna	short isintr2 ; retn
 22505                              <1> 	; 30/05/2014
 22506                              <1> 	;push	ax
 22507 000047DE 50                  <1> 	push	eax ; 30/11/2021 
 22508 000047DF 66A1[B26C0000]      <1> 	mov	ax, [u.quit]
 22509 000047E5 6609C0              <1> 	or	ax, ax ; 0 ?
 22510 000047E8 7408                <1> 	jz	short isintr1 ; zf = 1
 22511 000047EA 6683F8FE            <1> 	cmp	ax, 0FFFEh  ; 'ctrl + brk' check
 22512 000047EE 7702                <1> 	ja	short isintr1 ; 0FFFFh, zf = 0
 22513                              <1> 	;xor	ax, ax ; zf = 1
 22514                              <1> 	; 30/11/2021
 22515 000047F0 31C0                <1> 	xor	eax, eax
 22516                              <1> isintr1:
 22517                              <1> 	;pop	ax
 22518                              <1> 	; 30/11/2021
 22519 000047F2 58                  <1> 	pop	eax
 22520                              <1> isintr2: ; 22/09/2013
 22521                              <1> 	; zf=1 -> nothing to do
 22522 000047F3 C3                  <1> 	retn
 22523                              <1> 
 22524                              <1> 	; UNIX v1 original 'isintr' routine... 
 22525                              <1>        	;mov     r1,-(sp) / put number of wait channel on the stack
 22526                              <1>        	;mov     r2,-(sp) / save r2
 22527                              <1>        	;mov     u.ttyp,r1 / r1 = pointer to buffer of process control
 22528                              <1>         ;                 / typewriter
 22529                              <1>        	;beq     1f / if 0, do nothing except skip return
 22530                              <1>        	;movb    6(r1),r1 / put interrupt char in the tty buffer in r1
 22531                              <1>        	;beq     1f / if its 0 do nothing except skip return
 22532                              <1>        	;cmp     r1,$177 / is interrupt char = delete?
 22533                              <1>        	;bne     3f / no, so it must be a quit (fs)
 22534                              <1>        	;tst     u.intr / yes, value of u.intr determines handling
 22535                              <1>         ;              / of interrupts
 22536                              <1>        	;bne     2f / if not 0, 2f. If zero do nothing.
 22537                              <1>      ;1:
 22538                              <1>        	;tst     (r0)+ / bump r0 past system return (skip)
 22539                              <1>      ;4:
 22540                              <1>        	;mov     (sp)+,r2 / restore r1 and r2
 22541                              <1>        	;mov     (sp)+,r1
 22542                              <1>        	;rts     r0
 22543                              <1>      ;3: / interrupt char = quit (fs)
 22544                              <1>        	;tst     u.quit / value of u.quit determines handling of quits
 22545                              <1>        	;beq     1b / u.quit = 0 means do nothing
 22546                              <1>      ;2: / get here because either u.intr <> 0 or u.qult <> O
 22547                              <1>        	;mov     $tty+6,r1 / move pointer to tty block into r1
 22548                              <1>      ;1: / find process control tty entry in tty block
 22549                              <1>        	;cmp     (r1),u.ttyp / is this the process control tty buffer?
 22550                              <1>        	;beq     1f / block found go to 1f
 22551                              <1>        	;add     $8,r1 / look at next tty block
 22552                              <1>        	;cmp     r1,$tty+[ntty*8]+6 / are we at end of tty blocks
 22553                              <1>        	;blo     1b / no
 22554                              <1>        	;br      4b / no process control tty found so go to 4b
 22555                              <1>      ;1:
 22556                              <1>        	;mov     $240,*$ps / set processor priority to 5
 22557                              <1>        	;movb    -3(r1),0f / load getc call argument; character llst
 22558                              <1>         ;                  / identifier
 22559                              <1>        	;inc     0f / increment
 22560                              <1>      ;1:
 22561                              <1>        	;jsr     r0,getc; 0:.. / erase output char list for control
 22562                              <1>         ;        br 4b / process tty. This prevents a line of stuff
 22563                              <1>         ;             / being typed out after you hit the interrupt
 22564                              <1>         ;             / key
 22565                              <1>        	;br      1b
 22566                                  %include 'u5.s'      ; 03/06/2015
 22567                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 22568                              <1> ; (re-write kernel for test by using previous version without a major defect)
 22569                              <1> ; ****************************************************************************
 22570                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS5.INC
 22571                              <1> ; Last Modification: 17/07/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.3)
 22572                              <1> ; ----------------------------------------------------------------------------
 22573                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22574                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22575                              <1> ;
 22576                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22577                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22578                              <1> ; <Bell Laboratories (17/3/1972)>
 22579                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22580                              <1> ;
 22581                              <1> ; Retro UNIX 8086 v1 - U5.AS M (07/08/2013) //// UNIX v1 -> u5.s
 22582                              <1> ;
 22583                              <1> ; ****************************************************************************
 22584                              <1> 
 22585                              <1> 	; 09/03/2022
 22586                              <1> 	; 09/01/2022
 22587                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22588                              <1> mget_w:
 22589                              <1> 	; 28/10/2021
 22590                              <1> 	; 22/08/2021
 22591                              <1> 	; 20/08/2021
 22592                              <1> 	; 25/05/2020
 22593                              <1> 	; 24/05/2020 - Retro UNIX 386 v2	
 22594 000047F4 C605[FA6C0000]01    <1> 	mov	byte [mget_rw], 1 ; write access
 22595 000047FB EB07                <1> 	jmp	short mget
 22596                              <1> mget_r:
 22597                              <1> 	; 28/10/2021
 22598                              <1> 	; 22/08/2021
 22599                              <1> 	; 25/05/2020
 22600                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 22601 000047FD C605[FA6C0000]00    <1> 	mov	byte [mget_rw], 0 ; read access	
 22602                              <1> mget:
 22603                              <1> 	; 17/07/2022
 22604                              <1> 	; 09/03/2022
 22605                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 22606                              <1> 	; 28/11/2021
 22607                              <1> 	; 22/11/2021
 22608                              <1> 	; 28/10/2021 - temporary (simplified code)
 22609                              <1> 	; 22/08/2021
 22610                              <1> 	; 20/08/2021
 22611                              <1> 	; 25/05/2020
 22612                              <1> 	; 24/05/2020
 22613                              <1> 	; 05/05/2020
 22614                              <1> 	; 02/05/2020, 03/05/2020
 22615                              <1> 	; 29/04/2020 - Retro UNIX 386 v2
 22616                              <1> 	; New inode model/format (Modified UNIX v7 inode model)
 22617                              <1> 	;	
 22618                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22619                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 22620                              <1> 	;
 22621                              <1> 	; Get existing or (allocate) a new disk block for file
 22622                              <1> 	; 
 22623                              <1> 	; INPUTS ->
 22624                              <1> 	;    u.fofp (file offset pointer)
 22625                              <1> 	;    inode 
 22626                              <1> 	;    u.off (file offset)
 22627                              <1> 	; OUTPUTS ->
 22628                              <1> 	;    r1 (physical block number)
 22629                              <1> 	;    r2, r3, r5 (internal)
 22630                              <1> 	;
 22631                              <1> 	; ((AX = R1)) output
 22632                              <1> 	;    (Retro UNIX Prototype : 05/03/2013 - 14/11/2012, UNIXCOPY.ASM)
 22633                              <1> 	;
 22634                              <1> 	; Modified registers: eax, edx, ebx, ecx, esi, edi, ebp
 22635                              <1> 
 22636                              <1> 	; Retro UNIX 386 v2 'mget' procedure
 22637                              <1> 	; source code reference:
 22638                              <1> 	; 'mget' procedure in UNIXHDCP.ASM (25/01/2020) by Erdogan Tan
 22639                              <1> 
 22640                              <1> 	; Get sector/block address for current file pointer
 22641                              <1> 	; (If file pointer points to a number greater than current file
 22642                              <1> 	; size, a new -empty- sector/block will be created/written.)
 22643                              <1> 
 22644                              <1> 	; Note: 'mget' procedure will be used for only RUNIX v2 FS.
 22645                              <1> 	;	(installable file system drivers will not use 'mget')
 22646                              <1> 	;	 !!! 512 bytes per sector !!!  ; 02/05/2020
 22647                              <1> 
 22648                              <1> 	; ! 64 bit fofp ! but Retro UNIX 386 v2 kernel will use 32 bit
 22649                              <1> 	; file offset for regular files and directories.
 22650                              <1> 	; ('mget' procedure will be called for regular files & directories)
 22651                              <1> 
 22652                              <1> 	; 28/10/2021
 22653                              <1> 	; Note: 'mget' uses only current inode ([ii], 'inode:')
 22654                              <1> 	; (inode must be loaded at 'inode:' addr by 'iget' before 'mget')  
 22655                              <1> 
 22656                              <1> 		; mov *u.fofp,mq / file offset in mq
 22657                              <1> 		; clr ac / later to be high sig
 22658                              <1> 		; mov $-8,lsh   / divide ac/mq by 256.
 22659                              <1> 		; mov mq,r2
 22660                              <1> 		; bit $10000,i.flgs / lg/sm is this a large or small file
 22661                              <1> 		; bne 4f / branch for large file
 22662                              <1> 
 22663                              <1> 	; 09/01/2022
 22664                              <1> 	; Return: eax = physical block/sector number
 22665                              <1> mget_0:	
 22666 00004804 8B35[786C0000]      <1>         mov     esi, [u.fofp]
 22667 0000480A 8B1E                <1> 	mov	ebx, [esi]
 22668                              <1>         ; ebx = file offset
 22669                              <1> 
 22670                              <1> 	; 20/08/2021
 22671 0000480C C1EB09              <1> 	shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 22672                              <1> 
 22673 0000480F F605[E5670000]10    <1> 	test	byte [i.flgs+1], 10h ; is this a large or small file addr?
 22674 00004816 7405                <1> 	jz	short mget_1 ; small file addressing
 22675 00004818 E984000000          <1> 	jmp	mget_5	; large file addressing
 22676                              <1> mget_1:
 22677                              <1> 	; If large file flag is clear -not set- RUNIX v2 FS inode
 22678                              <1> 	; will contain 10 direct disk block/sector dword pointers.
 22679                              <1> 
 22680                              <1> 	; 05/05/2020
 22681                              <1> 	;shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 22682                              <1> 
 22683 0000481D 83FB0A              <1> 	cmp	ebx, 10	; block 10
 22684 00004820 7338                <1> 	jnb	short mget_3 ; file offset >= 5120
 22685                              <1> 
 22686                              <1> 	; 05/05/2020
 22687                              <1> 	;cmp	ebx, 5120
 22688                              <1> 	;jnb	short mget_3 ; file offset >= 5120
 22689                              <1> 
 22690                              <1> 	;mov	bl, bh
 22691                              <1> 	;and	bl, 1Eh ; clear all bits but bits 1,2,3,4 ; 0,2,..,18
 22692                              <1> 	;	; max. value = 12h = 10010b = 18 (because ebx <= 5119) 
 22693                              <1> 	;shl	bl, 1	; * 2 ; max. value = 24h = 100100b = 36
 22694                              <1> 	;xor	bh, bh  ; clear bh
 22695                              <1> 		; RUNIX v2 (RUFS 2) file system bytes per sector value
 22696                              <1> 		; is always 512.
 22697                              <1> 		; ebx = 4*(ebx/512)  = 0 to 36
 22698                              <1> 
 22699                              <1> 	; 05/05/2020
 22700 00004822 C0E302              <1> 	shl	bl, 2 ; * 4
 22701                              <1> 		 ; ebx = 0 to 36
 22702                              <1> 
 22703 00004825 8B83[F0670000]      <1> 	mov	eax, [ebx+i.dskp] ; disk sector addr ptr 0 to 9 for file
 22704                              <1> 	; 22/08/2021
 22705 0000482B 89DE                <1> 	mov	esi, ebx
 22706                              <1> 	;xor	ebx, ebx ; 0
 22707                              <1> 	; 09/03/2022
 22708                              <1> 	;; 09/01/2022
 22709                              <1> 	;xor	bl, bl
 22710                              <1> 
 22711 0000482D 09C0                <1> 	or	eax, eax
 22712 0000482F 7512                <1> 	jnz	short mget_2 ; existing block/sector (logical)
 22713                              <1> 
 22714 00004831 56                  <1> 	push	esi ; * ; 22/08/2021
 22715 00004832 E872010000          <1> 	call	alloc_m ; 24/05/2020	
 22716                              <1> 	;call	alloc	; allocate a new sector/block for this file	
 22717                              <1> 			; eax = sector/block number
 22718                              <1> 			; ebx = buffer header address
 22719 00004837 5E                  <1> 	pop	esi ; * ; 22/08/2021
 22720                              <1> 	; 28/11/2021
 22721                              <1> 	;jc	short mget_2 
 22722                              <1> 			; cf = 1 -> eax = 'no free block' error
 22723                              <1> 	; 22/08/2021
 22724 00004838 8986[F0670000]      <1> 	mov	[esi+i.dskp], eax  ; logical sector/block address
 22725                              <1> 
 22726                              <1> 	; 09/01/2022
 22727 0000483E E8BF040000          <1> 	call	setimod	; set inode modification flag
 22728                              <1> 			; and set modification time
 22729                              <1> 
 22730                              <1> 	; eax = logical sector/block number
 22731                              <1> 	; ([idev] = logical drive number)
 22732                              <1> 	; 28/10/2021
 22733                              <1> 	; [cdev] = logical drive number (0 or 1)
 22734                              <1> 	;	(0 = root fs, 1 = mounted fs)
 22735                              <1> mget_2:
 22736                              <1> 	; 09/01/2022
 22737                              <1> 	; eax = logical sector/block number
 22738 00004843 F605[416C0000]01    <1> 	test	byte [cdev], 1
 22739 0000484A 7507                <1> 	jnz	short mget_14
 22740                              <1> 	; convert to physical sector/block number
 22741 0000484C 0305[186D0000]      <1> 	add	eax, [systm+SB.BootSectAddr]
 22742 00004852 C3                  <1> 	retn
 22743                              <1> 	; 09/01/2022
 22744                              <1> mget_14:
 22745                              <1> 	; convert to physical sector/block number
 22746 00004853 0305[206F0000]      <1> 	add	eax, [mount+SB.BootSectAddr]
 22747 00004859 C3                  <1> 	retn
 22748                              <1> 	
 22749                              <1> 		; rts r0
 22750                              <1> mget_3: ; 3: / adding on block which changes small file to a large file
 22751                              <1> 	; 22/11/2021
 22752 0000485A E84A010000          <1> 	call	alloc_m ; 24/05/2020
 22753                              <1> 	;call	alloc	; allocate a new sector/block for this file
 22754                              <1> 			; eax = sector/block number
 22755                              <1> 			; ebx = buffer header  ; 24/05/2020
 22756                              <1> 	; 28/11/2021
 22757                              <1> 	;jc	short mget_2 ; error code in eax
 22758                              <1> 
 22759                              <1> 	; 09/01/2022
 22760                              <1> 	; convert to physical block/sector number
 22761 0000485F 50                  <1> 	push	eax ; *!* ; logical sector/block number 
 22762 00004860 E8DEFFFFFF          <1> 	call	mget_2
 22763                              <1> 
 22764                              <1>         ; EAX (r1) = Physical block (sector) number
 22765 00004865 E886110000          <1> 	call 	wslot
 22766                              <1> 		; jsr r0,wslot / set up I/O buffer for write, r5 points to 
 22767                              <1> 			     ; / first data word in buffer
 22768                              <1>         ; EAX (r1) = Physical block number
 22769                              <1> 	; 28/11/2021
 22770                              <1> 	; ebx = buffer (data) address
 22771                              <1> 	; 22/11/2021
 22772 0000486A 31C9                <1> 	xor	ecx, ecx
 22773 0000486C B10A                <1> 	mov 	cl, 10	; r3, transfer old physical block pointers
 22774                              <1> 			; into new indirect block area for the new
 22775                              <1> 			; large file		
 22776 0000486E 89DF                <1> 	mov 	edi, ebx ; r5
 22777 00004870 BE[F0670000]        <1> 	mov	esi, i.dskp  ; current inode's direct disk addr ptrs
 22778 00004875 89C2                <1> 	mov	edx, eax
 22779 00004877 31C0                <1> 	xor	eax, eax
 22780                              <1> mget_4:
 22781 00004879 A5                  <1> 	movsd 	
 22782 0000487A 8946FC              <1> 	mov	[esi-4], eax ; 0
 22783 0000487D E2FA                <1> 	loop	mget_4
 22784                              <1> 
 22785                              <1> 	; 22/11/2021
 22786 0000487F B176                <1> 	mov 	cl, 128-10 ; clear rest of data buffer
 22787                              <1> ;mget_4: ; 1
 22788 00004881 F3AB                <1> 	rep 	stosd
 22789                              <1> 		; clr (r5)+
 22790                              <1> 		; dec r3
 22791                              <1> 		; bgt 1b
 22792 00004883 89D0                <1> 	mov	eax, edx
 22793                              <1>         ; EAX (r1) = Physical block number
 22794 00004885 E873110000          <1> 	call	dskwr
 22795                              <1> 		; jsr r0,dskwr / write new indirect block on disk
 22796                              <1> 
 22797                              <1> 	;; EAX (r1) = Physical block number
 22798                              <1> 
 22799                              <1> 	; 09/01/2022        
 22800 0000488A 8F05[F0670000]      <1> 	pop	dword [i.dskp] ; *!* ; logical sector/block number
 22801                              <1>  
 22802                              <1> 	; eax = logical disk sector/block number/addr ; 09/01/2022
 22803                              <1> 	;mov 	[i.dskp], eax ; 22/11/2021 
 22804                              <1> 		; mov r1,i.dskp / put pointer to indirect block in i-node
 22805                              <1> 
 22806 00004890 800D[E5670000]10    <1> 	or	byte [i.flgs+1], 10000b ; 10h ; 16  ; large file flag
 22807                              <1> 		; bis $10000,i.flgs / set large file bit 
 22808                              <1> 				  ; / in i.flgs word of i-node
 22809 00004897 E866040000          <1> 	call	setimod
 22810                              <1> 		; jsr r0,setimod / set i-node modified flag
 22811                              <1> 
 22812 0000489C E963FFFFFF          <1> 	jmp	mget_0 ; 09/01/2022
 22813                              <1> 		; br mget
 22814                              <1> 
 22815                              <1> mget_5:  ; 4 ; large file
 22816                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 22817                              <1> 	;
 22818                              <1> 	; Retro UNIX 386 v2 disk inode contains..
 22819                              <1> 	; (if large file flag is set)
 22820                              <1> 	; 8 indirect disk block/sector dword pointers
 22821                              <1> 	; +1 double indirect disk block/sector dword pointers
 22822                              <1> 	; +1 triple indirect disk block/sector dword pointers
 22823                              <1> 
 22824                              <1> 	; check indirect pointers limit (as file offset)
 22825                              <1> 	; 8*128 = 1024 blocks (or sectors) or 512 KB
 22826                              <1> 	; check dx (file offset hw) value
 22827                              <1> 	
 22828                              <1> 	; 03/05/2020
 22829                              <1> 	;cmp	ebx, 524288  ; is file offset >= 524288 ?
 22830                              <1> 	;jnb	short mget_6 ; yes, check double indirect limit
 22831                              <1> 
 22832                              <1> 	; 05/05/2020
 22833 000048A1 81FB00040000        <1> 	cmp	ebx, 1024    ; block 1024 (byte 524288)	
 22834 000048A7 7320                <1> 	jnb	short mget_6 ; check double indirect limit
 22835                              <1> 
 22836 000048A9 C605[FC6C0000]01    <1> 	mov	byte [level], 1 ; levels, 1 = indirect blocks
 22837                              <1> 
 22838                              <1> 	; 05/05/2020
 22839                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 22840                              <1> 
 22841 000048B0 88D9                <1> 	mov	cl, bl
 22842 000048B2 80E17F              <1> 	and	cl, 127
 22843 000048B5 880D[FD6C0000]      <1> 	mov	[level+1], cl ; level 1, direct block ptr index (0 to 127)
 22844                              <1> 	;shr	bx, 7 ; bl = level 0, indirect block pointer index (0 to 7)
 22845                              <1> 	; 17/07/2022
 22846 000048BB C1EB07              <1> 	shr	ebx, 7
 22847                              <1> 	;mov	[level+2], bl
 22848                              <1> 
 22849 000048BE C0E302              <1> 	shl	bl, 2 ; * 4 to convert index number to offset
 22850                              <1> 
 22851                              <1> 	;mov	esi, i.dskp
 22852                              <1> 	;add	esi, ebx
 22853                              <1> 
 22854 000048C1 8DB3[F0670000]      <1> 	lea	esi, [ebx+i.dskp]
 22855                              <1> 
 22856 000048C7 EB64                <1> 	jmp	short mget_8
 22857                              <1> 
 22858                              <1> mget_6:
 22859                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22860                              <1> 	; 03/05/2020
 22861                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 22862                              <1> 	; check double indirect pointer limit (as file offset)
 22863                              <1> 	; (128*128)+1024 = 16384+1024 blocks or 8 MB + 512 KB
 22864                              <1> 	; check dx (file offset hw) value
 22865                              <1> 	
 22866                              <1> 	;cmp	ebx, 8912896 ; >= 17408 sectors (16384+1024) ?	
 22867                              <1> 	;jnb	short mget_7 ; yes, use triple indirect pointer (block)
 22868                              <1> 
 22869                              <1> 	; 05/05/2020
 22870 000048C9 81FB00440000        <1> 	cmp	ebx, 17408   ; block 17408 (byte 8912896)	
 22871 000048CF 7328                <1> 	jnb	short mget_7 ; use triple indirect pointer (block)
 22872                              <1> 
 22873 000048D1 C605[FC6C0000]02    <1> 	mov	byte [level], 2  ; levels, 2 = double indirect blocks
 22874                              <1> 	
 22875                              <1> 	;sub	ebx, 524288 ; 1024 sectors
 22876                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 22877                              <1> 			; (from sector 1024)
 22878                              <1> 	; 05/05/2020
 22879 000048D8 81EB00040000        <1> 	sub	ebx, 1024 ; offset from sector 1024
 22880                              <1> 	
 22881 000048DE 88D9                <1> 	mov	cl, bl
 22882 000048E0 80E17F              <1> 	and	cl, 127
 22883 000048E3 880D[FD6C0000]      <1> 	mov	[level+1], cl
 22884                              <1> 			; level 2, direct block ptr index (0 to 127)	
 22885                              <1> 	;shr	bx, 7
 22886                              <1> 	; 17/07/2022
 22887 000048E9 C1EB07              <1> 	shr	ebx, 7
 22888 000048EC 881D[FE6C0000]      <1> 	mov	[level+2], bl
 22889                              <1> 			; level 1, indirect block ptr index (0 to 127)
 22890                              <1> 
 22891 000048F2 BE[10680000]        <1> 	mov	esi, i.dskp + 32 ; 8*4
 22892                              <1> 			; level 0, double indirect block pointer
 22893 000048F7 EB34                <1> 	jmp	short mget_8
 22894                              <1> 
 22895                              <1> mget_7:
 22896                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22897                              <1> 	; 03/05/2020
 22898                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 22899                              <1> 	; triple indirect pointer ; 8912896 to 1082654720 bytes
 22900                              <1> 	;mov	esi, i.dskp + 36 ; 9*4
 22901                              <1> 
 22902 000048F9 C605[FC6C0000]03    <1> 	mov	byte [level], 3  ; levels, 3 = triple indirect blocks
 22903                              <1> 
 22904                              <1> 	;sub	ebx, 8912896 ; 17408 sectors (16384+1024)
 22905                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 22906                              <1> 			; (from sector 17408)
 22907                              <1> 	; 05/05/2020
 22908 00004900 81EB00440000        <1> 	sub	ebx, 17408 ; offset from sector 17408	
 22909                              <1> 
 22910 00004906 88D9                <1> 	mov	cl, bl
 22911 00004908 80E17F              <1> 	and	cl, 127
 22912 0000490B 880D[FD6C0000]      <1> 	mov	[level+1], cl  
 22913                              <1> 			; level 3, direct block ptr index (0 to 127)	
 22914 00004911 C1EB07              <1> 	shr	ebx, 7	
 22915 00004914 88D9                <1> 	mov	cl, bl
 22916 00004916 80E17F              <1> 	and	cl, 127
 22917 00004919 880D[FE6C0000]      <1> 	mov	[level+2], cl
 22918                              <1> 			; level 2, indirect block ptr index (0 to 127)
 22919                              <1> 	;shr	bx, 7
 22920                              <1> 	; 17/07/2022
 22921 0000491F C1EB07              <1> 	shr	ebx, 7
 22922 00004922 881D[FF6C0000]      <1> 	mov	[level+3], bl
 22923                              <1> 			; level 1, double indir blk ptr index (0 to 127)
 22924                              <1> 
 22925 00004928 BE[14680000]        <1> 	mov	esi, i.dskp + 36 ; 9*4
 22926                              <1> 			; level 0, triple indirect block pointer
 22927                              <1> mget_8:
 22928                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22929 0000492D 8B06                <1> 	mov	eax, [esi]
 22930 0000492F 09C0                <1> 	or 	eax, eax ; R1
 22931 00004931 751A                <1> 	jnz 	short mget_10 ; 2f
 22932                              <1> 		; bne 2f / if no indirect block exists
 22933 00004933 56                  <1> 	push	esi	; * ; 24/05/2020
 22934                              <1> 
 22935 00004934 E870000000          <1> 	call	alloc_m ; 24/05/2020
 22936                              <1> 	;call	alloc	; allocate a new block for this file	
 22937                              <1> 			; eax = block number
 22938                              <1> 			; ebx = buffer header address
 22939                              <1> 			; [pdn] = physical drive number ; 25/05/2020
 22940                              <1> 	;jc	mget_2	; cf -> 1 & eax = 0 -> no free block
 22941                              <1> 
 22942 00004939 5E                  <1> 	pop	esi	; * ; 24/05/2020
 22943                              <1> 	;jc	short mget_9
 22944                              <1> 
 22945                              <1> 	; 09/01/2022
 22946                              <1> 	; eax = logical sector/block number
 22947                              <1> 
 22948 0000493A 8906                <1> 	mov	[esi], eax ; record sector/block address on i.dskp area
 22949                              <1> 
 22950 0000493C E8C1030000          <1> 	call 	setimod
 22951                              <1> 		; jsr r0,setimod / set i-node modified byte
 22952                              <1> 	; EAX = new block number (logical)
 22953                              <1> 
 22954                              <1> 	; 09/01/2022
 22955                              <1> 	; convert to physical block/sector number
 22956 00004941 E8FDFEFFFF          <1> 	call	mget_2
 22957                              <1> 	;
 22958 00004946 E8AEFDFFFF          <1> 	call 	clear
 22959                              <1> 		; jsr r0,clear / clear new block
 22960                              <1> 	; 09/03/2022
 22961                              <1> 	;add	ebx, 8
 22962                              <1> 	; ebx = buffer data address
 22963                              <1> 	; 22/11/2021
 22964 0000494B EB0A                <1> 	jmp	short mget_11
 22965                              <1> ;mget_9:
 22966                              <1> ;	pop	edx ; *  ; 09/01/2022
 22967                              <1> ;	retn
 22968                              <1> mget_10: ;2
 22969                              <1> 	; 09/01/2022
 22970                              <1> 	; eax = logical sector/block number/address
 22971                              <1> 	; convert to physical sector/block number/address
 22972 0000494D E8F1FEFFFF          <1> 	call	mget_2	
 22973                              <1> 	; 05/03/2013
 22974                              <1> 	; EAX = r1, physical block number (of indirect block)
 22975 00004952 E835100000          <1> 	call 	dskrd ; read indirect block
 22976                              <1> 		; jsr r0,dskrd / read in indirect block
 22977                              <1> 	;jc	short mget_9
 22978                              <1> mget_11:
 22979                              <1> 	; 22/11/2021
 22980                              <1> 	; eax = physical block/sector address
 22981                              <1> 	; ebx = buffer (data) address ; 09/03/2022
 22982                              <1> 
 22983 00004957 89C2                <1> 	mov	edx, eax ; *  ; save physical sector number in edx
 22984                              <1> 
 22985 00004959 0FB605[FC6C0000]    <1> 	movzx	eax, byte [level]
 22986 00004960 8A80[FC6C0000]      <1> 	mov	al, [eax+level] ; get sector pointer offset
 22987 00004966 C1E002              <1> 	shl	eax, 2 ; * 4 ; 09/01/2022
 22988                              <1> 	;shl	ax, 2 ; * 4
 22989                              <1> 
 22990 00004969 01C3                <1> 	add	ebx, eax
 22991                              <1> 
 22992 0000496B 8B03                <1> 	mov 	eax, [ebx] ; put logical block no of block
 22993                              <1> 			   ; in file sought in R1 (EAX)
 22994                              <1> 		; mov (r2),r1 / put physical block no of block in file
 22995                              <1> 	               	    ; / sought in r1
 22996                              <1> 
 22997 0000496D 21C0                <1> 	and	eax, eax  ; if logical sector/block number is zero
 22998                              <1> 			  ; then we need a new block for file
 22999 0000496F 740D                <1> 	jz	short mget_12
 23000                              <1> 
 23001 00004971 FE0D[FC6C0000]      <1> 	dec	byte [level]
 23002 00004977 75D4                <1> 	jnz	short mget_10
 23003                              <1> 
 23004                              <1> 	; 09/03/2022
 23005                              <1> 	;sub	ebx, ebx ; ebx = 0 ; existing sector
 23006                              <1> 
 23007                              <1> 	;retn
 23008                              <1> 	; 09/01/2022
 23009                              <1> 	; eax = logical block/sector number
 23010 00004979 E9C5FEFFFF          <1> 	jmp	mget_2
 23011                              <1> 
 23012                              <1> mget_12:
 23013                              <1> 	; 22/11/2021
 23014 0000497E 52                  <1> 	push	edx ; *
 23015 0000497F 53                  <1> 	push	ebx ; ** ; buffer data position
 23016 00004980 E824000000          <1> 	call	alloc_m
 23017                              <1> 	;call	alloc	 ; allocate a new block for this file	
 23018                              <1> 			 ; eax = block number (logical)
 23019                              <1> 			 ; ebx = buffer header address
 23020 00004985 5E                  <1> 	pop	esi ; **
 23021                              <1> 	; 09/01/2022
 23022                              <1> 	;pop	edx ; *
 23023                              <1> 	;jc	short mget_9 ; cf -> 1 & eax = 0 -> no free block
 23024                              <1> 
 23025 00004986 8906                <1> 	mov	[esi], eax ; record/save block number (logical)
 23026                              <1> 
 23027                              <1> 	; 22/11/2021
 23028 00004988 870424              <1> 	xchg	eax, [esp] ; *
 23029                              <1> 
 23030                              <1> 	; eax (r1) = physical block number (of indirect block)
 23031 0000498B E860100000          <1> 	call 	wslot
 23032                              <1> 		; jsr r0,wslot
 23033                              <1>         ; eax (r1) = physical block number
 23034                              <1> 	; ebx (r5) = pointer to buffer (indirect block)
 23035 00004990 E868100000          <1> 	call 	dskwr
 23036                              <1> 	; eax = r1 = physical block number (of indirect block)
 23037                              <1> 		; jsr r0,dskwr / write newly modified indirect block 
 23038                              <1> 			     ; / back out on disk
 23039 00004995 58                  <1> 	pop	eax ; *  ; 31/07/2013
 23040                              <1> 		; mov (sp),r1 / restore block number of new block	
 23041                              <1> 
 23042                              <1> 	; 09/01/2022
 23043                              <1> 	; eax = logical sector/block number/address of new block
 23044                              <1> 	; convert to physical sector/block number/address
 23045 00004996 E8A8FEFFFF          <1> 	call	mget_2	
 23046                              <1> 
 23047 0000499B E859FDFFFF          <1> 	call 	clear
 23048                              <1> 		; jsr r0,clear / clear new block
 23049                              <1> 
 23050 000049A0 FE0D[FC6C0000]      <1> 	dec	byte [level]
 23051 000049A6 75AF                <1> 	jnz	short mget_11 
 23052                              <1> 		; ebx = buffer (data) address ; 09/03/2022
 23053                              <1> 
 23054                              <1> 	; 09/01/2022
 23055                              <1> 	; eax = physical sector/block number/address of new block
 23056                              <1> 	
 23057                              <1> 	; 22/11/2021
 23058                              <1> 	; ebx = buffer address
 23059                              <1> mget_13: ; 2
 23060                              <1> 	; eax (r1) = Block number of new block
 23061 000049A8 C3                  <1> 	retn
 23062                              <1> 		; rts r0
 23063                              <1> 
 23064                              <1> 	; 09/01/2022
 23065                              <1> 	; 26/11/2021
 23066                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23067                              <1> alloc_m:
 23068                              <1> 	; 27/11/2021
 23069                              <1> 	; 28/10/2021
 23070                              <1> 	; 07/05/2021
 23071                              <1> 	; 26/05/2020
 23072                              <1> 	; 25/05/2020
 23073                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 23074                              <1> 	; 'alloc' call in 'mget'
 23075                              <1> 	;
 23076                              <1> 	; (('mget_r' will be returned with error))
 23077                              <1> 	; (('mget_w' will continue to 'alloc'))
 23078                              <1> 
 23079                              <1> 	; Note: 'sysread' will return with cf = 0, eax = 0
 23080                              <1> 	; if [fofp] >= file size (eax = 0 --> EOF)
 23081                              <1> 	; So, if we are here, that means [fofp] < file size
 23082                              <1> 	;     but disk address is 0. 
 23083                              <1> 	
 23084 000049A9 803D[FA6C0000]01    <1> 	cmp	byte [mget_rw], 1 ; write access ? (mget_w) 
 23085 000049B0 730F                <1> 	jnb	short alloc ; yes (this is a call from 'mget_w')
 23086                              <1> 	; ((cf = 1))	
 23087                              <1> 	; no (this is a call from 'mget_r') !
 23088                              <1> 	;mov	eax, ERR_FILE_SIZE ; file size error (inode error!)
 23089                              <1> 		; [User may change this empty/invalid inode (disk) sector
 23090                              <1> 		; pointer with a new valid inode (disk) sector pointer 
 23091                              <1> 		; by writing new clear (zero) sector to same file position
 23092                              <1> 		; in order to correct file size -inode parm/content- error.
 23093                              <1> 		; It may be useful for recovering lost data if other sector
 23094                              <1> 		; pointers are not empty.]	
 23095                              <1> 	;retn
 23096                              <1> 	; 27/11/2021
 23097 000049B2 C705[D86C0000]1400- <1> 	mov	dword [u.error], ERR_FILE_SIZE 
 23098 000049BA 0000                <1>
 23099                              <1> 			; file size error (inode error!)
 23100 000049BC E9A0E7FFFF          <1> 	jmp	error
 23101                              <1> alloc:
 23102                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23103                              <1> 	; 27/11/2021
 23104                              <1> 	; 26/11/2021 - Major modification for Runix v2 file system
 23105                              <1> 	;	(I have called this kernel version as v1.2, it is a
 23106                              <1> 	;	 debug/test version just before Retro UNIX 386 v2 kernel)
 23107                              <1> 	;	((there were running problems on new version, 
 23108                              <1> 	;	  so i am developing an intermediate version with minimum
 23109                              <1> 	;	  modification on v1.1 code which is successfuly running))
 23110                              <1> 	;	 ; /// Erdogan Tan - Istanbul, 26/11/2021 /// 
 23111                              <1> 	;	 
 23112                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23113                              <1> 	; 01/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 23114                              <1> 	;
 23115                              <1> 	; get a free block and 
 23116                              <1> 	; set the corresponding bit in the free storage map
 23117                              <1> 	; 
 23118                              <1> 	; INPUTS ->
 23119                              <1> 	;    cdev (current device)
 23120                              <1> 	;    r2 
 23121                              <1> 	;    r3
 23122                              <1> 	; OUTPUTS ->
 23123                              <1> 	;    r1 (physical block number of block assigned)
 23124                              <1> 	;    smod, mmod, systm (super block), mount (mountable super block)	
 23125                              <1> 	;
 23126                              <1> 	; ((AX = R1)) output
 23127                              <1> 	;    (Retro UNIX Prototype : 14/11/2012 - 21/07/2012, UNIXCOPY.ASM)
 23128                              <1>         ;    ((Modified registers: edx, ecx)) 
 23129                              <1> 
 23130                              <1> 	; 26/11/2021
 23131                              <1> 	; INPUT:
 23132                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 23133                              <1> 	; OUTPUT:
 23134                              <1> 	;	eax = disk block/sector number/address (physical)
 23135                              <1> 	;	(ebx = disk buffer address for sector/block in eax)
 23136                              <1> 	;
 23137                              <1> 	;    Note:	
 23138                              <1> 	;	Free blocks map will be modified and written to it's disk.
 23139                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 23140                              <1> 	;	modification flag will be set; but the superblock 
 23141                              <1> 	;	will not be written to it's disk in this 'alloc' procedure)
 23142                              <1> 	;
 23143                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi, ebp
 23144                              <1> 
 23145                              <1> 	; 09/01/2022
 23146                              <1> 	; Return: eax = logical block/sector number 
 23147                              <1> 
 23148                              <1> 	; 26/11/2021
 23149 000049C1 BB[146D0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 23150                              <1> 		; mov $systm,r2 / start of inode and free storage map for drum
 23151 000049C6 F605[416C0000]01    <1> 	test	byte [cdev], 1
 23152                              <1> 		; tst cdev
 23153 000049CD 7405                <1> 	jz	short alloc_1
 23154                              <1> 		; beq 1f / drum is device
 23155 000049CF BB[1C6F0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 23156                              <1> 		; mov $mount,r2 / disk or tape is device, start of inode and
 23157                              <1> 			      ; / free storage map
 23158                              <1> alloc_1: ; 1
 23159                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23160 000049D4 F6436A01            <1> 	test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 23161 000049D8 7507                <1> 	jnz	short alloc_2  ; 'read only file system' error
 23162                              <1> 	;
 23163 000049DA 8B4B38              <1> 	mov	ecx, [ebx+SB.FreeBlocks] ; count of free blocks/sectors
 23164 000049DD 21C9                <1> 	and	ecx, ecx
 23165 000049DF 750F                <1> 	jnz	short alloc_3
 23166                              <1> alloc_2:
 23167                              <1> 	; 'no free blocks on disk !' error
 23168 000049E1 C705[D86C0000]2100- <1> 	mov	dword [u.error], ERR_ALLOC
 23169 000049E9 0000                <1>
 23170 000049EB E971E7FFFF          <1> 	jmp	error
 23171                              <1> alloc_3:
 23172                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23173 000049F0 31C0                <1> 	xor	eax, eax
 23174                              <1> 	; 23/07/2021
 23175 000049F2 8B4B3C              <1> 	mov	ecx, [ebx+SB.FirstFreeBlk] ; 1st free sector number
 23176                              <1> 					 ; (as logical sector number)
 23177 000049F5 09C9                <1> 	or	ecx, ecx
 23178 000049F7 7415                <1> 	jz	short alloc_5 ; 0 = initial/reset value or 'not valid'
 23179 000049F9 41                  <1> 	inc	ecx ; 0FFFFFFFFh -> 0
 23180 000049FA 7412                <1> 	jz	short alloc_5 ; 'not valid' or 'not calculated'
 23181 000049FC 49                  <1> 	dec	ecx ; restore first free block value
 23182 000049FD 89C8                <1> 	mov	eax, ecx
 23183                              <1> 	; 1 allocation byte (in fbm) is for 8 sectors
 23184 000049FF C1E903              <1> 	shr	ecx, 3	; first free block number / 8
 23185 00004A02 80E1FC              <1> 	and	cl, ~3	; dword alignment (to backward)
 23186                              <1> 	; 27/11/2021
 23187 00004A05 890D[006D0000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm
 23188                              <1> alloc_4:
 23189 00004A0B C1E80C              <1> 	shr	eax, 12 ; 1 fbm sector for 4096 sectors
 23190                              <1> alloc_5:
 23191                              <1> 	; 26/11/2021
 23192 00004A0E 53                  <1> 	push	ebx ; ** ; superblock buffer address 
 23193                              <1> 	; eax = fbm sector index
 23194 00004A0F A3[046D0000]        <1> 	mov	[free_map_index], eax
 23195 00004A14 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 23196                              <1> 			; free blocks map start sector addr
 23197                              <1> 	; 09/01/2022
 23198 00004A17 034304              <1> 	add	eax, [ebx+SB.BootSectAddr] 
 23199                              <1> 			; + Hidden Sectors
 23200                              <1> 	;
 23201                              <1> 	; eax = physical sector number
 23202 00004A1A E86D0F0000          <1> 	call	dskrd
 23203                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 23204                              <1> 	; eax = physical sector number
 23205                              <1> 	; ebx = buffer data address
 23206                              <1> 	; 27/11/2021
 23207 00004A1F 8B15[006D0000]      <1> 	mov	edx, [free_map_offset] ; byte position on fbm
 23208 00004A25 A3[086D0000]        <1> 	mov	[free_map_sector], eax ; physical sector number
 23209 00004A2A B9FF010000          <1> 	mov	ecx, 511
 23210                              <1> 	;and	edx, 511
 23211 00004A2F 21CA                <1> 	and 	edx, ecx ; fbm byte offset in fbm buffer
 23212 00004A31 41                  <1> 	inc	ecx ; 512
 23213 00004A32 01D9                <1> 	add	ecx, ebx
 23214 00004A34 01DA                <1> 	add	edx, ebx ; + buffer address
 23215 00004A36 5B                  <1> 	pop	ebx ; ** ; superblock buffer address 
 23216                              <1> 	;
 23217                              <1> 	; ebx = superblock buffer address
 23218                              <1> 	; edx = fbm buffer address + byte offset (dword aligned)
 23219                              <1> 	; ecx = fbm buffer address + 512
 23220                              <1> alloc_6:
 23221                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23222                              <1> 	;		for Retro UNIX 386 v1.2
 23223                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 code
 23224                              <1> 	; (dword scan) ((1 dword = 32 sectors, 1 byte = 8 sectors))
 23225                              <1> 	; ((Note: Logical drive size must be multiplies of 32 sectors))
 23226                              <1> 	; 19/05/2020
 23227                              <1> 	; edx = free blocks map byte address 
 23228 00004A37 0FBC02              <1> 	bsf	eax, [edx] ; Scans source operand for first bit set (1).
 23229                              <1> 			  ; Clear ZF if a bit is found set (1) and 
 23230                              <1> 			  ; loads the destination with an index to
 23231                              <1> 			  ; first set bit. (0 -> 31) 
 23232                              <1> 			  ; Sets ZF to 1 if no bits are found set.
 23233 00004A3A 752A                <1> 	jnz	short alloc_8 ; ZF = 0 -> a free block has been found
 23234                              <1> 
 23235 00004A3C A1[006D0000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 23236 00004A41 83C004              <1> 	add	eax, 4 ; next dword
 23237 00004A44 3B431C              <1> 	cmp	eax, [ebx+SB.FreeMapSize] ; fbm size in bytes
 23238 00004A47 7209                <1> 	jb	short alloc_7
 23239                              <1> 	; invalidate superblock's first free block field
 23240 00004A49 C7433CFFFFFFFF      <1> 	mov	dword [ebx+SB.FirstFreeBlk], 0FFFFFFFFh
 23241                              <1> 	; 'no free blocks on disk !' error
 23242 00004A50 EB8F                <1> 	jmp	alloc_2
 23243                              <1> alloc_7:
 23244                              <1> 		; 26/05/2020
 23245                              <1> 		; NOTE: If ldrv size is not multiplies of 32 sectors,
 23246                              <1> 		; mod (ldrv size / 32) sectors (at the end of ldrv)
 23247                              <1> 		; can not be allocated (for regular files or dirs)! 
 23248                              <1> 		; (Kernel or runix fs installation program can use
 23249                              <1> 		;  this fact to save/duplicate critical sectors/data 
 23250                              <1> 		;  onto end sectors of that logical drive's runix fs.)
 23251                              <1> 
 23252                              <1> 	; 26/11/2021
 23253 00004A52 A3[006D0000]        <1> 	mov	[free_map_offset], eax
 23254                              <1> 	; 28/07/2021
 23255                              <1> 	; set next first free block value for search
 23256 00004A57 C1E003              <1> 	shl	eax, 3 ; * 8 ; first free block
 23257                              <1>  	; 26/11/2021
 23258 00004A5A 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 23259                              <1> 	; search (scan) for next free block map dword (in buffer)
 23260 00004A5D 83C204              <1> 	add	edx, 4 ; next dword
 23261 00004A60 39CA                <1> 	cmp	edx, ecx
 23262 00004A62 72D3                <1> 	jb	short alloc_6
 23263                              <1> 	; 27/11/2021
 23264 00004A64 EBA5                <1> 	jmp	short alloc_4
 23265                              <1> 
 23266                              <1> alloc_8:
 23267                              <1> 	; 26/11/2021
 23268                              <1> 	; convert bit index to xor value
 23269                              <1> 	; and then set allocated flag for corresponding fbm bit 
 23270 00004A66 89C1                <1> 	mov	ecx, eax
 23271                              <1> 	;mov	cl, al 
 23272                              <1> 	;sub	eax, eax
 23273                              <1> 	;inc	al ; eax = 1
 23274 00004A68 B001                <1> 	mov	al, 1
 23275 00004A6A D3E0                <1> 	shl	eax, cl
 23276 00004A6C 3102                <1> 	xor	[edx], eax  ; clear allocated block's bit in the fbm
 23277                              <1> 	; zero bit means allocated disk block (1 means free disk block) 
 23278                              <1> 
 23279 00004A6E A1[006D0000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 23280                              <1> 		; note: eax is dword aligned (0,4,8,12..) !
 23281 00004A73 C1E003              <1> 	shl	eax, 3 ; * 8 ; free block number base
 23282 00004A76 01C8                <1> 	add	eax, ecx ; add allocation bit index (0 to 31)	
 23283 00004A78 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax ; current free block
 23284                              <1> 				; (which is being allocated here)
 23285                              <1> 
 23286                              <1> 	;mov	eax, [ebx+SB.FreeMapAddr] 
 23287                              <1> 	;		; free blocks map start sector addr
 23288                              <1> 	;add	eax, [free_map_index]
 23289                              <1> 	
 23290                              <1> 	;;add	eax, [ebx+SB.BootSectAddr] 
 23291                              <1> 	;		; + Hidden Sectors
 23292                              <1> 	; eax = physical sector number
 23293                              <1> 	
 23294                              <1> 	; 27/11/2021
 23295 00004A7B A1[086D0000]        <1> 	mov	eax, [free_map_sector] ; physical sector number
 23296                              <1> 	
 23297 00004A80 E86B0F0000          <1> 	call	wslot
 23298                              <1> 	; ebx = buffer data address (write operation bit is set)
 23299                              <1> 	; eax = physical sector number
 23300                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 23301                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 23302                              <1> 
 23303                              <1> 	; 27/11/2021
 23304                              <1> 	;mov	[free_map_buffer], ebx ; save free map buffer address
 23305                              <1> 
 23306 00004A85 E8730F0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 23307                              <1> 		      ; (at the beginning/head of the buffer chain)
 23308                              <1> 
 23309                              <1> 	; if we are here, buffer has been written to disk successfully 
 23310                              <1> 	; (otherwise cpu would jump to 'error' address)
 23311                              <1> 
 23312                              <1> 	; set superblock modified flag
 23313 00004A8A BA[566C0000]        <1> 	mov	edx, smod
 23314 00004A8F BB[146D0000]        <1> 	mov	ebx, systm
 23315 00004A94 F605[416C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 23316 00004A9B 7406                <1> 	jz	short alloc_9  ; no, root device
 23317                              <1> 	; yes, mounted device
 23318 00004A9D BB[1C6F0000]        <1> 	mov	ebx, mount
 23319                              <1> 	;mov	edx, mmod
 23320 00004AA2 42                  <1> 	inc	edx ; edx = offset mmod
 23321                              <1> alloc_9: 
 23322 00004AA3 FE02                <1> 	inc	byte [edx] ; superblock modified !
 23323                              <1> 	
 23324                              <1> 	; Allocating a new sector/block (for file) has been completed here.
 23325 00004AA5 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 23326 00004AA8 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0 
 23327 00004AA9 7405                <1> 	jz	short alloc_10 ; not valid (not set)
 23328 00004AAB 48                  <1> 	dec	eax ; Free Blocks
 23329 00004AAC 48                  <1> 	dec	eax ; Free Blocks = Free Blocks - 1
 23330 00004AAD 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax
 23331                              <1> alloc_10:
 23332 00004AB0 E89E100000          <1> 	call	get_system_time
 23333                              <1> 		; eax = current time (as unix epoch time)
 23334                              <1> 	; 30/07/2021
 23335 00004AB5 89435C              <1> 	mov	[ebx+SB.ModifTime], eax
 23336                              <1> 
 23337 00004AB8 8B433C              <1> 	mov	eax, [ebx+SB.FirstFreeBlk] ; allocated block address
 23338 00004ABB FF433C              <1> 	inc	dword [ebx+SB.FirstFreeBlk] 
 23339                              <1> 				; +1, new value of first free block
 23340                              <1> 				; (new search will be started from here)
 23341                              <1> 				; ((it may not be free, no problem))
 23342                              <1> 
 23343                              <1> 	; put free map buffer address in ebx
 23344                              <1> 	; 27/11/2021
 23345                              <1> 	;mov	ebx, [free_map_buffer]
 23346                              <1> 
 23347 00004ABE C3                  <1> 	retn	
 23348                              <1> 
 23349                              <1> 	; 11/02/2022
 23350                              <1> 	; 09/01/2022
 23351                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23352                              <1> free:
 23353                              <1> 	; 12/04/2022 (BugFix)
 23354                              <1> 	; 09/03/2022
 23355                              <1> 	; 11/02/2022
 23356                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23357                              <1> 	; 05/11/2021
 23358                              <1> 	; 29/10/2021 - temporary (simplified code)
 23359                              <1> 	; 14/08/2021
 23360                              <1> 	; 12/06/2021
 23361                              <1> 	; 07/06/2020
 23362                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 23363                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23364                              <1> 	; 07/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 23365                              <1> 	;
 23366                              <1> 	; calculates byte address and bit position for given block number
 23367                              <1> 	; then sets the corresponding bit in the free storage map
 23368                              <1> 	; 
 23369                              <1> 	; INPUTS ->
 23370                              <1> 	;    r1 - block number for a block structured device
 23371                              <1> 	;    cdev - current device 
 23372                              <1> 	; OUTPUTS ->
 23373                              <1> 	;    free storage map is updated
 23374                              <1> 	;    smod is incremented if cdev is root device (fixed disk)
 23375                              <1> 	;    mmod is incremented if cdev is a removable disk 	
 23376                              <1> 	;
 23377                              <1> 	;  (Retro UNIX Prototype : 01/12/2012, UNIXCOPY.ASM)
 23378                              <1>         ;  ((Modified registers: DX, CX))  
 23379                              <1> 
 23380                              <1> 	; 27/11/2021
 23381                              <1> 	; INPUT:
 23382                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 23383                              <1> 	;	eax = disk block/sector number/address (logical)
 23384                              <1> 	; OUTPUT:
 23385                              <1> 	;	ebx = superblock buffer address
 23386                              <1> 	;
 23387                              <1> 	;    Note:	
 23388                              <1> 	;	Free blocks map will be modified and written to it's disk.
 23389                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 23390                              <1> 	;	modification flag will be set; but the superblock 
 23391                              <1> 	;	will not be written to it's disk in this 'free' procedure)
 23392                              <1> 	;
 23393                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp 
 23394                              <1> 
 23395                              <1> 	; 27/11/2021
 23396 00004ABF BB[146D0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 23397 00004AC4 F605[416C0000]01    <1> 	test	byte [cdev], 1
 23398 00004ACB 7405                <1> 	jz	short free_1
 23399 00004ACD BB[1C6F0000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 23400                              <1> free_1: ; 1
 23401                              <1> 	; 11/02/2022
 23402                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 file system compatibility code
 23403 00004AD2 F6436A01            <1> 	test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 23404 00004AD6 740F                <1> 	jz	short free_2 
 23405                              <1> 	; 'read only file system' error
 23406 00004AD8 C705[D86C0000]1E00- <1> 	mov	dword [u.error], ERR_READ_ONLY_FS
 23407 00004AE0 0000                <1>
 23408 00004AE2 E97AE6FFFF          <1> 	jmp	error
 23409                              <1> free_2:
 23410 00004AE7 89C1                <1> 	mov	ecx, eax ; logical sector/block number
 23411 00004AE9 A3[086D0000]        <1> 	mov	[free_map_sector], eax
 23412 00004AEE C1E903              <1> 	shr	ecx, 3	; convert to fbmap byte offset
 23413 00004AF1 C1E80C              <1> 	shr	eax, 12 ; convert to fbmap sector index 
 23414                              <1> 			; (1 fb sector for 4096 sectors)
 23415                              <1> 	;and	cl, ~3	; dword alignment (to backward)
 23416                              <1> 	; 11/02/2022
 23417                              <1> 	;and	ecx, 511 ; convert to offset within fbm buffer
 23418 00004AF4 81E1FC010000        <1> 	and	ecx, 1FCh ; 508, dword aligned offset (32 bit scan)
 23419                              <1> 	;
 23420 00004AFA 890D[006D0000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm buffer
 23421                              <1> 	; 27/11/2021
 23422                              <1> 	; eax = fbm sector index
 23423 00004B00 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 23424                              <1> 			; free blocks map start sector address
 23425                              <1> 	; 09/01/2022
 23426 00004B03 034304              <1> 	add	eax, [ebx+SB.BootSectAddr]
 23427                              <1> 			; + Hidden Sectors
 23428                              <1> 	; 12/04/2022
 23429 00004B06 53                  <1> 	push	ebx ; (*)
 23430                              <1> 	; ebx = superblock address
 23431                              <1> 	; eax = physical sector number
 23432 00004B07 E8800E0000          <1> 	call	dskrd
 23433                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 23434                              <1> 	; eax = physical sector number
 23435                              <1> 	; ebx = (fbm sector) buffer data address
 23436                              <1> 	; 27/11/2021
 23437 00004B0C A3[046D0000]        <1> 	mov	[free_map_index], eax  ; save physical sector address
 23438                              <1> 	; 12/04/2022
 23439 00004B11 8B15[006D0000]      <1> 	mov	edx, [free_map_offset] ; byte position in fbm buffer
 23440                              <1> 	; 11/02/2022
 23441                              <1> 	;(EDX contains -rounded down- dword aligned offset value)
 23442 00004B17 01DA                <1> 	add	edx, ebx ; + (fbm sector) buffer start address
 23443                              <1> 	; 12/04/2022
 23444 00004B19 5B                  <1> 	pop	ebx ; (*) superblock buffer address 	
 23445                              <1> 	;
 23446 00004B1A 29C0                <1> 	sub	eax, eax
 23447 00004B1C A0[086D0000]        <1> 	mov	al, [free_map_sector] ; logical sector number
 23448                              <1> 	;and	al, 7
 23449                              <1> 	; 11/02/2022
 23450 00004B21 241F                <1> 	and	al, 31 ; 32 bit fbm scan (with dword aligned offset)
 23451                              <1> 
 23452                              <1> 	; al = bit offset in fbm allocation byte
 23453                              <1> 	; edx = buffer address (start+offset)
 23454                              <1> 	; [free_map_offset] = byte position on fbm
 23455                              <1> 	; 27/11/2021
 23456 00004B23 0FAB02              <1> 	bts	[edx], eax  ; copy value of bit position in eax to cf
 23457                              <1> 			    ; then set same bit position at [edx]
 23458 00004B26 7305                <1> 	jnc	short free_3 ; it was allocated sector
 23459                              <1> 
 23460                              <1> 	; already free sector !? 
 23461                              <1> 	; (nonsence or defective fs)
 23462                              <1> 
 23463 00004B28 30C0                <1> 	xor	al, al ; 0  ; eax = 0
 23464 00004B2A 48                  <1> 	dec	eax ; 0FFFFFFFFh
 23465                              <1> 	;mov	[ebx+SB.FreeBlocks], eax 
 23466                              <1> 		; invalidate free blocks count
 23467 00004B2B EB18                <1> 	jmp	short free_5
 23468                              <1> free_3:
 23469                              <1> 	; 27/11/2021
 23470 00004B2D 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 23471 00004B30 40                  <1> 	inc	eax
 23472                              <1> 	;jz	short free_4 ; 0FFFFFFFFh -> 0 (invalid!)
 23473                              <1> 	; 09/03/2022
 23474 00004B31 7501                <1> 	jnz	short free_4
 23475 00004B33 48                  <1> 	dec	eax  ; 0 -> 0FFFFFFFFh (invalid!)
 23476                              <1> free_4: 
 23477 00004B34 50                  <1> 	push	eax ; * ; number of free blocks 
 23478                              <1> 	;mov	eax, [free_map_index] ; fbm sector index
 23479                              <1> 	;add	eax, [ebx+SB.FreeMapAddr] 
 23480                              <1> 			; free blocks map start sector address
 23481                              <1> 	;add	eax, [ebx+SB.BootSectAddr]
 23482                              <1> 	;		; + Hidden Sectors
 23483 00004B35 A1[046D0000]        <1> 	mov	eax, [free_map_index] ; restore physical sector address
 23484                              <1> 	; eax = physical sector number
 23485 00004B3A E8B10E0000          <1> 	call	wslot
 23486                              <1> 	; ebx = buffer data address (write operation bit is set)
 23487                              <1> 	; eax = physical sector number
 23488                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 23489                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 23490                              <1> 
 23491 00004B3F E8B90E0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 23492                              <1> 		      ; (at the beginning/head of the buffer chain)
 23493                              <1> 
 23494                              <1> 	; if we are here, buffer has been written to disk successfully 
 23495                              <1> 	; (otherwise cpu would jump to 'error' address)
 23496 00004B44 58                  <1> 	pop	eax ; *  ; number of free blocks 
 23497                              <1> free_5:
 23498                              <1> 	; eax = number of free blocks 
 23499                              <1> 	;
 23500                              <1> 	; set superblock modified flag
 23501 00004B45 BA[566C0000]        <1> 	mov	edx, smod
 23502 00004B4A BB[146D0000]        <1> 	mov	ebx, systm
 23503 00004B4F F605[416C0000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 23504 00004B56 7406                <1> 	jz	short free_6 ; no, root device
 23505                              <1> 	; yes, mounted device
 23506 00004B58 BB[1C6F0000]        <1> 	mov	ebx, mount
 23507                              <1> 	;mov	edx, mmod
 23508 00004B5D 42                  <1> 	inc	edx ; edx = offset mmod
 23509                              <1> free_6: 
 23510 00004B5E 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax 
 23511                              <1> 
 23512 00004B61 A1[086D0000]        <1> 	mov	eax, [free_map_sector] ; logical sector number
 23513 00004B66 3B433C              <1> 	cmp	eax, [ebx+SB.FirstFreeBlk]
 23514 00004B69 7303                <1> 	jnb	short free_7
 23515 00004B6B 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 23516                              <1> free_7:
 23517 00004B6E FE02                <1> 	inc	byte [edx] ; superblock modified !
 23518 00004B70 C3                  <1> 	retn
 23519                              <1> 	
 23520                              <1> iget:
 23521                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23522                              <1> 	; 30/11/2021
 23523                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 23524                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23525                              <1> 	; 07/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 23526                              <1> 	;
 23527                              <1> 	; get a new i-node whose i-number in r1 and whose device is in cdev
 23528                              <1> 	;
 23529                              <1> 	; ('iget' returns current i-number in r1, if input value of r1 is 0)
 23530                              <1> 	; 
 23531                              <1> 	; INPUTS ->
 23532                              <1> 	;    ii - current i-number, rootdir
 23533                              <1> 	;    cdev - new i-node device
 23534                              <1> 	;    idev - current i-node device
 23535                              <1> 	;    imod - current i-node modified flag
 23536                              <1> 	;    mnti - cross device file i-number
 23537                              <1> 	;    r1 - i-numbe rof new i-node
 23538                              <1> 	;    mntd - mountable device number		
 23539                              <1> 	; 	 
 23540                              <1> 	; OUTPUTS ->
 23541                              <1> 	;    cdev, idev, imod, ii, r1
 23542                              <1> 	;
 23543                              <1> 	; ((AX = R1)) input/output
 23544                              <1> 	;
 23545                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 23546                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 23547                              <1> 
 23548                              <1> 	; 22/11/2021
 23549                              <1> 	;;mov	dl, [cdev] ; 18/07/2013
 23550                              <1> 	;;mov	dh, [idev] ; 07/08/2013
 23551                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 23552                              <1> 	;mov	dh, [cdev]
 23553                              <1> 	;mov	dl, [idev]
 23554 00004B71 668B15[406C0000]    <1> 	mov	dx, [idev] ; [idev] in dl, [cdev] in dh
 23555                              <1> 	;
 23556                              <1> 	; 22/11/2021
 23557 00004B78 25FFFF0000          <1> 	and	eax, 0FFFFh
 23558 00004B7D 3B05[3C6C0000]      <1> 	cmp 	eax, [ii]
 23559                              <1> 		; cmp r1,ii / r1 = i-number of current file
 23560 00004B83 7504                <1> 	jne 	short iget_1
 23561                              <1> 		; bne 1f
 23562 00004B85 38F2                <1> 	cmp	dl, dh
 23563                              <1> 		; cmp idev,cdev
 23564                              <1> 			  ; / is device number of i-node = current device
 23565 00004B87 746C                <1>         je	short iget_5
 23566                              <1> 	;	; beq 2f
 23567                              <1> 	; 14/08/2021
 23568                              <1> iget_1: ; 1:
 23569 00004B89 30DB                <1> 	xor	bl, bl
 23570 00004B8B 381D[546C0000]      <1> 	cmp	[imod], bl ; 0	
 23571                              <1> 		; tstb imod / has i-node of current file
 23572                              <1> 			  ; / been modified i.e., imod set
 23573 00004B91 7628                <1> 	jna	short iget_2
 23574                              <1> 		; beq 1f
 23575 00004B93 881D[546C0000]      <1> 	mov	[imod], bl ; 0
 23576                              <1> 		; clrb imod / if it has, 
 23577                              <1> 			   ; / we must write the new i-node out on disk
 23578                              <1> 	; 22/11/2021 (32 bit push-pop)
 23579 00004B99 50                  <1> 	push	eax ; *
 23580                              <1> 		; mov r1,-(sp)
 23581 00004B9A 52                  <1> 	push	edx ; **
 23582                              <1> 		; mov cdev,-(sp)
 23583 00004B9B A1[3C6C0000]        <1> 	mov	eax, [ii]
 23584                              <1> 		; mov ii,r1
 23585                              <1> 	;mov	dh, [idev]
 23586                              <1> 	;mov	[cdev], dh
 23587                              <1> 	; 09/01/2022
 23588 00004BA0 8815[416C0000]      <1> 	mov	[cdev], dl  ; dl = [idev]
 23589                              <1> 		; mov idev,cdev
 23590 00004BA6 FEC3                <1> 	inc	bl ; 1
 23591                              <1> 	; 31/07/2013
 23592 00004BA8 881D[F86C0000]      <1> 	mov     [rw], bl ; 1 == write 
 23593                              <1> 	;;28/07/2013 rw -> u.rw
 23594                              <1>         ;;mov   [u.rw], bl ; 1 == write
 23595 00004BAE E843000000          <1> 	call	icalc
 23596                              <1> 		; jsr r0,icalc; 1
 23597 00004BB3 5A                  <1> 	pop	edx ; **
 23598 00004BB4 8835[416C0000]      <1> 	mov	[cdev], dh ; 22/11/2021
 23599                              <1> 		; mov (sp)+,cdev
 23600 00004BBA 58                  <1> 	pop	eax ; *
 23601                              <1> 		; mov (sp)+,r1
 23602                              <1> iget_2: ; 1:
 23603                              <1> 	;and	ax, ax
 23604 00004BBB 21C0                <1> 	and	eax, eax ; 22/11/2021 (32 bit inode number)
 23605                              <1> 		; tst r1 / is new i-number non zero
 23606 00004BBD 7431                <1> 	jz	short iget_4 ; 2f
 23607                              <1> 		; beq 2f / branch if r1=0
 23608                              <1> 
 23609                              <1> 	;mov 	dh, [cdev]
 23610 00004BBF 08F6                <1> 	or	dh, dh ; 22/11/2021
 23611                              <1> 		; tst cdev / is the current device number non zero
 23612                              <1> 			 ; / (i.e., device =/ drum)
 23613 00004BC1 7515                <1> 	jnz	short iget_3 ;  1f
 23614                              <1> 		; bne 1f / branch 1f cdev =/ 0  ;; (cdev != 0)
 23615                              <1> 	; 22/11/2021
 23616 00004BC3 3B05[4A6C0000]      <1> 	cmp	eax, [mnti]
 23617                              <1> 	;cmp	ax, [mnti]			
 23618                              <1> 		; cmp r1,mnti / mnti is the i-number of the cross device
 23619                              <1> 			    ; / file (root directory of mounted device)
 23620 00004BC9 750D                <1> 	jne	short iget_3 ; 1f
 23621                              <1> 		; bne 1f
 23622                              <1>         ;mov    bl, [mntd]
 23623 00004BCB FEC6                <1> 	inc	dh ; mov dh, 1 ; 22/11/2021
 23624 00004BCD 8835[416C0000]      <1>         mov	[cdev], dh ; 22/11/2021
 23625                              <1> 		; mov mntd,cdev / make mounted device the current device
 23626                              <1> 	; 22/11/2021
 23627 00004BD3 A1[466C0000]        <1> 	mov	eax, [rootdir] ; rootdir = 1 (for runix v2 file system)
 23628                              <1> 	;mov	ax, [rootdir]
 23629                              <1> 		; mov rootdir,r1
 23630                              <1> iget_3: ; 1:
 23631                              <1> 	; 22/11/2021
 23632 00004BD8 A3[3C6C0000]        <1> 	mov	[ii], eax ; 32 bit inode number
 23633                              <1> 	;mov	[ii], ax
 23634                              <1> 		; mov r1,ii
 23635                              <1> 	; 30/11/2021
 23636 00004BDD 8835[406C0000]      <1> 	mov	[idev], dh ; cdev 
 23637                              <1> 	;mov	[idev], dl ; cdev
 23638                              <1> 		; mov cdev,idev
 23639 00004BE3 30DB                <1> 	xor	bl, bl
 23640                              <1>         ; 31/07/2013
 23641 00004BE5 881D[F86C0000]      <1> 	mov     [rw], bl ; 0 == read 
 23642                              <1> 	;;28/07/2013 rw -> u.rw       
 23643                              <1>         ;;mov   [u.rw], bl ; 0 = read
 23644 00004BEB E806000000          <1> 	call	icalc
 23645                              <1> 		; jsr r0,icalc; 0 / read in i-node ii
 23646                              <1> iget_4: ; 2:
 23647                              <1> 	; 22/11/2021
 23648 00004BF0 A1[3C6C0000]        <1> 	mov	eax, [ii]
 23649                              <1> 	;mov	ax, [ii]
 23650                              <1> 		; mov ii,r1
 23651                              <1> iget_5:
 23652 00004BF5 C3                  <1> 	retn
 23653                              <1> 		; rts r0
 23654                              <1> 
 23655                              <1> icalc:
 23656                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 23657                              <1> 	; 28/11/2021
 23658                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification 
 23659                              <1> 	; 02/07/2015
 23660                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23661                              <1> 	; 07/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 23662                              <1> 	;
 23663                              <1> 	; calculate physical block number from i-number then
 23664                              <1> 	; read or write that block
 23665                              <1> 	;
 23666                              <1> 	; 'icalc' is called from 'iget'
 23667                              <1> 	;
 23668                              <1> 	; for original unix v1:
 23669                              <1> 	; / i-node i is located in block (i+31.)/16. and begins 32.*
 23670                              <1>        	; / (i+31.) mod 16. bytes from its start
 23671                              <1> 	;
 23672                              <1> 	; for retro unix 8086 v1:
 23673                              <1> 	;  i-node is located in block (i+47)/16 and
 23674                              <1> 	;  begins 32*(i+47) mod 16 bytes from its start
 23675                              <1> 	;
 23676                              <1> 	; INPUTS ->
 23677                              <1> 	;    r1 - i-number of i-node
 23678                              <1> 	; 	 
 23679                              <1> 	; OUTPUTS ->
 23680                              <1> 	;    inode r/w
 23681                              <1> 	;
 23682                              <1> 	; ((AX = R1)) input
 23683                              <1> 	;
 23684                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 23685                              <1>         ;  ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))  
 23686                              <1> 	;
 23687                              <1> 
 23688                              <1> 	; 28/11/2021
 23689                              <1> 	;cmp	byte [idev], 0 ; [cdev] = [idev]
 23690 00004BF6 803D[416C0000]00    <1> 	cmp	byte [cdev], 0
 23691 00004BFD 7607                <1> 	jna	short icalc_0r
 23692 00004BFF BD[1C6F0000]        <1> 	mov	ebp, mount  ; mounted file system's superblock 
 23693 00004C04 EB05                <1> 	jmp	short icalc_0m
 23694                              <1> icalc_0r:
 23695                              <1> 	; 28/11/2021
 23696 00004C06 BD[146D0000]        <1> 	mov	ebp, systm  ; root file system's superblock 
 23697                              <1> icalc_0m:
 23698                              <1> 	; 22/11/2021
 23699                              <1> 	;mov	edx, eax
 23700 00004C0B 8B15[3C6C0000]      <1> 	mov	edx, [ii] ; 32 bit inode number
 23701 00004C11 8B4528              <1> 	mov	eax, [ebp+SB.InodeTblAddr] ; inode table base address
 23702                              <1> 	;
 23703 00004C14 4A                  <1> 	dec	edx ; 0 based inode number 
 23704                              <1> 		    ; (inode index in inode table)
 23705 00004C15 52                  <1> 	push	edx ; *
 23706 00004C16 C1EA03              <1> 	shr	edx, 3
 23707 00004C19 7402                <1> 	jz	short icalc_0t ; 0 for inodes 1 to 8
 23708 00004C1B 01D0                <1> 	add	eax, edx
 23709                              <1> icalc_0t:
 23710                              <1> 	; 09/01/2022
 23711                              <1> 	; eax = locical block/sector number 
 23712 00004C1D 034504              <1> 	add	eax, [ebp+SB.BootSectAddr]
 23713                              <1> 	; eax = physical block/sector number 
 23714 00004C20 E8670D0000          <1> 	call	dskrd
 23715                              <1> 		; jsr r0,dskrd / read in block containing i-node i.
 23716                              <1> 	; 31/07/2013
 23717 00004C25 803D[F86C0000]00    <1>         cmp     byte [rw], 0 ; Retro Unix 8086 v1 feature !
 23718                              <1> 	;; 28/07/2013 rw -> u.rw
 23719                              <1>         ;;cmp	byte [u.rw], 0 ; Retro Unix 8086 v1 feature !
 23720                              <1> 		; tst (r0)
 23721 00004C2C 7605                <1> 	jna	short icalc_1
 23722                              <1> 		; beq 1f / branch to wslot when argument
 23723                              <1> 		       ; / in icalc call = 1
 23724                              <1> 	; eAX = r1 = block number
 23725 00004C2E E8BD0D0000          <1> 	call	wslot
 23726                              <1> 		; jsr r0,wslot / set up data buffer for write
 23727                              <1> 			     ; / (will be same buffer as dskrd got)
 23728                              <1> 	; EBX = r5 points to first word in data area for this block
 23729                              <1> icalc_1: ; 1:
 23730 00004C33 5A                  <1> 	pop	edx ; *
 23731                              <1> 	; 22/11/2021
 23732 00004C34 83E207              <1> 	and 	edx, 07h ; 8 inodes per inode table sector
 23733 00004C37 C1E206              <1> 	shl 	edx, 6 ; * 64 (inode size)
 23734                              <1> 	; edx = 64 * (mod(inodenumber-1)/8)
 23735 00004C3A 89DE                <1> 	mov	esi, ebx  ; ebx points to 1st word of the buffer
 23736 00004C3C 01D6                <1> 	add	esi, edx  ; edx is inode offset in the buffer
 23737                              <1>           	; eSI (r5) points to first word in i-node i.	
 23738                              <1> 		; mov (sp)+,mq / calculate offset in data buffer; 
 23739                              <1> 			     ; / 32.*(i+31.)mod16
 23740                              <1> 		; mov $5,lsh / for i-node i.
 23741                              <1> 		; add mq,r5 / r5 points to first word in i-node i.
 23742 00004C3E BF[E4670000]        <1> 	mov	edi, inode
 23743                              <1> 		; mov $inode,r1 / inode is address of first word 
 23744                              <1> 			      ; / of current i-node
 23745                              <1> 	;mov 	ecx, 8 ; 02/07/2015 (32 bit modification)
 23746                              <1> 	;	; mov $16.,r3
 23747                              <1> 	; 28/11/2021
 23748 00004C43 29C9                <1> 	sub	ecx, ecx
 23749 00004C45 B110                <1> 	mov	cl, 16 ; Retro UNIX 386 v2 inode size = 64 bytes
 23750                              <1> 	; 31/07/2013
 23751 00004C47 382D[F86C0000]      <1>   	cmp     [rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 23752                              <1>        ;;28/07/2013 rw -> u.rw                 
 23753                              <1>        ;;cmp    [u.rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 23754                              <1> 		; tst (r0)+ / branch to 2f when argument in icalc call = 0
 23755 00004C4D 7609                <1> 	jna	short icalc_3
 23756                              <1> 		; beq 2f / r0 now contains proper return address 
 23757                              <1> 		       ; / for rts r0
 23758                              <1> icalc_2: ; 1:
 23759 00004C4F 87F7                <1> 	xchg 	esi, edi
 23760                              <1> 	; overwrite old i-node (in buffer to be written)
 23761 00004C51 F3A5                <1> 	rep 	movsd
 23762                              <1> 		; mov (r1)+,(r5)+ / over write old i-node
 23763                              <1> 		; dec r3
 23764                              <1> 		; bgt 1b
 23765                              <1> 	;call	dskwr
 23766                              <1> 	;	; jsr r0,dskwr / write inode out on device
 23767                              <1> 	;retn
 23768                              <1> 	;	; rts r0
 23769                              <1> 	; 28/11/2021
 23770 00004C53 E9A50D0000          <1> 	jmp	dskwr
 23771                              <1> icalc_3: ; 2:
 23772                              <1> 	; copy new i-node into inode area of (core) memory
 23773 00004C58 F3A5                <1> 	rep 	movsd
 23774                              <1> 		; mov (r5)+,(r1)+ / read new i-node into 
 23775                              <1> 		                ; / "inode" area of core
 23776                              <1> 		; dec r3
 23777                              <1> 		; bgt 2b
 23778 00004C5A C3                  <1> 	retn
 23779                              <1> 		; rts r0
 23780                              <1> 
 23781                              <1> access:
 23782                              <1> 	; 13/03/2022
 23783                              <1> 	; 25/12/2021
 23784                              <1> 	; 19/12/2021
 23785                              <1> 	; 28/11/2021
 23786                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 23787                              <1> 	; 31/10/2021 - temporary (simplified code)
 23788                              <1> 	; 14/06/2021
 23789                              <1> 	; 02/05/2021
 23790                              <1> 	; 27/03/2021
 23791                              <1> 	; 26/03/2021
 23792                              <1> 	; 25/03/2021
 23793                              <1> 	; 23/03/2021 (Retro UNIX 386 v2 - Beginning)
 23794                              <1> 	;	((ref: unix v7 source - fio.c))
 23795                              <1> 	; ref: INODE STRUCTURE of Retro UNIX v2 file system
 23796                              <1> 	;	07/02/2020, 'RETRO UNIX v2 Inodes.pdf'
 23797                              <1> 	;	 
 23798                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 23799                              <1> 	; 24/04/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 23800                              <1> 	;
 23801                              <1> 	; check whether user is owner of file or user has read or write
 23802                              <1> 	; permission (based on i.flgs).
 23803                              <1> 	;
 23804                              <1> 	; INPUTS ->
 23805                              <1> 	;    r1 - i-number of file
 23806                              <1> 	;    u.uid
 23807                              <1> 	; arg0 -> (owner flag mask)	 		
 23808                              <1> 	;     Retro UNIX 8086 v1 feature -> owner flag mask in DL (DX) 	 
 23809                              <1> 	; OUTPUTS ->
 23810                              <1> 	;    inode (or jump to error)
 23811                              <1> 	;
 23812                              <1> 	; ((AX = R1)) input/output
 23813                              <1> 	;
 23814                              <1> 	;  ((Modified registers: eCX, eBX, eDX, eSI, eDI, eBP))
 23815                              <1> 
 23816                              <1> 	; 26/03/2021
 23817                              <1> 	; INPUT:
 23818                              <1> 	;	eax = inode number (ax)
 23819                              <1> 	;	 dx = mode (IEXEC, IREAD or IWRITE) 
 23820                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 23821                              <1> 	;	
 23822                              <1> 	; OUTPUT:
 23823                              <1> 	;	inode (or jump to error)
 23824                              <1> 	;	eax (ax) = [ii] = inode number
 23825                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 23826                              <1> 	;
 23827                              <1> 	; Modified registers: (eax), ebx, ecx, edx, esi, edi, ebp
 23828                              <1> 	;
 23829                              <1> 	; IREAD	 equ 100h ; read permission flag, owner
 23830                              <1> 	; IWRITE equ 80h  ; write permission flag, owner
 23831                              <1> 	; IEXEC	 equ 40h  ; execute permission flag, owner	 
 23832                              <1> 		
 23833                              <1> 	; 23/03/2021
 23834 00004C5B 52                  <1> 	push	edx ; save flag (DX)
 23835                              <1> 	;push	dx  ; save flag (DL)
 23836 00004C5C E810FFFFFF          <1> 	call	iget
 23837                              <1> 		; jsr r0,iget / read in i-node for current directory
 23838                              <1> 			    ; / (i-number passed in r1)
 23839                              <1> 	;;mov	cl, [i.flgs]
 23840                              <1> 	;;	; mov i.flgs,r2
 23841                              <1> 	; 23/03/2021
 23842                              <1> 	;mov	cx, [i.iflgs]	
 23843                              <1> 
 23844                              <1> 	;;pop	dx  ; restore flag (DL)
 23845                              <1> 	; 23/03/2021
 23846 00004C61 5A                  <1> 	pop	edx ; restore flag (DX)
 23847                              <1> 
 23848                              <1> 	; 28/11/2021 (iget will not return here if there is an error)
 23849                              <1> 	; 31/10/2021
 23850                              <1> 	;jc	short access_5
 23851                              <1> 
 23852                              <1> 	; 31/10/2021
 23853                              <1> 	; Note: If eax input is same with [mnti], 'iget' will change
 23854                              <1> 	; [cdev] to 1 and eax will be 1 (root dir of mounted fs) 
 23855                              <1> 
 23856                              <1> 	; 27/03/2021
 23857                              <1> 	; 23/03/2021
 23858                              <1> 	; (check if it is write permission flag)
 23859 00004C62 6681FA8000          <1> 	cmp	dx, 80h ; IWRITE
 23860 00004C67 775E                <1> 	ja	short access_r	; IREAD = 100h (owner)
 23861 00004C69 722B                <1> 	jb	short access_x	; IEXEC = 40h (owner)
 23862                              <1> 	; IWRITE (80h)
 23863                              <1> access_w:
 23864                              <1> 	; 23/03/2021
 23865                              <1> 	; ((ref: Retro UNIX 386 v2, 'ux.s', 'ldrv' structure))
 23866                              <1> 	;mov	bl, [idev]
 23867                              <1> 	;call	getfs
 23868                              <1>  	;movzx	ebx, byte [idev]  ; logical drive number
 23869                              <1> 	;shl	bx, 6 ; * 64	  ; of current inode	
 23870                              <1> 	;add	ebx, ldrvtable	
 23871                              <1> 	;;test	byte [ebx+ldrv.pflags], 01h ; read only fs flag
 23872                              <1> 	;;jz	short access_0
 23873                              <1> 	;; 14/06/2021
 23874                              <1> 	; 14/06/2021
 23875                              <1> 	; check block device (fs) if it is read only fs or not ? 
 23876                              <1> 	;mov	edi, [ebx+ldrv.superblk]
 23877                              <1> 	;test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 23878                              <1> 	;jz	short access_0
 23879                              <1> 	; 31/10/2021
 23880 00004C6B 803D[416C0000]01    <1> 	cmp	byte [cdev], 1
 23881 00004C72 7207                <1> 	jb	short access_7 ; [cdev] = 0
 23882                              <1> 	; [cdev] = 1
 23883                              <1> 	; 28/11/2021
 23884 00004C74 BF[1C6F0000]        <1> 	mov	edi, mount ; mounted file system's superblock buffer
 23885 00004C79 EB05                <1> 	jmp	short access_8
 23886                              <1> access_7:
 23887                              <1> 	; 28/11/2021
 23888 00004C7B BF[146D0000]        <1> 	mov	edi, systm ; root file system's superblock buffer
 23889                              <1> access_8:
 23890 00004C80 F6476A01            <1> 	test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 23891 00004C84 7441                <1> 	jz	short access_0
 23892                              <1> 
 23893                              <1> 	; 23/03/2021
 23894                              <1> 	;mov	dword [u.error], ERR_READ_ONLY_FS
 23895                              <1> 	;		; 'read only file system !' error
 23896                              <1> 	;jmp	error
 23897                              <1> 
 23898                              <1> 	; 19/12/2021
 23899 00004C86 F605[E5670000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file ?
 23900 00004C8D 7438                <1> 	jz	short access_0  ; no, device file
 23901                              <1> 
 23902                              <1> 	; 31/10/2021
 23903 00004C8F B81E000000          <1> 	mov	eax, ERR_READ_ONLY_FS
 23904                              <1> 			; 'read only file system !' error
 23905                              <1> 	; 27/03/2021
 23906 00004C94 EB27                <1> 	jmp	short access_5
 23907                              <1> 
 23908                              <1> 	; check block device (fs) if it is read only fs or not ? 
 23909                              <1> 
 23910                              <1> 	;mov	dh, [u.uid]
 23911                              <1> 	;cmp	dh, [i.uid]
 23912                              <1> 	;	; cmpb i.uid,u.uid / is user same as owner of file
 23913                              <1> 	;jne	short access_1
 23914                              <1> 		; bne 1f / no, then branch
 23915                              <1> access_x:
 23916                              <1> 	; IEXEC (40h)
 23917                              <1> 	; 27/03/2021
 23918 00004C96 668B1D[E4670000]    <1> 	mov	bx, [i.flgs]
 23919 00004C9D F6C780              <1> 	test	bh, 80h ; regular file ?
 23920 00004CA0 7416                <1> 	jz	short access_4 ; not executable file !
 23921 00004CA2 F6C740              <1> 	test	bh, 40h	; directory ?
 23922 00004CA5 7511                <1> 	jnz	short access_4 ; not executable file !
 23923 00004CA7 668B0D[B66C0000]    <1> 	mov	cx, [u.uid]
 23924 00004CAE 6609C9              <1> 	or	cx, cx
 23925 00004CB1 7520                <1> 	jnz	short access_3 ; (restricted user)
 23926                              <1> 	; (super user)
 23927                              <1> 	;test	[i.flgs], dl ; execute permission for owner
 23928                              <1> 	;test	byte [i.flgs], 49h ; for owner, group, others
 23929 00004CB3 F6C349              <1> 	test	bl, 49h ; exec perm for owner, group, others
 23930 00004CB6 7549                <1> 	jnz	short access_2
 23931                              <1> access_4:
 23932                              <1> 	; 31/10/2021
 23933 00004CB8 B816000000          <1> 	mov	eax, ERR_NOT_EXECUTABLE
 23934                              <1> 			; 'not executable file !' error
 23935                              <1> 	; 26/03/2021
 23936                              <1> ;;sysexec_not_exf:
 23937                              <1> ;	mov	dword [u.error], ERR_NOT_EXECUTABLE
 23938                              <1> ;			; 'not executable file !' error
 23939                              <1> ;access_5:
 23940                              <1> ;	jmp	error
 23941                              <1> 	
 23942                              <1> 	; 31/10/2021
 23943                              <1> access_5:
 23944 00004CBD A3[D86C0000]        <1> 	mov	[u.error], eax
 23945 00004CC2 E99AE4FFFF          <1> 	jmp	error
 23946                              <1> 
 23947                              <1> access_r:
 23948                              <1> 	; 27/03/2021
 23949                              <1> access_0:
 23950                              <1> 	; 23/03/2021
 23951 00004CC7 668B0D[B66C0000]    <1> 	mov	cx, [u.uid]
 23952 00004CCE 6609C9              <1> 	or	cx, cx ; 0 ; root ?
 23953                              <1> 	;jz	short access_2 ; yes
 23954                              <1> 	; 25/12/2021
 23955 00004CD1 741E                <1> 	jz	short access_1 ; yes
 23956                              <1> access_3:
 23957                              <1> 	; 13/03/2022
 23958 00004CD3 663B0D[E8670000]    <1> 	cmp	cx, [i.uid] ; owner ?
 23959 00004CDA 7415                <1> 	je	short access_1 ; yes
 23960                              <1> 	;; owner ?
 23961 00004CDC 8A1D[EA670000]      <1> 	mov	bl, [i.gid]
 23962                              <1> 	;cmp	cx, [i.uid]
 23963                              <1> 	;;je	short access_1
 23964                              <1> 	;; 02/05/2021
 23965                              <1> 	;jne	short access_6
 23966                              <1> 	; 13/03/2022
 23967                              <1> 	; same group ?
 23968 00004CE2 66C1EA03            <1> 	shr	dx, 3
 23969                              <1> 	; check owner's group number/ID
 23970 00004CE6 3A1D[BA6C0000]      <1> 	cmp	bl, [u.gid] ; same group number/ID ?
 23971 00004CEC 7403                <1> 	je	short access_1 ; yes
 23972                              <1> 	; one of others
 23973                              <1> 	;shr	dx, 6
 23974                              <1> 	;jmp	short access_1 ; others
 23975                              <1> 	; 13/03/2022
 23976                              <1> 	; one of others
 23977 00004CEE C0EA03              <1> 	shr	dl, 3
 23978                              <1> ;	; 13/03/2022
 23979                              <1> ;	jmp	short access_1 ; others
 23980                              <1> ;access_6:
 23981                              <1> ;	;shr	cl, 2
 23982                              <1> ;	;	; asrb r2 / shift owner read write bits into non owner
 23983                              <1> ;	;	;       ; / read/write bits
 23984                              <1> ;	;	; asrb r2
 23985                              <1> ;
 23986                              <1> ;	; 23/03/2021
 23987                              <1> ;	; same group ?
 23988                              <1> ;	shr	dx, 3
 23989                              <1> ;	;mov	cl, [u.gid]
 23990                              <1> ;	;cmp	cl, [i.gid]
 23991                              <1> ;	;je	short access_1
 23992                              <1> ;	; 02/05/2021
 23993                              <1> ;	cmp	bl, [u.gid]
 23994                              <1> ;	je	short access_1 ; same group, different owner
 23995                              <1> ;
 23996                              <1> ;	; others
 23997                              <1> ;	;shr	dx, 3
 23998                              <1> ;	shr	dl, 3
 23999                              <1> ;	;jmp	short access_1	
 24000                              <1> ;
 24001                              <1> ;;access_1: ; 1:
 24002                              <1> ;	;and	cl, dl
 24003                              <1> ;	;	; bit r2,(r0)+ / test read-write flags against argument
 24004                              <1> ;	;		     ; / in access call
 24005                              <1> ;	;jnz	short access_2
 24006                              <1> ;	;	; bne 1f
 24007                              <1> ;	
 24008                              <1> ;	;or	dh, dh	; super user (root) ?
 24009                              <1> ;	;	; tstb u.uid
 24010                              <1> ;	;jz	short access_2 ; yes, super user
 24011                              <1> ;	;;jnz	error
 24012                              <1> ;	;	; beq 1f
 24013                              <1> ;	;	; jmp error
 24014                              <1> ;	
 24015                              <1> ;	;mov	dword [u.error], ERR_FILE_ACCESS 
 24016                              <1> ;	;		; 'permission denied !' error
 24017                              <1> ;	;jmp	error
 24018                              <1> 
 24019                              <1> access_1:
 24020                              <1> 	; 23/03/2021
 24021 00004CF1 668515[E4670000]    <1> 	test	dx, [i.flgs]
 24022 00004CF8 7507                <1> 	jnz	short access_2
 24023                              <1> 
 24024                              <1> 	;; r/w permission error
 24025                              <1> 	;mov	dword [u.error], ERR_FILE_ACCESS 
 24026                              <1> 	;		; 'permission denied !' error
 24027                              <1> 	;;jmp	error
 24028                              <1> 
 24029                              <1> 	; 31/10/2021
 24030 00004CFA B80B000000          <1> 	mov	eax, ERR_FILE_ACCESS 
 24031                              <1> 			; 'permission denied !' error
 24032                              <1> 	; 27/03/2021
 24033 00004CFF EBBC                <1> 	jmp	short access_5
 24034                              <1> 
 24035                              <1> access_2: ; 1:
 24036                              <1> 	;; DL = flags
 24037                              <1> 	;retn
 24038                              <1> 	;	; rts r0
 24039                              <1> 	; 27/03/2021
 24040                              <1> 	; DX = flag (100h-20h-04h or 80h-10h-02h or 40h-08h-01h)
 24041 00004D01 C3                  <1> 	retn
 24042                              <1> 
 24043                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 24044                              <1> %if 0
 24045                              <1> 
 24046                              <1> setimod:
 24047                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24048                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 24049                              <1> 	;
 24050                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 24051                              <1> 	; the inode has been modified. Also puts the time of modification
 24052                              <1> 	; into the inode.
 24053                              <1> 	;
 24054                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 24055                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 24056                              <1> 	;
 24057                              <1> 	
 24058                              <1> 	;push 	edx
 24059                              <1> 	push	eax
 24060                              <1> 
 24061                              <1> 	mov 	byte [imod], 1
 24062                              <1> 		; movb $1,imod / set current i-node modified bytes
 24063                              <1> 	; Erdogan Tan 14-7-2012
 24064                              <1> 	call 	epoch
 24065                              <1> 		 ; mov s.time,i.mtim 
 24066                              <1> 			    ; / put present time into file modified time
 24067                              <1> 		 ; mov s.time+2,i.mtim+2
 24068                              <1> 
 24069                              <1> 	mov 	[i.mtim], eax
 24070                              <1> 	
 24071                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 24072                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 24073                              <1> 	cmp	dword [i.ctim], 0
 24074                              <1> 	jnz	short setimod_ok
 24075                              <1> 
 24076                              <1> 	mov 	[i.ctim], eax
 24077                              <1> 
 24078                              <1> setimod_ok: ; 31/07/2013
 24079                              <1> 	pop	eax
 24080                              <1> 	;pop	edx
 24081                              <1> 	
 24082                              <1> 	retn
 24083                              <1> 		; rts r0
 24084                              <1> %endif
 24085                              <1> 
 24086                              <1> setimod:
 24087                              <1> 	; 12/01/2022 - Retro UNIX 386 v1.2
 24088                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 24089                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24090                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 24091                              <1> 	;
 24092                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 24093                              <1> 	; the inode has been modified. Also puts the time of modification
 24094                              <1> 	; into the inode.
 24095                              <1> 	;
 24096                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 24097                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 24098                              <1> 	;
 24099                              <1> 
 24100                              <1> 	; Reference:
 24101                              <1> 	; 25/01/2020 - 'UNIXHDCP.ASM', 'setimod' procedure
 24102                              <1> 	;	(Retro UNIX 386 v2 file system installation utility)
 24103                              <1> 
 24104                              <1> 	; 25/05/2020
 24105                              <1> 	;
 24106                              <1> 	; INPUT:
 24107                              <1> 	;	none
 24108                              <1> 	; OUTPUT:
 24109                              <1> 	;	inode times and [imod] will be set
 24110                              <1> 	;	      ([imodx] will be reset)
 24111                              <1> 	;	cf = 0 	
 24112                              <1> 
 24113                              <1> 	; Modified registers: ecx, (edx)?
 24114                              <1> 	
 24115                              <1> 	;push 	edx
 24116 00004D02 50                  <1> 	push	eax
 24117                              <1> 
 24118 00004D03 C605[546C0000]01    <1> 	mov 	byte [imod], 1
 24119                              <1> 		; movb $1,imod / set current i-node modified bytes
 24120                              <1> 
 24121                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 24122 00004D0A A1[20680000]        <1> 	mov	eax, [i.ctim] ; inode (file) creation time
 24123 00004D0F 21C0                <1> 	and	eax, eax
 24124 00004D11 7518                <1> 	jnz	short setimod_4
 24125                              <1> 
 24126                              <1> 	; New file
 24127                              <1> setimod_1:
 24128                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 by Erdogan Tan
 24129                              <1> 	;	 (Modified UNIX v7 inode and new FS construction) 	
 24130                              <1> 	;
 24131 00004D13 E83B0E0000          <1> 	call	get_system_time ; get current (unix epoch) time
 24132                              <1> 
 24133                              <1> 	;; Erdogan Tan 14-7-2012
 24134                              <1> 	;call 	epoch
 24135                              <1> 	;	 ; mov s.time,i.mtim 
 24136                              <1> 	;		    ; / put present time into file modified time
 24137                              <1> 	;	 ; mov s.time+2,i.mtim+2
 24138                              <1> 	;
 24139                              <1> 	;mov 	[i.mtim], eax
 24140                              <1> 
 24141                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 24142                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 24143                              <1> 	;cmp	dword [i.ctim], 0
 24144                              <1> 	;jnz	short setimod_ok
 24145                              <1> 		
 24146 00004D18 A3[20680000]        <1> 	mov 	[i.ctim], eax
 24147                              <1> 	
 24148                              <1> 	; 25/05/2020
 24149 00004D1D EB05                <1> 	jmp	short setimod_3
 24150                              <1> 
 24151                              <1> setimod_2:
 24152                              <1> 	; File/Directory data (file size or content) is changed
 24153                              <1> 	; This is last modification date&time
 24154 00004D1F A3[1C680000]        <1> 	mov	[i.mtim], eax
 24155                              <1> setimod_3:
 24156                              <1> 	; 19/09/2019 ('UNIXHDCP.ASM', 'setimod' by Erdogan Tan)
 24157                              <1> 	; This is last access or last changing date&time
 24158                              <1> 	; of inode (chmod,chown,chgrp,link)
 24159                              <1> 	; parameters (without file/dir data changing)
 24160 00004D24 A3[18680000]        <1> 	mov	[i.atim], eax
 24161                              <1> 
 24162                              <1> setimod_ok: ; 31/07/2013
 24163 00004D29 58                  <1> 	pop	eax
 24164                              <1> 	;pop	edx
 24165                              <1> 	
 24166 00004D2A C3                  <1> 	retn
 24167                              <1> 		; rts r0
 24168                              <1> setimod_4:
 24169                              <1> 	; 25/05/2020 - Retro UNIX 386 v2
 24170 00004D2B 31C9                <1> 	xor	ecx, ecx
 24171 00004D2D 390D[1C680000]      <1> 	cmp	[i.mtim], ecx ; 0
 24172 00004D33 76EA                <1> 	jna	short setimod_2
 24173                              <1> 
 24174 00004D35 E8190E0000          <1> 	call	get_system_time ; get current (unix epoch) time
 24175                              <1> 	; ((system time will be updated directly by timer interrupt))
 24176                              <1> 
 24177 00004D3A 803D[556C0000]00    <1> 	cmp	byte [imodx], 0 ; flag means "file/dir data is same but
 24178 00004D41 76DC                <1> 	jna	short setimod_2 ; inode has been changed"
 24179                              <1> 
 24180                              <1> 	; File/Dir data (File size or content) is same but
 24181                              <1> 	; inode's mode, link count, owner or group id has been changed
 24182                              <1> 	; (so, we do not change last modification date&time)
 24183 00004D43 C605[556C0000]00    <1> 	mov	byte [imodx], 0 ; reset inode modified (extended) flag
 24184 00004D4A EBD8                <1> 	jmp	short setimod_3
 24185                              <1> 
 24186                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 24187                              <1> %if 0
 24188                              <1> 	; Retro UNIX 386 v1.1 'itrunc' code
 24189                              <1> itrunc:
 24190                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24191                              <1> 	; 23/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 24192                              <1> 	;
 24193                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 24194                              <1> 	;  to zero length.
 24195                              <1> 	;
 24196                              <1> 	; INPUTS ->
 24197                              <1> 	;    r1 - i-number of i-node
 24198                              <1> 	;    i.dskp - pointer to contents or indirect block in an i-node
 24199                              <1> 	;    i.flgs - large file flag		
 24200                              <1> 	;    i.size - size of file	
 24201                              <1> 	; 	 
 24202                              <1> 	; OUTPUTS ->
 24203                              <1> 	;    i.flgs - large file flag is cleared
 24204                              <1> 	;    i.size - set to 0	
 24205                              <1> 	;    i.dskp .. i.dskp+16 - entire list is cleared
 24206                              <1> 	;    setimod - set to indicate i-node has been modified
 24207                              <1> 	;    r1 - i-number of i-node  					
 24208                              <1> 	;
 24209                              <1> 	; ((AX = R1)) input/output
 24210                              <1> 	;
 24211                              <1> 	;  (Retro UNIX Prototype : 01/12/2012 - 10/03/2013, UNIXCOPY.ASM)
 24212                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 24213                              <1> 
 24214                              <1> 	call	iget
 24215                              <1> 		; jsr r0,iget
 24216                              <1> 	mov	esi, i.dskp
 24217                              <1> 		; mov $i.dskp,r2 / address of block pointers in r2
 24218                              <1> 	xor	eax, eax
 24219                              <1> itrunc_1: ; 1:
 24220                              <1> 	lodsw
 24221                              <1> 		; mov (r2)+,r1 / move physical block number into r1
 24222                              <1> 	or 	ax, ax
 24223                              <1> 	jz	short itrunc_5
 24224                              <1> 		; beq 5f
 24225                              <1> 	push	esi
 24226                              <1> 		; mov r2,-(sp)
 24227                              <1> 	test    word [i.flgs], 1000h    
 24228                              <1> 		; bit $10000,i.flgs / test large file bit?
 24229                              <1> 	jz	short itrunc_4
 24230                              <1> 		; beq 4f / if clear, branch
 24231                              <1> 	push	eax
 24232                              <1> 		; mov r1,-(sp) / save block number of indirect block
 24233                              <1> 	call	dskrd
 24234                              <1> 		; jsr r0,dskrd / read in block, 1st data word 
 24235                              <1> 			     ; / pointed to by r5
 24236                              <1> 	; eBX = r5 = Buffer data address (the 1st word)
 24237                              <1> 	mov	ecx, 256
 24238                              <1> 		; mov $256.,r3 / move word count into r3
 24239                              <1> 	mov	esi, ebx
 24240                              <1> itrunc_2: ; 2:
 24241                              <1> 	lodsw
 24242                              <1> 		; mov (r5)+,r1 / put 1st data word in r1; 
 24243                              <1> 			     ; / physical block number
 24244                              <1> 	and	ax, ax
 24245                              <1> 	jz	short itrunc_3
 24246                              <1> 		; beq 3f / branch if zero
 24247                              <1> 	;push	ecx
 24248                              <1> 	push	cx
 24249                              <1> 		; mov r3,-(sp) / save r3, r5 on stack
 24250                              <1> 	;push	esi
 24251                              <1> 		; mov r5,-(sp)
 24252                              <1> 	call	free
 24253                              <1> 		; jsr r0,free / free block in free storage map
 24254                              <1> 	;pop	esi
 24255                              <1> 		; mov(sp)+,r5
 24256                              <1> 	pop	cx
 24257                              <1> 	;pop	ecx
 24258                              <1> 		; mov (sp)+,r3
 24259                              <1> itrunc_3: ; 3:
 24260                              <1> 	loop	itrunc_2
 24261                              <1> 		; dec r3 / decrement word count
 24262                              <1> 		; bgt 2b / branch if positive
 24263                              <1> 	pop	eax
 24264                              <1> 		; mov (sp)+,r1 / put physical block number of 
 24265                              <1> 			     ; / indirect block
 24266                              <1> 	; 01/08/2013
 24267                              <1>         and     word [i.flgs], 0EFFFh ; 1110111111111111b
 24268                              <1> itrunc_4: ; 4:
 24269                              <1> 	call	free
 24270                              <1> 		; jsr r0,free / free indirect block
 24271                              <1> 	pop	esi
 24272                              <1> 		; mov (sp)+,r2
 24273                              <1> itrunc_5: ; 5:
 24274                              <1> 	cmp	esi, i.dskp+16
 24275                              <1> 		; cmp r2,$i.dskp+16.
 24276                              <1> 	jb	short itrunc_1	
 24277                              <1> 		; bne 1b / branch until all i.dskp entries check
 24278                              <1> 	; 01/08/2013
 24279                              <1> 	;and     word [i.flgs], 0EFFFh ; 1110111111111111b
 24280                              <1> 		; bic $10000,i.flgs / clear large file bit
 24281                              <1> 	mov	edi, i.dskp
 24282                              <1> 	mov	cx, 8
 24283                              <1> 	xor 	ax, ax
 24284                              <1> 	mov	[i.size], ax ; 0
 24285                              <1> 		; clr i.size / zero file size
 24286                              <1> 	rep	stosw
 24287                              <1> 		; jsr r0,copyz; i.dskp; i.dskp+16. 
 24288                              <1> 			   ; / zero block pointers
 24289                              <1> 	call	setimod
 24290                              <1> 		; jsr r0,setimod / set i-node modified flag
 24291                              <1> 	mov	ax, [ii]
 24292                              <1> 		; mov ii,r1
 24293                              <1> 	retn
 24294                              <1> 		; rts r0
 24295                              <1> 
 24296                              <1> 	; Retro UNIX 386 v1.1 'imap' code
 24297                              <1> imap:
 24298                              <1> 	; 17/07/2022 (Retro UNIX 386 v1.2)
 24299                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 24300                              <1> 	; 26/04/2013 (Retro UNIX 8086 v1)
 24301                              <1> 	;
 24302                              <1> 	; 'imap' finds the byte in core (superblock) containing
 24303                              <1> 	; allocation bit for an i-node whose number in r1.
 24304                              <1> 	;
 24305                              <1> 	; INPUTS ->
 24306                              <1> 	;    r1 - contains an i-number
 24307                              <1> 	;    fsp - start of table containing open files
 24308                              <1> 	;
 24309                              <1> 	; OUTPUTS ->
 24310                              <1> 	;    r2 - byte address of byte with the allocation bit
 24311                              <1> 	;    mq - a mask to locate the bit position.	
 24312                              <1> 	;	  (a 1 is in calculated bit posisiton)
 24313                              <1> 	;
 24314                              <1> 	; ((AX = R1)) input/output
 24315                              <1> 	; ((DL/DX = MQ)) output
 24316                              <1> 	; ((BX = R2)) output
 24317                              <1> 	;
 24318                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 24319                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI))  
 24320                              <1> 	;
 24321                              <1> 		; / get the byte that has the allocation bit for 
 24322                              <1> 		; / the i-number contained in r1
 24323                              <1> 	;mov	dx, 1
 24324                              <1> 	mov	dl, 1
 24325                              <1> 		; mov $1,mq / put 1 in the mq
 24326                              <1> 	movzx	ebx, ax
 24327                              <1> 		; mov r1,r2 / r2 now has i-number whose byte
 24328                              <1>  		          ; / in the map we must find
 24329                              <1> 	sub	bx, 41
 24330                              <1> 		; sub $41.,r2 / r2 has i-41
 24331                              <1> 	mov	cl, bl
 24332                              <1> 		; mov r2,r3 / r3 has i-41
 24333                              <1> 	and	cl, 7
 24334                              <1> 		; bic $!7,r3 / r3 has (i-41) mod 8 to get 
 24335                              <1> 			   ; / the bit position
 24336                              <1> 	jz	short imap1
 24337                              <1> 	;shl	dx, cl
 24338                              <1> 	shl	dl, cl
 24339                              <1> 		; mov r3,lsh / move the 1 over (i-41) mod 8 positions
 24340                              <1> imap1:			   ; / to the left to mask the correct bit
 24341                              <1> 	;shr	bx, 3
 24342                              <1> 	; 17/07/2022
 24343                              <1> 	shr	ebx, 3
 24344                              <1> 		; asr r2
 24345                              <1> 		; asr r2
 24346                              <1> 		; asr r2 / r2 has (i-41) base 8 of the byte number
 24347                              <1> 		       ; / from the start of the map
 24348                              <1> 		; mov r2,-(sp) / put (i-41) base 8 on the stack
 24349                              <1> 	mov	esi, systm
 24350                              <1> 		; mov $systm,r2 / r2 points to the in-core image of
 24351                              <1> 				; / the super block for drum
 24352                              <1> 	;cmp	word [cdev], 0
 24353                              <1> 	cmp	byte [cdev], 0
 24354                              <1> 		; tst cdev / is the device the disk
 24355                              <1> 	jna	short imap2
 24356                              <1> 		; beq 1f / yes
 24357                              <1> 	add	esi, mount - systm
 24358                              <1> 		; add $mount-systm,r2 / for mounted device,
 24359                              <1> 			; / r2 points to 1st word of its super block
 24360                              <1> imap2: ; 1:
 24361                              <1> 	add	bx, [esi] ;; add free map size to si
 24362                              <1> 		; add (r2)+,(sp) / get byte address of allocation bit
 24363                              <1> 	add	bx, 4
 24364                              <1> 	add	ebx, esi
 24365                              <1>         	; add (sp)+,r2 / ?
 24366                              <1> 	;add	ebx, 4 ;; inode map offset in superblock
 24367                              <1> 		      ;; (2 + free map size + 2)
 24368                              <1> 		; add $2,r2 / ?
 24369                              <1>  	; DL/DX (MQ) has a 1 in the calculated bit position
 24370                              <1>         ; BX (R2) has byte address of the byte with allocation bit
 24371                              <1> 	retn
 24372                              <1> 		; rts r0
 24373                              <1> %endif
 24374                              <1> 
 24375                              <1> 	; Retro UNIX 386 v2.0 'itrunc' code
 24376                              <1> itrunc:
 24377                              <1> 	; 26/03/2022
 24378                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
 24379                              <1> 	; 07/06/2020
 24380                              <1> 	; 02/06/2020
 24381                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 24382                              <1> 	;
 24383                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 24384                              <1> 	;  to zero length.
 24385                              <1> 	; 07/06/2020
 24386                              <1> 	; 02/06/2020
 24387                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 24388                              <1> 	;
 24389                              <1> 	; 'itrunc' truncates a file whose i-number is given
 24390                              <1> 	; in ax to zero length.
 24391                              <1> 	;
 24392                              <1> 
 24393                              <1> 	; Reference: 
 24394                              <1> 	;	Retro UNIX 386 v2 FS installation utility
 24395                              <1> 	; 17/01/2020 - 'UNIXHDCP.ASM', 'itrunc' procedure
 24396                              <1> 
 24397                              <1> 	; * Free all the disk blocks associated
 24398                              <1> 	; * with the specified inode structure.
 24399                              <1> 	
 24400                              <1> 	; INPUT: 
 24401                              <1> 	;	(e)ax = inode number
 24402                              <1> 	; OUTPUT: 
 24403                              <1> 	;	inode will be modified (file size = 0)
 24404                              <1> 	;	; 26/03/20221
 24405                              <1> 	;	eax = 0 (if cf=0)
 24406                              <1> 
 24407                              <1> 	; (Modified registers: eax, edx, ecx, ebx, esi, edi, ebp) 
 24408                              <1> 
 24409                              <1> 	; 07/06/2020
 24410                              <1> 
 24411                              <1> 	; [cdev] = current logical drive number
 24412                              <1> 	;    eax = inode number (for [cdev])
 24413                              <1> 
 24414 00004D4C E820FEFFFF          <1> 	call 	iget
 24415                              <1> 	; 10/01/2022
 24416                              <1> 	;jc	short itrunc_0 ; error code in eax (al)
 24417                              <1> 
 24418                              <1> 	;    eax = inode number, [ii]
 24419                              <1> 	; [cdev] = current logical drive number (same with input)
 24420                              <1> 	; [idev] = logical drive number of current inode, [ii]
 24421                              <1> 	;   [ii] = current inode ([ii] = ax input, if ax was not zero)
 24422                              <1> 	; [imod] = 0		
 24423                              <1> 	; ([imodx] = 0)
 24424                              <1> 
 24425 00004D51 F605[E5670000]80    <1> 	test	byte [i.flgs+1], 80h ; regular file or directory	
 24426 00004D58 750F                <1> 	jnz	short itrunc_1
 24427                              <1> 
 24428                              <1> 	; 10/01/2022
 24429 00004D5A C705[D86C0000]FF00- <1> 	mov	dword [u.error], ERR_NOT_REGULAR ; 255 
 24430 00004D62 0000                <1>
 24431                              <1> 			; 'not a regular file (or directory) !' error
 24432                              <1> itrunc_0:
 24433 00004D64 E9F8E3FFFF          <1> 	jmp	error
 24434                              <1> itrunc_1:
 24435 00004D69 F605[E5670000]10    <1> 	test	byte [i.flgs+1], 10h ; large file (indirect blocks)
 24436 00004D70 7528                <1> 	jnz	short itrunc_5 ; large file
 24437 00004D72 BE[F0670000]        <1> 	mov	esi, i.dskp ; disk address pointer 0
 24438                              <1> itrunc_2:
 24439 00004D77 AD                  <1> 	lodsd
 24440 00004D78 21C0                <1> 	and	eax, eax
 24441 00004D7A 740C                <1> 	jz	short itrunc_3 ; empty ! (no more sectors/blocks)
 24442                              <1> 	; eax = block address to be released
 24443 00004D7C 56                  <1> 	push	esi ; * ; 10/01/2022
 24444 00004D7D E83DFDFFFF          <1> 	call	free
 24445                              <1> 	; modified registers: ebx, ecx, edx, esi, edi, ebp 
 24446                              <1> 	; 10/01/2022
 24447                              <1> 	;jc	short itrunc_0 ; error code in eax
 24448 00004D82 5E                  <1> 	pop	esi ; * ; 10/01/2022
 24449 00004D83 31C0                <1> 	xor	eax, eax ; 0
 24450 00004D85 8946FC              <1> 	mov	[esi-4], eax ; 0
 24451                              <1> itrunc_3:
 24452 00004D88 81FE[18680000]      <1> 	cmp	esi, i.dskp+40
 24453 00004D8E 72E7                <1> 	jb	short itrunc_2 ; next disk address ptr
 24454                              <1> itrunc_4:
 24455 00004D90 A3[EC670000]        <1> 	mov	[i.size], eax ; 0
 24456                              <1> 	;mov	[i.size_h], al ; 0
 24457                              <1> 	
 24458                              <1> 	; clear large file flag
 24459                              <1> 	;and     byte [i.flgs+1], 0EFh ; 11101111b ; not 10h
 24460                              <1> 		
 24461                              <1> 	;call	setimod
 24462                              <1> 	;retn
 24463 00004D95 E968FFFFFF          <1> 	jmp	setimod
 24464                              <1> 
 24465                              <1> itrunc_5:
 24466                              <1> 	; free disk blocks by using triple indirect blocks at first
 24467 00004D9A BE[14680000]        <1> 	mov	esi, i.dskp+36
 24468 00004D9F 8B06                <1> 	mov	eax, [esi]
 24469 00004DA1 09C0                <1> 	or	eax, eax
 24470 00004DA3 740C                <1> 	jz	short itrunc_6
 24471                              <1> 
 24472 00004DA5 BA02000000          <1> 	mov	edx, 2 ; Triple indirect sign (level = 2)
 24473 00004DAA E835000000          <1> 	call	tloop
 24474                              <1> 	; 10/01/2022
 24475                              <1> 	;jc	short itrunc_0
 24476                              <1> 		; eax = 0	
 24477 00004DAF 8906                <1> 	mov	[esi], eax ; 0
 24478                              <1> itrunc_6:
 24479                              <1> 	; free disk blocks by using double indirect blocks at second
 24480 00004DB1 BE[10680000]        <1> 	mov	esi, i.dskp+32
 24481 00004DB6 8B06                <1> 	mov	eax, [esi]
 24482 00004DB8 21C0                <1> 	and	eax, eax 
 24483 00004DBA 740C                <1> 	jz	short itrunc_7
 24484                              <1> 
 24485 00004DBC BA01000000          <1> 	mov	edx, 1 ; Double indirect sign (level = 1)
 24486 00004DC1 E81E000000          <1> 	call	tloop
 24487                              <1> 	; 10/01/2022
 24488                              <1> 	;jc	short itrunc_0
 24489                              <1> 		; eax = 0	
 24490 00004DC6 8906                <1> 	mov	[esi], eax ; 0
 24491                              <1> 	;esi = i.dskp+32
 24492                              <1> itrunc_7:
 24493                              <1> 	; free disk blocks by using single indirect blocks at third
 24494 00004DC8 83EE04              <1> 	sub	esi, 4
 24495 00004DCB 8B06                <1> 	mov	eax, [esi]
 24496 00004DCD 09C0                <1> 	or	eax, eax
 24497 00004DCF 7409                <1> 	jz	short itrunc_8
 24498                              <1> 
 24499 00004DD1 29D2                <1> 	sub	edx, edx ; 0  ; Single indirect sign (level = 0)
 24500 00004DD3 E80C000000          <1> 	call	tloop
 24501                              <1> 	; 10/01/2022
 24502                              <1> 	;jc	short itrunc_0
 24503                              <1> 		; eax = 0
 24504 00004DD8 8906                <1> 	mov	[esi], eax ; 0
 24505                              <1> itrunc_8:
 24506 00004DDA 81FE[F0670000]      <1> 	cmp	esi, i.dskp
 24507 00004DE0 77E6                <1> 	ja	short itrunc_7
 24508 00004DE2 EBAC                <1> 	jmp	short itrunc_4
 24509                              <1> 
 24510                              <1> tloop:
 24511                              <1> 	; 26/03/2022
 24512                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
 24513                              <1> 	; 07/06/2020
 24514                              <1> 	; 03/06/2020
 24515                              <1> 	; 02/06/2020
 24516                              <1> 	; 26/05/2020 - Retro UNIX 386 v2 by Erdogan Tan
 24517                              <1> 	; 
 24518                              <1> 	; * Free all the disk blocks associated
 24519                              <1> 	; * with the specified inode structure.
 24520                              <1> 
 24521                              <1> 	; Reference: 
 24522                              <1> 	;	Retro UNIX 386 v2 FS installation utility
 24523                              <1> 	; 17/01/2020 - 'UNIXHDCP.ASM', 'tloop' procedure
 24524                              <1> 
 24525                              <1> 	; INPUT: 
 24526                              <1> 	;	03/06/2020
 24527                              <1> 	;	eax = indirect block number/address (logical)
 24528                              <1> 	;	edx = level (in dl) 
 24529                              <1> 	;	(0 = indirect, 1 = double indr. 2 = triple indr.) 	
 24530                              <1> 	;
 24531                              <1> 	; OUTPUT: 
 24532                              <1> 	;	indirect blocks will be released
 24533                              <1> 	;
 24534                              <1> 	; Modified registers: eax, ebx, ecx, edx
 24535                              <1> 
 24536                              <1> 	; 03/06/2020
 24537                              <1> 
 24538 00004DE4 57                  <1> 	push	edi ; *
 24539 00004DE5 56                  <1> 	push	esi ; **
 24540                              <1> 
 24541 00004DE6 50                  <1> 	push	eax ; ***
 24542                              <1> 
 24543 00004DE7 52                  <1> 	push	edx ; **** level
 24544                              <1> 
 24545                              <1> 	; [ii] = current inode number
 24546                              <1> 	;;[idev] = logical drive number of current inode, [ii]
 24547                              <1> 	; eax = logical sector/block number
 24548                              <1> 
 24549                              <1> 	; 26/03/2022
 24550                              <1> 	; [cdev] = logical drive number (0 or 1)
 24551                              <1> 
 24552                              <1> 	; 10/01/2022
 24553                              <1> 	; convert to physical sector/block number/address
 24554 00004DE8 E856FAFFFF          <1> 	call	mget_2	
 24555                              <1> 
 24556 00004DED E89A0B0000          <1> 	call	dskrd ; read disk sector
 24557                              <1> 
 24558                              <1> 		;; ebx = buffer header address
 24559                              <1> 		;; eax = physical sector/block number 
 24560                              <1> 		;; [pdn] = phsysical drive (index) number
 24561                              <1> 		
 24562                              <1> 		;; Modified registers: eax, edx, ecx, esi, edi
 24563                              <1> 		;; If cf = 1 --> eax = error code (al)
 24564                              <1> 
 24565                              <1> 	; 10/01/2022
 24566                              <1> 	; Return from 'dskrd': (Retro UNIX 386 v1.2)
 24567                              <1> 	; 	eax = physical block/sector number
 24568                              <1> 	; 	ebx = buffer data address
 24569                              <1>  	; Modified registers: edx, ecx, ebx, esi, edi, ebp
 24570                              <1>  
 24571 00004DF2 5A                  <1> 	pop	edx ; **** ; level in dl
 24572                              <1> 	; 10/01/2022
 24573                              <1> 	;jc	short tloop_5
 24574                              <1> 
 24575                              <1> 	;mov	esi, [ebx+bufhdr.address] ; buffer address
 24576                              <1> 	; 10/01/2022
 24577 00004DF3 89DE                <1> 	mov	esi, ebx ; buffer data address	
 24578                              <1> 
 24579                              <1> 	; 07/06/2020
 24580 00004DF5 B980000000          <1> 	mov	ecx, 512/4 ; 128 dwords	
 24581                              <1> 
 24582 00004DFA 80FA01              <1> 	cmp	dl, 1 ; -
 24583 00004DFD 722C                <1> 	jb	short tloop_7
 24584 00004DFF 7407                <1> 	je	short tloop_1
 24585 00004E01 BF[24750000]        <1> 	mov	edi, trpi_buf ; triple indirect buffer address
 24586 00004E06 EB05                <1> 	jmp	short tloop_2
 24587                              <1> tloop_1:
 24588 00004E08 BF[24730000]        <1> 	mov	edi, dbli_buf ; double indirect buffer address
 24589                              <1> tloop_2:
 24590                              <1> 	; copy disk r/w buffer content to indirect block buffer
 24591                              <1> 	;mov	ecx, 512/4 ; 128 dwords	
 24592 00004E0D F3A5                <1> 	rep	movsd
 24593                              <1> 
 24594 00004E0F FECA                <1> 	dec	dl ; -
 24595                              <1> 		   ; next indirect block level, 2 -> 1, 1 -> 0
 24596 00004E11 89FE                <1> 	mov	esi, edi  ; (dbli, trpi) indirect buffer + 512
 24597 00004E13 B180                <1> 	mov	cl, 128 ; 128 dwords
 24598                              <1> tloop_3:
 24599 00004E15 83EE04              <1> 	sub	esi, 4  ; previous pointer
 24600                              <1> 
 24601 00004E18 8B06                <1> 	mov	eax, [esi]
 24602                              <1> 
 24603 00004E1A 09C0                <1> 	or	eax, eax ; 0
 24604 00004E1C 7409                <1> 	jz	short tloop_4
 24605                              <1> 
 24606                              <1> 	; 26/03/2022
 24607 00004E1E 52                  <1> 	push	edx ; @@
 24608                              <1> 	; 03/06/2020
 24609 00004E1F 51                  <1> 	push	ecx ; @
 24610 00004E20 E8BFFFFFFF          <1> 	call	tloop
 24611 00004E25 59                  <1> 	pop	ecx ; @
 24612                              <1> 	; 26/03/2022
 24613 00004E26 5A                  <1> 	pop	edx ; @@
 24614                              <1> 	; 10/01/2022
 24615                              <1> 	;jc	short tloop_5
 24616                              <1> tloop_4:
 24617 00004E27 E2EC                <1> 	loop	tloop_3
 24618                              <1> 
 24619 00004E29 EB1A                <1> 	jmp	short tloop_10
 24620                              <1> 
 24621                              <1> 	; 10/01/2022
 24622                              <1> ;tloop_5:
 24623                              <1> ;	pop	edx ; ***  ; discard eax
 24624                              <1> ;	; error code in eax
 24625                              <1> ;tloop_6:
 24626                              <1> ;	pop	esi ; **
 24627                              <1> ;	pop	edi ; *
 24628                              <1> ;	retn
 24629                              <1> 	
 24630                              <1> 	; free blocks in current indirect block
 24631                              <1> tloop_7:
 24632                              <1> 	;mov	ecx, 512/4  ; 128 dwords
 24633 00004E2B 81C6FC010000        <1> 	add	esi, 508
 24634                              <1> tloop_8:
 24635 00004E31 8B06                <1> 	mov	eax, [esi]
 24636 00004E33 21C0                <1> 	and	eax, eax ; 0 ?
 24637 00004E35 7409                <1> 	jz	short tloop_9
 24638                              <1> 	
 24639 00004E37 56                  <1> 	push	esi ; **** ; 10/01/2022
 24640 00004E38 51                  <1> 	push	ecx ; *****
 24641 00004E39 E881FCFFFF          <1> 	call	free
 24642                              <1> 		; if cf = 0 -> eax = 0
 24643                              <1> 		; if cf = 1 -> eax = error code (in al)
 24644 00004E3E 59                  <1> 	pop	ecx ; *****
 24645 00004E3F 5E                  <1> 	pop	esi ; **** ; 10/01/2022
 24646                              <1> 	; 10/01/2022
 24647                              <1> 	;; 07/06/2020
 24648                              <1> 	;jc	short tloop_6
 24649                              <1> tloop_9:
 24650 00004E40 83EE04              <1> 	sub	esi, 4
 24651 00004E43 E2EC                <1> 	loop	tloop_8
 24652                              <1> tloop_10:
 24653 00004E45 58                  <1> 	pop	eax ; *** ; free indirect block's itself
 24654 00004E46 E874FCFFFF          <1> 	call	free
 24655                              <1> 		;; if cf = 0 -> eax = 0
 24656                              <1> 		;; if cf = 1 -> eax = error code (in al)
 24657                              <1> 	; 10/01/2022
 24658                              <1> 	; (if we are here, there is not an error, cf=0) 
 24659                              <1> 	;jmp	short tloop_6
 24660                              <1> 
 24661                              <1> 	; 10/02/2022
 24662 00004E4B 31C0                <1> 	xor	eax, eax ; 0
 24663 00004E4D 5E                  <1> 	pop	esi ; **
 24664 00004E4E 5F                  <1> 	pop	edi ; *
 24665 00004E4F C3                  <1> 	retn
 24666                              <1> 
 24667                              <1> 	; Retro UNIX 386 v2.0 'imap' code
 24668                              <1> 	;	(runix v2 fs inode map)
 24669                              <1> imap:
 24670                              <1> 	; 18/04/2022
 24671                              <1> 	; 26/03/2022
 24672                              <1> 	; 12/03/2022
 24673                              <1> 	; 10/01/2022 - Retro UNIX 386 v1.2
 24674                              <1> 	;	(major modification)
 24675                              <1> 	; 05/11/2021 - temporary (simplified code)
 24676                              <1> 	; 21/08/2021
 24677                              <1> 	; 15/08/2021
 24678                              <1> 	; 14/06/2021
 24679                              <1> 	; 02/05/2021
 24680                              <1> 	; 01/04/2021, 08/04/2021, 24/04/2021
 24681                              <1> 	; 29/03/2021
 24682                              <1> 	; 28/03/2021 - Retro UNIX 386 v2 (beginning)
 24683                              <1> 	;
 24684                              <1> 	; 'imap' finds the byte in inode map containing
 24685                              <1> 	; allocation bit for an i-node whose number in (E)AX
 24686                              <1> 	;
 24687                              <1> 	; (ref: 'UNIXHDCP.ASM', imap', 22/01/2020) 
 24688                              <1> 	;
 24689                              <1> 	; ((Retro UNIX 386 v2 'imap' code is mostly different
 24690                              <1> 	; than Retro UNIX 386 v1.1 'imap' code.))
 24691                              <1> 	;
 24692                              <1> 	; INPUTS ->
 24693                              <1> 	;   EAX = inode number
 24694                              <1> 	;        0 = first free inode
 24695                              <1> 	;       >0 = requested inode
 24696                              <1> 	;   [cdev] = current (logical) drive/device
 24697                              <1> 	;	
 24698                              <1> 	; OUTPUTS ->
 24699                              <1> 	;    EBX = address of the byte contains allocation bit
 24700                              <1> 	;     DX has 1 at calculated bit position
 24701                              <1> 	;   ; 05/11/2021	
 24702                              <1> 	;    EBP = superblock buffer address  
 24703                              <1> 	;    (EAX = inode number)
 24704                              <1> 	;   12/03/2022
 24705                              <1> 	;    (if EAX input is 0, EAX = first free inode > 1)
 24706                              <1> 	;	 		  	
 24707                              <1> 	;   ; 08/04/2021
 24708                              <1> 	;     If cf=1 -> error code in eax (al) 	
 24709                              <1> 	;
 24710                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp
 24711                              <1> 
 24712                              <1> 	; 05/11/2021
 24713 00004E50 803D[416C0000]00    <1> 	cmp	byte [cdev], 0
 24714 00004E57 7616                <1> 	jna	short imap_0
 24715                              <1> 	; 10/01/2022
 24716 00004E59 BD[1C6F0000]        <1> 	mov	ebp, mount ; mounted fs superblock buffer
 24717 00004E5E EB14                <1> 	jmp	short imap_1
 24718                              <1> 
 24719                              <1> imap_ialloc_err:
 24720                              <1> 	; 10/01/2022
 24721 00004E60 C705[D86C0000]2100- <1> 	mov	dword [u.error], ERR_INO_ALLOC ; 33
 24722 00004E68 0000                <1>
 24723                              <1> 			; 'inode allocation error !'
 24724 00004E6A E9F2E2FFFF          <1> 	jmp	error
 24725                              <1>  
 24726                              <1> imap_0:
 24727                              <1> 	; 10/01/2022
 24728 00004E6F BD[146D0000]        <1> 	mov	ebp, systm ; root fs superblock buffer
 24729                              <1> imap_1:
 24730                              <1> 	; 26/03/2022
 24731                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 24732                              <1> imap_x:
 24733                              <1> 	; 05/11/2021
 24734                              <1> 	; 21/08/2021
 24735                              <1> 	; 15/08/2021 (Retro UNIX 386 v2)
 24736                              <1> 	; call from 'maknod2' ; 10/01/2022
 24737                              <1> 	;
 24738                              <1> 	; eax = inode number
 24739                              <1> 	; [cdev] = device number for inode in eax
 24740                              <1> 	; ebp = superblock buffer address
 24741                              <1> 
 24742                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 24743                              <1> 	; 'imap' and 'imap_x' will return with..
 24744                              <1> 	;    ECX = byte offset from inode map buff (imap_x)
 24745                              <1> 	;    EBX = byte addr of the byte with allocation bit
 24746                              <1> 	;    EDX (DL) has a 1 in the calculated bit position
 24747                              <1> 
 24748                              <1> 	; 02/05/2021
 24749                              <1> 	; convert inode number to first free inode if it is 0
 24750 00004E74 E83B000000          <1> 	call	imap_3 ; 10/01/2022
 24751 00004E79 72E5                <1> 	jc	short imap_ialloc_err
 24752                              <1> 	; eax = inode number > 1 (1 = root directory inode)
 24753                              <1> 
 24754 00004E7B 898584000000        <1> 	mov	[ebp+SB.LastInode], eax
 24755                              <1> 	
 24756 00004E81 50                  <1> 	push	eax ; * ; save inode number
 24757                              <1> 
 24758                              <1> 	; convert inode number to inode map sector index
 24759 00004E82 E845000000          <1> 	call	imap_8 ; 10/01/2022
 24760 00004E87 50                  <1> 	push	eax ; ** ; byte offset in inode map buffer
 24761                              <1> 
 24762                              <1> 	; edx = inode map buffer sector index number (< 16)
 24763                              <1> 	; eax = byte offset in inode map buffer (< 512)
 24764                              <1> 
 24765                              <1> 	; 15/08/2021
 24766 00004E88 89958C000000        <1> 	mov	[ebp+SB.ImapIndex], edx
 24767 00004E8E 8B4520              <1> 	mov	eax, [ebp+SB.InodeMapAddr]
 24768 00004E91 01D0                <1> 	add	eax, edx
 24769 00004E93 034504              <1> 	add	eax, [ebp+SB.BootSectAddr]
 24770                              <1> 	; eax = physical sector number
 24771                              <1> 	; [cdev] = current device/disk number
 24772                              <1> 	
 24773                              <1> 	; 10/01/2022 (Retro UNIX 386 v1.2)
 24774 00004E96 55                  <1> 	push	ebp ; ***
 24775 00004E97 E8F00A0000          <1> 	call	dskrd
 24776 00004E9C 5D                  <1> 	pop	ebp ; ***
 24777                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 24778                              <1> 	; eax = physical sector number
 24779                              <1> 	; ebx = buffer data address
 24780                              <1> 
 24781                              <1> 	; 26/03/2022
 24782                              <1> 	; (ecx may be > 255 at return from dskrd)
 24783                              <1> 	;sub	ecx, ecx ; 0
 24784                              <1> 	; 10/01/2022
 24785                              <1> 	;mov	cl, [esp+4] ; * ; inode number
 24786                              <1> 	; 18/04/2022
 24787 00004E9D 8B4C2404            <1> 	mov	ecx, [esp+4] ; * ; inode number
 24788 00004EA1 FEC9                <1> 	dec	cl
 24789                              <1> 	; 26/03/2022
 24790 00004EA3 31D2                <1> 	xor	edx, edx
 24791                              <1> 	;mov	dl, 1
 24792 00004EA5 FEC2                <1> 	inc	dl ; dl = 1
 24793                              <1> 	;and	ecx, 7
 24794                              <1> 	; 26/03/2022
 24795                              <1> 	; 02/05/2021
 24796                              <1> 	;dec	cl
 24797                              <1> 	;jz	short imap_2 ; 15/08/2021
 24798 00004EA7 80E107              <1> 	and	cl, 7	; 1 imap byte is for 8 inodes 
 24799                              <1> 	;jz	short imap_2
 24800 00004EAA D2E2                <1> 	shl	dl, cl
 24801                              <1> imap_2:
 24802                              <1> 	; 10/01/2022
 24803                              <1> 	; save physical sector number of imap sector in the SB
 24804 00004EAC 89457C              <1> 	mov	[ebp+SB.ImapBuffer], eax ; ! sector addr !
 24805                              <1> 	; 
 24806 00004EAF 59                  <1> 	pop	ecx ; ** ; byte offset in inode map buffer
 24807 00004EB0 01CB                <1> 	add	ebx, ecx ; + byte position
 24808 00004EB2 58                  <1> 	pop	eax ; * ; inode number
 24809                              <1> 
 24810                              <1> 	; 10/01/2022
 24811                              <1> 	; ECX contains byte offset from inode map buff (imap_x)
 24812                              <1> 	; EDX (DL) has a 1 in the calculated bit position
 24813                              <1> 	; EBX has byte address of the byte with allocation bit
 24814                              <1> 
 24815 00004EB3 C3                  <1> 	retn
 24816                              <1> 
 24817                              <1> imap_3:
 24818                              <1> 	; 10/01/2022
 24819                              <1> 	; 15/08/2021
 24820                              <1> 	; 02/05/2021
 24821                              <1> 	; 28/03/2021
 24822                              <1> 	; get first free inode number (from superblock)
 24823                              <1> 	; and check inode number against inode count
 24824                              <1> 	;
 24825                              <1> 	; INPUT:
 24826                              <1> 	;    eax = 0 -> get first free inode number
 24827                              <1> 	;    (eax > 0 -> check inode number)
 24828                              <1> 	;    ebp = superblock address ; 15/08/2021
 24829                              <1> 	; OUTPUT:
 24830                              <1> 	;    eax = inode number 
 24831                              <1> 	;    (eax will be 2 when SB.FirstFreeIno is invalid)
 24832                              <1> 	;    cf = 1 -> inode allocation error/problem
 24833                              <1> 	
 24834 00004EB4 21C0                <1> 	and	eax, eax	
 24835 00004EB6 750E                <1> 	jnz	short imap_5
 24836                              <1> 
 24837                              <1> 	; get first free inode
 24838                              <1> 	;mov	eax, [ebp+SB.FreeInodes]
 24839                              <1> 	;and	eax, eax
 24840                              <1> 	;jz	short imap_6
 24841                              <1> 	; 10/01/2022
 24842 00004EB8 394530              <1> 	cmp	[ebp+SB.FreeInodes], eax ; 0
 24843 00004EBB 760D                <1> 	jna	short imap_6	
 24844 00004EBD 8B4534              <1> 	mov	eax, [ebp+SB.FirstFreeIno] ; 1 based inode num
 24845 00004EC0 40                  <1> 	inc	eax
 24846 00004EC1 7502                <1> 	jnz	short imap_4 ; 0FFFFFFFFh -> 0
 24847                              <1> 	; invalid first free inode value (not initialized)
 24848 00004EC3 B003                <1> 	mov	al, 3 ; first free inode to be searched + 1
 24849                              <1> imap_4:
 24850 00004EC5 48                  <1> 	dec	eax
 24851                              <1> imap_5:
 24852                              <1> 	; 15/08/2021
 24853                              <1> 	; check inode number against inode count of the fs
 24854 00004EC6 394514              <1> 	cmp	[ebp+SB.InodeCount], eax
 24855 00004EC9 C3                  <1> 	retn	; if cf = 1 --> inode number > inode count
 24856                              <1> imap_6:
 24857                              <1> 	; 'imap' inode allocation error !
 24858 00004ECA F9                  <1> 	stc
 24859                              <1> imap_7:
 24860 00004ECB C3                  <1> 	retn
 24861                              <1> 
 24862                              <1> imap_8:
 24863                              <1> 	; 10/01/2022
 24864                              <1> 	; 15/08/2021
 24865                              <1> 	; 02/05/2021
 24866                              <1> 	; 28/03/2021
 24867                              <1> 	; convert inode count to inode map sector index
 24868                              <1> 	;
 24869                              <1> 	; INPUT: 
 24870                              <1> 	;    eax = inode number
 24871                              <1> 	; OUTPUT:
 24872                              <1> 	;    edx = inode map sector offset/index number
 24873                              <1> 	;    eax = byte offset from start of imapbuf	 
 24874                              <1> 
 24875 00004ECC 31D2                <1> 	xor	edx, edx
 24876 00004ECE 48                  <1> 	dec	eax ; zero based inode number
 24877 00004ECF 74FA                <1> 	jz	short imap_7
 24878                              <1> 
 24879 00004ED1 C1E803              <1> 	shr	eax, 3 ; 8 inodes per inode map byte
 24880                              <1> 		; eax = byte offset from start of inode map
 24881 00004ED4 88E2                <1> 	mov	dl, ah ; ah <= 31 (1Fh) for Retro UNIX 386 v2
 24882 00004ED6 D0EA                <1> 	shr	dl, 1
 24883                              <1> 		; edx = inode map sector offset/index number
 24884                              <1> 	;and	eax, 511
 24885 00004ED8 6625FF01            <1> 	and	ax, 511
 24886                              <1> 		; eax = byte offset from start of imapbuf
 24887 00004EDC C3                  <1> 	retn
 24888                                  %include 'u6.s'      ; 31/05/2015
 24889                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 24890                              <1> ; (re-write kernel for test by using previous version without a major defect)
 24891                              <1> ; ****************************************************************************
 24892                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS6.INC
 24893                              <1> ; Last Modification: 19/07/2022
 24894                              <1> ; ----------------------------------------------------------------------------
 24895                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 24896                              <1> ; (v0.1 - Beginning: 11/07/2012)
 24897                              <1> ;
 24898                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 24899                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 24900                              <1> ; <Bell Laboratories (17/3/1972)>
 24901                              <1> ; <Preliminary Release of UNIX Implementation Document>
 24902                              <1> ;
 24903                              <1> ; Retro UNIX 8086 v1 - U6.ASM (23/07/2014) //// UNIX v1 -> u6.s
 24904                              <1> ;
 24905                              <1> ; ****************************************************************************
 24906                              <1> 
 24907                              <1> 	; 09/03/2022
 24908                              <1> 	; 25/12/2021
 24909                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 24910                              <1> readi:
 24911                              <1> 	; 20/05/2015
 24912                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 24913                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 24914                              <1> 	;
 24915                              <1> 	; Reads from an inode whose number in R1
 24916                              <1> 	; 
 24917                              <1> 	; INPUTS ->
 24918                              <1> 	;    r1 - inode number
 24919                              <1> 	;    u.count - byte count user desires
 24920                              <1> 	;    u.base - points to user buffer
 24921                              <1> 	;    u.fofp - points to word with current file offset
 24922                              <1> 	; OUTPUTS ->
 24923                              <1> 	;    u.count - cleared
 24924                              <1> 	;    u.nread - accumulates total bytes passed back
 24925                              <1> 	;
 24926                              <1> 	; ((AX = R1)) input/output
 24927                              <1> 	;    (Retro UNIX Prototype: 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
 24928                              <1>         ;    ((Modified registers: edx, ebx, ecx, esi, edi)) -15/07/2022- 
 24929                              <1> 
 24930 00004EDD 31D2                <1> 	xor	edx, edx ; 0
 24931 00004EDF 8915[906C0000]      <1> 	mov 	[u.nread], edx ; 0
 24932                              <1> 		; clr u.nread / accumulates number of bytes transmitted
 24933 00004EE5 668915[D06C0000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
 24934 00004EEC 3915[8C6C0000]      <1> 	cmp 	[u.count], edx ; 0
 24935                              <1> 		; tst u.count / is number of bytes to be read greater than 0
 24936 00004EF2 7701                <1> 	ja 	short readi_1 ; 1f
 24937                              <1> 		; bgt 1f / yes, branch
 24938 00004EF4 C3                  <1> 	retn
 24939                              <1> 		; rts r0 / no, nothing to read; return to caller
 24940                              <1> readi_1: ; 1:
 24941                              <1> 	;	; mov r1,-(sp) / save i-number on stack
 24942                              <1> 	;cmp	ax, 40
 24943                              <1> 	;	; cmp r1,$40. / want to read a special file 
 24944                              <1> 	;	;             / (i-nodes 1,...,40 are for special files)
 24945                              <1>         ;ja	dskr 
 24946                              <1> 	;	; ble 1f / yes, branch
 24947                              <1> 	;	; jmp dskr / no, jmp to dskr; 
 24948                              <1> 	;	;         / read file with i-node number (r1)
 24949                              <1> 	;	;    / starting at byte ((u.fofp)), read in u.count bytes
 24950                              <1> 	
 24951                              <1> 	; 28/11/2021
 24952 00004EF5 F605[D66C0000]FF    <1> 	test	byte [u.kcall], 0FFh
 24953                              <1> 	;jnz	short readi_2  ; 'readi' called by 'namei'
 24954                              <1> 	; 09/03/2022
 24955                              <1> 	;jz	short _readi_2
 24956                              <1> 	;jmp	dskr
 24957 00004EFC 750C                <1> 	jnz	short readi_2 ; 'readi' called by 'namei'
 24958                              <1> ;_readi_2:	; 09/03/2022
 24959                              <1> 	; eax = inode number
 24960                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 24961 00004EFE E86EFCFFFF          <1> 	call	iget
 24962                              <1> ;readi_2:
 24963                              <1> 	; 28/11/2021
 24964                              <1> 	; eax = inode number
 24965                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 24966 00004F03 E800050000          <1> 	call	is_regular_file
 24967                              <1> 	;jz	dskr ; regular file 
 24968                              <1> 	; 25/12/2021
 24969 00004F08 7505                <1> 	jnz	short readi_5 ; device file 
 24970                              <1> readi_2:	 ; 09/03/2022
 24971                              <1> 	; regular file
 24972 00004F0A E9E3000000          <1> 	jmp	dskr
 24973                              <1> readi_5:
 24974                              <1> 	; (20/05/2015)
 24975 00004F0F 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 24976                              <1> 
 24977                              <1> 	; 28/11/2021	
 24978                              <1> 	; device file
 24979 00004F10 BB[2A4F0000]        <1> 	mov	ebx, readi_4
 24980 00004F15 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 24981 00004F18 720E                <1> 	jb	short readi_3
 24982 00004F1A 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 24983 00004F1D 7709                <1> 	ja	short readi_3	
 24984                              <1> 	
 24985                              <1> 	; convert v2 inode number to v1 device inode number
 24986 00004F1F 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 24987 00004F21 89C1                <1> 	mov	ecx, eax
 24988 00004F23 C0E102              <1> 	shl	cl, 2 ; * 4
 24989 00004F26 01CB                <1> 	add	ebx, ecx
 24990                              <1> readi_3:
 24991 00004F28 FF23                <1> 	jmp	dword [ebx]	
 24992                              <1> 		 ; jmp *1f-2(r1)
 24993                              <1> readi_4: ; 1:
 24994 00004F2A [7A4F0000]          <1> 	dd	null ; 28/11/2021
 24995 00004F2E [7E4F0000]          <1> 	dd	rtty ; tty, AX = 1 (runix)
 24996                              <1> 		 ;rtty / tty; r1=2
 24997                              <1> 		 ;rppt / ppt; r1=4
 24998 00004F32 [CE4F0000]          <1> 	dd	rmem ; mem, AX = 2 (runix)
 24999                              <1> 		 ;rmem / mem; r1=6
 25000                              <1> 		 ;rrf0 / rf0
 25001                              <1> 		 ;rrk0 / rk0
 25002                              <1> 		 ;rtap / tap0
 25003                              <1> 		 ;rtap / tap1
 25004                              <1> 		 ;rtap / tap2
 25005                              <1> 		 ;rtap / tap3
 25006                              <1> 		 ;rtap / tap4
 25007                              <1> 		 ;rtap / tap5
 25008                              <1> 		 ;rtap / tap6
 25009                              <1> 		 ;rtap / tap7
 25010 00004F36 [4D580000]          <1> 	dd	rfd ; fd0, AX = 3 (runix only)
 25011 00004F3A [4D580000]          <1> 	dd	rfd ; fd1, AX = 4 (runix only)
 25012 00004F3E [4D580000]          <1> 	dd	rhd ; hd0, AX = 5 (runix only)
 25013 00004F42 [4D580000]          <1> 	dd	rhd ; hd1, AX = 6 (runix only)	
 25014 00004F46 [4D580000]          <1> 	dd	rhd ; hd2, AX = 7 (runix only)
 25015 00004F4A [4D580000]          <1> 	dd	rhd ; hd3, AX = 8 (runix only)	
 25016 00004F4E [E34F0000]          <1> 	dd	rlpr ; lpr, AX = 9 (invalid, write only device !?)
 25017 00004F52 [CA4F0000]          <1> 	dd	rcvt ; tty0, AX = 10 (runix)	  
 25018                              <1> 		 ;rcvt / tty0
 25019 00004F56 [CA4F0000]          <1> 	dd	rcvt ; tty1, AX = 11 (runix)	  
 25020                              <1> 		 ;rcvt / tty1
 25021 00004F5A [CA4F0000]          <1> 	dd	rcvt ; tty2, AX = 12 (runix)	  
 25022                              <1> 		 ;rcvt / tty2
 25023 00004F5E [CA4F0000]          <1> 	dd	rcvt ; tty3, AX = 13 (runix)	  
 25024                              <1> 		 ;rcvt / tty3
 25025 00004F62 [CA4F0000]          <1> 	dd	rcvt ; tty4, AX = 14 (runix)	  
 25026                              <1> 		 ;rcvt / tty4
 25027 00004F66 [CA4F0000]          <1> 	dd	rcvt ; tty5, AX = 15 (runix)	  
 25028                              <1> 		 ;rcvt / tty5
 25029 00004F6A [CA4F0000]          <1> 	dd	rcvt ; tty6, AX = 16 (runix)	  
 25030                              <1> 		 ;rcvt / tty6
 25031 00004F6E [CA4F0000]          <1> 	dd	rcvt ; tty7, AX = 17 (runix)	  
 25032                              <1> 		 ;rcvt / tty7
 25033 00004F72 [CA4F0000]          <1> 	dd	rcvt ; COM1, AX = 18 (runix only)	  
 25034                              <1> 		 ;rcrd / crd
 25035 00004F76 [CA4F0000]          <1> 	dd	rcvt ; COM2, AX = 19 (runix only)
 25036                              <1> 
 25037                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25038                              <1> null:
 25039 00004F7A 31C0                <1> 	xor	eax, eax
 25040 00004F7C 58                  <1> 	pop	eax
 25041 00004F7D C3                  <1> 	retn
 25042                              <1> 
 25043                              <1> 	; 11/01/2022
 25044                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 25045                              <1> rtty: ; / read from console tty
 25046                              <1> 	; 17/10/2015 - 16/07/2015 (Retro UNIX 8086 v1)
 25047                              <1> 	; 	     (Only 1 byte is read, by ignoring byte count!)
 25048                              <1> 	;  	     WHAT FOR: Every character from Keyboard input 
 25049                              <1> 	;	     must be written immediate on video page (screen)
 25050                              <1> 	;	     when it is required.	
 25051                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25052                              <1> 	; 11/03/2013 - 19/06/2014 (Retro UNIX 8086 v1)
 25053                              <1> 	;
 25054                              <1> 	; Console tty buffer is PC keyboard buffer
 25055                              <1> 	; and keyboard-keystroke handling is different than original
 25056                              <1> 	; unix (PDP-11) here. TTY/Keyboard procedures here are changed
 25057                              <1> 	; according to IBM PC compatible ROM BIOS keyboard functions. 
 25058                              <1> 	;
 25059                              <1> 	; 06/12/2013
 25060 00004F7E 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 25061 00004F85 8A83[63680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 25062                              <1> rttys:
 25063                              <1> 		; mov tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
 25064                              <1> 	               ; / of the control and status block
 25065                              <1> 		; tst 2(r5) / for the console tty; this word points to the console
 25066                              <1> 		       ; / tty buffer
 25067                              <1> 	; 28/07/2013
 25068 00004F8B A2[996C0000]        <1> 	mov 	[u.ttyn], al
 25069                              <1> 	; 13/01/2014
 25070 00004F90 FEC0                <1> 	inc	al
 25071 00004F92 A2[9A6C0000]        <1> 	mov	[u.ttyp], al ; tty number + 1
 25072                              <1> rtty_nc: ; 01/02/2014
 25073                              <1> 	; 29/09/2013
 25074                              <1> 	;mov	ecx, 10
 25075                              <1> 	; 11/01/2022
 25076 00004F97 29C9                <1> 	sub	ecx, ecx
 25077 00004F99 B10A                <1> 	mov	cl, 10
 25078                              <1> rtty_1: 	; 01/02/2014
 25079                              <1> 	;push 	cx ; 29/09/2013
 25080                              <1> 	; 11/12/2021
 25081 00004F9B 51                  <1> 	push	ecx
 25082                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 25083 00004F9C B001                <1> 	mov 	al, 1
 25084 00004F9E E8C20B0000          <1> 	call 	getc
 25085                              <1> 	;pop 	cx ; 29/09/2013	
 25086                              <1> 	; 11/12/2021
 25087 00004FA3 59                  <1> 	pop	ecx
 25088 00004FA4 7516                <1> 	jnz	short rtty_2
 25089                              <1> 		; bne 1f / 2nd word of console tty buffer contains number
 25090                              <1> 	               ; / of chars. Is this number non-zero?
 25091 00004FA6 E20D                <1> 	loop	rtty_idle ; 01/02/2014
 25092                              <1> 	; 05/10/2013
 25093 00004FA8 8A25[996C0000]      <1> 	mov	ah, [u.ttyn]
 25094                              <1> 	; 29/09/2013
 25095 00004FAE E8C9F7FFFF          <1> 	call	sleep
 25096                              <1> 		; jsr r0,canon; ttych / if 0, call 'canon' to get a line
 25097                              <1>                 ;           / (120 chars.)
 25098                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 25099 00004FB3 EBE2                <1> 	jmp	short rtty_nc ; 01/02/2014
 25100                              <1> 
 25101                              <1> rtty_idle:
 25102                              <1> 	; 29/07/2013
 25103 00004FB5 E835F7FFFF          <1> 	call 	idle
 25104 00004FBA EBDF                <1> 	jmp	short rtty_1 ; 01/02/2014
 25105                              <1> 	;1:
 25106                              <1> 		; tst 2(r5) / is the number of characters zero
 25107                              <1> 		; beq ret1 / yes, return to caller via 'ret1'
 25108                              <1> 		; movb *4(r5),r1 / no, put character in r1
 25109                              <1> 		; inc 4(r5) / 3rd word of console tty buffer points to byte which
 25110                              <1> 		          ; / contains the next char.
 25111                              <1> 		; dec 2(r5) / decrement the character count
 25112                              <1> rtty_2:
 25113 00004FBC 30C0                <1> 	xor 	al, al
 25114 00004FBE E8A20B0000          <1> 	call 	getc
 25115 00004FC3 E895000000          <1> 	call	passc
 25116                              <1> 		; jsr r0,passc / move the character to core (user)
 25117                              <1> 	;; 17/10/2015 - 16/07/2015
 25118                              <1> 	; 19/06/2014
 25119                              <1> 	;;jnz	short rtty_nc
 25120 00004FC8 58                  <1> 	pop	eax  ; (20/05/2015)
 25121 00004FC9 C3                  <1> 	retn 
 25122                              <1> ;ret1:
 25123                              <1> 		; jmp ret / return to caller via 'ret'
 25124                              <1> 
 25125                              <1> rcvt:   ; < receive/read character from tty >
 25126                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25127                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 25128                              <1> 	;
 25129                              <1> 	; Retro UNIX 8086 v1 modification !
 25130                              <1> 	; 
 25131                              <1> 	; In original UNIX v1, 'rcvt' routine 
 25132                              <1> 	;		(exactly different than this one)
 25133                              <1> 	;	was in 'u9.s' file.
 25134                              <1> 	;
 25135 00004FCA 2C0A                <1> 	sub 	al, 10
 25136                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 25137                              <1> 	; 16/07/2013
 25138                              <1> 	; 21/05/2013
 25139 00004FCC EBBD                <1>         jmp     short rttys
 25140                              <1>       
 25141                              <1> ;rppt: / read paper tape
 25142                              <1> ;	jsr	r0,pptic / gets next character in clist for ppt input and
 25143                              <1> ;			 / places
 25144                              <1> ;		br ret / it in r1; if there 1s no problem with reader, it
 25145                              <1> ;		       / also enables read bit in prs
 25146                              <1> ;	jsr	r0,passc / place character in users buffer area
 25147                              <1> ;	br	rppt
 25148                              <1> 
 25149                              <1> rmem: ; / transfer characters from memory to a user area of core
 25150                              <1> 	; 17/10/2015
 25151                              <1> 	; 11/06/2015
 25152                              <1> 	; 24/05/2015
 25153                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25154                              <1> 	;
 25155 00004FCE 8B35[786C0000]      <1> 	mov     esi, [u.fofp]
 25156                              <1> rmem_1:
 25157 00004FD4 8B1E                <1>         mov     ebx, [esi]        
 25158                              <1> 	        ; mov *u.fofp,r1 / save file offset which points to the char
 25159                              <1> 		               ; / to be transferred to user
 25160 00004FD6 FF06                <1>         inc     dword [esi] ; 17/10/2015
 25161                              <1> 		; inc *u.fofp / increment file offset to point to 'next' 
 25162                              <1> 			    ; / char in memory file
 25163 00004FD8 8A03                <1> 	mov	al, [ebx]
 25164                              <1> 		; movb (r1),r1 / get character from memory file, 
 25165                              <1> 		             ; / put it in r1
 25166 00004FDA E87E000000          <1> 	call	passc        ; jsr r0,passc / move this character to 
 25167                              <1> 			     ;  / the next byte of the users core area
 25168                              <1> 		; br rmem / continue
 25169 00004FDF 75F3                <1> 	jnz	short rmem_1
 25170                              <1> ret_:
 25171 00004FE1 58                  <1> 	pop	eax ; 09/06/2015
 25172 00004FE2 C3                  <1> 	retn
 25173                              <1> 
 25174                              <1> rlpr:
 25175                              <1> ;1:
 25176                              <1> ;rcrd:
 25177 00004FE3 C705[D86C0000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 25178 00004FEB 0000                <1>
 25179 00004FED E96FE1FFFF          <1> 	jmp	error
 25180                              <1> 		;jmp	error / see 'error' routine
 25181                              <1> 
 25182                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25183                              <1> dskr:
 25184                              <1> 	; 19/07/2022
 25185                              <1> 	; 12/10/2015
 25186                              <1> 	; 21/08/2015
 25187                              <1> 	; 25/07/2015
 25188                              <1> 	; 10/07/2015
 25189                              <1> 	; 16/06/2015
 25190                              <1> 	; 31/05/2015
 25191                              <1> 	; 24/05/2015 (Retro UNIX 386 v1 - Beginning)
 25192                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 25193                              <1> dskr_0:
 25194 00004FF2 50                  <1> 	push	eax
 25195                              <1> 		; mov (sp),r1 / i-number in r1
 25196                              <1> 	; AX = i-number
 25197 00004FF3 E879FBFFFF          <1> 	call	iget
 25198                              <1> 		; jsr r0,iget / get i-node (r1) into i-node section of core
 25199                              <1>         ;movzx	edx, word [i.size] ; 16/06/2015
 25200                              <1> 	;	; mov i.size,r2 / file size in bytes in r2
 25201                              <1> 	; 28/11/2021
 25202 00004FF8 8B15[EC670000]      <1> 	mov	edx, [i.size] ; 32 bit file size (runix v2 inode)
 25203                              <1> 	;
 25204 00004FFE 8B1D[786C0000]      <1> 	mov	ebx, [u.fofp]
 25205 00005004 2B13                <1> 	sub	edx, [ebx]
 25206                              <1> 		; sub *u.fofp,r2 / subtract file offset
 25207                              <1>         ; 12/10/2015
 25208                              <1> 	; jna	short ret_ 
 25209                              <1> 		; blos ret
 25210 00005006 7709                <1> 	ja	short dskr_1
 25211                              <1> 	;
 25212                              <1> dskr_retn: ; 12/10/2015
 25213 00005008 58                  <1> 	pop	eax
 25214 00005009 C605[D66C0000]00    <1> 	mov	byte [u.kcall], 0
 25215 00005010 C3                  <1> 	retn	
 25216                              <1> dskr_1: 
 25217 00005011 3B15[8C6C0000]      <1> 	cmp     edx, [u.count] 
 25218                              <1> 		; cmp r2,u.count / are enough bytes left in file 
 25219                              <1> 			       ; / to carry out read
 25220 00005017 7306                <1> 	jnb	short dskr_2
 25221                              <1> 		; bhis 1f
 25222 00005019 8915[8C6C0000]      <1> 	mov	[u.count], edx
 25223                              <1> 		; mov r2,u.count / no, just read to end of file
 25224                              <1> dskr_2: ; 1:
 25225                              <1> 	; (E)AX = i-number ; 28/11/2021 (32 bit inode number)
 25226                              <1> 	;call	mget
 25227                              <1> 		; jsr r0,mget / returns physical block number of block 
 25228                              <1> 		    ; / in file where offset points
 25229                              <1> 	; 28/11/2021
 25230 0000501F E8D9F7FFFF          <1> 	call	mget_r
 25231                              <1> 
 25232                              <1> 	; eax = physical block number
 25233                              <1> 	; [cdev] = current device number 
 25234 00005024 E863090000          <1> 	call	dskrd
 25235                              <1> 		; jsr r0,dskrd / read in block, r5 points to 
 25236                              <1> 			     ; / 1st word of data in buffer
 25237                              <1> 	; 09/06/2015
 25238 00005029 803D[D66C0000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
 25239 00005030 770F                <1> 	ja	short dskr_4	  ; zf=0 -> the caller is 'namei'
 25240 00005032 66833D[D06C0000]00  <1> 	cmp	word [u.pcount], 0
 25241 0000503A 7705                <1> 	ja	short dskr_4
 25242                              <1> dskr_3:
 25243                              <1> 	; [u.base] = virtual address to transfer (as destination address)
 25244 0000503C E857000000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 25245                              <1> dskr_4:
 25246                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
 25247 00005041 E843030000          <1> 	call	sioreg
 25248                              <1> 		; jsr r0,sioreg
 25249                              <1> 	
 25250                              <1> 	; 19/07/2022
 25251                              <1> 	;xchg	esi, edi
 25252                              <1> 	
 25253                              <1> 	; 19/07/2022
 25254                              <1> 	;  EDX = user data offset (previous value of [u.pbase])
 25255                              <1> 	;  ESI = pointer to file offset 
 25256                              <1> 	;  EDI = system (I/O) buffer offset
 25257                              <1> 	;  ECX = byte count
 25258                              <1> 	;  EBX = system buffer (data) address	
 25259                              <1> 	;  EAX = remain bytes after byte count within page frame 
 25260                              <1> 
 25261 00005046 010E                <1> 	add	[esi], ecx 
 25262                              <1> 			; new file offset (old offset + byte count)
 25263                              <1> 	;
 25264 00005048 89FE                <1> 	mov	esi, edi ; sector (I/O) buffer offset
 25265 0000504A 89D7                <1> 	mov	edi, edx
 25266                              <1> 
 25267                              <1> 	; EDI = file (user data) offset
 25268                              <1> 	; ESI = sector (I/O) buffer offset
 25269                              <1> 	; ECX = byte count
 25270 0000504C F3A4                <1> 	rep	movsb
 25271                              <1> 		; movb (r2)+,(r1)+ / move data from buffer into working core
 25272                              <1> 		                 ; / starting at u.base
 25273                              <1> 		; dec r3
 25274                              <1> 		; bne 2b / branch until proper number of bytes are transferred
 25275                              <1> 	; 25/07/2015
 25276                              <1> 	; eax = remain bytes in buffer
 25277                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 25278 0000504E 09C0                <1> 	or	eax, eax
 25279 00005050 75EA                <1> 	jnz	short dskr_3 ; (page end before system buffer end!)		
 25280                              <1> 	; 03/08/2013
 25281                              <1> 	;pop	eax
 25282 00005052 390D[8C6C0000]      <1> 	cmp	[u.count], ecx ; 0
 25283                              <1> 		; tst u.count / all bytes read off disk
 25284                              <1> 		; bne dskr
 25285                              <1> 		; br ret
 25286                              <1>         ;ja	short dskr_0
 25287                              <1> 	;mov	[u.kcall], cl ; 0 ; 09/06/2015
 25288                              <1> 	;retn
 25289                              <1> 	; 12/10/2015
 25290 00005058 76AE                <1> 	jna	short dskr_retn
 25291 0000505A 58                  <1> 	pop	eax  ; (i-node number)
 25292 0000505B EB95                <1> 	jmp	short dskr_0
 25293                              <1> 	
 25294                              <1> passc:
 25295                              <1> 	; 18/10/2015
 25296                              <1> 	; 10/07/2015
 25297                              <1> 	; 01/07/2015
 25298                              <1> 	; 08/06/2015
 25299                              <1> 	; 04/06/2015
 25300                              <1> 	; 20/05/2015
 25301                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25302                              <1> 	;
 25303                              <1>    	;(Retro UNIX 386 v1 - translation from user's virtual address
 25304                              <1> 	;		      to physical address
 25305 0000505D 66833D[D06C0000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 25306                              <1> 			     ; 1-4095 --> use previous physical base address
 25307                              <1> 			     ; in [u.pbase]
 25308 00005065 7705                <1> 	ja	short passc_3
 25309                              <1> 	; 08/06/2015 - 10/07/2015
 25310 00005067 E82C000000          <1> 	call	trans_addr_w
 25311                              <1> passc_3:
 25312                              <1> 	; 19/05/2015
 25313 0000506C 66FF0D[D06C0000]    <1> 	dec	word [u.pcount]
 25314                              <1> 	;
 25315 00005073 8B1D[CC6C0000]      <1> 	mov	ebx, [u.pbase]
 25316 00005079 8803                <1> 	mov	[ebx], al
 25317                              <1> 		; movb r1,*u.base / move a character to the next byte of the
 25318                              <1> 		               ; / users buffer
 25319 0000507B FF05[886C0000]      <1> 	inc	dword [u.base]
 25320                              <1> 		; inc u.base / increment the pointer to point to 
 25321                              <1> 			  ; / the next byte in users buffer
 25322 00005081 FF05[CC6C0000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 25323 00005087 FF05[906C0000]      <1> 	inc	dword [u.nread]
 25324                              <1> 		; inc u.nread / increment the number of bytes read
 25325 0000508D FF0D[8C6C0000]      <1> 	dec	dword [u.count]
 25326                              <1> 		; dec u.count / decrement the number of bytes to be read
 25327                              <1> 		; bne 1f / any more bytes to read? ; yes, branch
 25328 00005093 C3                  <1> 	retn
 25329                              <1> 		; mov (sp)+,r0 / no, do a non-local return to the caller of
 25330                              <1> 		             ; / 'readi' by:
 25331                              <1> 		;/ (1) pop the return address off the stack into r0
 25332                              <1> 		; mov (sp)+,r1 / (2) pop the i-number off the stack into r1
 25333                              <1> 	;1:
 25334                              <1> 		; clr	*$ps / clear processor status
 25335                              <1> 		; rts r0 / return to address currently on top of stack
 25336                              <1> 
 25337                              <1> trans_addr_r:
 25338                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 25339                              <1> 	;	-'add_to_swap_queue' call is disabled as temporary-
 25340                              <1> 	; Translate virtual address to physical address 
 25341                              <1> 	; for reading from user's memory space
 25342                              <1> 	; (Retro UNIX 386 v1 feature only !)
 25343                              <1> 	; 18/10/2015
 25344                              <1> 	; 10/07/2015
 25345                              <1> 	; 09/06/2015
 25346                              <1> 	; 08/06/2015 
 25347                              <1> 	; 04/06/2015
 25348                              <1> 	;
 25349                              <1> 	; 18/10/2015
 25350 00005094 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
 25351 00005096 EB04                <1> 	jmp 	short trans_addr_rw
 25352                              <1> 
 25353                              <1> 	;push	eax
 25354                              <1> 	;push	ebx
 25355                              <1> 	;mov	ebx, [u.base]
 25356                              <1> 	;call	get_physical_addr ; get physical address
 25357                              <1> 	;;jnc	short cpass_0
 25358                              <1> 	;jnc	short passc_1
 25359                              <1> 	;mov	[u.error], eax
 25360                              <1> 	;;pop	ebx
 25361                              <1> 	;;pop	eax
 25362                              <1> 	;jmp	error
 25363                              <1> ;cpass_0:
 25364                              <1> 	; 18/10/2015
 25365                              <1> 	; 20/05/2015
 25366                              <1> 	;mov 	[u.pbase], eax ; physical address	
 25367                              <1> 	;mov	[u.pcount], cx ; remain byte count in page (1-4096)
 25368                              <1> 	;pop	ebx
 25369                              <1> 	;pop	eax
 25370                              <1> 	;retn	; 08/06/2015
 25371                              <1> 
 25372                              <1> trans_addr_w:
 25373                              <1> 	; 31/12/2021
 25374                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 25375                              <1> 	;	-'add_to_swap_queue' call is disabled as temporary-
 25376                              <1> 	; Translate virtual address to physical address
 25377                              <1> 	; for writing to user's memory space
 25378                              <1> 	; (Retro UNIX 386 v1 feature only !)
 25379                              <1> 	; 18/10/2015
 25380                              <1> 	; 29/07/2015
 25381                              <1> 	; 10/07/2015
 25382                              <1> 	; 09/06/2015
 25383                              <1> 	; 08/06/2015
 25384                              <1> 	; 04/06/2015 (passc)
 25385                              <1> 	;
 25386                              <1> 	; 18/10/2015
 25387 00005098 29D2                <1> 	sub	edx, edx
 25388 0000509A FEC2                <1> 	inc	dl ; 1 (write access sign)
 25389                              <1> trans_addr_rw:
 25390 0000509C 50                  <1> 	push	eax
 25391 0000509D 53                  <1> 	push	ebx
 25392                              <1> 	; 18/10/2015
 25393 0000509E 52                  <1> 	push 	edx ; r/w sign (in DL)
 25394                              <1> 	;
 25395 0000509F 8B1D[886C0000]      <1> 	mov	ebx, [u.base]
 25396 000050A5 E81DD7FFFF          <1> 	call	get_physical_addr ; get physical address
 25397 000050AA 730A                <1> 	jnc	short passc_0
 25398 000050AC A3[D86C0000]        <1> 	mov	[u.error], eax
 25399                              <1> 	;pop	edx
 25400                              <1> 	;pop 	ebx
 25401                              <1> 	;pop	eax
 25402 000050B1 E9ABE0FFFF          <1> 	jmp	error
 25403                              <1> passc_0:
 25404 000050B6 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page ; 18/10/2015
 25405 000050B9 5A                  <1> 	pop	edx ; 18/10/2015
 25406 000050BA 7517                <1> 	jnz	short passc_1
 25407                              <1> 	; 18/10/2015
 25408 000050BC 20D2                <1> 	and 	dl, dl
 25409 000050BE 7413                <1> 	jz	short passc_1
 25410                              <1> 	; 20/05/2015
 25411                              <1> 	; read only (duplicated) page -must be copied to a new page-
 25412                              <1> 	; EBX = linear address
 25413 000050C0 51                  <1> 	push 	ecx
 25414                              <1> 	; 31/12/2021 - Retro UNIX 386 v1.2 (BugFix)
 25415 000050C1 53                  <1> 	push	ebx ;* ; BugFix  ; 31/12/2021
 25416 000050C2 E871D6FFFF          <1> 	call 	copy_page
 25417 000050C7 5B                  <1> 	pop	ebx ;* ; BugFix  ; 31/12/2021
 25418 000050C8 59                  <1> 	pop	ecx
 25419 000050C9 7217                <1> 	jc	short passc_2
 25420                              <1> 	; 30/11/2021
 25421                              <1> 	;push	eax ; physical address of the new/allocated page
 25422                              <1> 	;call	add_to_swap_queue
 25423                              <1> 	;pop	eax
 25424                              <1> 	; 18/10/2015
 25425 000050CB 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
 25426                              <1> 	;mov 	ecx, PAGE_SIZE
 25427                              <1> 	;sub	ecx, ebx 
 25428 000050D1 01D8                <1> 	add	eax, ebx  
 25429                              <1> passc_1: 
 25430                              <1> 	; 18/10/2015
 25431                              <1> 	; 20/05/2015
 25432 000050D3 A3[CC6C0000]        <1> 	mov 	[u.pbase], eax ; physical address	
 25433 000050D8 66890D[D06C0000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
 25434 000050DF 5B                  <1> 	pop	ebx
 25435 000050E0 58                  <1> 	pop	eax
 25436 000050E1 C3                  <1> 	retn	; 08/06/2015
 25437                              <1> passc_2:
 25438 000050E2 C705[D86C0000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
 25439 000050EA 0000                <1>
 25440                              <1> 	;pop 	ebx
 25441                              <1> 	;pop	eax
 25442 000050EC E970E0FFFF          <1> 	jmp	error
 25443                              <1> 
 25444                              <1> 	; 09/03/2022
 25445                              <1> 	; 25/12/2021
 25446                              <1> 	; 11/12/2021
 25447                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25448                              <1> writei:
 25449                              <1> 	; 20/05/2015
 25450                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25451                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 25452                              <1> 	;
 25453                              <1> 	; Write data to file with inode number in R1
 25454                              <1> 	; 
 25455                              <1> 	; INPUTS ->
 25456                              <1> 	;    r1 - inode number
 25457                              <1> 	;    u.count - byte count to be written
 25458                              <1> 	;    u.base - points to user buffer
 25459                              <1> 	;    u.fofp - points to word with current file offset
 25460                              <1> 	; OUTPUTS ->
 25461                              <1> 	;    u.count - cleared
 25462                              <1> 	;    u.nread - accumulates total bytes passed back	
 25463                              <1> 	; ((AX = R1))
 25464                              <1> 	;    (Retro UNIX Prototype: 18/11/2012 - 11/11/2012, UNIXCOPY.ASM)
 25465                              <1> 	;    ((Modified registers: edx, ebx, ecx, esi, edi)) -15/07/2022-	
 25466                              <1> 
 25467 000050F1 31C9                <1> 	xor	ecx, ecx
 25468 000050F3 890D[906C0000]      <1> 	mov 	[u.nread], ecx  ; 0
 25469                              <1> 		; clr u.nread / clear the number of bytes transmitted during
 25470                              <1> 		            ; / read or write calls
 25471 000050F9 66890D[D06C0000]    <1> 	mov	[u.pcount], cx	; 19/05/2015
 25472 00005100 390D[8C6C0000]      <1> 	cmp 	[u.count], ecx
 25473                              <1> 	;	; tst u.count / test the byte count specified by the user
 25474 00005106 770B                <1> 	ja 	short writei_1	; 1f
 25475                              <1> 		; bgt 1f / any bytes to output; yes, branch
 25476                              <1> 
 25477                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 25478 00005108 83F810              <1> 	cmp	eax, 16  ; LPR_INODE ; lpt (parallel port printer) ?
 25479 0000510B 7505                <1> 	jne	short writei_0
 25480 0000510D E943010000          <1> 	jmp	lpr_stat	; get/read line status
 25481                              <1> writei_0:
 25482 00005112 C3                  <1> 	retn
 25483                              <1> 	;	; rts r0 / no, return - no writing to do
 25484                              <1> writei_1: ;1:
 25485                              <1> 	;	; mov r1 ,-(sp) / save the i-node number on the stack
 25486                              <1> 	;cmp 	ax, 40
 25487                              <1> 	;	; cmp r1,$40.
 25488                              <1> 	;	; / does the i-node number indicate a special file?
 25489                              <1>         ;ja	dskw 
 25490                              <1> 	;	; bgt dskw / no, branch to standard file output
 25491                              <1> 
 25492                              <1> 	; 28/11/2021
 25493 00005113 F605[D66C0000]FF    <1> 	test	byte [u.kcall], 0FFh
 25494 0000511A 750C                <1> 	jnz	short writei_2  ; 'writei' called by 'mkdir'
 25495                              <1> 
 25496                              <1> 	; eax = inode number
 25497                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 25498 0000511C E850FAFFFF          <1> 	call	iget
 25499                              <1> ;writei_2:
 25500                              <1> 	; 28/11/2021
 25501                              <1> 	; eax = inode number
 25502                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 25503 00005121 E8E2020000          <1> 	call	is_regular_file
 25504                              <1> 	;jz	dskw ; regular file 
 25505                              <1> 	; 25/12/2021
 25506 00005126 7505                <1> 	jnz	short writei_5 ; device file
 25507                              <1> writei_2:	 ; 09/03/2022 
 25508                              <1> 	; regular file
 25509 00005128 E968010000          <1> 	jmp	dskw
 25510                              <1> writei_5:
 25511                              <1> 	; (20/05/2015)
 25512 0000512D 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 25513                              <1> 	
 25514                              <1> 	; 28/11/2021	
 25515                              <1> 	; device file
 25516 0000512E BB[48510000]        <1> 	mov	ebx, writei_4
 25517 00005133 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 25518 00005136 720E                <1> 	jb	short writei_3
 25519 00005138 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 25520 0000513B 7709                <1> 	ja	short writei_3 ; 11/12/2021	
 25521                              <1> 	
 25522                              <1> 	; convert v2 inode number to v1 device inode number
 25523 0000513D 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 25524 0000513F 89C1                <1> 	mov	ecx, eax
 25525 00005141 C0E102              <1> 	shl	cl, 2 ; * 4
 25526 00005144 01CB                <1> 	add	ebx, ecx
 25527                              <1> writei_3:
 25528 00005146 FF23                <1> 	jmp	dword [ebx]	
 25529                              <1> 		; jmp *1f-2(r1)
 25530                              <1> 		; / jump table and jump to the appropriate routine
 25531                              <1> writei_4: ;1:
 25532 00005148 [7A4F0000]          <1> 	dd	null ; 28/11/2021
 25533 0000514C [98510000]          <1> 	dd	wtty ; tty, AX = 1 (runix)
 25534                              <1> 		 ;wtty / tty; r1=2
 25535                              <1> 		 ;wppt / ppt; r1=4
 25536 00005150 [EB510000]          <1> 	dd	wmem ; mem, AX = 2 (runix)
 25537                              <1> 		 ;wmem / mem; r1=6
 25538                              <1> 		 ;wrf0 / rf0
 25539                              <1> 		 ;wrk0 / rk0
 25540                              <1> 		 ;wtap / tap0
 25541                              <1> 		 ;wtap / tap1
 25542                              <1> 		 ;wtap / tap2
 25543                              <1> 		 ;wtap / tap3
 25544                              <1> 		 ;wtap / tap4
 25545                              <1> 		 ;wtap / tap5
 25546                              <1> 		 ;wtap / tap6
 25547                              <1> 		 ;wtap / tap7
 25548 00005154 [C2580000]          <1> 	dd	wfd ; fd0, AX = 3 (runix only)
 25549 00005158 [C2580000]          <1> 	dd	wfd ; fd1, AX = 4 (runix only)
 25550 0000515C [C2580000]          <1> 	dd	whd ; hd0, AX = 5 (runix only)
 25551 00005160 [C2580000]          <1> 	dd	whd ; hd1, AX = 6 (runix only)	
 25552 00005164 [C2580000]          <1> 	dd	whd ; hd2, AX = 7 (runix only)
 25553 00005168 [C2580000]          <1> 	dd	whd ; hd3, AX = 8 (runix only)	
 25554 0000516C [1B520000]          <1> 	dd	wlpr ; lpr, AX = 9   (runix)
 25555 00005170 [E5510000]          <1> 	dd	xmtt ; tty0, AX = 10 (runix)	  
 25556                              <1> 		 ;xmtt / tty0
 25557 00005174 [E5510000]          <1> 	dd	xmtt ; tty1, AX = 11 (runix)	  
 25558                              <1> 		 ;xmtt / tty1
 25559 00005178 [E5510000]          <1> 	dd	xmtt ; tty2, AX = 12 (runix)	  
 25560                              <1> 		 ;xmtt / tty2
 25561 0000517C [E5510000]          <1> 	dd	xmtt ; tty3, AX = 13 (runix)	  
 25562                              <1> 		 ;xmtt / tty3
 25563 00005180 [E5510000]          <1> 	dd	xmtt ; tty4, AX = 14 (runix)	  
 25564                              <1> 		 ;xmtt / tty4
 25565 00005184 [E5510000]          <1> 	dd	xmtt ; tty5, AX = 15 (runix)	  
 25566                              <1> 		 ;xmtt / tty5
 25567 00005188 [E5510000]          <1> 	dd	xmtt ; tty6, AX = 16 (runix)	  
 25568                              <1> 		 ;xmtt / tty6
 25569 0000518C [E5510000]          <1> 	dd	xmtt ; tty7, AX = 17 (runix)	  
 25570                              <1> 		 ;xmtt / tty7
 25571 00005190 [E5510000]          <1> 	dd	xmtt ; COM1, AX = 18 (runix only)	  
 25572                              <1> 		; / wlpr / lpr
 25573 00005194 [E5510000]          <1> 	dd	xmtt ; COM2, AX = 19 (runix only)
 25574                              <1> 
 25575                              <1> ;	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25576                              <1> ;null:
 25577                              <1> ;	xor	eax, eax
 25578                              <1> ;	pop	eax
 25579                              <1> ;	retn	
 25580                              <1> 
 25581                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 25582                              <1> wtty: ; write to console tty (write to screen)
 25583                              <1> 	; 18/11/2015
 25584                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25585                              <1> 	; 12/03/2013 - 07/07/2014 (Retro UNIX 8086 v1)
 25586                              <1> 	;
 25587                              <1> 	; Console tty output is on current video page
 25588                              <1> 	; Console tty character output procedure is changed here
 25589                              <1> 	; acconding to IBM PC compatible ROM BIOS video (text mode) functions.
 25590                              <1> 	;
 25591 00005198 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 25592 0000519F 8AA3[63680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 25593 000051A5 88E0                <1> 	mov	al, ah ; 07/07/2014
 25594                              <1> wttys:	
 25595                              <1> 	; 10/10/2013
 25596 000051A7 8825[996C0000]      <1> 	mov 	[u.ttyn], ah
 25597                              <1> 	; 13/01/2014
 25598 000051AD FEC0                <1> 	inc	al
 25599 000051AF A2[9B6C0000]        <1> 	mov	[u.ttyp+1], al ; tty number + 1
 25600                              <1> wtty_nc: ; 15/05/2013
 25601                              <1> 	; AH = [u.ttyn] = tty number ; 28/07/2013
 25602 000051B4 E870010000          <1> 	call	cpass
 25603                              <1> 		; jsr r0,cpass / get next character from user buffer area; if
 25604                              <1> 		             ; / none go to return address in syswrite
 25605                              <1> 		; tst r1 / is character = null
 25606                              <1> 		; beq wtty / yes, get next character
 25607                              <1> 	; 10/10/2013
 25608 000051B9 7428                <1> 	jz	short wret
 25609                              <1> 	;1 :
 25610                              <1> 		;mov 	$240,*$ps / no, set processor priority to five
 25611                              <1> 		;cmpb	cc+1,$20. / is character count for console tty greater
 25612                              <1> 		;	          / than 20
 25613                              <1> 		;bhis	2f / yes; branch to put process to sleep
 25614                              <1> 	; 27/06/2014
 25615                              <1> wtty_1:
 25616                              <1> 	; AH = tty number
 25617                              <1> 	; AL = ASCII code of the character
 25618                              <1> 	; 15/04/2014
 25619                              <1> 	;push	ax
 25620                              <1> 	; 11/12/2021
 25621 000051BB 50                  <1> 	push	eax
 25622 000051BC E8120A0000          <1> 	call	putc ; 14/05/2013
 25623 000051C1 731D                <1> 	jnc	short wtty_2
 25624                              <1> 	; 18/11/2015
 25625 000051C3 E827F5FFFF          <1> 	call	idle
 25626                              <1> 	;mov	ax, [esp]
 25627                              <1> 	; 11/12/2021
 25628 000051C8 8B0424              <1> 	mov	eax, [esp]
 25629 000051CB E8030A0000          <1> 	call	putc
 25630 000051D0 730E                <1> 	jnc	short wtty_2 
 25631                              <1> 	; 02/06/2014
 25632 000051D2 8A25[996C0000]      <1> 	mov	ah, [u.ttyn]
 25633 000051D8 E89FF5FFFF          <1> 	call	sleep
 25634                              <1> 	;pop	ax
 25635                              <1> 	; 11/12/2021
 25636 000051DD 58                  <1> 	pop	eax
 25637 000051DE EBDB                <1> 	jmp 	short wtty_1
 25638                              <1> 		; jc 	error ; 15/05/2013 (COM1 or COM2 serial port error)
 25639                              <1> 		; jsr 	r0,putc; 1 / find place in freelist to assign to 
 25640                              <1> 			      ; / console tty and
 25641                              <1> 		; br 	2f / place character in list; if none available
 25642                              <1> 		   	  ; / branch to put process to sleep
 25643                              <1> 		; jsr	r0,startty / attempt to output character on tty
 25644                              <1> wtty_2:
 25645                              <1> 	; 15/04/2014
 25646                              <1> 	;pop	ax
 25647                              <1> 	; 11/12/2021
 25648 000051E0 58                  <1> 	pop	eax
 25649 000051E1 EBD1                <1> 	jmp	short wtty_nc
 25650                              <1> 		; br wtty
 25651                              <1> wret:	; 10/10/2013 (20/05/2015)
 25652 000051E3 58                  <1> 	pop	eax
 25653 000051E4 C3                  <1> 	retn
 25654                              <1> 	;2:
 25655                              <1> 		;mov	r1,-(sp) / place character on stack
 25656                              <1> 		;jsr	r0,sleep; 1 / put process to sleep
 25657                              <1> 		;mov	(sp)+,r1 / remove character from stack
 25658                              <1> 		;br	1b / try again to place character in clist and output
 25659                              <1> 
 25660                              <1> xmtt:   ; < send/write character to tty >
 25661                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25662                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 25663                              <1> 	;
 25664                              <1> 	; Retro UNIX 8086 v1 modification !
 25665                              <1> 	; 
 25666                              <1> 	; In original UNIX v1, 'xmtt' routine 
 25667                              <1> 	;		(exactly different than this one)
 25668                              <1> 	;	was in 'u9.s' file.
 25669                              <1> 	;
 25670 000051E5 2C0A                <1> 	sub 	al, 10
 25671                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 25672                              <1> 	; 10/10/2013
 25673 000051E7 88C4                <1> 	mov	ah, al
 25674                              <1> 	; 28/07/2013
 25675 000051E9 EBBC                <1> 	jmp	short wttys
 25676                              <1> 
 25677                              <1> ;wppt:
 25678                              <1> ;	jsr	r0,cpass / get next character from user buffer area,
 25679                              <1> ;		         / if none return to writei's calling routine
 25680                              <1> ;	jsr	r0,pptoc / output character on ppt
 25681                              <1> ;	br	wppt
 25682                              <1> 
 25683                              <1> wmem: ; / transfer characters from a user area of core to memory file
 25684                              <1> 	; 17/10/2015
 25685                              <1> 	; 11/06/2015
 25686                              <1> 	; 24/05/2015
 25687                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 25688                              <1> 	;
 25689 000051EB 813D[09070000]-     <1> 	cmp	dword [x_timer], clock ; multi tasking clock/timer
 25690 000051F1 [12470000]          <1>
 25691 000051F5 7415                <1>         je      short wmem_acc_err
 25692                              <1> 	;
 25693 000051F7 8B35[786C0000]      <1>         mov     esi, [u.fofp] 
 25694                              <1> wmem_1:
 25695 000051FD E827010000          <1> 	call	cpass
 25696                              <1> 		; jsr r0,cpass / get next character from users area of
 25697                              <1> 			     ; / core and put it in r1
 25698                              <1>         	; mov r1,-(sp) / put character on the stack
 25699                              <1> 	; 20/09/2013
 25700 00005202 74DF                <1> 	jz	short wret ; wmem_2  
 25701 00005204 8B1E                <1>         mov     ebx, [esi]
 25702                              <1> 		; mov *u.fofp,r1 / save file offset in r1
 25703 00005206 FF06                <1>         inc     dword [esi] ; 17/10/2015
 25704                              <1> 		; inc *u.fofp / increment file offset to point to next
 25705                              <1> 			    ; / available location in file
 25706 00005208 8803                <1> 	mov	[ebx], al	
 25707                              <1> 		; movb (sp)+,(r1) / pop char off stack, put in memory loc 
 25708                              <1> 			        ; / assigned to it
 25709 0000520A EBF1                <1> 	jmp	short wmem_1
 25710                              <1> 		; br wmem / continue
 25711                              <1> 	;1:
 25712                              <1> 	;jmp	error / ?
 25713                              <1> ;wmem_2:	
 25714                              <1> ;	; 20/09/2013
 25715                              <1> ;	pop	ax
 25716                              <1> ;	retn
 25717                              <1> 
 25718                              <1> wmem_acc_err:
 25719 0000520C C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 25720 00005214 0000                <1>
 25721 00005216 E946DFFFFF          <1> 	jmp	error
 25722                              <1> 
 25723                              <1> ;wlpr:
 25724                              <1> 	; 12/06/2022
 25725                              <1> 	;mov	dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 25726                              <1> 	;jmp 	error   ; ... Printing procedure will be located here ...
 25727                              <1> 		;/	jsr	r0,cpass
 25728                              <1> 		;/	cmp	r0,$'a
 25729                              <1> 		;/	blo	1f
 25730                              <1> 		;/	cmp	r1,$'z
 25731                              <1> 		;/	bhi	1f
 25732                              <1> 		;/	sub	$40,r1
 25733                              <1> 		;/1:
 25734                              <1> 		;/	jsr	r0,lptoc
 25735                              <1> 		;/	br	wlpr
 25736                              <1> 		; br rmem / continue
 25737                              <1> 
 25738                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - PRINTER BIOS (Functions)
 25739                              <1> 
 25740                              <1> ;; Ref: MSDOS 3.3 (Retro DOS 3.2) Printer driver code (MSLPT.ASM)
 25741                              <1> ;; MSLPT.ASM - MSDOS 3.3 - 24/07/1987
 25742                              <1> ;; 23/03/2018 - Retro DOS v2.0
 25743                              <1> ;; RETRODOS32.ASM - 03/08/2019 (Retro DOS v3.2)
 25744                              <1> 
 25745                              <1> ; IBM ROMBIOS (INT 17h) STATUS BITS
 25746                              <1> 
 25747                              <1> NOTBUSYSTATUS	equ 10000000b	; NOT BUSY
 25748                              <1> ACKSTATUS	equ 01000000b	; ACKNOWLEDGE (FOR WHAT?)
 25749                              <1> NOPAPERSTATUS	equ 00100000b	; NO MORE PAPER
 25750                              <1> SELECTEDSTATUS	equ 00010000b	; THE PRINTER SAID IT WAS SELECTED
 25751                              <1> IOERRSTATUS	equ 00001000b	; SOME KIND ERROR
 25752                              <1> RESERVED	equ 00000110b	; NOPS
 25753                              <1> TIMEOUTSTATUS	equ 00000001b	; TIME OUT.
 25754                              <1> 
 25755                              <1> ;----------------------------------------------------------------
 25756                              <1> ;								:
 25757                              <1> ;		WRITE TO PRINTER DEVICE 			:
 25758                              <1> ;								:
 25759                              <1> ;   CX has count of bytes to be printed 			:
 25760                              <1> ;   ES:DI point to source buffer contains characters		:
 25761                              <1> ;   AuxNum (in msbio.asm) has printer number			:
 25762                              <1> ;								:
 25763                              <1> ;----------------------------------------------------------------
 25764                              <1> 
 25765                              <1> wlpr:
 25766                              <1> 	; 15/07/2022
 25767                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 25768                              <1> PRN$WRIT:
 25769                              <1> 	; INPUT:
 25770                              <1> 	;	[u.count] = count of characters to be printed
 25771                              <1> 	;	[u.base] = buffer address in user's memory space
 25772                              <1> 	;
 25773                              <1> 	;	(if ECX = 0, printer status will be returned)
 25774                              <1> 	
 25775                              <1> 	;xor	ebx, ebx
 25776                              <1> PRN$LOOP:
 25777 0000521B E809010000          <1> 	call	cpass		  ; Get a character into AL
 25778 00005220 7431                <1> 	jz	short pr_exit
 25779                              <1> 	;
 25780 00005222 B302                <1> 	mov	bl, 2  ; retry count
 25781                              <1> PRN$OUT:
 25782                              <1> 	; al = character which will be printed
 25783 00005224 30E4                <1> 	xor	ah, ah ; 0	  ; PRINT THE CHARACTER IN (AL)
 25784 00005226 E850000000          <1> 	call	PRNOP
 25785 0000522B 74EE                <1> 	jz	short PRN$LOOP 	  ; if error, try to print again
 25786                              <1> PrRetry:
 25787                              <1> 	; al = character
 25788 0000522D FECB                <1> 	dec	bl
 25789 0000522F 75F3                <1> 	jnz	short PRN$OUT
 25790                              <1> pr_err_exit:
 25791 00005231 0FB6C0              <1> 	movzx	eax, al
 25792 00005234 A3[D86C0000]        <1> 	mov	[u.error], eax
 25793 00005239 A3[646C0000]        <1> 	mov	[u.r0], eax ; error code in AL
 25794                              <1> 	;mov 	ebp, [u.sp]
 25795 0000523E 8B1D[5C6C0000]      <1> 	mov	ebx, [u.sp] ; 15/07/2022
 25796                              <1> 			; Kernel stack at the beginning of sys call
 25797 00005244 8B15[906C0000]      <1> 	mov	edx, [u.nread]
 25798 0000524A 4A                  <1> 	dec	edx ; last char failed
 25799                              <1> 	;mov	[ebp+20], edx ; count of printed characters in edx
 25800 0000524B 895314              <1> 	mov	[ebx+20], edx ; 15/07/2022
 25801 0000524E E90EDFFFFF          <1> 	jmp	error
 25802                              <1> pr_exit:
 25803 00005253 58                  <1> 	pop	eax ; inode number
 25804                              <1> 
 25805                              <1> 	;mov	eax, [u.nread]
 25806                              <1> 	;mov	[u.r0], eax ; count of printed chacters
 25807                              <1> 	;jmp	sysret
 25808 00005254 C3                  <1> 	retn	; return from writei to syswrite (rw0)
 25809                              <1> 
 25810                              <1> ; 12/06/2022
 25811                              <1> 
 25812                              <1> ;----------------------------------------------------------------
 25813                              <1> ;								:
 25814                              <1> ;		PRINTER STATUS ROUTINE				:
 25815                              <1> ;								:
 25816                              <1> ;----------------------------------------------------------------
 25817                              <1> ;
 25818                              <1> 	
 25819                              <1> lpr_stat:
 25820                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2					   
 25821                              <1> PRN$STAT:
 25822 00005255 E81F000000          <1> 	call	PRNSTAT		  ; get the status
 25823 0000525A 750E                <1> 	jnz	short prn_stat_retn
 25824                              <1> 				  ; if error jump to error routine
 25825                              <1> 	;mov	al, 9		  ; AGAIN, ASSUME OUT OF PAPER...    
 25826 0000525C B01F                <1> 	mov	al, ERR_PRN_PAPER
 25827 0000525E F6C420              <1> 	test	ah, NOPAPERSTATUS					   
 25828 00005261 7507                <1> 	jnz	short prn_stat_retn
 25829 00005263 F6C480              <1> 	test	ah, NOTBUSYSTATUS					   
 25830 00005266 750D                <1> 	jnz	short prn_stat_ok ; if not busy return (with cf=0)
 25831 00005268 B022                <1> 	mov	al, ERR_PRN_BUSY  ; else busy, return to busy exit
 25832                              <1> prn_stat_retn:
 25833                              <1> 	; al = error code
 25834                              <1> 	; ah = status flags
 25835 0000526A A3[646C0000]        <1> 	mov	[u.r0], eax
 25836                              <1> 	;movzx	eax, al
 25837                              <1> 	;mov 	[u.error], eax
 25838 0000526F 58                  <1> 	pop	eax ; discard return address to syswrite
 25839 00005270 E90CDFFFFF          <1> 	jmp	sysret
 25840                              <1> prn_stat_ok:
 25841 00005275 30C0                <1> 	xor	al, al ; 0
 25842 00005277 EBF1                <1> 	jmp	short prn_stat_retn
 25843                              <1> 
 25844                              <1> ;
 25845                              <1> ;   PRNSTAT	get printer status
 25846                              <1> ;   PRNOP	print a character
 25847                              <1> ;
 25848                              <1> ; PRNSTAT and PRNOP are two routines which call on the ROM-BIOS
 25849                              <1> ; printer routines.  The routines share code which calls on the bios and
 25850                              <1> ; then determines which, if any, error occured. PRNSTAT and PRNOP differ
 25851                              <1> ; only by the value put into AH before the ROM-BIOS call.
 25852                              <1> ;
 25853                              <1> ;   INPUT	if PRNOP then character in AL
 25854                              <1> ;
 25855                              <1> ;   OUTPUT	- AL holds error code
 25856                              <1> ;		- AH status byte from printer
 25857                              <1> ;		- flag NZ if error
 25858                              <1> 
 25859                              <1> PRNSTAT:						   
 25860 00005279 B402                <1> 	mov	ah, 2		  ; set command for get status 
 25861                              <1> 
 25862                              <1> PRNOP:
 25863                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 25864                              <1> 	;
 25865                              <1> 	; Print character (on paper)
 25866                              <1> 
 25867                              <1> 	; INPUT:
 25868                              <1> 	;	al = character to be printed
 25869                              <1> 	; OUTPUT:
 25870                              <1> 	;	zf = 1 -> ok
 25871                              <1> 	;	zf = 0 -> error code in AL
 25872                              <1> 
 25873 0000527B E8A20B0000          <1> 	call	int17h	 ; call lpt bios
 25874                              <1> 	
 25875 00005280 F6C408              <1> 	test	ah, IOERRSTATUS	  ; I/O ERROR?			   
 25876 00005283 740A                <1> 	jz	short short prnop_chk_nrdy ; NO, TRY NOT READY
 25877                              <1> 
 25878                              <1> 	; AT THIS POINT, WE KNOW WE HAVE AN ERROR.
 25879                              <1> 	; THE CONVERSE IS NOT TRUE.	   
 25880                              <1> 									   
 25881                              <1> 	;mov	al, 9		  ; FIRST, ASSUME OUT OF PAPER	   
 25882 00005285 B01F                <1> 	mov	al, ERR_PRN_PAPER
 25883 00005287 F6C420              <1> 	test	ah, NOPAPERSTATUS ; OUT OF PAPER SET?		   
 25884 0000528A 7502                <1> 	jnz	short PRNOP1	  ; YES, ERROR IS SET
 25885                              <1> 	;mov	al, ERR_PRN_IO
 25886 0000528C FEC0                <1> 	inc	al		  ; INDICATE I/O ERROR		   
 25887                              <1> PRNOP1:									   
 25888                              <1> 									   
 25889                              <1> ; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT)	   
 25890                              <1> 									   
 25891 0000528E C3                  <1> 	retn			  ; RETURN WITH ERROR		   
 25892                              <1> 									   
 25893                              <1> ; THE BITS SAID NO ERROR.
 25894                              <1> ; UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WORK HERE. 								   
 25895                              <1> 									   
 25896                              <1> prnop_chk_nrdy:								   
 25897                              <1> 	;mov	al, 2		  ; ASSUME NOT-READY		   
 25898 0000528F B019                <1> 	mov	al, ERR_PRN_TIMEOUT ; ''time out !' error
 25899                              <1> 	
 25900 00005291 F6C401              <1> 	test	ah, TIMEOUTSTATUS ; IS TIME-OUT SET?		   
 25901                              <1> 				  ; IF NZ THEN ERROR, ELSE OK???
 25902                              <1> PRNOP2: 
 25903 00005294 C3                  <1> 	retn
 25904                              <1> 
 25905                              <1> 
 25906                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 25907                              <1> 
 25908                              <1> dskw: ; / write routine for non-special files
 25909                              <1> 	;
 25910                              <1> 	; 19/07/2022
 25911                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 25912                              <1> 	; 28/11/2021
 25913                              <1> 	; 25/07/2015
 25914                              <1> 	; 16/06/2015
 25915                              <1> 	; 09/06/2015
 25916                              <1> 	; 31/05/2015 (Retro UNIX 386 v1 - Beginning)
 25917                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
 25918                              <1> 
 25919                              <1> 	; 01/08/2013 (mkdir_w check)
 25920                              <1> 	;push	ax ; 26/04/2013
 25921                              <1> 	;	; mov (sp),r1 / get an i-node number from the stack into r1
 25922                              <1> 	; 28/11/2021
 25923 00005295 50                  <1> 	push	eax
 25924                              <1> 	; AX = inode number
 25925 00005296 E8D6F8FFFF          <1> 	call	iget
 25926                              <1> 		; jsr r0,iget / write i-node out (if modified), 
 25927                              <1> 		            ; / read i-node 'r1' into i-node area of core
 25928 0000529B 8B1D[786C0000]      <1>         mov     ebx, [u.fofp] 
 25929 000052A1 8B13                <1> 	mov 	edx, [ebx]
 25930                              <1> 		; mov *u.fofp,r2 / put the file offset [(u.off) or the offset
 25931                              <1> 			       ; / in the fsp entry for this file] in r2
 25932 000052A3 0315[8C6C0000]      <1> 	add 	edx, [u.count]	
 25933                              <1> 		; add u.count,r2 / no. of bytes to be written
 25934                              <1> 			       ; / + file offset is put in r2
 25935                              <1> 	;; 16/06/2015        
 25936                              <1> 	;cmp	edx, 65535 ; file size limit (for UNIX v1 file system)
 25937                              <1> 	;jna	short dskw_0
 25938                              <1> 	;mov	dword [u.error], ERR_FILE_SIZE ; 'file size error !'
 25939                              <1> 	;jmp	error
 25940                              <1> dskw_0:	
 25941                              <1> 	; 28/11/2021
 25942 000052A9 3B15[EC670000]      <1> 	cmp	edx, [i.size] ; 32 bit file size (runix v2 inode)
 25943                              <1> 	;cmp	dx, [i.size]
 25944                              <1> 	;	; cmp r2,i.size / is this greater than the present size of
 25945                              <1> 		              ; / the file?
 25946 000052AF 760B                <1> 	jna	short dskw_1
 25947                              <1> 		; blos 1f / no, branch
 25948 000052B1 8915[EC670000]      <1> 	mov	[i.size], edx ; 32 bit file size (runix v2 inode)
 25949                              <1> 	;mov	[i.size], dx
 25950                              <1> 	 	; mov r2,i.size / yes, increase the file size to 
 25951                              <1> 			      ; / file offset + no. of data bytes
 25952 000052B7 E846FAFFFF          <1> 	call	setimod
 25953                              <1> 	 	; jsr r0,setimod / set imod=1 (i.e., core inode has been
 25954                              <1> 		          ; / modified), stuff time of modification into
 25955                              <1> 	          	  ; / core image of i-node
 25956                              <1> dskw_1: ; 1:
 25957                              <1> 	; 28/11/2021
 25958                              <1> 	;call	mget
 25959 000052BC E833F5FFFF          <1> 	call	mget_w
 25960                              <1> 		; jsr r0,mget / get the block no. in which to write 
 25961                              <1> 			    ; /	the next data byte
 25962                              <1> 	; eax = physical block/sector number
 25963 000052C1 8B1D[786C0000]      <1> 	mov     ebx, [u.fofp]
 25964 000052C7 8B13                <1> 	mov	edx, [ebx]
 25965 000052C9 81E2FF010000        <1> 	and	edx, 1FFh  
 25966                              <1> 		; bit *u.fofp,$777 / test the lower 9 bits of the file offset
 25967 000052CF 750C                <1> 	jnz	short dskw_2
 25968                              <1> 		; bne 2f / if its non-zero, branch; if zero, file offset = 0,
 25969                              <1> 		       ; / 512, 1024,...(i.e., start of new block)
 25970 000052D1 813D[8C6C0000]0002- <1> 	cmp	dword [u.count], 512
 25971 000052D9 0000                <1>
 25972                              <1> 		; cmp u.count,$512. / if zero, is there enough data to fill
 25973                              <1> 				  ; / an entire block? (i.e., no. of
 25974 000052DB 7305                <1> 	jnb	short dskw_3
 25975                              <1> 		; bhis 3f / bytes to be written greater than 512.? 
 25976                              <1> 			; / Yes, branch. Don't have to read block
 25977                              <1> dskw_2: ; 2: / in as no past info. is to be saved (the entire block will be
 25978                              <1>    		; / overwritten).
 25979 000052DD E8AA060000          <1> 	call	dskrd
 25980                              <1> 		; jsr r0,dskrd / no, must retain old info.. 
 25981                              <1> 			     ; / Hence, read block 'r1' into an I/O buffer
 25982                              <1> dskw_3: ; 3:
 25983                              <1> 	; EAX (r1) = block/sector number
 25984 000052E2 E809070000          <1> 	call	wslot
 25985                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
 25986                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
 25987 000052E7 803D[D66C0000]00    <1> 	cmp	byte [u.kcall], 0
 25988 000052EE 770F                <1> 	ja	short dskw_5 ; zf=0 -> the caller is 'mkdir'
 25989                              <1> 	;
 25990 000052F0 66833D[D06C0000]00  <1> 	cmp	word [u.pcount], 0
 25991 000052F8 7705                <1> 	ja	short dskw_5
 25992                              <1> dskw_4:
 25993                              <1> 	; [u.base] = virtual address to transfer (as source address)
 25994 000052FA E895FDFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 25995                              <1> dskw_5:
 25996                              <1> 	; eBX (r5) = system (I/O) buffer address
 25997 000052FF E885000000          <1> 	call	sioreg
 25998                              <1> 		; jsr r0,sioreg / r3 = no. of bytes of data, 
 25999                              <1> 			     ; / r1 = address of data, r2 points to location
 26000                              <1> 			     ; / in buffer in which to start writing data
 26001                              <1> 	; 19/07/2022
 26002                              <1> 	;  EDX = user data offset (previous value of [u.pbase])
 26003                              <1> 	;  ESI = pointer to file offset 
 26004                              <1> 	;  EDI = system (I/O) buffer offset
 26005                              <1> 	;  ECX = byte count
 26006                              <1> 	;  EBX = system buffer (data) address	
 26007                              <1> 	;  EAX = remain bytes after byte count within page frame 
 26008                              <1> 
 26009                              <1> 	; 19/07/2022 - Erdogan Tan
 26010                              <1> 	; BugFix (Also original unix v1 kernel code has this bug!)
 26011                              <1> 	; ((Against a possible disk write failure/error, 
 26012                              <1> 	;   file offset must not be updated/increased before 'dskwr'
 26013                              <1> 	;   but it was updated in 'sioreg'. I have modified 'sioreg'
 26014                              <1> 	;   and 'dskw' procedures for that.))
 26015                              <1> 
 26016                              <1> 	; 19/07/2022
 26017 00005304 56                  <1> 	push	esi ; *	 ; save file offset (pointer)
 26018 00005305 51                  <1> 	push	ecx ; ** ; save byte count
 26019 00005306 89D6                <1> 	mov	esi, edx
 26020                              <1> 
 26021                              <1> 	; ESI = file (user data) offset
 26022                              <1> 	; EDI = sector (I/O) buffer offset
 26023                              <1> 	; ECX = byte count
 26024                              <1> 	;
 26025 00005308 F3A4                <1>   	rep	movsb
 26026                              <1> 		; movb (r1 )+,(r2)+ 
 26027                              <1> 		         ; / transfer a byte of data to the I/O buffer
 26028                              <1> 		; dec r3 / decrement no. of bytes to be written
 26029                              <1> 		; bne 2b / have all bytes been transferred? No, branch
 26030                              <1> 	; 25/07/2015
 26031                              <1> 	; eax = remain bytes in buffer
 26032                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 26033 0000530A 09C0                <1> 	or	eax, eax
 26034 0000530C 75EC                <1> 	jnz	short dskw_4 ; (page end before system buffer end!)	
 26035                              <1> dskw_6:
 26036 0000530E E8EA060000          <1> 	call	dskwr
 26037                              <1> 		; jsr r0,dskwr / yes, write the block and the i-node
 26038                              <1> 
 26039                              <1> 	; 19/07/2022
 26040                              <1> 	; (there is not a disk write error, we can increase file offset)
 26041 00005313 58                  <1> 	pop	eax ; ** ; byte count
 26042 00005314 5F                  <1> 	pop	edi ; *  ; file offset (pointer)
 26043                              <1> 	;
 26044 00005315 0107                <1> 	add	[edi], eax
 26045                              <1> 			; new file offset (old offset + byte count)
 26046                              <1> 
 26047 00005317 833D[8C6C0000]00    <1>         cmp     dword [u.count], 0
 26048                              <1> 		; tst u.count / any more data to write?
 26049 0000531E 779C                <1> 	ja	short dskw_1
 26050                              <1> 		; bne 1b / yes, branch
 26051                              <1> 	; 03/08/2013
 26052 00005320 C605[D66C0000]00    <1> 	mov	byte [u.kcall], 0
 26053                              <1> 	; 20/09/2013 (;;)
 26054                              <1> 	;pop	ax
 26055                              <1> 	; 28/11/2021
 26056 00005327 58                  <1> 	pop	eax  
 26057 00005328 C3                  <1> 	retn
 26058                              <1> 	;;jmp 	short dskw_ret 
 26059                              <1> 	        ; jmp ret / no, return to the caller via 'ret'
 26060                              <1> 
 26061                              <1> 	; 24/12/2021
 26062                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 26063                              <1> cpass: ; / get next character from user area of core and put it in r1
 26064                              <1> 	; 18/10/2015
 26065                              <1> 	; 10/10/2015
 26066                              <1> 	; 10/07/2015
 26067                              <1> 	; 02/07/2015
 26068                              <1> 	; 01/07/2015
 26069                              <1> 	; 24/06/2015
 26070                              <1> 	; 08/06/2015
 26071                              <1> 	; 04/06/2015
 26072                              <1> 	; 20/05/2015
 26073                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 26074                              <1> 	;
 26075                              <1> 	; INPUTS -> 
 26076                              <1> 	;     [u.base] = virtual address in user area
 26077                              <1> 	;     [u.count] = byte count (max.)
 26078                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
 26079                              <1> 	; OUTPUTS -> 
 26080                              <1> 	;     AL = the character which is pointed by [u.base]
 26081                              <1> 	;     zf = 1 -> transfer count has been completed	
 26082                              <1>         ;
 26083                              <1> 	; ((Modified registers: EAX, EDX, ECX))
 26084                              <1> 	;
 26085                              <1> 	;
 26086 00005329 833D[8C6C0000]00    <1> 	cmp 	dword [u.count], 0  ; 14/08/2013
 26087                              <1> 		; tst u.count / have all the characters been transferred
 26088                              <1> 			    ; / (i.e., u.count, # of chars. left
 26089 00005330 763F                <1> 	jna	short cpass_3
 26090                              <1> 		; beq 1f / to be transferred = 0?) yes, branch
 26091 00005332 FF0D[8C6C0000]      <1> 	dec	dword [u.count]
 26092                              <1> 		; dec u.count / no, decrement u.count
 26093                              <1>         ; 19/05/2015 
 26094                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
 26095                              <1> 	;		      to physical address
 26096 00005338 66833D[D06C0000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 26097                              <1> 			     ; 1-4095 --> use previous physical base address
 26098                              <1> 			     ; in [u.pbase]
 26099 00005340 770E                <1> 	ja	short cpass_1
 26100                              <1> 	; 02/07/2015
 26101 00005342 833D[C86C0000]00    <1> 	cmp	dword [u.ppgdir], 0  ; is the caller os kernel
 26102 00005349 7427                <1> 	je	short cpass_k 	; (sysexec, '/etc/init') ? 
 26103                              <1> 	; 08/06/2015 - 10/07/2015
 26104 0000534B E844FDFFFF          <1> 	call	trans_addr_r
 26105                              <1> cpass_1:
 26106                              <1> 	; 02/07/2015
 26107                              <1> 	; 24/06/2015
 26108 00005350 66FF0D[D06C0000]    <1> 	dec	word [u.pcount]
 26109                              <1> cpass_2: 
 26110                              <1> 	; 10/10/2015
 26111                              <1> 	; 02/07/2015
 26112 00005357 8B15[CC6C0000]      <1> 	mov	edx, [u.pbase]
 26113 0000535D 8A02                <1> 	mov	al, [edx] ; 10/10/2015
 26114                              <1> 		; movb *u.base,r1 / take the character pointed to 
 26115                              <1> 				; / by u.base and put it in r1
 26116 0000535F FF05[906C0000]      <1> 	inc	dword [u.nread]
 26117                              <1> 		; inc u.nread / increment no. of bytes transferred
 26118 00005365 FF05[886C0000]      <1> 	inc	dword [u.base]
 26119                              <1> 		; inc u.base / increment the buffer address to point to the
 26120                              <1> 			   ; / next byte
 26121 0000536B FF05[CC6C0000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 26122                              <1> cpass_3:
 26123 00005371 C3                  <1> 	retn
 26124                              <1> 		; rts	r0 / next byte
 26125                              <1> 	; 1: 
 26126                              <1> 		; mov (sp)+,r0 
 26127                              <1> 		         ; / put return address of calling routine into r0
 26128                              <1> 		; mov (sp)+,r1 / i-number in r1
 26129                              <1> 		; rts r0 / non-local return
 26130                              <1> cpass_k:
 26131                              <1> 	; 02/07/2015
 26132                              <1> 	; The caller is os kernel 
 26133                              <1> 	; (get sysexec arguments from kernel's memory space)
 26134                              <1> 	;
 26135 00005372 8B1D[886C0000]      <1> 	mov	ebx, [u.base]
 26136 00005378 66C705[D06C0000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
 26137 00005380 10                  <1>
 26138 00005381 891D[CC6C0000]      <1> 	mov	[u.pbase], ebx
 26139 00005387 EBCE                <1> 	jmp	short cpass_2
 26140                              <1> 	
 26141                              <1> sioreg: 
 26142                              <1> 	; 19/07/2022
 26143                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 26144                              <1> 	; 25/07/2015
 26145                              <1> 	; 18/07/2015
 26146                              <1> 	; 02/07/2015
 26147                              <1> 	; 17/06/2015
 26148                              <1> 	; 09/06/2015
 26149                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 26150                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
 26151                              <1> 	;
 26152                              <1> 	; INPUTS -> 
 26153                              <1> 	;     EBX = system buffer (data) address (r5)
 26154                              <1> 	;     [u.fofp] = pointer to file offset pointer
 26155                              <1> 	;     [u.base] = virtual address of the user buffer
 26156                              <1> 	;     [u.pbase] = physical address of the user buffer
 26157                              <1> 	;     [u.count] = byte count
 26158                              <1> 	;     [u.pcount] = byte count within page frame 			
 26159                              <1> 	; OUTPUTS -> 
 26160                              <1> 	;     ESI = user data offset (r1)
 26161                              <1> 	;     EDI = system (I/O) buffer offset (r2)
 26162                              <1> 	;     ECX = byte count (r3)
 26163                              <1> 	;     EAX = remain bytes after byte count within page frame
 26164                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
 26165                              <1>         ;
 26166                              <1> 	; ((Modified registers:  EDX))
 26167                              <1> 
 26168                              <1> 	; 19/07/2022
 26169                              <1> 	; OUTPUTS -> 
 26170                              <1> 	;	EDX = user data offset (previous value of [u.pbase])
 26171                              <1> 	;	ESI = pointer to file offset 
 26172                              <1> 	; 	EDI = system (I/O) buffer offset
 26173                              <1> 	;	ECX = byte count
 26174                              <1> 	;	EBX = system buffer (data) address	
 26175                              <1> 	;	EAX = remain bytes after byte count within page frame
 26176                              <1>  
 26177 00005389 8B35[786C0000]      <1>         mov     esi, [u.fofp]
 26178 0000538F 8B3E                <1>         mov     edi, [esi]
 26179                              <1> 		; mov *u.fofp,r2 / file offset (in bytes) is moved to r2
 26180 00005391 89F9                <1> 	mov	ecx, edi
 26181                              <1> 		; mov r2,r3 / and also to r3
 26182 00005393 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
 26183                              <1> 		; bis $177000,r3 / set bits 9,...,15 of file offset in r3
 26184 00005399 81E7FF010000        <1> 	and	edi, 1FFh
 26185                              <1> 		; bic $!777,r2 / calculate file offset mod 512.
 26186 0000539F 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
 26187                              <1> 		; add r5,r2 / r2 now points to 1st byte in system buffer
 26188                              <1> 			  ; / where data is to be placed
 26189                              <1>                 ; mov u.base,r1 / address of data is in r1
 26190 000053A1 F7D9                <1> 	neg	ecx
 26191                              <1> 		; neg r3 / 512 - file offset (mod512.) in r3 
 26192                              <1> 		       ; / (i.e., the no. of free bytes in the file block)
 26193 000053A3 3B0D[8C6C0000]      <1> 	cmp	ecx, [u.count]
 26194                              <1> 		; cmp r3,u.count / compare this with the no. of data bytes
 26195                              <1> 			       ; / to be written to the file
 26196 000053A9 7606                <1> 	jna	short sioreg_0
 26197                              <1> 		; blos	2f / if less than branch. Use the no. of free bytes
 26198                              <1> 			 ; / in the file block as the number to be written
 26199 000053AB 8B0D[8C6C0000]      <1> 	mov	ecx, [u.count]
 26200                              <1> 		; mov u.count,r3 / if greater than, use the no. of data 
 26201                              <1> 			       ; / bytes as the number to be written
 26202                              <1> sioreg_0:
 26203                              <1> 	; 17/06/2015
 26204 000053B1 803D[D66C0000]00    <1> 	cmp	byte [u.kcall], 0 
 26205 000053B8 7613                <1> 	jna	short sioreg_1
 26206                              <1> 	; 25/07/2015
 26207                              <1> 	 ; the caller is 'mkdir' or 'namei'
 26208 000053BA A1[886C0000]        <1> 	mov	eax, [u.base] ; 25/07/2015
 26209 000053BF A3[CC6C0000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
 26210 000053C4 66890D[D06C0000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
 26211 000053CB EB0B                <1> 	jmp	short sioreg_2
 26212                              <1> sioreg_1:
 26213                              <1> 	; 25/07/2015
 26214                              <1> 	; 18/07/2015
 26215                              <1> 	; 09/06/2015 
 26216 000053CD 0FB715[D06C0000]    <1> 	movzx	edx, word [u.pcount]
 26217                              <1> 		; ecx and [u.pcount] are always > 0, here
 26218 000053D4 39D1                <1> 	cmp	ecx, edx	
 26219 000053D6 7728                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
 26220                              <1> sioreg_2: ; 2:
 26221 000053D8 31C0                <1> 	xor 	eax, eax ; 25/07/2015
 26222                              <1> sioreg_3:
 26223 000053DA 010D[906C0000]      <1> 	add 	[u.nread], ecx
 26224                              <1> 		; add r3,u.nread / r3 + number of bytes xmitted 
 26225                              <1> 			         ; / during write is put into u.nread
 26226 000053E0 290D[8C6C0000]      <1> 	sub 	[u.count], ecx
 26227                              <1> 		; sub r3,u.count / u.count = no. of bytes that still 
 26228                              <1> 			       ; / must be written or read
 26229 000053E6 010D[886C0000]      <1> 	add 	[u.base], ecx
 26230                              <1> 		; add r3,u.base / u.base points to the 1st of the remaining
 26231                              <1> 			      ; / data bytes
 26232                              <1>         ; 19/07/2022
 26233                              <1> 	;add 	[esi], ecx 
 26234                              <1> 	;	; add r3,*u.fofp / new file offset = number of bytes done
 26235                              <1> 			       ; / + old file offset
 26236                              <1> 	; 25/07/2015
 26237                              <1> 	;mov	esi, [u.pbase]
 26238                              <1> 	; 19/07/2022
 26239 000053EC 8B15[CC6C0000]      <1> 	mov	edx, [u.pbase]
 26240                              <1> 
 26241 000053F2 66290D[D06C0000]    <1> 	sub	[u.pcount], cx
 26242 000053F9 010D[CC6C0000]      <1> 	add	[u.pbase], ecx
 26243 000053FF C3                  <1>         retn
 26244                              <1> 		; rts r0
 26245                              <1> 		; transfer count > [u.pcount]
 26246                              <1> sioreg_4:
 26247                              <1> 	; 25/07/2015
 26248                              <1> 	; transfer count > [u.pcount] 
 26249                              <1> 	; (ecx > edx)
 26250 00005400 89C8                <1> 	mov	eax, ecx
 26251 00005402 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
 26252 00005404 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
 26253 00005406 EBD2                <1> 	jmp	short sioreg_3
 26254                              <1> 
 26255                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 26256                              <1> is_regular_file:
 26257                              <1> 	; check if it is a regular file or device file inode
 26258                              <1> 	;
 26259                              <1> 	; INPUT:
 26260                              <1> 	;	current inode
 26261                              <1> 	; OUTPUT:
 26262                              <1> 	;	cf = 0 and zf = 1 -> regular file
 26263                              <1> 	;	cf = 0 and zf = 0 -> device file
 26264                              <1> 	;	cf = 1 -> invalid file (jump to 'error')
 26265                              <1> 	;
 26266                              <1> 	; Modified registers: ecx (cl)
 26267                              <1> 
 26268                              <1> 	; 28/11/2021
 26269 00005408 8A0D[E5670000]      <1> 	mov	cl, [i.flgs+1]
 26270 0000540E F6C180              <1> 	test	cl, 80h		; regular file ?
 26271 00005411 7514                <1> 	jnz	short isregf_1  ; yes 
 26272 00005413 80E120              <1> 	and	cl, 20h 	; device file ?
 26273 00005416 7511                <1> 	jnz	short isregf_2  ; yes 
 26274                              <1> 
 26275                              <1> 	; 28/11/2021
 26276                              <1> 	; invalid inode/file type !
 26277 00005418 C705[D86C0000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
 26278 00005420 0000                <1>
 26279                              <1> 	;stc
 26280                              <1> 	;retn
 26281 00005422 E93ADDFFFF          <1> 	jmp	error
 26282                              <1> isregf_1:
 26283 00005427 30C9                <1> 	xor	cl, cl  ; cl = 0
 26284                              <1> 	; zf = 1
 26285                              <1> 	;retn
 26286                              <1> isregf_2:
 26287                              <1> 	; zf = 0
 26288                              <1> 	; cl = 20h
 26289 00005429 C3                  <1> 	retn	
 26290                                  %include 'u7.s'      ; 18/04/2015
 26291                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 26292                              <1> ; (re-write kernel for test by using previous version without a major defect)
 26293                              <1> ; ****************************************************************************
 26294                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - SYS7.INC
 26295                              <1> ; Last Modification: 12/06/2022
 26296                              <1> ; ----------------------------------------------------------------------------
 26297                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 26298                              <1> ; (v0.1 - Beginning: 11/07/2012)
 26299                              <1> ;
 26300                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 26301                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 26302                              <1> ; <Bell Laboratories (17/3/1972)>
 26303                              <1> ; <Preliminary Release of UNIX Implementation Document>
 26304                              <1> ;
 26305                              <1> ; Retro UNIX 8086 v1 - U7.ASM (13/07/2014) //// UNIX v1 -> u7.s
 26306                              <1> ;
 26307                              <1> ; ****************************************************************************
 26308                              <1> 
 26309                              <1> sysmount: ; / mount file system; args special; name
 26310                              <1> 	; 15/05/2022
 26311                              <1> 	; 09/05/2022
 26312                              <1> 	;	 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 26313                              <1> 	; 08/02/2022
 26314                              <1> 	; 07/02/2022
 26315                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
 26316                              <1> 	; 14/11/2015
 26317                              <1> 	; 24/10/2015
 26318                              <1> 	; 13/10/2015
 26319                              <1> 	; 10/07/2015
 26320                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 26321                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 26322                              <1> 	;
 26323                              <1> 	; 'sysmount' anounces to the system that a removable 
 26324                              <1> 	; file system has been mounted on a special file.
 26325                              <1> 	; The device number of the special file is obtained via
 26326                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
 26327                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
 26328                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
 26329                              <1> 	; to read file system into core, i.e. the first block on the
 26330                              <1> 	; mountable file system is read in. This block is super block
 26331                              <1> 	; for the file system. This call is super user restricted.	
 26332                              <1> 	;
 26333                              <1> 	; Calling sequence:
 26334                              <1> 	;	sysmount; special; name
 26335                              <1> 	; Arguments:
 26336                              <1> 	;	special - pointer to name of special file (device)
 26337                              <1> 	;	name -  pointer to name of the root directory of the
 26338                              <1> 	;		newly mounted file system. 'name' should 
 26339                              <1> 	;		always be a directory.
 26340                              <1> 	; Inputs: - 
 26341                              <1> 	; Outputs: -
 26342                              <1> 	; ...............................................................
 26343                              <1> 	;				
 26344                              <1> 	; Retro UNIX 8086 v1 modification: 
 26345                              <1> 	;       'sysmount' system call has two arguments; so,
 26346                              <1> 	;	* 1st argument, special is pointed to by BX register
 26347                              <1> 	;	* 2nd argument, name is in CX register
 26348                              <1> 	;
 26349                              <1> 	;	NOTE: Device numbers, names and related procedures are 
 26350                              <1> 	;	       already modified for IBM PC compatibility and 
 26351                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
 26352                              <1> 	
 26353                              <1> 	;call	arg2
 26354                              <1> 		; jsr r0,arg2 / get arguments special and name
 26355 0000542A 891D[806C0000]      <1> 	mov	[u.namep], ebx
 26356                              <1> 	; 07/02/2022
 26357                              <1> 	;push	ecx ; directory name
 26358                              <1> 	;cmp	dword [mnti], 0 ; 11/01/2022 (32 bit inode number)
 26359 00005430 66833D[4A6C0000]00  <1> 	cmp	word [mnti], 0
 26360                              <1> 		; tst mnti / is the i-number of the cross device file
 26361                              <1> 			 ; / zero?
 26362                              <1> 	;;ja	error
 26363                              <1>         	; bne errora / no, error
 26364                              <1> 	;ja	sysmnt_err0
 26365                              <1> 	; 11/01/2022
 26366 00005438 7605                <1> 	jna	short sysmnt_0 ; 12/01/2022
 26367                              <1> sysmnt_0_err:
 26368 0000543A E993010000          <1> 	jmp	sysmnt_err0
 26369                              <1> sysmnt_0:
 26370                              <1> 	; 07/02/2022
 26371 0000543F 51                  <1> 	push	ecx ; directory name
 26372 00005440 E875010000          <1> 	call	getspl
 26373                              <1> 		; jsr r0,getspl / get special files device number in r1
 26374                              <1> 	; 07/02/2022
 26375 00005445 8F05[806C0000]      <1> 	pop	dword [u.namep] ; directory name
 26376                              <1> 
 26377                              <1> 	; 09/05/2022 - Retro UNIX v1.2 (Kernel v0.2.2.1)
 26378                              <1> 	; (root fs/device must not be mounted again)
 26379 0000544B 3A05[426C0000]      <1> 	cmp	al, [rdev]
 26380                              <1> 	;je	sysmnt_err0
 26381 00005451 74E7                <1> 	je	short sysmnt_0_err ; permission denied error
 26382                              <1> 
 26383                              <1> 	; 13/10/2015
 26384                              <1> 	;movzx	ebx, ax ; Retro UNIX 8086 v1 device number (0 to 5)
 26385                              <1>         ; 11/01/2022
 26386 00005453 29DB                <1> 	sub	ebx, ebx
 26387 00005455 88C3                <1> 	mov	bl, al
 26388 00005457 F683[6E620000]80    <1> 	test    byte [ebx+drv.status], 80h ; 24/10/2015 
 26389 0000545E 750F                <1> 	jnz	short sysmnt_1
 26390                              <1> sysmnt_err1:
 26391 00005460 C705[D86C0000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
 26392 00005468 0000                <1>
 26393 0000546A E9F2DCFFFF          <1> 	jmp	error
 26394                              <1> sysmnt_1:
 26395                              <1> 	; 07/02/2022
 26396                              <1> 	;pop	dword [u.namep]
 26397                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
 26398                              <1> 				  ; / on the device
 26399                              <1> 	; 14/11/2015
 26400 0000546F 53                  <1> 	push	ebx ; 13/10/2015
 26401                              <1> 		; mov r1,-(sp) / save the device number
 26402                              <1>         ;
 26403 00005470 E803ECFFFF          <1> 	call	namei
 26404                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 26405                              <1> 		       ; ax = 0 -> file not found 	
 26406                              <1> 	;jz	error
 26407                              <1> 	;jc	error
 26408                              <1> 		; jsr r0,namei / get the i-number of the file
 26409                              <1>                	; br errora
 26410 00005475 730F                <1> 	jnc	short sysmnt_2
 26411                              <1> sysmnt_err2:
 26412 00005477 C705[D86C0000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
 26413 0000547F 0000                <1>
 26414 00005481 E9DBDCFFFF          <1> 	jmp	error
 26415                              <1> sysmnt_2:
 26416                              <1> 	; 11/01/2022
 26417 00005486 A3[4A6C0000]        <1> 	mov	[mnti], eax ; 32 bit inode number (<= 65535)	
 26418                              <1> 	;mov	[mnti], ax
 26419                              <1>         	; mov r1,mnti / put it in mnti
 26420                              <1> 
 26421                              <1> 	; 15/05/2022
 26422                              <1> 	; -Retro UNIX 8086/386 v1 feaure only-
 26423 0000548B A1[3C6C0000]        <1> 	mov	eax, [ii]
 26424 00005490 A3[4E6C0000]        <1> 	mov	[mntp], eax ; parent dir inumber of [mnti]
 26425                              <1> 
 26426                              <1> 	; 11/01/2022
 26427 00005495 BB[146F0000]        <1> 	mov	ebx, sb1 ; super block buffer header (of mounted disk)
 26428                              <1> sysmnt_3: ;1:
 26429                              <1>         ;cmp	byte [ebx+1], 0
 26430                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
 26431                              <1> 			   ; / dismountable device set?
 26432                              <1>         ;jna	short sysmnt_4		
 26433                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
 26434                              <1> 	;call	idle 	; (wait for hardware interrupt)
 26435                              <1> 	;jmp	short sysmnt_3
 26436                              <1> sysmnt_4:   
 26437 0000549A 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
 26438 0000549B A2[436C0000]        <1> 	mov	[mdev], al
 26439                              <1> 		; mov (sp),mntd / no, put the device number in mntd
 26440 000054A0 8803                <1> 	mov	[ebx], al
 26441                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
 26442                              <1> 			      ; / of the I/O queue entry
 26443                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
 26444                              <1>         	; mov (sp)+,cdev / put device number in cdev
 26445 000054A2 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
 26446                              <1> 		; bis $2000,sb1 / set the read bit
 26447                              <1> 
 26448                              <1> 	; 09/05/2022
 26449 000054A7 31FF                <1> 	xor	edi, edi
 26450 000054A9 897B04              <1> 	mov	dword [ebx+4], edi ; 0 ; physical block number = 0
 26451                              <1> 
 26452                              <1> 	; 09/05/2022
 26453                              <1> 	; Retro UNIX v2 Hard Disk FS recognition.
 26454                              <1> 	;
 26455 000054AC 3C02                <1> 	cmp	al, 2 ; fd0 = 0, fd1 = 1, hd0 = 2, hd1 = 3
 26456 000054AE 7217                <1> 	jb	short sysmnt_8
 26457                              <1> 
 26458                              <1> 	; hard disk, read masterboot sector/block at first 
 26459 000054B0 E817060000          <1> 	call 	diskio
 26460 000054B5 721A                <1> 	jc	short sysmnt_9 ; disk read error !
 26461                              <1> sysmnt_6:
 26462                              <1>   	; return start sector address of
 26463                              <1> 	; retro unix v2 partition in esi
 26464 000054B7 8D7308              <1> 	lea	esi, [ebx+8] ; (mbr buffer data address)
 26465 000054BA E86DDBFFFF          <1> 	call	runix_p_bs
 26466 000054BF 7206                <1> 	jc	short sysmnt_8 ; runix partition not found
 26467                              <1> 			       ; try to read superblock on
 26468                              <1> 			       ; physical sector 1	 
 26469                              <1> 	; eax = start sector/block
 26470 000054C1 894304              <1> 	mov	dword [ebx+4], eax ; (boot sector address)
 26471                              <1> 	; esi = partition table entry + 4
 26472 000054C4 8B7E08              <1> 	mov	edi, [esi+ptSectors-ptFileSystemID]
 26473                              <1> 	; edi = partition size in sectors
 26474                              <1> sysmnt_8:
 26475                              <1> 	; Retro UNIX 386 v1 modification : 
 26476                              <1> 	;	32 bit block number at buffer header offset 4
 26477                              <1> 	; 09/05/2022
 26478                              <1> 	;mov	dword [ebx+4], 1 ; physical block number = 1
 26479 000054C7 FF4304              <1> 	inc	dword [ebx+4] ; +1 ; superblock address
 26480 000054CA E8FD050000          <1> 	call 	diskio
 26481 000054CF 7345                <1> 	jnc	short sysmnt_5
 26482                              <1> sysmnt_9:
 26483 000054D1 31C0                <1> 	xor 	eax, eax
 26484 000054D3 66A3[4A6C0000]      <1> 	mov	[mnti], ax ; 0
 26485 000054D9 A2[436C0000]        <1> 	mov	[mdev], al ; 0
 26486                              <1> 	;mov	[cdev], al ; 0
 26487                              <1> 	; 08/02/2022
 26488 000054DE 803D[D76C0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
 26489 000054E5 7508                <1> 	jne	short sysmnt_err3
 26490                              <1> 	; yes, clear [u.brwdev] for next check
 26491                              <1> 	; ([u.error] = DRV_NOT_RDY or OUT_OF_VOLUME error) 
 26492 000054E7 FE05[D76C0000]      <1> 	inc	byte [u.brwdev] ; 0, reset
 26493 000054ED EB0A                <1> 	jmp	short sysmnt_err4
 26494                              <1> sysmnt_err3:	; 08/02/2022
 26495                              <1> 	; no, set [u.error] to disk read error
 26496 000054EF C705[D86C0000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; 'disk read error !'
 26497 000054F7 0000                <1>
 26498                              <1> sysmnt_err4:
 26499                              <1> 	; 08/02/2022
 26500                              <1> 	; 14/11/2015
 26501 000054F9 FEC8                <1> 	dec 	al
 26502 000054FB 8903                <1> 	mov	[ebx], eax ; 000000FFh
 26503 000054FD FEC0                <1> 	inc	al
 26504 000054FF 48                  <1> 	dec	eax
 26505 00005500 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
 26506 00005503 E959DCFFFF          <1> 	jmp	error
 26507                              <1> sysmnt_invd:
 26508                              <1> 	; 08/02/2022
 26509 00005508 C705[D86C0000]1C00- <1> 	mov	dword [u.error], ERR_INV_FS ; 28
 26510 00005510 0000                <1>
 26511                              <1> 				 ;'invalid fs/superblock !' error
 26512 00005512 30C0                <1> 	xor	al, al ; 0
 26513 00005514 EBE3                <1> 	jmp	short sysmnt_err4
 26514                              <1> 
 26515                              <1> sysmnt_5:
 26516                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 26517                              <1> 	; Retro UNIX v2 Hard Disk FS recognition.
 26518                              <1> 	; edi = 0 -> diskette or 'not a runix v2 hdfs partition'
 26519                              <1> 	; edi > 0 -> retro unix v2 hdfs partition (volume) size
 26520                              <1> 	;	     in sectors
 26521                              <1> 
 26522 00005516 21FF                <1> 	and	edi, edi
 26523 00005518 740D                <1> 	jz	short sysmnt_10
 26524                              <1> 
 26525 0000551A 8B530C              <1> 	mov	edx, [ebx+12] ; SB.BootSectAddr (Hidden Sectors)
 26526 0000551D 42                  <1> 	inc	edx ; +1 
 26527 0000551E 3B5304              <1> 	cmp	edx, [ebx+4]  ; superblock (disk) address
 26528 00005521 75E5                <1> 	jne	short sysmnt_invd  ; invalid file system !
 26529                              <1> 
 26530 00005523 89F9                <1> 	mov	ecx, edi ; volume size (from partition table entry)
 26531 00005525 EB0C                <1> 	jmp	short sysmnt_11 ; bypass disk size comparison
 26532                              <1> 
 26533                              <1> sysmnt_10:
 26534                              <1> 	; 08/02/2022
 26535                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.1 BugFix)
 26536                              <1> 	;  v1.2 Note: This code will be changed for hard disk partitions
 26537                              <1> 	;	    ! (for now, rufs v2 floppy disks can be mounted) !		
 26538                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
 26539                              <1> 	; (Following check is needed to prevent mounting an
 26540                              <1> 	; invalid file system (invalid super block).
 26541                              <1> 	; 
 26542 00005527 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
 26543 0000552A C0E002              <1> 	shl	al, 2 ; 4*index
 26544 0000552D 8B88[52620000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
 26545                              <1> 	;shr 	ecx, 3 ; 11/01/2021 (8 sectors per 1 fbm byte)
 26546                              <1> 	; ecx = number of free map bytes (required)
 26547                              <1> 	;;movzx	edx, word [sb1+8] ; the 1st data word ('mount:')
 26548                              <1> 	;movzx	edx, word [ebx+8] ; the 1st data word (of the buffer)	
 26549                              <1> 	; edx = number of free blocks map bytes
 26550                              <1> 	;;shl	edx, 3 ; convert free map bytes to free map bits
 26551                              <1> 	;cmp	ecx, edx ; compare free map bits and volume size
 26552                              <1> 	;		 ; (in sectors), if they are not equal
 26553                              <1> 	;		 ; the disk to be mounted is an...
 26554                              <1> 	;jne	short sysmnt_invd ; invalid disk !
 26555                              <1> 	;		 ; (which has not got a valid super block)
 26556                              <1> sysmnt_11:	
 26557                              <1> 	; 07/02/2022
 26558                              <1> 	;xor	al, al ; 08/02/2022
 26559                              <1> 	; 11/01/2022
 26560                              <1> 	; Retro UNIX 386 v2 superblock (offset 8, volume size)
 26561 00005533 8B5310              <1> 	mov	edx, [ebx+16] ; SB.VolumeSize (in sectors)
 26562 00005536 39D1                <1> 	cmp	ecx, edx ; compare SB.VolumeSize and Disk volume size
 26563                              <1> 			 ; (in sectors), if they are not equal
 26564                              <1> 			 ; the disk to be mounted is an...	
 26565 00005538 75CE                <1> 	jne	short sysmnt_invd ; invalid disk !
 26566                              <1> 			 ; (which has not got a valid shuper block)
 26567                              <1> 	;
 26568 0000553A C6430100            <1> 	mov	byte [ebx+1], 0
 26569                              <1> 	       	; jsr r0,ppoke / read in entire file system
 26570                              <1> ;sysmnt_6: ;1:
 26571                              <1> 	;;cmp	byte [sb1+1], 0
 26572                              <1> 		; tstb sb1+1 / done reading?
 26573                              <1>    	;;jna	sysret
 26574                              <1> 	;;call	idle ; (wait for hardware interrupt)
 26575                              <1> 	;;jmp	short sysmnt_6
 26576                              <1> 		;bne 1b / no, wait
 26577                              <1>         	;br sysreta / yes
 26578 0000553E E93EDCFFFF          <1> 	jmp	sysret
 26579                              <1> 
 26580                              <1> sysumount: ; / special dismount file system
 26581                              <1> 	; 15/05/2022
 26582                              <1> 	; 09/05/2022 (Retro UNIX 386 v1.2, Kernel v0.2.2.1)
 26583                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
 26584                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 26585                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 26586                              <1> 	;
 26587                              <1> 	; 04/11/2013
 26588                              <1> 	; 09/07/2013
 26589                              <1> 	; 'sysumount' anounces to the system that the special file, 
 26590                              <1> 	; indicated as an argument is no longer contain a removable
 26591                              <1> 	; file system. 'getspl' gets the device number of the special
 26592                              <1> 	; file. If no file system was mounted on that device an error
 26593                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
 26594                              <1> 	; to 'sysret'.
 26595                              <1> 	;
 26596                              <1> 	; Calling sequence:
 26597                              <1> 	;	sysmount; special
 26598                              <1> 	; Arguments:
 26599                              <1> 	;	special - special file to dismount (device)
 26600                              <1> 	;
 26601                              <1> 	; Inputs: - 
 26602                              <1> 	; Outputs: -
 26603                              <1> 	; ...............................................................
 26604                              <1> 	;				
 26605                              <1> 	; Retro UNIX 8086 v1 modification: 
 26606                              <1> 	;       'sysumount' system call has one argument; so,
 26607                              <1> 	;	* Single argument, special is pointed to by BX register
 26608                              <1> 	;
 26609                              <1> 	
 26610                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
 26611                              <1> 	;call	arg
 26612                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
 26613 00005543 891D[806C0000]      <1>         mov	[u.namep], ebx
 26614 00005549 E86C000000          <1> 	call	getspl
 26615                              <1> 		; jsr r0,getspl / get the device number in r1
 26616                              <1> 	;;;
 26617                              <1> 	; 09/05/2022 - Erdogan Tan
 26618                              <1> 	; (I have added [mnti] check because
 26619                              <1> 	;  retro unix device number of /dev/fd0 is 0
 26620                              <1> 	;  .. so, 'cmp al, [mdev]' is not enough
 26621                              <1> 	;  for dismounting /dev/fd0. sysumount system call would give
 26622                              <1> 	;  wrong cf=0 result while /dev/fd0 is not mounted.)
 26623 0000554E 66833D[4A6C0000]00  <1> 	cmp	word [mnti], 0
 26624 00005556 767A                <1> 	jna	short sysmnt_err0 ; there is not a mounted device !
 26625                              <1> 	;;;	
 26626                              <1> 
 26627 00005558 3A05[436C0000]      <1> 	cmp	al, [mdev]
 26628                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
 26629 0000555E 7572                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
 26630                              <1> 	;jne	error
 26631                              <1>         	; bne errora / no error
 26632 00005560 30C0                <1> 	xor	al, al ; ah = 0
 26633                              <1> 	; (eax = 0) ; 11/01/2022
 26634                              <1> sysumnt_0: ;1:
 26635                              <1>      	; 11/01/2022
 26636                              <1> 	;cmp 	[sb1+1], al ; 0
 26637                              <1> 	;	; tstb sb1+1 / yes, is the device still doing I/O 
 26638                              <1> 	;		   ; / (inhibit bit set)?
 26639                              <1> 	;jna	short sysumnt_1		
 26640                              <1> 	;	; bne 1b / yes, wait
 26641                              <1> 	;call	idle ; (wait for hardware interrupt)
 26642                              <1> 	;jmp	short sysumnt_0
 26643                              <1> sysumnt_1:
 26644                              <1> 	; 15/05/2022
 26645                              <1> 	; change user's current directory to mounting directory
 26646                              <1> 	; if it is on the mounted device (chdir back to root fs)
 26647 00005562 3805[6C6C0000]      <1> 	cmp	byte [u.cdrv], al ; 0
 26648 00005568 7641                <1> 	jna	short sysumnt_4
 26649                              <1> 	;;;
 26650                              <1> 	; 15/05/2022
 26651                              <1> 	; It is needed to change the parent process's current
 26652                              <1> 	; directory because shell runs (/etc/umount) 
 26653                              <1> 	; as child process.
 26654 0000556A 31DB                <1> 	xor	ebx, ebx 
 26655 0000556C 8A1D[B56C0000]      <1> 	mov	bl, [u.uno]
 26656 00005572 D0E3                <1> 	shl	bl, 1 ; >= 2 .. <= 32
 26657 00005574 81C3[42680000]      <1> 	add	ebx, p.ppid-2
 26658 0000557A 668B13              <1> 	mov	dx, [ebx] ; process id of the parent [p.ppid]	
 26659 0000557D BE[24680000]        <1> 	mov	esi, p.pid
 26660 00005582 29C9                <1> 	sub	ecx, ecx
 26661 00005584 B110                <1> 	mov	cl, nproc ; 16  
 26662                              <1> sysumnt_2:	
 26663 00005586 66AD                <1> 	lodsw
 26664 00005588 6639D0              <1> 	cmp	ax, dx
 26665 0000558B 7402                <1> 	je	short sysumnt_3
 26666 0000558D E2F7                <1> 	loop	sysumnt_2
 26667                              <1> sysumnt_3:
 26668 0000558F 31C0                <1> 	xor	eax, eax
 26669 00005591 81EE[24680000]      <1> 	sub	esi, p.pid
 26670 00005597 D1E6                <1> 	shl	esi, 1
 26671 00005599 8B9E[90680000]      <1> 	mov	ebx, [esi+p.upage-4] ; the parent's upage
 26672                              <1> 	; ebx points to user (u) structure in upage
 26673 0000559F 8B15[4A6C0000]      <1> 	mov	edx, [mnti] ; * (32 bit inumber but < 65536)
 26674                              <1> 	;mov	[u.cdir], dx
 26675                              <1> 	;mov	[u.cdrv], al ; 0
 26676 000055A5 89530C              <1> 	mov	[ebx+u.cdir-user], edx 
 26677                              <1> 			    ; * (32 bit inumber but < 65536)
 26678 000055A8 884310              <1> 	mov	[ebx+u.cdrv-user], al ; 0
 26679                              <1> 	;;;
 26680                              <1> sysumnt_4:
 26681 000055AB A2[436C0000]        <1> 	mov	[mdev], al ; 0
 26682                              <1> 	     	; clr mntd / no, clear these
 26683 000055B0 A3[4A6C0000]        <1>    	mov	[mnti], eax ; 11/01/2022 (eax = 0)
 26684                              <1> 	;mov	[mnti], ax ; 0
 26685                              <1>         	; clr mnti
 26686                              <1> 
 26687                              <1> 	;; 15/05/2022
 26688                              <1> 	;mov	[cdev], al ; 0 ; [u.cdrv] = 0
 26689                              <1> 	;mov	eax, edx  ; [u.cdir]
 26690                              <1> 	;call	iget
 26691                              <1> 
 26692 000055B5 E9C7DBFFFF          <1>         jmp	sysret
 26693                              <1> 		; br sysreta / return
 26694                              <1> 
 26695                              <1> 	; 11/01/2022 - Retro UNIX 386 v1.2
 26696                              <1> 	;	(runix v2 fs inode numbers)
 26697                              <1> getspl: ; / get device number from a special file name
 26698 000055BA E8B9EAFFFF          <1> 	call	namei
 26699                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 26700                              <1> 		       ; ax = 0 -> file not found 	
 26701                              <1> 	;jc	sysmnt_err2 ; 'file not found !' error
 26702                              <1> 	; 11/01/2022 (Retro UNIX 386 v1.2)
 26703 000055BF 7305                <1> 	jnc	short getspl_0
 26704 000055C1 E9B1FEFFFF          <1> 	jmp	sysmnt_err2
 26705                              <1> getspl_0:
 26706                              <1> 	;jz	error
 26707                              <1> 	;jc	error
 26708                              <1> 		; jsr r0,namei / get the i-number of the special file
 26709                              <1>                 ; br errora / no such file
 26710                              <1>         ; 11/01/2022 - Retro UNIX 386 v1.2 (runix v2 fs inode numbers)
 26711 000055C6 6683E80A            <1> 	sub	ax, 10 ; fd0 inode number = 10, hd3 inode number = 15
 26712                              <1> 		      ;	i-number-10, 0 = fd0, 5 = hd3 
 26713                              <1> 	;sub	ax, 3 ; Retro UNIX 8086 v1 modification !
 26714                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
 26715                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
 26716 000055CA 7206                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
 26717                              <1> 	;jc	error
 26718                              <1> 		; ble errora / less than 0?  yes, error
 26719 000055CC 6683F805            <1>         cmp	ax, 5 ; 5 = hd3
 26720                              <1> 		; cmp r1,$9. / greater than 9  tap 7
 26721                              <1> 	;ja	short sysmnt_err0 ; 'permission denied !' error
 26722                              <1> 	;;ja	error
 26723                              <1> 		; bgt errora / yes, error
 26724                              <1> 	; 11/01/2022
 26725 000055D0 760F                <1> 	jna	short getspl_retn
 26726                              <1> 	; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
 26727                              <1> ;iopen_retn:
 26728                              <1> ;	retn
 26729                              <1> 		; rts    r0 / return with device number in r1
 26730                              <1> sysmnt_err0:
 26731 000055D2 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 26732 000055DA 0000                <1>
 26733 000055DC E980DBFFFF          <1> 	jmp	error
 26734                              <1> 
 26735                              <1> getspl_retn:
 26736                              <1> 	; 11/01/2022
 26737                              <1> 	; eax = Retro UNIX 386 v1 device number (0 to 5)
 26738                              <1> iopen_retn:
 26739 000055E1 C3                  <1> 	retn
 26740                              <1> 
 26741                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 
 26742                              <1> 	;			(Printer initialization)
 26743                              <1> 	; 11/02/2022
 26744                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
 26745                              <1> iopen:
 26746                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 26747                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
 26748                              <1> 	; 19/05/2015
 26749                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 26750                              <1> 	; 21/05/2013 - 27/08/2013 (Retro UNIX 8086 v1)
 26751                              <1> 	;
 26752                              <1> 	; open file whose i-number is in r1
 26753                              <1> 	; 
 26754                              <1> 	; INPUTS ->
 26755                              <1> 	;    r1 - inode number
 26756                              <1> 	; OUTPUTS ->
 26757                              <1> 	;    file's inode in core	
 26758                              <1> 	;    r1 - inode number (positive)
 26759                              <1> 	;
 26760                              <1> 	; ((AX = R1))
 26761                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi, ebp)) 
 26762                              <1> 	;        
 26763                              <1> ; / open file whose i-number is in r1
 26764                              <1> ;	test	ah, 80h ; Bit 15 of AX
 26765                              <1> ;		; tst r1 / write or read access?
 26766                              <1> ;       jnz	short iopen_2
 26767                              <1> ;		; blt 2f / write, go to 2f
 26768                              <1> ;	mov	dl, 2 ; read access
 26769                              <1> ;	call	access
 26770                              <1> ;       	; jsr r0,access; 2 
 26771                              <1> ;	; / get inode into core with read access
 26772                              <1> ;	; DL=2
 26773                              <1> ;iopen_0:
 26774                              <1> ;       cmp	ax, 40
 26775                              <1> ;		; cmp r1,$40. / is it a special file
 26776                              <1> ;       ja	short iopen_retn
 26777                              <1> ;		; bgt 3f / no. 3f
 26778                              <1> 
 26779                              <1> 	; 05/12/2021
 26780                              <1> 	; DL = 0 -> open for read
 26781                              <1> 	; DL = 1 -> open for write
 26782                              <1> 	; 11/02/2022
 26783                              <1> 	; DL = 2 -> create (open for write)
 26784                              <1> 		    ; (caller: syscreat)
 26785                              <1> 
 26786 000055E2 52                  <1> 	push	edx ; *
 26787                              <1> 
 26788                              <1> 	; set permission/mode flag for 'access' 
 26789                              <1> 	;	(DX = 100h -> IREAD, DX = 80h -> IWRITE)
 26790                              <1> 
 26791 000055E3 B601                <1> 	mov	dh, 1
 26792 000055E5 08D2                <1> 	or	dl, dl ; dl = 0, open for read	
 26793 000055E7 7404                <1> 	jz	short iopen_0 ; DX = IREAD (100h)
 26794                              <1> 	; dl = 1, open for write 
 26795                              <1> 	; or
 26796                              <1> 	; dl = 2, create (regular) file	; 11/02/2022
 26797 000055E9 FECE                <1> 	dec	dh
 26798 000055EB B280                <1> 	mov	dl, 80h
 26799                              <1> 	; DX = IWRITE (80h)
 26800                              <1> iopen_0:
 26801                              <1> 	; 27/03/2021
 26802                              <1> 	;   EAX = inode number (in AX)
 26803                              <1> 	;    DX = access mode, 100h = read, 80h = write
 26804                              <1> 
 26805                              <1> 	; 24/06/2020 - Retro UNIX 386 v2	
 26806 000055ED E869F6FFFF          <1> 	call	access
 26807                              <1> 		; jsr r0,access; 1 / get inode in core
 26808                              <1> 	
 26809                              <1> 	; 27/03/2021
 26810                              <1> 	; DX return value from 'access' subroutine
 26811                              <1> 	;    may be 100h, 20h, 04h for DX = 100h (IREAD) input
 26812                              <1> 	;	     80h, 10h, 02h for DX = 80h (IWRITE) input
 26813                              <1> 
 26814                              <1> 	; 05/12/2021
 26815 000055F2 5A                  <1> 	pop	edx ; * ; dl = 0 -> open for read
 26816                              <1> 			; dl = 1 -> open for write
 26817                              <1> 			; 11/02/2022
 26818                              <1> 			; dl = 2 -> create (regular) file
 26819                              <1> 			;	   (open for writing)
 26820                              <1> 	; 24/06/2020
 26821 000055F3 8A0D[E5670000]      <1> 	mov	cl, [i.flgs+1]
 26822                              <1> 
 26823 000055F9 F6C180              <1> 	test	cl, 80h		; regular file ?
 26824 000055FC 7525                <1> 	jnz	short iopen_1	; yes ; 05/12/2021
 26825 000055FE F6C120              <1> 	test	cl, 20h 	; device file ?
 26826                              <1> 	;jnz	short iopen_2	; yes
 26827                              <1> 	; 11/02/2022
 26828 00005601 7414                <1> 	jz	short iopen_invf ; no, invalid file/inode !
 26829                              <1> 	; device file/inode
 26830 00005603 F6C202              <1> 	test	dl, 2 ; create file ?
 26831 00005606 7425                <1> 	jz	short iopen_2	; device file r/w (dl=0 or dl=1)
 26832                              <1> 	; an attempt to create a file 
 26833                              <1> 	; whith name of existing device file in same directory!
 26834                              <1> iopen_pdnd:
 26835 00005608 C705[D86C0000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; 11
 26836 00005610 0000                <1>
 26837                              <1> 				; 'permission denied !' error
 26838                              <1> iopen_err:
 26839 00005612 E94ADBFFFF          <1> 	jmp	error
 26840                              <1> iopen_invf:
 26841                              <1> 	; invalid inode (flags)
 26842 00005617 C705[D86C0000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
 26843 0000561F 0000                <1>
 26844 00005621 EBEF                <1> 	jmp	short iopen_err
 26845                              <1> 
 26846                              <1> iopen_1:
 26847                              <1> 	; 05/12/2021
 26848                              <1> 	; (If open mode is 'write' and the file/inode is a directory,
 26849                              <1> 	;  open request will/must be rejected.)
 26850                              <1> 	;
 26851                              <1> 	; (If inode is a regular file and it is not a directory,
 26852                              <1> 	; there is nothing to do here, we need to return to 'sysopen'
 26853                              <1> 	; for completing the rest of file opening procedure.) 
 26854                              <1> 	
 26855 00005623 F6C140              <1> 	test	cl, 40h	; directory ?
 26856 00005626 74B9                <1> 	jz	short iopen_retn ; no
 26857                              <1> 	
 26858 00005628 20D2                <1> 	and	dl, dl ; open mode is 1 (write) 
 26859                              <1> 	;jz	short iopen_retn ; no
 26860                              <1> 	; 11/02/2022
 26861                              <1> 	; open mode 1 (write) or 2 (create)
 26862 0000562A 75DC                <1> 	jnz	short iopen_pdnd ; 'permission denied !' error
 26863                              <1> ;iopen_retn:
 26864 0000562C C3                  <1> 	retn
 26865                              <1> 
 26866                              <1> 	; !!!	
 26867                              <1> 	; 'sysopen' for writing
 26868                              <1> 	;	 is not applicable for directories
 26869                              <1> 	; (Directory entries must be created or deleted by
 26870                              <1> 	; relevant system calls.)
 26871                              <1> 
 26872                              <1> 	;;mov	dword [u.error], ERR_DIR_ACCESS ; 11
 26873                              <1> 	;mov	dword [u.error], ERR_PERM_DENIED ; 11
 26874                              <1> 	;			; 'permission denied !' error
 26875                              <1> 	;;jmp	error
 26876                              <1> 	;jmp	short iopen_err
 26877                              <1> 
 26878                              <1> ;iopen_retn:
 26879                              <1> ;	retn
 26880                              <1> 
 26881                              <1> iopen_2:
 26882                              <1> 	;push	ax
 26883                              <1> 	;	; mov r1,-(sp) / yes, figure out
 26884                              <1> 	;movzx	ebx, al
 26885                              <1> 	;shl	bx, 2
 26886                              <1> 	;	; asl r1
 26887                              <1>         ;add	ebx, iopen_1 - 4
 26888                              <1> 	;jmp	dword [ebx]
 26889                              <1>         ;	; jmp *1f-2(r1) / which one and transfer to it
 26890                              <1> 	
 26891                              <1> 	; 05/12/2021
 26892 0000562D 50                  <1> 	push	eax ; save inode number
 26893                              <1> 	; device file
 26894 0000562E BB[4A560000]        <1> 	mov	ebx, iopen_4
 26895 00005633 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 26896 00005636 720E                <1> 	jb	short iopen_3 ; null
 26897 00005638 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 26898 0000563B 7709                <1> 	ja	short iopen_3 ; null	
 26899                              <1> 	; convert v2 inode number to v1 device inode number
 26900 0000563D 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 26901 0000563F 89C1                <1> 	mov	ecx, eax
 26902 00005641 C0E102              <1> 	shl	cl, 2 ; * 4
 26903 00005644 01CB                <1> 	add	ebx, ecx
 26904                              <1> iopen_3:
 26905 00005646 FEC2                <1> 	inc	dl ; 1 = read, 2 = write
 26906 00005648 FF23                <1> 	jmp	dword [ebx]	
 26907                              <1> 		; jmp *1f-2(r1)
 26908                              <1> ;iopen_1: ; 1:
 26909                              <1> iopen_4:
 26910 0000564A [7A4F0000]          <1> 	dd	null ; 05/12/2021
 26911 0000564E [9A560000]          <1> 	dd	otty ; tty, AX = 1 (runix)
 26912                              <1>  		 ;otty / tty ; r1=2
 26913                              <1>         	 ;oppt / ppt ; r1=4
 26914 00005652 [52570000]          <1> 	dd	sret ; mem, AX = 2 (runix)
 26915                              <1> 		 ;sret / mem ; r1=6
 26916                              <1> 		 ;sret / rf0
 26917                              <1>         	 ;sret / rk0
 26918                              <1>         	 ;sret / tap0
 26919                              <1>         	 ;sret / tap1
 26920                              <1>         	 ;sret / tap2
 26921                              <1>         	 ;sret / tap3
 26922                              <1>         	 ;sret / tap4
 26923                              <1>         	 ;sret / tap5
 26924                              <1>         	 ;sret / tap6
 26925                              <1>         	 ;sret / tap7
 26926 00005656 [52570000]          <1>         dd	sret ; fd0, AX = 3 (runix only)
 26927 0000565A [52570000]          <1>         dd	sret ; fd1, AX = 4 (runix only)
 26928 0000565E [52570000]          <1>         dd	sret ; hd0, AX = 5 (runix only)
 26929 00005662 [52570000]          <1>         dd	sret ; hd1, AX = 6 (runix only) 
 26930 00005666 [52570000]          <1>         dd	sret ; hd2, AX = 7 (runix only)
 26931 0000566A [52570000]          <1>         dd	sret ; hd3, AX = 8 (runix only) 
 26932                              <1> 	;;dd	error ; lpr, AX = 9 (error !)
 26933                              <1>         ;dd	sret ; lpr, AX = 9 (runix)
 26934                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 (lpt_init)
 26935 0000566E [2E580000]          <1>         dd	ejec ; lpr, AX = 9 (runix)	
 26936 00005672 [AB560000]          <1> 	dd	ocvt ; tty0, AX = 10 (runix)	  
 26937                              <1> 		 ;ocvt / tty0
 26938 00005676 [AB560000]          <1> 	dd	ocvt ; tty1, AX = 11 (runix)	  
 26939                              <1> 		 ;ocvt / tty1
 26940 0000567A [AB560000]          <1> 	dd	ocvt ; tty2, AX = 12 (runix)	  
 26941                              <1> 		 ;ocvt / tty2
 26942 0000567E [AB560000]          <1> 	dd	ocvt ; tty3, AX = 13 (runix)	  
 26943                              <1> 		 ;ocvt / tty3
 26944 00005682 [AB560000]          <1> 	dd	ocvt ; tty4, AX = 14 (runix)	  
 26945                              <1> 		 ;ocvt / tty4
 26946 00005686 [AB560000]          <1> 	dd	ocvt ; tty5, AX = 15 (runix)	  
 26947                              <1> 		 ;ocvt / tty5
 26948 0000568A [AB560000]          <1> 	dd	ocvt ; tty6, AX = 16 (runix)	  
 26949                              <1> 		 ;ocvt / tty6
 26950 0000568E [AB560000]          <1> 	dd	ocvt ; tty7, AX = 17 (runix)	  
 26951                              <1> 		 ;ocvt / tty7
 26952 00005692 [AB560000]          <1> 	dd	ocvt ; COM1, AX = 18 (runix only)	  
 26953                              <1> 		 ;error / crd
 26954 00005696 [AB560000]          <1> 	dd	ocvt ; COM2, AX = 19 (runix only)
 26955                              <1> 
 26956                              <1> ;iopen_2: ; 2: / check open write access
 26957                              <1> ;	neg	ax
 26958                              <1> ;		; neg r1 / make inode number positive
 26959                              <1> ;	mov	dl, 1 ; write access
 26960                              <1> ;	call	access
 26961                              <1> ;		; jsr r0,access; 1 / get inode in core
 26962                              <1> ;	; DL=1
 26963                              <1> ;	test	word [i.flgs], 4000h ; Bit 14 : Directory flag
 26964                              <1> ;		;bit $40000,i.flgs / is it a directory?
 26965                              <1> ;	jz	short iopen_0
 26966                              <1> ;	;mov	[u.error], ERR_DIR_ACCESS
 26967                              <1> ;	;jmp	error ; permission denied !
 26968                              <1> ;	jmp	sysmnt_err0
 26969                              <1> ;	;;jnz	error		
 26970                              <1> ;      		; bne 2f / yes, transfer (error)
 26971                              <1> ;       ;;jmp     short iopen_0
 26972                              <1> ;	;cmp	ax, 40
 26973                              <1> ;		; cmp r1,$40. / no, is it a special file?
 26974                              <1> ;        ;ja	short iopen_2
 26975                              <1> ;		; bgt 3f / no, return
 26976                              <1> ;	;push	ax
 26977                              <1> ;		; mov r1,-(sp) / yes
 26978                              <1> ;	;movzx	ebx, al
 26979                              <1> ;	;shl	bx, 1
 26980                              <1> ;		; asl r1
 26981                              <1> ;	;add	ebx, ipen_3 - 2
 26982                              <1> ;	;jmp	dword [ebx]
 26983                              <1> ;		; jmp *1f-2(r1) / figure out 
 26984                              <1> ;			; / which special file it is and transfer
 26985                              <1> ;iopen_3: ; 1:
 26986                              <1> ;	dd 	otty ; tty, AX = 1 (runix)
 26987                              <1> ; 		 ;otty / tty ; r1=2
 26988                              <1> ;        	 ;leadr / ppt ; r1=4
 26989                              <1> ;	dd	sret ; mem, AX = 2 (runix)
 26990                              <1> ;		 ;sret / mem ; r1=6
 26991                              <1> ;		 ;sret / rf0
 26992                              <1> ;        	 ;sret / rk0
 26993                              <1> ;        	 ;sret / tap0
 26994                              <1> ;        	 ;sret / tap1
 26995                              <1> ;        	 ;sret / tap2
 26996                              <1> ;        	 ;sret / tap3
 26997                              <1> ;        	 ;sret / tap4
 26998                              <1> ;        	 ;sret / tap5
 26999                              <1> ;        	 ;sret / tap6
 27000                              <1> ;        	 ;sret / tap7
 27001                              <1> ;	dd 	sret ; fd0, AX = 3 (runix only)
 27002                              <1> ;	dd 	sret ; fd1, AX = 4 (runix only)
 27003                              <1> ;	dd 	sret ; hd0, AX = 5 (runix only)
 27004                              <1> ;	dd 	sret ; hd1, AX = 6 (runix only)	
 27005                              <1> ;	dd 	sret ; hd2, AX = 7 (runix only)
 27006                              <1> ;	dd 	sret ; hd3, AX = 8 (runix only)	
 27007                              <1> ;	dd	sret ; lpr, AX = 9  (runix)
 27008                              <1> ;	;dd	ejec ; lpr, AX = 9  (runix)
 27009                              <1> ;	dd	sret ; tty0, AX = 10 (runix)	  
 27010                              <1> ;		 ;ocvt / tty0
 27011                              <1> ;	dd	sret ; tty1, AX = 11 (runix)	  
 27012                              <1> ;		 ;ocvt / tty1
 27013                              <1> ;	dd	sret ; tty2, AX = 12 (runix)	  
 27014                              <1> ;		 ;ocvt / tty2
 27015                              <1> ;	dd	sret ; tty3, AX = 13 (runix)	  
 27016                              <1> ;		 ;ocvt / tty3
 27017                              <1> ;	dd	sret ; tty4, AX = 14 (runix)	  
 27018                              <1> ;		 ;ocvt / tty4
 27019                              <1> ;	dd	sret ; tty5, AX = 15 (runix)	  
 27020                              <1> ;		 ;ocvt / tty5
 27021                              <1> ;	dd	sret ; tty6, AX = 16 (runix)	  
 27022                              <1> ;		 ;ocvt / tty6
 27023                              <1> ;	dd	sret ; tty7, AX = 17 (runix)	  
 27024                              <1> ;		 ;ocvt / tty7
 27025                              <1> ;	dd	ocvt ; COM1, AX = 18 (runix only)	  
 27026                              <1> ;		 ;/ ejec / lpr
 27027                              <1> ;	dd	ocvt ; COM2, AX = 19 (runix only)
 27028                              <1> 
 27029                              <1> otty: ;/ open console tty for reading or writing
 27030                              <1> 	; 03/03/2022
 27031                              <1> 	; 23/02/2022
 27032                              <1> 	; 22/02/2022
 27033                              <1> 	; 09/02/2022
 27034                              <1> 	; 06/02/2022
 27035                              <1> 	; 08/01/2022
 27036                              <1> 	; 01/01/2022
 27037                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27038                              <1> 	; 16/11/2015
 27039                              <1> 	; 12/11/2015
 27040                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 27041                              <1> 	; 21/05/2013 - 13/07/2014 (Retro UNIX 8086 v1)
 27042                              <1> 	; 16/07/2013
 27043                              <1> 	; Retro UNIX 8086 v1 modification:
 27044                              <1> 	;  If a tty is open for read or write by
 27045                              <1> 	;     a process (u.uno), only same process can open
 27046                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 27047                              <1> 	;
 27048                              <1> 	; (INPUT: DL=2 for Read, DL=1 for Write, DL=0 for sysstty)
 27049                              <1> 	;
 27050                              <1> 
 27051 0000569A 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 27052 000056A1 8A83[63680000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 27053                              <1> 	; 13/01/2014
 27054                              <1> 	;jmp	short ottyp
 27055                              <1> 	; 23/02/2022
 27056 000056A7 88C4                <1> 	mov	ah, al
 27057                              <1> 	; 06/02/2022
 27058 000056A9 EB06                <1> 	jmp	short otty_0
 27059                              <1> ocvt:
 27060 000056AB 2C0A                <1> 	sub	al, 10
 27061                              <1> ;ottyp:	; (call from sysstty)
 27062                              <1> 	; 08/01/2022
 27063 000056AD 31DB                <1> 	xor	ebx, ebx
 27064                              <1> ottyp:	; 03/03/2022
 27065                              <1> 	; (ebx < 256) ; 06/02/2022
 27066                              <1> 	; 23/02/2022
 27067 000056AF B4FF                <1> 	mov	ah, 0FFh
 27068                              <1> 	; 22/02/2022
 27069                              <1> otty_0:
 27070                              <1> 	; 09/02/2022
 27071                              <1> 	; INPUT:
 27072                              <1> 	;	DL=1 for read, DL=2 for write, DL=0 for sysstty
 27073                              <1> 	;
 27074                              <1> 	; 08/01/2022
 27075                              <1> 	; 01/01/2022
 27076                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27077                              <1> 	; 16/11/2015
 27078                              <1> 	; 12/11/2015
 27079                              <1> 	; 18/05/2015 (32 bit modifications)
 27080                              <1> 	; 06/12/2013 - 13/07/2014
 27081 000056B1 88C6                <1> 	mov	dh, al ; tty number
 27082                              <1> 	;movzx 	ebx, al ; AL = tty number (0 to 9), AH = 0
 27083                              <1> 	; 08/01/2022
 27084 000056B3 88C3                <1> 	mov	bl, al
 27085 000056B5 D0E3                <1> 	shl 	bl, 1  ; aligned to word
 27086                              <1> 	; 26/01/2014	
 27087 000056B7 81C3[74670000]      <1> 	add 	ebx, ttyl
 27088 000056BD 668B0B              <1> 	mov 	cx, [ebx]
 27089                              <1> 		   ; CL = lock value (0 or process number)
 27090                              <1> 		   ; CH = open count 
 27091 000056C0 20C9                <1> 	and 	cl, cl
 27092                              <1> 	; 13/01/2014
 27093                              <1> 	;jz 	short otty_ret
 27094                              <1> 	; 05/12/2021
 27095 000056C2 7447                <1> 	jz 	short ottys_0
 27096                              <1> 	;
 27097                              <1> 	; 16/11/2015
 27098 000056C4 3A0D[B56C0000]      <1> 	cmp 	cl, [u.uno]
 27099 000056CA 746E                <1> 	je	short ottys_3
 27100                              <1> 	;
 27101                              <1> 	; 23/02/2022
 27102                              <1> 	; (is it the console tty of the current process?)
 27103                              <1> 	; ((fast check/permit for console tty open function))
 27104 000056CC 38E0                <1> 	cmp	al, ah ; cmp dh, ah
 27105 000056CE 746A                <1> 	je	short ottys_3 ; bypass parent process check
 27106                              <1> 	;
 27107                              <1> 	;
 27108                              <1> 	; 22/02/2022
 27109                              <1> 	;movzx 	ebx, cl ; the process which has locked the tty
 27110                              <1> 	;shl 	bl, 1
 27111                              <1> 	;mov 	ax, [ebx+p.pid-2]
 27112                              <1> 	;;movzx ebx, byte [u.uno]
 27113                              <1> 	;mov	bl, [u.uno]
 27114                              <1> 	;shl 	bl, 1
 27115                              <1> 	;cmp 	ax, [ebx+p.ppid-2]
 27116                              <1> 	;je 	short ottys_3  ; 16/11/2015
 27117                              <1> 	; 22/02/2022 (BugFix) ; *
 27118 000056D0 0FB6F1              <1> 	movzx 	esi, cl ; the process which has locked the tty
 27119 000056D3 D1E6                <1> 	shl 	esi, 1
 27120 000056D5 668B86[22680000]    <1> 	mov 	ax, [esi+p.pid-2]
 27121 000056DC 96                  <1> 	xchg	esi, eax
 27122 000056DD A0[B56C0000]        <1> 	mov	al, [u.uno]
 27123 000056E2 D0E0                <1> 	shl 	al, 1
 27124 000056E4 663BB0[42680000]    <1> 	cmp 	si, [eax+p.ppid-2]	
 27125 000056EB 744D                <1> 	je 	short ottys_3 ; *
 27126                              <1> 	; 23/02/2022
 27127                              <1> 	; check console tty of the process
 27128                              <1> 	; (open permission must be given if the -requested- tty is
 27129                              <1> 	;  console tty of current process)
 27130 000056ED D0E8                <1> 	shr	al, 1
 27131 000056EF 38B0[63680000]      <1> 	cmp	[eax+p.ttyc-1], dh ; console tty ?
 27132 000056F5 7443                <1> 	je 	short ottys_3
 27133                              <1> 	;
 27134                              <1> 	; the tty is locked by another process
 27135                              <1> 	; except the parent process (p.ppid)
 27136                              <1>         ; 09/02/2022
 27137                              <1> 	;mov	dword [u.error], ERR_DEV_ACCESS
 27138                              <1> 	;		; permission denied ! error
 27139                              <1> otty_err: ; 13/01/2014
 27140                              <1> 	;or 	dl, dl	; DL = 0 -> called by sysstty
 27141                              <1> 	;;jnz	error
 27142                              <1> 	; 05/12/2021
 27143                              <1> 	;jz	short otty_stc_retn
 27144                              <1> 	;jmp	error
 27145                              <1> 	; 09/02/2022
 27146 000056F7 80FA01              <1> 	cmp	dl, 1 ; dl = 0 ?
 27147 000056FA 7257                <1> 	jb	short otty_retn ; yes, cf=1, called by sysstty
 27148                              <1> 	; iopen (dl=1 or dl=2)
 27149 000056FC C705[D86C0000]0B00- <1> 	mov     dword [u.error], ERR_DEV_ACCESS
 27150 00005704 0000                <1>
 27151                              <1> 			; permission denied ! error
 27152 00005706 E956DAFFFF          <1> 	jmp	error
 27153                              <1> ;otty_stc_retn:
 27154                              <1> 	;stc
 27155                              <1> 	;retn
 27156                              <1> ottys_0:
 27157                              <1> 	; 05/12/2021
 27158                              <1> otty_ret:
 27159                              <1> 	; 13/01/2014
 27160 0000570B 80FE07              <1> 	cmp 	dh, 7
 27161 0000570E 7624                <1> 	jna	short ottys_2
 27162                              <1> 	; 16/11/2015
 27163                              <1> com_port_check:
 27164 00005710 BE[92670000]        <1> 	mov	esi, com1p
 27165 00005715 80FE08              <1> 	cmp	dh, 8	; COM1 (tty8) ?
 27166 00005718 7601                <1> 	jna	short ottys_1 ; yes, it is COM1
 27167 0000571A 46                  <1> 	inc	esi	; no, it is COM2 (tty9)
 27168                              <1> ottys_1:
 27169                              <1> 	; 12/11/2015
 27170 0000571B 803E00              <1> 	cmp	byte [esi], 0 ; E3h (or 23h)
 27171 0000571E 7714                <1> 	ja	short com_port_ready
 27172                              <1> 	;
 27173                              <1> 	; 09/02/2022
 27174 00005720 80FA01              <1> 	cmp	dl, 1 ; dl = 0 ?
 27175 00005723 722E                <1> 	jb	short otty_retn ; yes, cf=1, called by sysstty
 27176 00005725 C705[D86C0000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY
 27177 0000572D 0000                <1>
 27178                              <1> 			   ; device not ready ! error
 27179                              <1> 	;jmp	short otty_err
 27180 0000572F E92DDAFFFF          <1> 	jmp	error	 
 27181                              <1> com_port_ready:
 27182                              <1> ottys_2:
 27183                              <1> 	; 03/03/2022
 27184                              <1> 	;or	cl, cl  ; cl = lock/owner, ch = open count
 27185                              <1> 	;jnz	short ottys_3
 27186 00005734 8A0D[B56C0000]      <1> 	mov	cl, [u.uno]
 27187                              <1> ottys_3:
 27188 0000573A FEC5                <1> 	inc 	ch
 27189 0000573C 66890B              <1> 	mov 	[ebx], cx ; set tty lock again
 27190                              <1> 	; 06/12/2013
 27191 0000573F FEC6                <1> 	inc	dh ; tty number + 1
 27192 00005741 BB[9A6C0000]        <1> 	mov	ebx, u.ttyp
 27193                              <1> 	; 13/01/2014
 27194                              <1> 	;test	dl, 2 ; open for read sign
 27195                              <1> 	;jnz	short ottys_4
 27196                              <1> 	; 05/12/2021
 27197                              <1> 	;test	dl, 2
 27198                              <1> 	;jz	short ottys_4 ; open for read
 27199                              <1> 	; 01/01/2022
 27200 00005746 F6C201              <1> 	test	dl, 1
 27201 00005749 7501                <1> 	jnz	short ottys_4 ; open for read (dl=1)
 27202                              <1> 	; dl=2 (open for write) or dl=0 (sysstty)
 27203 0000574B 43                  <1> 	inc	ebx
 27204                              <1> ottys_4:
 27205                              <1> 	; Set 'u.ttyp' ('the recent TTY') value
 27206 0000574C 8833                <1> 	mov 	[ebx], dh ; tty number + 1
 27207                              <1> 	; 09/02/2022
 27208 0000574E 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 27209 00005750 7401                <1> 	jz	short otty_retn ; 03/03/2022
 27210                              <1> sret:
 27211                              <1> 	;pop 	ax
 27212                              <1> 	; 05/12/2021
 27213 00005752 58                  <1> 	pop	eax
 27214                              <1> otty_retn:	; 09/02/2022
 27215                              <1> iclose_retn:	
 27216 00005753 C3                  <1> 	retn
 27217                              <1> 
 27218                              <1> 	;
 27219                              <1> 	; Original UNIX v1 'otty' routine:
 27220                              <1> 	;	
 27221                              <1> 	;mov    $100,*$tks / set interrupt enable bit (zero others) in
 27222                              <1>         ;                 / reader status reg
 27223                              <1>         ;mov    $100,*$tps / set interrupt enable bit (zero others) in
 27224                              <1>         ;                 / punch status reg
 27225                              <1>         ;mov    tty+[ntty*8]-8+6,r5 / r5 points to the header of the
 27226                              <1>         ;                          / console tty buffer
 27227                              <1>         ;incb   (r5) / increment the count of processes that opened the
 27228                              <1>         ;            / console tty
 27229                              <1>         ;tst    u.ttyp / is there a process control tty (i.e., has a tty
 27230                              <1>         ;             / buffer header
 27231                              <1>         ;bne    sret / address been loaded into u.ttyp yet)?  yes, branch
 27232                              <1>         ;mov    r5,u.ttyp / no, make the console tty the process control
 27233                              <1>         ;                 / tty
 27234                              <1>         ;br     sret / ?
 27235                              <1> ;sret:
 27236                              <1> 		;clr *$ps / set processor priority to zero
 27237                              <1> ;	pop	ax
 27238                              <1>         	;mov (sp)+,r1 / pop stack to r1
 27239                              <1> ;3:
 27240                              <1> ;	retn
 27241                              <1>         	;rts r0
 27242                              <1> 	
 27243                              <1> ;ocvt:	; < open tty >
 27244                              <1> 	; 13/01/2014
 27245                              <1> 	; 06/12/2013 (major modification: p.ttyc, u.ttyp)
 27246                              <1> 	; 24/09/2013 consistency check -> ok
 27247                              <1> 	; 16/09/2013
 27248                              <1> 	; 03/09/2013
 27249                              <1> 	; 27/08/2013
 27250                              <1> 	; 16/08/2013
 27251                              <1> 	; 16/07/2013
 27252                              <1> 	; 27/05/2013
 27253                              <1> 	; 21/05/2013
 27254                              <1> 	;
 27255                              <1> 	; Retro UNIX 8086 v1 modification !
 27256                              <1> 	; 
 27257                              <1> 	; In original UNIX v1, 'ocvt' routine 
 27258                              <1> 	;		(exactly different than this one)
 27259                              <1> 	;	was in 'u9.s' file.
 27260                              <1> 	;
 27261                              <1> 	; 16/07/2013
 27262                              <1> 	; Retro UNIX 8086 v1 modification:
 27263                              <1> 	;  If a tty is open for read or write by
 27264                              <1> 	;     a process (u.uno), only same process can open
 27265                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 27266                              <1> 	;
 27267                              <1> 	; INPUT: DL=2 for Read DL=1 for Write
 27268                              <1> 
 27269                              <1> 	; 16/09/2013
 27270                              <1> 	; sub 	al, 10
 27271                              <1> 	
 27272                              <1> 	; 06/12/2013
 27273                              <1> 	;cmp	al, 7
 27274                              <1>         ;jna	short ottyp
 27275                              <1> 	; 13/01/2014
 27276                              <1> 	;jmp	short ottyp
 27277                              <1> 
 27278                              <1> ;oppt: / open paper tape for reading or writing
 27279                              <1> ;        mov    $100,*$prs / set reader interrupt enable bit
 27280                              <1> ;        tstb   pptiflg / is file already open
 27281                              <1> ;        bne    2f / yes, branch
 27282                              <1> ;1:
 27283                              <1> ;        mov    $240,*$ps / no, set processor priority to 5
 27284                              <1> ;        jsr    r0,getc; 2 / remove all entries in clist
 27285                              <1> ;               br .+4 / for paper tape input and place in free list
 27286                              <1> ;        br     1b
 27287                              <1> ;        movb   $2,pptiflg / set pptiflg to indicate file just open
 27288                              <1> ;        movb   $10.,toutt+1 / place 10 in paper tape input tout entry
 27289                              <1> ;        br     sret
 27290                              <1> ;2:
 27291                              <1> ;        jmp    error / file already open
 27292                              <1> 
 27293                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
 27294                              <1> iclose:
 27295                              <1> 	; 09/02/2022
 27296                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 27297                              <1> 	; 10/04/2021
 27298                              <1> 	; 08/04/2021
 27299                              <1> 	; 04/04/2021 - Retro UNIX 386 v2
 27300                              <1> 	; 19/05/2015
 27301                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 27302                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 27303                              <1> 	;
 27304                              <1> 	; close file whose i-number is in r1
 27305                              <1> 	; 
 27306                              <1> 	; INPUTS ->
 27307                              <1> 	;    r1 - inode number
 27308                              <1> 	; OUTPUTS ->
 27309                              <1> 	;    file's inode in core	
 27310                              <1> 	;    r1 - inode number (positive)
 27311                              <1> 	;
 27312                              <1> 	; ((AX = R1))
 27313                              <1>         ;    ((Modified registers: -ebx-, edx)) 
 27314                              <1> 	;        
 27315                              <1> ;;/ close file whose i-number is in r1
 27316                              <1> ;	mov	dl, 2 ; 12/01/2014
 27317                              <1> ;	test	ah, 80h ; Bit 15 of AX
 27318                              <1> ;		;tst r1 / test i-number
 27319                              <1> ;	;jnz	short iclose_2
 27320                              <1> ;		;blt 2f / if neg., branch
 27321                              <1> ;	jz	short iclose_0 ; 30/07/2013
 27322                              <1> ;	; 16/07/2013 
 27323                              <1> ;	neg	ax ; make it positive
 27324                              <1> ;	; 12/01/2014
 27325                              <1> ;	dec	dl ; dl = 1 (open for write)
 27326                              <1> ;iclose_0:
 27327                              <1> ;	cmp	ax, 40
 27328                              <1> ;		;cmp r1,$40. / is it a special file
 27329                              <1> ;       ja	short iclose_retn  ; 13/01/2014
 27330                              <1> ;		;bgt 3b / no, return
 27331                              <1> ;	; 12/01/2014
 27332                              <1> ;	; DL=2 -> special file was opened for reading
 27333                              <1> ;	; DL=1 -> special file was opened for writing
 27334                              <1> 
 27335                              <1> 	; 04/04/2021
 27336                              <1> 	; INPUT:
 27337                              <1> 	;	(e)ax = inode number
 27338                              <1> 	;	   dl = open mode
 27339                              <1> 	;		0 = control mode
 27340                              <1> 	;		1 = read
 27341                              <1> 	;		2 = write
 27342                              <1> 	; OUTPUT:
 27343                              <1> 	;	none
 27344                              <1> 	;	(if cf=1 -> eax = error code)
 27345                              <1> 	;	(if cf=0 -> ax = inode number)
 27346                              <1> 
 27347                              <1> 	; 10/04/2021
 27348                              <1>         ; Modified registers: ebx, ecx, edx, esi, edi, (ebp) 
 27349                              <1> 
 27350                              <1> 	; 05/12/2021
 27351                              <1> 	; 08/04/2021
 27352                              <1> 
 27353 00005754 52                  <1> 	push	edx
 27354 00005755 E817F4FFFF          <1> 	call	iget
 27355 0000575A 5A                  <1> 	pop	edx 
 27356                              <1> 
 27357 0000575B 8A0D[E5670000]      <1> 	mov	cl, [i.flgs+1]
 27358                              <1> 
 27359                              <1> 	; if i.flgs bit 15 is 1, it is regular file 
 27360                              <1> 	;test	byte [i.flgs+1], 80h ; is it a special file?
 27361 00005761 F6C180              <1> 	test	cl, 80h ; is it a special file?
 27362 00005764 75ED                <1> 	jnz	short iclose_retn ; no
 27363                              <1> 
 27364                              <1> 	;; inode flags - bit 13 must be 1 
 27365                              <1> 	;test	cl, 20h ; is it a valid device inode
 27366                              <1> 	;jz	short iclose_retn ; no ; 19/01/2022
 27367                              <1> 	
 27368                              <1> 	;push	ax
 27369                              <1> 	;	;mov r1,-(sp) / yes, save r1 on stack
 27370                              <1> 	;movzx	ebx, al
 27371                              <1> 	;shl	bx, 2
 27372                              <1> 	;	; asl r1
 27373                              <1> 	;add	ebx, iclose_1 - 4
 27374                              <1> 	;jmp	dword [ebx]
 27375                              <1> 	;	; jmp *1f-2(r1) / compute jump address and transfer
 27376                              <1> 
 27377                              <1> 	; 05/12/2021
 27378 00005766 50                  <1> 	push	eax ; save inode number
 27379                              <1> 	; device file
 27380 00005767 BB[81570000]        <1> 	mov	ebx, iclose_1
 27381 0000576C 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 27382 0000576F 720E                <1> 	jb	short iclose_0
 27383 00005771 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 27384 00005774 7709                <1> 	ja	short iclose_0
 27385                              <1> 	; convert v2 inode number to v1 device inode number
 27386 00005776 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 27387 00005778 89C1                <1> 	mov	ecx, eax
 27388 0000577A C0E102              <1> 	shl	cl, 2 ; * 4
 27389 0000577D 01CB                <1> 	add	ebx, ecx
 27390                              <1> iclose_0:
 27391 0000577F FF23                <1> 	jmp	dword [ebx]	
 27392                              <1> 		; jmp *1f-2(r1)
 27393                              <1> iclose_1: ; 1:
 27394 00005781 [7A4F0000]          <1> 	dd	null ; 05/12/2021
 27395 00005785 [D1570000]          <1> 	dd	ctty ; tty, AX = 1 (runix)
 27396 00005789 [2C580000]          <1> 	dd	cret ; mem, AX = 2 (runix)
 27397 0000578D [2C580000]          <1> 	dd	cret ; fd0, AX = 3 (runix only)
 27398 00005791 [2C580000]          <1> 	dd	cret ; fd1, AX = 4 (runix only)
 27399 00005795 [2C580000]          <1> 	dd	cret ; hd0, AX = 5 (runix only)
 27400 00005799 [2C580000]          <1> 	dd	cret ; hd1, AX = 6 (runix only)	
 27401 0000579D [2C580000]          <1> 	dd	cret ; hd2, AX = 7 (runix only)
 27402 000057A1 [2C580000]          <1> 	dd	cret ; hd3, AX = 8 (runix only)	
 27403 000057A5 [2C580000]          <1> 	dd	cret ; lpr, AX = 9 (runix)
 27404                              <1> 	;dd	error; lpr, AX = 9 (error!)
 27405                              <1> 	;;dd	ejec ;;lpr, AX = 9  
 27406 000057A9 [E0570000]          <1> 	dd	ccvt ; tty0, AX = 10 (runix)	  
 27407 000057AD [E0570000]          <1> 	dd	ccvt ; tty1, AX = 11 (runix)	  
 27408 000057B1 [E0570000]          <1> 	dd	ccvt ; tty2, AX = 12 (runix)	  
 27409 000057B5 [E0570000]          <1> 	dd	ccvt ; tty3, AX = 13 (runix)	  
 27410 000057B9 [E0570000]          <1> 	dd	ccvt ; tty4, AX = 14 (runix)	  
 27411 000057BD [E0570000]          <1> 	dd	ccvt ; tty5, AX = 15 (runix)	  
 27412 000057C1 [E0570000]          <1> 	dd	ccvt ; tty6, AX = 16 (runix)	  
 27413 000057C5 [E0570000]          <1> 	dd	ccvt ; tty7, AX = 17 (runix)	  
 27414 000057C9 [E0570000]          <1> 	dd	ccvt ; COM1, AX = 18 (runix only)	  
 27415 000057CD [E0570000]          <1> 	dd	ccvt ; COM2, AX = 19 (runix only)
 27416                              <1> 
 27417                              <1> 	; 1:
 27418                              <1> 	;        ctty   / tty
 27419                              <1> 	;        cppt   / ppt
 27420                              <1> 	;        sret   / mem
 27421                              <1> 	;        sret   / rf0
 27422                              <1> 	;        sret   / rk0
 27423                              <1> 	;        sret   / tap0
 27424                              <1> 	;        sret   / tap1
 27425                              <1> 	;        sret   / tap2
 27426                              <1> 	;        sret   / tap3
 27427                              <1> 	;        sret   / tap4
 27428                              <1> 	;        sret   / tap5
 27429                              <1> 	;        sret   / tap6
 27430                              <1> 	;        sret   / tap7
 27431                              <1> 	;        ccvt   / tty0
 27432                              <1> 	;        ccvt   / tty1
 27433                              <1> 	;        ccvt   / tty2
 27434                              <1> 	;        ccvt   / tty3
 27435                              <1> 	;        ccvt   / tty4
 27436                              <1> 	;        ccvt   / tty5
 27437                              <1> 	;        ccvt   / tty6
 27438                              <1> 	;        ccvt   / tty7
 27439                              <1> 	;        error / crd
 27440                              <1> 
 27441                              <1> ;iclose_2: ; 2: / negative i-number
 27442                              <1> 	;neg	ax
 27443                              <1> 		;neg r1 / make it positive
 27444                              <1> 	;cmp	ax, 40
 27445                              <1> 		;cmp r1,$40. / is it a special file?
 27446                              <1>         ;ja	short @b
 27447                              <1> 		;bgt 3b / no. return
 27448                              <1> 	;push	ax
 27449                              <1> 		;mov r1,-(sp)
 27450                              <1> 	;movzx	ebx, al
 27451                              <1> 	;shl	bx, 1
 27452                              <1> 		;asl r1 / yes. compute jump address and transfer
 27453                              <1> 	;add	ebx, iclose_3 - 2
 27454                              <1> 	;jmp	dword [ebx]
 27455                              <1> 		;jmp *1f-2(r1) / figure out 
 27456                              <1> ;iclose_3:
 27457                              <1> 	;dd	ctty ; tty, AX = 1 (runix)
 27458                              <1> 	;dd	sret ; mem, AX = 2 (runix)
 27459                              <1> 	;dd	sret ; fd0, AX = 3 (runix only)
 27460                              <1> 	;dd	sret ; fd1, AX = 4 (runix only)
 27461                              <1> 	;dd	sret ; hd0, AX = 5 (runix only)
 27462                              <1> 	;dd	sret ; hd1, AX = 6 (runix only)	
 27463                              <1> 	;dd	sret ; hd2, AX = 7 (runix only)
 27464                              <1> 	;dd	sret ; hd3, AX = 8 (runix only)
 27465                              <1> 	;;dd	sret ; lpr, AX = 9	
 27466                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 27467                              <1> 	;dd	ccvt ; tty0, AX = 10 (runix)	  
 27468                              <1> 	;dd	ccvt ; tty1, AX = 11 (runix)	  
 27469                              <1> 	;dd	ccvt ; tty2, AX = 12 (runix)	  
 27470                              <1> 	;dd	ccvt ; tty3, AX = 13 (runix)	  
 27471                              <1> 	;dd	ccvt ; tty4, AX = 14 (runix)	  
 27472                              <1> 	;dd	ccvt ; tty5, AX = 15 (runix)	  
 27473                              <1> 	;dd	ccvt ; tty6, AX = 16 (runix)	  
 27474                              <1> 	;dd	ccvt ; tty7, AX = 17 (runix)	  
 27475                              <1> 	;dd	ccvt ; COM1, AX = 18 (runix only)	  
 27476                              <1> 	;dd	ccvt ; COM2, AX = 19 (runix only) 
 27477                              <1> 	
 27478                              <1> 	;1:
 27479                              <1> 	;      	ctty   / tty
 27480                              <1> 	;       leadr  / ppt
 27481                              <1> 	;       sret   / mem
 27482                              <1> 	;       sret   / rf0
 27483                              <1> 	;       sret   / rk0
 27484                              <1> 	;       sret   / tap0
 27485                              <1> 	;       sret   / tap1
 27486                              <1> 	;       sret   / tap2
 27487                              <1> 	;       sret   / tap3
 27488                              <1> 	;       sret   / tap4
 27489                              <1> 	;       sret   / tap5
 27490                              <1> 	;       sret   / tap6
 27491                              <1> 	;       sret   / tap7
 27492                              <1> 	;       ccvt   / tty0
 27493                              <1> 	;       ccvt   / tty1
 27494                              <1> 	;       ccvt   / tty2
 27495                              <1> 	;       ccvt   / tty3
 27496                              <1> 	;       ccvt   / tty4
 27497                              <1> 	;       ccvt   / tty5
 27498                              <1> 	;       ccvt   / tty6
 27499                              <1> 	;       ccvt   / tty7
 27500                              <1> 	;/      ejec   / lpr
 27501                              <1> 
 27502                              <1> ctty: ; / close console tty
 27503                              <1> 	; 09/02/2022
 27504                              <1> 	; 06/02/2022
 27505                              <1> 	; 08/01/2022
 27506                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27507                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 27508                              <1> 	; 21/05/2013 - 26/01/2014 (Retro UNIX 8086 v1)
 27509                              <1> 	;
 27510                              <1> 	; Retro UNIX 8086 v1 modification !
 27511                              <1> 	; (DL = 2 -> it is open for reading)
 27512                              <1> 	; (DL = 1 -> it is open for writing)
 27513                              <1> 	; (DL = 0 -> it is open for sysstty system call)
 27514                              <1> 	;
 27515                              <1> 	; 06/12/2013
 27516 000057D1 0FB61D[B56C0000]    <1>         movzx   ebx, byte [u.uno] ; process number
 27517 000057D8 8A83[63680000]      <1>         mov     al, [ebx+p.ttyc-1]
 27518                              <1> 	; 13/01/2014
 27519                              <1> 	;jmp	short cttyp
 27520                              <1> 	; 06/02/2022
 27521 000057DE EB04                <1> 	jmp	short ctty_0
 27522                              <1> ccvt:
 27523 000057E0 2C0A                <1> 	sub 	al, 10
 27524                              <1> cttyp:
 27525                              <1> 	; 08/01/2022
 27526 000057E2 31DB                <1> 	xor	ebx, ebx
 27527                              <1> ctty_0:		; 06/02/2022
 27528                              <1> 	; 09/02/2022
 27529                              <1> 	;    DL=2 -> open for writing
 27530                              <1> 	;    DL=1 -> open for reading
 27531                              <1> 	;    DL=0 -> open for sysstty system call	
 27532                              <1> 	; 08/01/2022
 27533                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 27534                              <1> 	; 18/05/2015 (32 bit modifications)
 27535                              <1> 	; 16/08/2013 - 26/01/2014
 27536                              <1> 	;movzx 	ebx, al ; tty number (0 to 9)
 27537                              <1> 	; 08/01/2022
 27538 000057E4 88C3                <1> 	mov	bl, al
 27539 000057E6 D0E3                <1> 	shl 	bl, 1  ; aligned to word	
 27540                              <1> 	; 26/01/2014
 27541 000057E8 81C3[74670000]      <1> 	add 	ebx, ttyl
 27542 000057EE 88C6                <1> 	mov 	dh, al ; tty number
 27543 000057F0 668B03              <1> 	mov 	ax, [ebx]
 27544                              <1> 		   ; AL = lock value (0 or process number)
 27545                              <1> 		   ; AH = open count 
 27546 000057F3 20E4                <1> 	and 	ah, ah
 27547 000057F5 7514                <1> 	jnz	short ctty_ret
 27548                              <1> 	; 09/02/2022
 27549 000057F7 80FA01              <1> 	cmp	dl, 1	; DL = 0 -> called by sysstty
 27550 000057FA 7231                <1> 	jb	short ctty_stc_retn ; cf=1
 27551                              <1> 	; iclose (dl=1 or dl=2)
 27552 000057FC C705[D86C0000]0A00- <1>         mov     dword [u.error], ERR_DEV_NOT_OPEN
 27553 00005804 0000                <1>
 27554                              <1> 			; device not open ! error
 27555                              <1> 	;jmp 	short ctty_err ; open count = 0, it is not open !
 27556 00005806 E956D9FFFF          <1> 	jmp	error
 27557                              <1> 	; 26/01/2014
 27558                              <1> ctty_ret:
 27559 0000580B FECC                <1> 	dec 	ah ; decrease open count
 27560 0000580D 7502                <1> 	jnz	short ctty_1
 27561 0000580F 30C0                <1> 	xor	al, al ; unlock/free tty
 27562                              <1> ctty_1:
 27563 00005811 668903              <1> 	mov 	[ebx], ax ; close tty instance
 27564                              <1> 	;
 27565 00005814 BB[9A6C0000]        <1> 	mov	ebx, u.ttyp
 27566                              <1> 	;;test	dl, 1 ; open for write sign
 27567                              <1> 	;;jz	short ctty_2
 27568                              <1> 	; 05/12/2021
 27569                              <1> 	;test	dl, 2 ; open for write sign
 27570                              <1> 	;jz	short ctty_2	
 27571                              <1> 	; 09/02/2022
 27572 00005819 F6C201              <1> 	test	dl, 1 ; open for read sign
 27573 0000581C 7501                <1> 	jnz	short ctty_2
 27574                              <1> 	; open for write (dl=0 or dl=2)
 27575 0000581E 43                  <1> 	inc	ebx
 27576                              <1> ctty_2:
 27577 0000581F FEC6                <1> 	inc	dh ; tty number + 1
 27578 00005821 3A33                <1> 	cmp	dh, [ebx]
 27579                              <1> 	;jne	short cret
 27580 00005823 7503                <1> 	jne	short ctty_3 ; 09/02/2022
 27581                              <1> 	; Reset/Clear 'u.ttyp' ('the recent TTY') value
 27582 00005825 C60300              <1> 	mov	byte [ebx], 0
 27583                              <1> ctty_3:
 27584                              <1> 	; 09/02/2022
 27585 00005828 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 27586 0000582A 7401                <1> 	jz	short ctty_4
 27587                              <1> cret:
 27588                              <1> 	;pop	ax
 27589                              <1> 	; 05/12/2021
 27590 0000582C 58                  <1> 	pop	eax
 27591                              <1> ctty_stc_retn:	; 09/02/2022
 27592                              <1> ctty_4:
 27593 0000582D C3                  <1> 	retn
 27594                              <1> 
 27595                              <1> ;ctty_err: ; 13/01/2014
 27596                              <1> ;	or 	dl, dl ; DL = 0 -> called by sysstty
 27597                              <1> ;	jnz	error
 27598                              <1> ;	stc
 27599                              <1> ;	retn
 27600                              <1> 
 27601                              <1> 	; Original UNIX v1 'ctty' routine:
 27602                              <1> 	;	
 27603                              <1>         ;mov    tty+[ntty*8]-8+6,r5 
 27604                              <1> 	;		;/ point r5 to the console tty buffer
 27605                              <1>         ;decb   (r5) / dec number of processes using console tty
 27606                              <1>         ;br     sret / return via sret
 27607                              <1> 
 27608                              <1> ;ccvt:	; < close tty >
 27609                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 27610                              <1> 	;
 27611                              <1> 	; Retro UNIX 8086 v1 modification !
 27612                              <1> 	; 
 27613                              <1> 	; In original UNIX v1, 'ccvt' routine 
 27614                              <1> 	;		(exactly different than this one)
 27615                              <1> 	;	was in 'u9.s' file.
 27616                              <1> 	;
 27617                              <1> 	; DL = 2 -> it is open for reading
 27618                              <1> 	; DL = 1 -> it is open for writing
 27619                              <1> 	;
 27620                              <1> 	; 17/09/2013
 27621                              <1> 	;sub 	al, 10
 27622                              <1> 	;cmp	al, 7
 27623                              <1> 	;jna	short cttyp
 27624                              <1> 	; 13/01/2014
 27625                              <1> 	;jmp	short cttyp
 27626                              <1> 
 27627                              <1> ;cppt: / close paper tape
 27628                              <1> ;        clrb   pptiflg / set pptiflg to indicate file not open
 27629                              <1> ;1:
 27630                              <1> ;        mov    $240,*$ps /set process or priority to 5
 27631                              <1> ;        jsr    r0,getc; 2 / remove all ppt input entries from clist
 27632                              <1> ;                          / and assign to free list
 27633                              <1> ;               br sret
 27634                              <1> ;        br     1b
 27635                              <1> 
 27636                              <1> ;ejec:	
 27637                              <1> ;	jmp	error
 27638                              <1> ;/ejec:
 27639                              <1> ;/       mov    $100,*$lps / set line printer interrupt enable bit
 27640                              <1> ;/       mov    $14,r1 / 'form feed' character in r1 (new page).
 27641                              <1> ;/       jsr    r0,lptoc / space the printer to a new page
 27642                              <1> ;/       br     sret / return to caller via 'sret'
 27643                              <1> 
 27644                              <1> ejec:
 27645                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2 - Printer Initialization
 27646                              <1> lpt_init:	
 27647                              <1> 	; Ref: IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985
 27648                              <1> 	;
 27649                              <1> 	; Default printer port: 378h ; LPT1
 27650                              <1> 	
 27651 0000582E B401                <1>  	mov	ah, 1  ; INITIALIZE THE PRINTER PORT
 27652                              <1> 	;call	int17h
 27653 00005830 E846FAFFFF          <1> 	call	PRNOP
 27654 00005835 7414                <1> 	jz	short lpt_init_ok
 27655                              <1> 	
 27656                              <1> 	; replace error code with 'device not ready' error
 27657                              <1> 	; (this may be better for 'sysopen')
 27658 00005837 B80F000000          <1> 	mov	eax, ERR_PRN_NOT_RDY
 27659 0000583C A3[D86C0000]        <1> 	mov	[u.error], eax
 27660                              <1> 	;jmp	sysret ; (may be) ? ([u.r0] = file descriptor)
 27661 00005841 A3[646C0000]        <1> 	mov	[u.r0], eax
 27662 00005846 E916D9FFFF          <1> 	jmp	error ; (better)	
 27663                              <1> 	
 27664                              <1> lpt_init_ok:
 27665                              <1> 	;jmp	short cret
 27666 0000584B 58                  <1> 	pop	eax    ; inode number
 27667 0000584C C3                  <1> 	retn
 27668                              <1> 	
 27669                                  %include 'u8.s'      ; 11/06/2015
 27670                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 27671                              <1> ; (re-write kernel for test by using previous version without a major defect)
 27672                              <1> ; ****************************************************************************
 27673                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - SYS8.INC
 27674                              <1> ; Last Modification: 19/07/2022
 27675                              <1> ; ----------------------------------------------------------------------------
 27676                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 27677                              <1> ; (v0.1 - Beginning: 11/07/2012)
 27678                              <1> ;
 27679                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 27680                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 27681                              <1> ; <Bell Laboratories (17/3/1972)>
 27682                              <1> ; <Preliminary Release of UNIX Implementation Document>
 27683                              <1> ;
 27684                              <1> ; Retro UNIX 8086 v1 - U8.ASM (18/01/2014) //// UNIX v1 -> u8.s
 27685                              <1> ;
 27686                              <1> ; ****************************************************************************
 27687                              <1> 
 27688                              <1> ; 15/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 27689                              <1> ; 15/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
 27690                              <1> ; 14/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
 27691                              <1> ;---------------------------------------------------------------------
 27692                              <1> ; Buffer Header: -8 bytes-
 27693                              <1> ; word 1 - byte 0 - device (disk index) number (0 to 5)
 27694                              <1> ;	   byte 1 - status bits
 27695                              <1> ;	 	bit 0 - valid buffer bit (1 = valid, 0 = invalid, new)
 27696                              <1> ;		bit 1 - write bit (also modified bit)
 27697                              <1> ;		bit 2 - read bit	
 27698                              <1> ;		bit 3 to bit 7 are not used
 27699                              <1> ; word 2 - byte & byte 3 not used
 27700                              <1> ; word 3 & word 4 - byte 3, byte 5, byte 6, byte 7:
 27701                              <1> ;		physical block/sector address (32 bit LBA)
 27702                              <1> ;---------------------------------------------------------------------
 27703                              <1> 
 27704                              <1> ;; I/O Buffer - Retro UNIX 386 v1 modification
 27705                              <1> ;;     (8+512 bytes, 8 bytes header, 512 bytes data)
 27706                              <1> ;; Word 1, byte 0 = device id
 27707                              <1> ;; Word 1, byte 1 = status bits (bits 8 to 15)
 27708                              <1> ;;          bit 9 = write bit
 27709                              <1> ;;	    bit 10 = read bit	  
 27710                              <1> ;;	    bit 12 = waiting to write bit	
 27711                              <1> ;;	    bit 13 = waiting to read bit
 27712                              <1> ;;	    bit 15 = inhibit bit
 27713                              <1> ;; Word 2 (byte 2 & byte 3) = reserved (for now - 07/06/2015)
 27714                              <1> ;; Word 3 + Word 4 (byte 4,5,6,7) = physical block number 
 27715                              <1> ;;		   (In fact, it is 32 bit LBA for Retro UNIX 386 v1)
 27716                              <1> ;;
 27717                              <1> ;; I/O Buffer ((8+512 bytes in original Unix v1))
 27718                              <1> ;;	      ((4+512 bytes in Retro UNIX 8086 v1))
 27719                              <1> ;;
 27720                              <1> ;; I/O Queue Entry (of original UNIX operating system v1)
 27721                              <1> ;; Word 1, Byte 0 = device id
 27722                              <1> ;; Word 1, Byte 1 = (bits 8 to 15)
 27723                              <1> ;;          bit 9 = write bit
 27724                              <1> ;;	    bit 10 = read bit	  
 27725                              <1> ;;	    bit 12 = waiting to write bit	
 27726                              <1> ;;	    bit 13 = waiting to read bit
 27727                              <1> ;;	    bit 15 = inhibit bit
 27728                              <1> ;; Word 2 = physical block number (In fact, it is LBA for Retro UNIX 8086 v1)
 27729                              <1> ;;
 27730                              <1> ;; Original UNIX v1 ->
 27731                              <1> ;;		Word 3 = number of words in buffer (=256) 		
 27732                              <1> ;; Original UNIX v1 -> 
 27733                              <1> ;;		Word 4 = bus address (addr of first word of data buffer)
 27734                              <1> ;;
 27735                              <1> ;; Retro UNIX 8086 v1 -> Buffer Header (I/O Queue Entry) size is 4 bytes !
 27736                              <1> ;;
 27737                              <1> ;; Device IDs (of Retro Unix 8086 v1)
 27738                              <1> ;;          0 = fd0
 27739                              <1> ;;	    1 = fd1
 27740                              <1> ;;	    2 = hd0
 27741                              <1> ;;	    3 = hd1
 27742                              <1> ;;	    4 = hd2
 27743                              <1> ;;	    5 = hd3
 27744                              <1> 
 27745                              <1> ; Retro UNIX 386 v1 - 32 bit modifications (rfd, wfd, rhd, whd) - 09/06/2015
 27746                              <1> 
 27747                              <1> 	; 08/02/2022
 27748                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27749                              <1> rfd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27750                              <1> 	; 26/04/2013
 27751                              <1>    	; 13/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27752                              <1>    	;sub 	ax, 3 ; zero based device number (Floppy disk)
 27753                              <1>       	;jmp 	short bread ; **** returns to routine that called readi			
 27754                              <1> 
 27755                              <1> 	; 08/02/2022
 27756                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27757                              <1> rhd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27758                              <1> 	; 26/04/2013
 27759                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27760                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 27761                              <1>    	;jmp	short bread ; **** returns to routine that called readi	
 27762                              <1> 
 27763                              <1> bread: 
 27764                              <1> 	; 19/07/2022
 27765                              <1> 	; 15/07/2022
 27766                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 27767                              <1> 	; 08/02/2022
 27768                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27769                              <1> 	; 14/07/2015
 27770                              <1> 	; 10/07/2015
 27771                              <1> 	; 09/06/2015
 27772                              <1> 	; 07/06/2015 (Retro UNIX 386 v1 - Beginning)
 27773                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 27774                              <1> 	;	
 27775                              <1> 	; / read a block from a block structured device
 27776                              <1> 	;
 27777                              <1> 	; INPUTS ->
 27778                              <1> 	;    [u.fopf] points to the block number
 27779                              <1> 	;    ECX = maximum block number allowed on device
 27780                              <1> 	;	 ; that was an arg to bread, in original Unix v1, but
 27781                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 27782                              <1> 	;    [u.count] number of bytes to read in
 27783                              <1> 	; OUTPUTS ->
 27784                              <1> 	;    [u.base] starting address of data block or blocks in user area  	
 27785                              <1> 	;    [u.fopf] points to next consecutive block to be read
 27786                              <1> 	;
 27787                              <1> 	; ((Modified registers: eax, edx, ecx, ebx, esi, edi))
 27788                              <1> 	;
 27789                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if read
 27790                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 27791                              <1> 	;	is increased by 1. For example: If user/program request 
 27792                              <1> 	;       to read 16 bytes in current block, 'sys read' increases
 27793                              <1> 	;  	the next block number just as 512 byte reading is done.
 27794                              <1> 	;       This wrong is done in 'bread'. So, in Retro UNIX 8086 v1, 
 27795                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 27796                              <1> 	;       enough to keep byte position/offset of the disk), this
 27797                              <1> 	;	defect will not be corrected, user/program must request
 27798                              <1> 	;	512 byte read per every 'sys read' call to block devices
 27799                              <1> 	;       for achieving correct result. In future version(s), 
 27800                              <1> 	;	this defect will be corrected by using different 
 27801                              <1> 	;       user (u) structure. 26/07/2013 - Erdogan Tan 	
 27802                              <1> 
 27803                              <1> 	   	; jsr r0,tstdeve / error on special file I/O 
 27804                              <1> 			       ; / (only works on tape)
 27805                              <1> 		; mov *u.fofp,r1 / move block number to r1
 27806                              <1> 		; mov $2.-cold,-(sp) / "2-cold" to stack
 27807                              <1> ;1:
 27808                              <1> 		; cmp r1,(r0) / is this block # greater than or equal to
 27809                              <1> 			    ; / maximum block # allowed on device
 27810                              <1> 		; jnb short @f
 27811                              <1> 		; bhis	1f / yes, 1f (error)
 27812                              <1> 		; mov r1,-(sp) / no, put block # on stack
 27813                              <1> 		; jsr r0,preread / read in the block into an I/O buffer
 27814                              <1> 		; mov (sp)+,r1 / return block # to r1
 27815                              <1> 		; inc r1 / bump block # to next consecutive block
 27816                              <1> 		; dec (sp) / "2-1-cold" on stack
 27817                              <1> 		; bgt 1b / 2-1-cold = 0? No, go back and read in next block
 27818                              <1> ;1:
 27819                              <1> 		; tst (sp)+ / yes, pop stack to clear off cold calculation
 27820                              <1> 	;push	ecx ; **
 27821                              <1> 	; 26/04/2013
 27822                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 27823 0000584D 2C03                <1> 	sub	al, 3
 27824                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 27825 0000584F A2[D76C0000]        <1> 	mov	[u.brwdev], al
 27826                              <1> 	; 09/06/2015
 27827                              <1> 	;movzx	ebx, al
 27828                              <1> 	;mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 27829                              <1> 	; 12/01/2022 (BugFix)
 27830 00005854 C0E002              <1> 	shl	al, 2 ; * 4
 27831 00005857 8B88[52620000]      <1> 	mov	ecx, [eax+drv.size] ; disk size (in sectors)
 27832                              <1> bread_0:
 27833 0000585D 51                  <1> 	push	ecx ; ** ; 09/06/2015 
 27834                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 27835                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 27836 0000585E 8B1D[786C0000]      <1> 	mov	ebx, [u.fofp]
 27837 00005864 8B03                <1> 	mov	eax, [ebx]
 27838 00005866 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 27839                              <1> 		; mov *u.fofp,r1 / restore r1 to initial value of the
 27840                              <1> 			       ; / block #
 27841 00005869 39C8                <1> 	cmp	eax, ecx
 27842                              <1> 		; cmp r1,(r0)+ / block # greater than or equal to maximum
 27843                              <1>        	                     ; / block number allowed
 27844                              <1> 	;jnb	error 	     ; 18/04/2013
 27845                              <1> 		; bhis error10 / yes, error
 27846                              <1> 	; 08/02/2022
 27847                              <1> 	;jb	short bread_1
 27848                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
 27849                              <1> 	;jmp	error
 27850 0000586B 7346                <1> 	jnb	short brw_oov_err ; 'out of volume' error
 27851                              <1> bread_1:
 27852                              <1> 	;inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 27853                              <1> 		; inc *u.fofp / no, *u.fofp has next block number
 27854                              <1> 	; EAX = Block number (zero based)
 27855                              <1> 		;;jsr r0,preread / read in the block whose number is in r1
 27856                              <1> preread: ;; call preread
 27857 0000586D BF[D76C0000]        <1> 	mov	edi, u.brwdev ; block device number for direct I/O
 27858 00005872 E8E1010000          <1> 	call	bufaloc_0 ; 26/04/2013
 27859                              <1> 	;; jc 	error
 27860                              <1> 	; EBX = Buffer (Header) Address -Physical-
 27861                              <1>         ; EAX = Block/Sector number (r1)
 27862                              <1> 	       ; jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
 27863                              <1> 	; 14/03/2013
 27864 00005877 7411                <1>         jz	short bread_2 ; Retro UNIX 8086 v1 modification
 27865                              <1>        		; br 1f / branch if block already in a I/O buffer
 27866 00005879 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 27867                              <1>         	; bis $2000,(r5) / set read bit (bit 10 in I/O buffer)
 27868 0000587E E8AD010000          <1> 	call	poke
 27869                              <1>         	; jsr r0,poke / perform the read
 27870                              <1> 	;;jc	error ;2 0/07/2013
 27871                              <1> ; 1:
 27872                              <1>  		; clr *$ps / ps = 0
 27873                              <1>         	; rts r0
 27874                              <1> 	; 08/02/2022
 27875 00005883 7305                <1> 	jnc	short bread_2
 27876 00005885 E919010000          <1> 	jmp	dskrd_err
 27877                              <1> 	;
 27878                              <1> ;; return from preread
 27879                              <1> bread_2:
 27880                              <1> 	; 15/07/2022
 27881                              <1> 	;or	word [ebx], 4000h 
 27882                              <1> 	;	; bis $40000,(r5) 
 27883                              <1> 	;		; / set bit 14 of the 1st word of the I/O buffer
 27884                              <1> bread_3: ; 1:
 27885                              <1> 	; 15/07/2022
 27886                              <1> 	;test	word [ebx], 2400h
 27887                              <1> 	;	; bit $22000,(r5) / are 10th and 13th bits set (read bits)
 27888                              <1> 	;jz	short bread_4
 27889                              <1> 	;	; beq 1f / no
 27890                              <1> 	;	; cmp cdev,$1 / disk or drum?
 27891                              <1> 	;	; ble 2f / yes
 27892                              <1> 	;	; tstb uquant / is the time quantum = 0?
 27893                              <1> 	;	; bne 2f / no, 2f
 27894                              <1> 	;	; mov r5,-(sp) / yes, save r5 (buffer address)
 27895                              <1> 	;	; jsr r0,sleep; 31. 
 27896                              <1> 	;		; / put process to sleep in channel 31 (tape)
 27897                              <1> 	;	; mov (sp)+,r5 / restore r5
 27898                              <1> 	;	; br 1b / go back
 27899                              <1> ; 2: / drum or disk
 27900                              <1>         ;; mov     cx, [s.wait_]+2 ;; 29/07/2013
 27901                              <1> 	;call	idle
 27902                              <1> 	;	; jsr r0,idle; s.wait+2 / wait
 27903                              <1> 	;jmp	short bread_3
 27904                              <1>        	;	; br 1b
 27905                              <1> bread_4: ; 1: / 10th and 13th bits not set
 27906                              <1> 	;and	word [ebx], 0BFFFh ; 1011111111111111b
 27907                              <1> 	;	; bic $40000,(r5) / clear bit 14
 27908                              <1>        	;	; jsr r0,tstdeve / test device for error (tape)
 27909                              <1> 	; 15/07/2022
 27910 0000588A 83C308              <1> 	add	ebx, 8
 27911                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 27912                              <1> 	; 09/06/2015
 27913 0000588D 66833D[D06C0000]00  <1> 	cmp	word [u.pcount], 0
 27914 00005895 7705                <1> 	ja	short bread_5
 27915 00005897 E8FCF7FFFF          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 27916                              <1> bread_5:
 27917                              <1> 	; EBX = system (I/O) buffer address
 27918 0000589C E87C000000          <1> 	call	dioreg
 27919                              <1>        		; jsr r0,dioreg / do bookkeeping on u.count etc.
 27920                              <1> 
 27921                              <1> 	; 19/07/2022
 27922                              <1> 	; EDI = user data offset (previous value of [u.pbase])
 27923                              <1> 	; ESI = pointer to file offset 
 27924                              <1> 	; EAX = system (I/O) buffer offset (>= EBX)
 27925                              <1> 	; ECX = byte count
 27926                              <1> 	; EBX = system buffer (data) address
 27927                              <1> 
 27928                              <1> 	; 19/07/2022
 27929 000058A1 010E                <1> 	add	[esi], ecx ; new file (disk) offset
 27930 000058A3 89C6                <1> 	mov	esi, eax
 27931                              <1> 
 27932                              <1> 	; esi = start address of the transfer (in the buffer)
 27933                              <1> 	; edi = [u.pbase], destination address in user's memory space
 27934                              <1> 	; ecx = transfer count (in bytes)
 27935                              <1> 	;
 27936                              <1> ;1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
 27937                              <1> ;   / of users data
 27938 000058A5 F3A4                <1> 	rep	movsb
 27939                              <1> 		; movb (r5)+,(r2)+ / move data from the I/O buffer
 27940                              <1>        		; dec r3 / to the user's area in core starting at u.base
 27941                              <1>        		; bne 1b
 27942 000058A7 59                  <1> 	pop	ecx ; **
 27943 000058A8 833D[8C6C0000]00    <1> 	cmp	dword [u.count], 0
 27944                              <1> 		; tst u.count / done
 27945 000058AF 77AC                <1> 	ja	short bread_0 ; 09/06/2015
 27946                              <1>        		; beq 1f / yes, return
 27947                              <1> 		; tst -(r0) / no, point r0 to the argument again
 27948                              <1>        		; br bread / read some more
 27949                              <1> ; 1:
 27950 000058B1 58                  <1> 	pop	eax ; ****
 27951                              <1>        		; mov (sp)+,r0
 27952 000058B2 C3                  <1>         retn		; 09/06/2015
 27953                              <1> 	;jmp	ret_ 
 27954                              <1> 		;jmp ret / jump to routine that called readi
 27955                              <1> 
 27956                              <1> 	; 08/02/2022
 27957                              <1> brw_oov_err:
 27958 000058B3 C705[D86C0000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
 27959 000058BB 0000                <1>
 27960 000058BD E99FD8FFFF          <1> 	jmp	error
 27961                              <1> 
 27962                              <1> 	; 08/02/2022
 27963                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27964                              <1> wfd:    ; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27965                              <1> 	; 26/04/2013
 27966                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27967                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 27968                              <1>    	;jmp	short bwrite ; **** returns to routine that called writei
 27969                              <1> 
 27970                              <1> 	; 08/02/2022
 27971                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)				
 27972                              <1> whd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27973                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 27974                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 27975                              <1>    	;jmp 	short bwrite ; **** returns to routine that called writei ('jmp ret')
 27976                              <1> 
 27977                              <1> bwrite:
 27978                              <1> 	; 19/07/2022
 27979                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 27980                              <1> 	; 15/07/2022
 27981                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3) 
 27982                              <1> 	; 08/02/2022
 27983                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 27984                              <1> 	; 14/07/2015
 27985                              <1> 	; 10/07/2015
 27986                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 27987                              <1> 	; 14/03/2013 - 20/07/2013 (Retro UNIX 8086 v1)
 27988                              <1> 	;	
 27989                              <1> 	;; / write on block structured device
 27990                              <1> 	;
 27991                              <1> 	; INPUTS ->
 27992                              <1> 	;    [u.fopf] points to the block number
 27993                              <1> 	;    ECX = maximum block number allowed on device
 27994                              <1> 	;	 ; that was an arg to bwrite, in original Unix v1, but
 27995                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 27996                              <1> 	;    [u.count]	number of bytes to user desires to write
 27997                              <1> 	; OUTPUTS ->
 27998                              <1> 	;    [u.fopf] points to next consecutive block to be written into
 27999                              <1> 	;
 28000                              <1> 	; ((Modified registers: edx, ecx, ebx, esi, edi))
 28001                              <1> 	;
 28002                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if write
 28003                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 28004                              <1> 	;	is increased by 1. For example: If user/program request 
 28005                              <1> 	;       to write 16 bytes in current block, 'sys write' increases
 28006                              <1> 	;  	the next block number just as 512 byte writing is done.
 28007                              <1> 	;       This wrong is done in 'bwrite'. So, in Retro UNIX 8086 v1, 
 28008                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 28009                              <1> 	;       enough to keep byte position/offset of the disk), this
 28010                              <1> 	;	defect will not be corrected, user/program must request
 28011                              <1> 	;	512 byte write per every 'sys write' call to block devices
 28012                              <1> 	;       for achieving correct result. In future version(s), 
 28013                              <1> 	;	this defect will be corrected by using different 
 28014                              <1> 	;       user (u) structure. 26/07/2013 - Erdogan Tan 	
 28015                              <1> 
 28016                              <1>        		; jsr r0,tstdeve / test the device for an error
 28017                              <1> 	;push	ecx ; **
 28018                              <1> 	;26/04/2013
 28019                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 28020 000058C2 2C03                <1> 	sub	al, 3
 28021                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 28022 000058C4 A2[D76C0000]        <1> 	mov	[u.brwdev], al
 28023                              <1> 	; 09/06/2015
 28024                              <1> 	;movzx	ebx, al
 28025                              <1> 	;mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 28026                              <1> 	; 12/01/2022 (BugFix)
 28027 000058C9 C0E002              <1> 	shl	al, 2 ; * 4
 28028 000058CC 8B88[52620000]      <1> 	mov	ecx, [eax+drv.size] ; disk size (in sectors)
 28029                              <1> bwrite_0:
 28030 000058D2 51                  <1> 	push	ecx ; ** ; 09/06/2015
 28031                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 28032                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 28033 000058D3 8B1D[786C0000]      <1> 	mov	ebx, [u.fofp]
 28034 000058D9 8B03                <1> 	mov	eax, [ebx]       
 28035 000058DB C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 28036                              <1> 		; mov *u.fofp,r1 / put the block number in r1
 28037 000058DE 39C8                <1> 	cmp	eax, ecx
 28038                              <1> 		; cmp r1,(r0)+ / does block number exceed maximum allowable #
 28039                              <1>        	                     ; / block number allowed
 28040                              <1> 	;jnb	error	     ; 18/04/2013
 28041                              <1> 		; bhis error10 / yes, error
 28042                              <1>      	; 08/02/2022
 28043                              <1> 	;jb	short bwrite_1
 28044                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error
 28045                              <1> 	;jmp	error
 28046 000058E0 73D1                <1> 	jnb	short brw_oov_err ; 'out of volume' error
 28047                              <1> bwrite_1:
 28048                              <1> 	;inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 28049                              <1> 		; inc *u.fofp / no, increment block number
 28050                              <1> 	; 09/06/2015 - 10/07/2015
 28051 000058E2 66833D[D06C0000]00  <1> 	cmp	word [u.pcount], 0
 28052 000058EA 7705                <1> 	ja	short bwrite_2
 28053 000058EC E8A3F7FFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 28054                              <1> bwrite_2:
 28055 000058F1 BF[D76C0000]        <1> 	mov	edi, u.brwdev  ; block device number for direct I/O
 28056 000058F6 E8C9000000          <1>        	call	bwslot ; 26/04/2013 (wslot -> bwslot)	 				
 28057                              <1> 		; jsr r0,wslot / get an I/O buffer to write into
 28058                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 28059 000058FB E81D000000          <1>         call	dioreg
 28060                              <1> 		; jsr r0,dioreg / do the necessary bookkeeping
 28061                              <1> 
 28062                              <1> 	; 19/07/2022
 28063                              <1> 	; EDI = user data offset (previous value of [u.pbase])
 28064                              <1> 	; ESI = pointer to file offset 
 28065                              <1> 	; EAX = system (I/O) buffer offset (>= EBX)
 28066                              <1> 	; ECX = byte count
 28067                              <1> 	; EBX = system buffer (data) address
 28068                              <1> 
 28069                              <1> 	; 19/07/2022 - Erdogan Tan
 28070                              <1> 	; ((Against a possible disk write failure/error, 
 28071                              <1> 	;   file offset must not be updated/increased before 'dskwr'
 28072                              <1> 	;   but it was updated in 'dioreg'. I have modified 'dioreg'
 28073                              <1> 	;   and 'bwrite' procedures for that.))
 28074                              <1> 
 28075                              <1> 	; 19/07/2022
 28076 00005900 56                  <1> 	push	esi ; (!)  ; save file offset (pointer)
 28077 00005901 51                  <1> 	push	ecx ; (!!) ; save byte count
 28078                              <1> 	;mov	esi, eax
 28079                              <1> 	
 28080                              <1> 	; esi = destination address (in the buffer)
 28081                              <1> 	; edi = [u.pbase], start address of transfer in user's memory space
 28082                              <1> 	; ecx = transfer count (in bytes)
 28083                              <1> ; 1: / r2 points to the users data; r5 points to the I/O buffers data area
 28084                              <1> 	;xchg 	esi, edi ; 14/07/2015
 28085                              <1> 
 28086                              <1> 	; 19/07/2022
 28087 00005902 89FE                <1> 	mov	esi, edi
 28088 00005904 89C7                <1> 	mov	edi, eax
 28089                              <1> 
 28090 00005906 F3A4                <1> 	rep	movsb
 28091                              <1> 		; movb (r2)+,(r5)+ / ; r3, has the byte count
 28092                              <1>        		; dec r3 / area to the I/O buffer
 28093                              <1>        		; bne 1b
 28094                              <1> 
 28095 00005908 E8F0000000          <1> 	call	dskwr
 28096                              <1> 		; jsr r0,dskwr / write it out on the device
 28097                              <1> 
 28098                              <1> 	; 19/07/2022
 28099                              <1> 	; (there is not a disk write error, we can increase file offset)
 28100 0000590D 58                  <1> 	pop	eax ; (!!) ; byte count
 28101 0000590E 5F                  <1> 	pop	edi ; (!)  ; file offset (pointer)
 28102                              <1> 	;
 28103 0000590F 0107                <1> 	add	[edi], eax ; new file offset (old offset + byte count)
 28104                              <1> 
 28105 00005911 59                  <1> 	pop	ecx ; **
 28106                              <1> 
 28107 00005912 833D[8C6C0000]00    <1>         cmp     dword [u.count], 0
 28108                              <1> 		; tst u.count / done
 28109 00005919 77B7                <1> 	ja	short bwrite_0 ; 09/06/2015
 28110                              <1> 		; beq 1f / yes, 1f
 28111                              <1> 		; tst -(r0) / no, point r0 to the argument of the call
 28112                              <1>        		; br bwrite / go back and write next block
 28113                              <1> ; 1:
 28114 0000591B 58                  <1> 	pop	eax ; ****
 28115                              <1>        		; mov (sp)+,r0
 28116 0000591C C3                  <1> 	retn		; 09/06/2015
 28117                              <1>         ;jmp	ret_ 
 28118                              <1> 		; jmp ret / return to routine that called writei
 28119                              <1> ;error10:
 28120                              <1> ;       jmp     error  ; / see 'error' routine
 28121                              <1> 
 28122                              <1> dioreg:
 28123                              <1> 	; 19/07/2022
 28124                              <1> 	;	(file offset bugfix for 'dskwr' error return situation)
 28125                              <1> 	;
 28126                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
 28127                              <1> 	; 14/07/2015
 28128                              <1> 	; 10/07/2015 (UNIX v1 bugfix - [u.fofp]: byte pos., not block)
 28129                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28130                              <1> 	; 14/03/2013 (Retro UNIX 8086 v1)
 28131                              <1> 	;	
 28132                              <1> 	; bookkeeping on block transfers of data
 28133                              <1> 	;
 28134                              <1> 	; * returns value of u.pbase before it gets updated, in EDI
 28135                              <1> 	; * returns byte count (to transfer) in ECX (<=512)
 28136                              <1> 	; 10/07/2015
 28137                              <1> 	; * returns byte offset from beginning of current sector buffer
 28138                              <1> 	; (beginning of data) in ESI
 28139                              <1> 
 28140                              <1> 	; 19/07/2022
 28141                              <1> 	; OUTPUTS:
 28142                              <1> 	;   EDI = user data offset (previous value of [u.pbase])
 28143                              <1> 	;   ESI = pointer to file offset 
 28144                              <1> 	;   EAX = system (I/O) buffer offset
 28145                              <1> 	;   ECX = byte count
 28146                              <1> 	;   EBX = system buffer (data) address	
 28147                              <1> 
 28148 0000591D 8B0D[8C6C0000]      <1> 	mov	ecx, [u.count]
 28149                              <1> 		; mov u.count,r3 / move char count to r3
 28150                              <1> 	; 08/02/2022
 28151 00005923 31D2                <1> 	xor	edx, edx
 28152 00005925 B602                <1> 	mov	dh, 2
 28153                              <1> 	; edx = 512
 28154 00005927 39D1                <1> 	cmp	ecx, edx ; 512
 28155                              <1> 	;cmp 	ecx, 512
 28156                              <1> 		; cmp r3,$512. / more than 512. char?
 28157 00005929 7602                <1> 	jna	short dioreg_0
 28158                              <1> 		; blos 1f / no, branch
 28159 0000592B 89D1                <1> 	mov	ecx, edx ; 512
 28160                              <1> 	;mov	ecx, 512
 28161                              <1> 		; mov $512.,r3 / yes, just take 512.
 28162                              <1> dioreg_0:
 28163                              <1> 	; 09/06/2015
 28164 0000592D 663B0D[D06C0000]    <1> 	cmp	cx, [u.pcount]
 28165 00005934 7607                <1> 	jna	short dioreg_1
 28166 00005936 668B0D[D06C0000]    <1> 	mov	cx, [u.pcount]
 28167                              <1> dioreg_1:
 28168                              <1> ; 1:
 28169 0000593D 8B15[886C0000]      <1> 	mov	edx, [u.base] ; 09/06/2015 (eax -> edx)
 28170                              <1> 	        ; mov u.base,r2 / put users base in r2
 28171 00005943 010D[906C0000]      <1> 	add	[u.nread], ecx
 28172                              <1> 		; add r3,u.nread / add the number to be read to u.nread
 28173 00005949 290D[8C6C0000]      <1> 	sub	[u.count], ecx
 28174                              <1> 		; sub r3,u.count / update count
 28175 0000594F 010D[886C0000]      <1> 	add	[u.base], ecx
 28176                              <1> 		; add r3,u.base / update base
 28177                              <1> 	; 10/07/2015
 28178                              <1> 	; Retro UNIX 386 v1 - modification !
 28179                              <1> 	; (File pointer points to byte position, not block/sector no.)
 28180                              <1> 	; (It will point to next byte position instead of next block no.)
 28181 00005955 8B35[786C0000]      <1> 	mov	esi, [u.fofp] ; u.fopf points to byte position pointer  
 28182 0000595B 8B06                <1> 	mov	eax, [esi] ; esi points to current byte pos. on the disk
 28183                              <1> 	; 19/07/2022
 28184                              <1> 	;add	[esi], ecx ; ecx is added to set the next byte position
 28185 0000595D 25FF010000          <1> 	and	eax, 1FFh  ; get offset from beginning of current block	
 28186                              <1> 	;mov	esi, ebx   ; beginning of data in sector/block buffer
 28187                              <1> 	;add	esi, eax   ; esi contains start address of the transfer
 28188                              <1> 	; 19/07/2022
 28189 00005962 01D8                <1> 	add	eax, ebx   ; eax contains start address of the transfer	
 28190                              <1> 	; 09/06/2015 - 10/07/2015
 28191 00005964 66290D[D06C0000]    <1> 	sub	[u.pcount], cx
 28192 0000596B 81E2FF0F0000        <1> 	and	edx, PAGE_OFF ; 0FFFh
 28193 00005971 8B3D[CC6C0000]      <1> 	mov	edi, [u.pbase]
 28194 00005977 81E700F0FFFF        <1> 	and	edi, ~PAGE_OFF
 28195 0000597D 01D7                <1> 	add	edi, edx
 28196 0000597F 893D[CC6C0000]      <1> 	mov	[u.pbase], edi
 28197 00005985 010D[CC6C0000]      <1> 	add	[u.pbase], ecx ; 14/07/2015
 28198 0000598B C3                  <1> 	retn
 28199                              <1> 		; rts r0 / return
 28200                              <1> 
 28201                              <1> dskrd:
 28202                              <1> 	; 15/07/2022
 28203                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28204                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
 28205                              <1> 	; 18/08/2015
 28206                              <1> 	; 02/07/2015
 28207                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28208                              <1> 	; 14/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 28209                              <1> 	;
 28210                              <1> 	; 'dskrd' acquires an I/O buffer, puts in the proper
 28211                              <1> 	; I/O queue entries (via bufaloc) then reads a block
 28212                              <1> 	; (number specified in r1) in the acquired buffer.)
 28213                              <1> 	; If the device is busy at the time dskrd is called,	
 28214                              <1> 	; dskrd calls idle.
 28215                              <1> 	; 
 28216                              <1> 	; INPUTS ->
 28217                              <1> 	;    r1 - block number
 28218                              <1> 	;    cdev - current device number 
 28219                              <1> 	; OUTPUTS ->
 28220                              <1> 	;    r5 - points to first data word in I/O buffer
 28221                              <1> 	;
 28222                              <1> 	; ((AX = R1)) input/output
 28223                              <1> 	; ((BX = R5)) output 
 28224                              <1> 	;
 28225                              <1>         ; ((Modified registers: edx, ecx, ebx, esi, edi))  
 28226                              <1> 	;
 28227 0000598C E8BA000000          <1> 	call 	bufaloc
 28228                              <1> 		; jsr r0,bufaloc / shuffle off to bufaloc; 
 28229                              <1> 			       ; / get a free I/O buffer
 28230                              <1> 	;;jc	error ; 20/07/2013
 28231 00005991 740C                <1> 	jz	short dskrd_1 ; Retro UNIX 8086 v1 modification
 28232                              <1>        		; br 1f / branch if block already in a I/O buffer
 28233                              <1> 	
 28234                              <1> 	; 15/07/2022
 28235                              <1> 	; (buffer header byte 1, bit 2 is disk read bit/flag)
 28236                              <1> dskrd_0:
 28237                              <1> 	; 10/07/2015 (wslot)
 28238 00005993 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 28239                              <1>         	; bis $2000,(r5) / set bit 10 of word 1 of 
 28240                              <1> 		               ; / I/O queue entry for buffer
 28241 00005998 E893000000          <1> 	call	poke
 28242                              <1> 		; jsr r0,poke / just assigned in bufaloc, 
 28243                              <1> 			    ; /	bit 10=1 says read
 28244                              <1> 	; 09/06/2015
 28245                              <1> 	;jnc	short dskrd_1
 28246                              <1> 	;mov	dword [u.error], ERR_DRV_READ ; disk read error !
 28247                              <1> 	;jmp	error
 28248                              <1> 	; 08/02/2022
 28249 0000599D 7204                <1> 	jc	short dskrd_3
 28250                              <1> dskrd_1: ; 1:
 28251                              <1>        	; 15/07/2022
 28252                              <1> 	;
 28253                              <1> 	;	;clr *$ps
 28254                              <1>        	;test	word [ebx], 2400h
 28255                              <1> 	;	; bit $22000,(r5) / if either bits 10, or 13 are 1; 
 28256                              <1> 	;			; / jump to idle
 28257                              <1>        	;jz	short dskrd_2
 28258                              <1> 	;	; beq 1f
 28259                              <1>         ;;;mov   ecx, [s.wait_]
 28260                              <1>        	;call	idle
 28261                              <1> 	;	; jsr r0,idle; s.wait+2
 28262                              <1> 	;jmp 	short dskrd_1
 28263                              <1>        	;	; br 1b
 28264                              <1> dskrd_2: ; 1:
 28265 0000599F 83C308              <1>         add	ebx, 8
 28266                              <1> 		; add $8,r5 / r5 points to first word of data in block 
 28267                              <1> 			  ; / just read in
 28268 000059A2 C3                  <1>        	retn
 28269                              <1> 		; rts r0
 28270                              <1> dskrd_err: 
 28271                              <1> 	; 08/02/2022
 28272                              <1> 	; (jump from 'bread' error)	
 28273                              <1> dskrd_3:	
 28274                              <1> 	; 08/02/2022
 28275 000059A3 803D[D76C0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
 28276 000059AA 7509                <1> 	jne	short dskrd_4 ; no
 28277                              <1> 	; yes, clear [u.brwdev] for next check and jump to 'error'
 28278 000059AC C605[D76C0000]00    <1> 	mov	byte [u.brwdev], 0
 28279 000059B3 EB0A                <1> 	jmp	short dskrd_5
 28280                              <1> dskrd_4:
 28281 000059B5 C705[D86C0000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; disk read error !
 28282 000059BD 0000                <1>
 28283                              <1> dskrd_5:
 28284 000059BF E99DD7FFFF          <1> 	jmp	error
 28285                              <1> 
 28286                              <1> bwslot:
 28287                              <1> 	; 15/07/2022
 28288                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28289                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 28290                              <1> 	; 10/07/2015
 28291                              <1> 	;	If the block/sector is not placed in a buffer
 28292                              <1> 	;	before 'wslot', it must be read before
 28293                              <1> 	;	it is written! (Otherwise transfer counts less
 28294                              <1> 	;	than 512 bytes will be able to destroy existing 
 28295                              <1> 	;	data on disk.)
 28296                              <1> 	;
 28297                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28298                              <1> 	; 26/04/2013(Retro UNIX 8086 v1)
 28299                              <1> 	; Retro UNIX 8086 v1 modification !
 28300                              <1> 	; ('bwslot' will be called from 'bwrite' only!)
 28301                              <1> 	; INPUT -> EDI - points to device id (in u.brwdev)	
 28302                              <1> 	;	-> EAX = block number
 28303                              <1> 	;
 28304 000059C4 E88F000000          <1> 	call	bufaloc_0
 28305 000059C9 742A                <1> 	jz	short wslot_0 ; block/sector already is in the buffer
 28306                              <1> 	; 12/01/2022
 28307                              <1> 	; ebx = buffer header address
 28308                              <1> bwslot_0:
 28309                              <1> 	; 10/07/2015
 28310 000059CB 8B35[786C0000]      <1> 	mov	esi, [u.fofp]
 28311 000059D1 8B06                <1> 	mov	eax, [esi]
 28312 000059D3 25FF010000          <1> 	and	eax, 1FFh ; offset from beginning of the sector/block
 28313 000059D8 750C                <1> 	jnz 	short bwslot_1 ; it is not a full sector write
 28314                              <1> 		       ; recent disk data must be placed in the buffer
 28315 000059DA 813D[8C6C0000]0002- <1> 	cmp	dword [u.count], 512
 28316 000059E2 0000                <1>
 28317 000059E4 730F                <1> 	jnb	short wslot_0	
 28318                              <1> bwslot_1:
 28319 000059E6 E8A8FFFFFF          <1> 	call	dskrd_0
 28320                              <1> 	; 12/01/2022
 28321                              <1> 	; ebx = buffer data address = buffer header addr + 8
 28322 000059EB 83EB08              <1> 	sub	ebx, 8 ; set ebx to the buffer header address again	
 28323 000059EE EB05                <1> 	jmp 	short wslot_0
 28324                              <1> 
 28325                              <1> wslot:
 28326                              <1> 	; 16/07/2022
 28327                              <1> 	; 15/07/2022
 28328                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28329                              <1> 	;
 28330                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28331                              <1> 	; 		(32 bit modifications)
 28332                              <1> 	; 14/03/2013 - 29/07/2013(Retro UNIX 8086 v1)
 28333                              <1> 	;
 28334                              <1> 	; 'wslot' calls 'bufaloc' and obtains as a result, a pointer
 28335                              <1> 	; to the I/O queue of an I/O buffer for a block structured
 28336                              <1> 	; device. It then checks the first word of I/O queue entry.	
 28337                              <1> 	; If bits 10 and/or 13 (read bit, waiting to read bit) are set,
 28338                              <1> 	; wslot calls 'idle'. When 'idle' returns, or if bits 10 
 28339                              <1> 	; and/or 13 are not set, 'wslot' sets bits 9 and 15 of the first
 28340                              <1> 	; word of the I/O queue entry (write bit, inhibit bit).
 28341                              <1> 	;
 28342                              <1> 	; INPUTS ->
 28343                              <1>  	;    r1 - block number
 28344                              <1> 	;    cdev - current (block/disk) device number
 28345                              <1>  	;
 28346                              <1> 	; OUTPUTS ->
 28347                              <1> 	;    bufp - bits 9 and 15 are set, 
 28348                              <1> 	;           the remainder of the word left unchanged
 28349                              <1> 	;    r5 - points to first data word in I/O buffer
 28350                              <1> 	;
 28351                              <1> 	; ((AX = R1)) input/output
 28352                              <1> 	; ((BX = R5)) output 
 28353                              <1> 	;
 28354                              <1>         ; ((Modified registers: edx, ecx, ebx, esi, edi)) 
 28355                              <1> 
 28356 000059F0 E856000000          <1> 	call	bufaloc
 28357                              <1> 	; 10/07/2015
 28358                              <1> 		; jsr r0,bufaloc / get a free I/O buffer; pointer to first
 28359                              <1>         	; br 1f / word in buffer in r5
 28360                              <1> 	; EBX = Buffer (Header) Address (r5) (ES=CS=DS, system/kernel segment)
 28361                              <1>         ; EAX = Block/Sector number (r1)
 28362                              <1> wslot_0: ;1:
 28363                              <1> 	; 15/07/2022
 28364                              <1> 	;
 28365                              <1>      	;test	word [ebx], 2400h
 28366                              <1> 	;	; bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
 28367                              <1> 	;			; / of I/O queue entry
 28368                              <1> 	;jz	short wslot_1
 28369                              <1>         ;       ; beq 1f  / branch if 10, 13 zero (i.e., not reading, 
 28370                              <1> 	;	       ; / or not waiting to read)
 28371                              <1> 	;
 28372                              <1> 	;;mov	ecx, [s.wait_] ; 29/07/2013
 28373                              <1> 	;call	idle
 28374                              <1> 	;	; jsr r0,idle; / if buffer is reading or writing to read,
 28375                              <1>        	;                   ; / idle
 28376                              <1> 	;jmp	short wslot_0
 28377                              <1> 	;	; br 1b / till finished
 28378                              <1> wslot_1: ;1:
 28379                              <1> 	;or	word [ebx], 8200h
 28380                              <1>        	;	; bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
 28381                              <1>         ;			; / (write, inhibit bits)
 28382                              <1> 	;	; clr *$ps / clear processor status
 28383                              <1> 
 28384                              <1> 	; 16/07/2022
 28385                              <1> ;dskwr_1:	; 09/03/2022
 28386                              <1> 	;add	ebx, 8 ; 11/06/2015
 28387                              <1> 		; add $8,r5 / r5 points to first word in data area 
 28388                              <1> 			  ; / for this block
 28389                              <1> 	; 15/07/2022
 28390                              <1> 	; (set disk write bit/flag)
 28391                              <1> 	;or	word [ebx], 200h	
 28392 000059F5 43                  <1> 	inc	ebx
 28393 000059F6 800B02              <1> 	or	byte [ebx], 2
 28394 000059F9 83C307              <1> 	add	ebx, 7
 28395                              <1> 	; 16/07/2022
 28396                              <1> dskwr_1:	; 08/02/2022
 28397 000059FC C3                  <1>        	retn
 28398                              <1> 		; rts r0
 28399                              <1> dskwr:
 28400                              <1> 	; 16/07/2022
 28401                              <1> 	; 15/07/2022
 28402                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28403                              <1> 	; 09/03/2022
 28404                              <1> 	; 08/02/2022 (Retro UNIX 386 v1.2)
 28405                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28406                              <1> 	; 14/03/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 28407                              <1> 	;
 28408                              <1> 	; 'dskwr' writes a block out on disk, via ppoke. The only
 28409                              <1> 	; thing dskwr does is clear bit 15 in the first word of I/O queue
 28410                              <1> 	; entry pointed by 'bufp'. 'wslot' which must have been called
 28411                              <1> 	; previously has supplied all the information required in the
 28412                              <1> 	; I/O queue entry.
 28413                              <1> 	;
 28414                              <1> 	; (Modified registers: ebx, ecx, edx, esi, edi)
 28415                              <1> 	;
 28416 000059FD 8B1D[F46B0000]      <1> 	mov	ebx, [bufp]
 28417 00005A03 668123FF7F          <1> 	and	word [ebx], 7FFFh ; 0111111111111111b
 28418                              <1> 		; bic $100000,*bufp / clear bit 15 of I/O queue entry at
 28419                              <1>                                   ; / bottom of queue
 28420 00005A08 E823000000          <1> 	call	poke
 28421                              <1> 	; 09/06/2015
 28422 00005A0D 73ED                <1> 	jnc	short dskwr_1 ; 16/07/2022
 28423                              <1> 	; ebx = buffer header ; 09/03/2022
 28424                              <1> 	; 08/02/2022
 28425 00005A0F 803D[D76C0000]FF    <1> 	cmp	byte [u.brwdev], 0FFh ; is error code set in [u.error] ?
 28426 00005A16 7509                <1> 	jne	short dskwr_0 ; no
 28427                              <1> 	; yes, clear [u.brwdev] for next check and jump to 'error'
 28428 00005A18 C605[D76C0000]00    <1> 	mov	byte [u.brwdev], 0
 28429 00005A1F EB0A                <1> 	jmp	short dskwr_2
 28430                              <1> dskwr_0:
 28431 00005A21 C705[D86C0000]1200- <1> 	mov	dword [u.error], ERR_DRV_WRITE ; disk write error !
 28432 00005A29 0000                <1>
 28433                              <1> dskwr_2:
 28434 00005A2B E931D7FFFF          <1> 	jmp	error
 28435                              <1> ;dskwr_1:
 28436                              <1> ;	add	ebx, 8 ; 09/03/2022
 28437                              <1> ;	; ebx = buffer data address
 28438                              <1> ;	retn
 28439                              <1> 
 28440                              <1> ;ppoke:
 28441                              <1>        		; mov $340,*$ps
 28442                              <1>        		; jsr r0,poke
 28443                              <1>        		; clr *$ps
 28444                              <1> 		; rts r0
 28445                              <1> 
 28446                              <1> poke:
 28447                              <1> 	; 15/07/2022
 28448                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28449                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
 28450                              <1> 	; 14/07/2022
 28451                              <1> 	;	! Major Modification !
 28452                              <1> 	;	Retro UNIX 386 v1 (Kernel v0.2.0.22)
 28453                              <1> 	;
 28454                              <1> 	; 04/02/2022 (32 bit reg push pop)
 28455                              <1> 	; 24/10/2015
 28456                              <1> 	; 20/08/2015
 28457                              <1> 	; 18/08/2015
 28458                              <1> 	; 02/07/2015
 28459                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28460                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 28461                              <1> 	;
 28462                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 28463                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 28464                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 28465                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 28466                              <1> 	;
 28467                              <1> 	; Basic I/O functions for all block structured devices
 28468                              <1> 	;
 28469                              <1>         ; (Modified registers: ECX, EDX, ESI, EDI)
 28470                              <1> 	;
 28471                              <1> 	; 20/07/2013 modifications
 28472                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 28473                              <1> 	; INPUTS -> 
 28474                              <1> 	;        EBX = buffer header address
 28475                              <1> 	; OUTPUTS ->
 28476                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 28477                              <1> 	;	 cf=1 -> error, word [EBX] = 0FFFFh
 28478                              <1> 	;		(drive not ready or r/w error!)
 28479                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 28480                              <1> 	;	 (dword [EBX+4] = 0FFFFFFFFh means RW/IO error)
 28481                              <1> 	;        (also it indicates invalid buffer data)
 28482                              <1> 	
 28483                              <1> 	; 15/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.6)
 28484                              <1> 	; 14/07/2022 - Retro UNIX 386 v1 (Kernel v0.2.0.22)
 28485                              <1> 	; Buffer header:
 28486                              <1> 	;	byte 0 - device/disk (index) number
 28487                              <1> 	;	byte 1 - status
 28488                              <1> 	;	    before 'poke'	
 28489                              <1> 	;		bit 0 - valid bit 
 28490                              <1> 	;		   (0 for new buffer)
 28491                              <1> 	;		   (1 for existing buffer)	
 28492                              <1> 	;		bit 1 - write (modified) bit, disk write flag
 28493                              <1> 	;		bit 2 - read bit, disk read flag
 28494                              <1> 	;	    after 'poke'
 28495                              <1> 	;		if disk r/w is successed
 28496                              <1> 	;		   bit 0 = 1
 28497                              <1> 	;		   bit 1 = 0
 28498                              <1> 	;		   bit 2 = 0
 28499                              <1> 	;		if disk r/w is failed
 28500                              <1> 	;		   bit 0 = 0 (invalid buffer)
 28501                              <1> 	;		   bit 1 = 0 (write bit)
 28502                              <1> 	;		   bit 2 = 0 (read bit)	
 28503                              <1>  	;
 28504                              <1> 	;	byte 2 & byte 3 - not used
 28505                              <1> 	;	byte 4 to byte 7 - disk block/sector address
 28506                              <1> 	
 28507                              <1> 	; 04/02/2022
 28508 00005A30 50                  <1> 	push	eax
 28509 00005A31 E896000000          <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 28510 00005A36 58                  <1> 	pop	eax
 28511 00005A37 730D                <1> 	jnc	short seta ; 14/07/2022
 28512                              <1> 	
 28513                              <1> 	; 14/07/2022
 28514                              <1> 	; (invalidate buffer)
 28515                              <1> 	
 28516                              <1> 	; 02/07/2015 (32 bit modification)
 28517                              <1> 	; 20/07/2013
 28518 00005A39 C74304FFFFFFFF      <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 28519                              <1>        		; mov $-1,2(r1) / destroy associativity
 28520 00005A40 66C703FF00          <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 28521                              <1> 		; clrb 1(r1) / do not do I/O
 28522                              <1> 	;stc
 28523 00005A45 C3                  <1> 	retn
 28524                              <1>         	; rts r0
 28525                              <1> seta: 
 28526 00005A46 C6430101            <1> 	mov	byte [ebx+1], 1 ; clear write/read bits, set valid bit
 28527                              <1> 	;clc
 28528 00005A4A C3                  <1> 	retn
 28529                              <1> 
 28530                              <1> %if 0
 28531                              <1> 
 28532                              <1> poke:
 28533                              <1> 	; 29/11/2021 (32 bit reg push-pop)
 28534                              <1> 	; 24/10/2015
 28535                              <1> 	; 20/08/2015
 28536                              <1> 	; 18/08/2015
 28537                              <1> 	; 02/07/2015
 28538                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 28539                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 28540                              <1> 	;
 28541                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 28542                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 28543                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 28544                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 28545                              <1> 	;
 28546                              <1> 	; Basic I/O functions for all block structured devices
 28547                              <1> 	;
 28548                              <1>         ; (Modified registers: ecx, edx, esi, edi)
 28549                              <1> 	;
 28550                              <1> 	; 20/07/2013 modifications
 28551                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 28552                              <1> 	; INPUTS -> 
 28553                              <1> 	;        (EBX = buffer header address)
 28554                              <1> 	; OUTPUTS ->
 28555                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 28556                              <1> 	;	 cf=1 -> error, word [EBX] = 0FFFFh
 28557                              <1> 	;		(drive not ready or r/w error!)
 28558                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 28559                              <1> 	;	 (dword [EBx+4] = 0FFFFFFFFh means RW/IO error)
 28560                              <1> 	;        (also it indicates invalid buffer data)
 28561                              <1> 	;
 28562                              <1> 	push	ebx
 28563                              <1>        		; mov r1,-(sp)
 28564                              <1>        		; mov r2,-(sp)
 28565                              <1>        		; mov r3,-(sp)
 28566                              <1> 	push 	eax ; Physical Block Number (r1) (mget)
 28567                              <1> 	;
 28568                              <1> 	; 09/06/2015
 28569                              <1> 	; (permit read/write after a disk R/W error)
 28570                              <1> 	mov	cl, [ebx] ; device id (0 to 5)
 28571                              <1> 	mov	al, 1
 28572                              <1> 	shl	al, cl
 28573                              <1> 	test 	al, [active] ; busy ? (error)
 28574                              <1> 	jz	short poke_0
 28575                              <1> 	not	al
 28576                              <1> 	and	[active], al ; reset busy bit for this device only
 28577                              <1> poke_0:
 28578                              <1>         mov     esi, bufp + (4*(nbuf+2)) 
 28579                              <1> 		; mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority
 28580                              <1> 					 ; / I/O queue pointer
 28581                              <1> poke_1: ; 1:
 28582                              <1>         sub	esi, 4
 28583                              <1> 	mov	ebx, [esi]
 28584                              <1> 		; mov -(r2),r1 / r1 points to an I/O queue entry
 28585                              <1> 	mov	ax, [ebx] ; 17/07/2013
 28586                              <1>        	test	ah, 06h
 28587                              <1> 	;test	word [ebx], 600h ; 0000011000000000b
 28588                              <1> 		; bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O 
 28589                              <1> 			       ; / queue entry
 28590                              <1>         jz      short poke_5
 28591                              <1> 		; beq 2f / branch to 2f if both are clear
 28592                              <1> 	; 31/07/2013
 28593                              <1> 	;test	ah, 0B0h ; (*)
 28594                              <1> 	;;test	word [ebx], 0B000h ; 1011000000000000b
 28595                              <1> 		; bit $130000,(r1) / test bits 12, 13, and 15
 28596                              <1>         ;jnz	short poke_5 ; 31/07/2013 (*)
 28597                              <1> 		; bne 2f / branch if any are set
 28598                              <1> 	;movzx	ecx, byte [ebx] ; 09/06/2015 ; Device Id
 28599                              <1>     		; movb (r1),r3 / get device id
 28600                              <1> 	movzx	ecx, al ; 18/08/2015
 28601                              <1> 	;mov	edi, ecx ; 26/04/2013
 28602                              <1> 	xor 	eax, eax ; 0
 28603                              <1> 	;cmp 	[edi+drv.error], al ; 0
 28604                              <1> 		; tstb deverr(r3) / test for errors on this device
 28605                              <1>        	;jna	short poke_2 
 28606                              <1> 		; beq 3f / branch if no errors
 28607                              <1> 	; 02/07/2015
 28608                              <1> 	;dec	eax
 28609                              <1> 	;mov	[ebx+4], ax ; 0FFFFFFFFh ; -1 
 28610                              <1>        		; mov $-1,2(r1) / destroy associativity
 28611                              <1> 	;shr	eax, 24
 28612                              <1> 	;mov	[ebx], eax ; 000000FFh, reset
 28613                              <1> 		; clrb 1(r1) / do not do I/O
 28614                              <1> 	;jmp	short poke_5
 28615                              <1>         ;       ; br 2f
 28616                              <1>                 ; rts r0
 28617                              <1> poke_2: ; 3:
 28618                              <1> 	; 02/07/2015
 28619                              <1> 	inc	cl ; 0FFh -> 0
 28620                              <1> 	jz	short poke_5
 28621                              <1> 	inc	al ; mov ax, 1
 28622                              <1> 	dec	cl
 28623                              <1> 	jz	short poke_3
 28624                              <1> 	; 26/04/2013 Modification
 28625                              <1> 	;inc	al ; mov ax, 1
 28626                              <1> 	;or	cl, cl ; Retro UNIX 8086 v1 device id.
 28627                              <1> 	;jz	short poke_3 ; cl = 0
 28628                              <1> 	shl	al, cl ; shl ax, cl
 28629                              <1> poke_3:
 28630                              <1> 	;test	[active], ax
 28631                              <1> 	test	[active], al
 28632                              <1> 		; bit $2,active / test disk busy bit
 28633                              <1> 	jnz     short poke_5
 28634                              <1> 		; bne 2f / branch if bit is set
 28635                              <1> 	;or	[active], ax
 28636                              <1> 	or	[active], al
 28637                              <1> 		; bis $2,active / set disk busy bit
 28638                              <1> 	push	eax ; 29/11/2021
 28639                              <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 28640                              <1> 	;mov    [edi+drv.error], ah
 28641                              <1> 	pop	eax
 28642                              <1> 	jnc	short poke_4 ; 20/07/2013
 28643                              <1> 	;cmp 	[edi+drv.error], al ; 0	
 28644                              <1> 	;jna	short poke_4
 28645                              <1> 		; tstb deverr(r3) / test for errors on this device
 28646                              <1>        		; beq 3f / branch if no errors
 28647                              <1> 	; 02/07/2015 (32 bit modification)
 28648                              <1> 	; 20/07/2013
 28649                              <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 28650                              <1>        		; mov $-1,2(r1) / destroy associativity
 28651                              <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 28652                              <1> 		; clrb 1(r1) / do not do I/O
 28653                              <1> 	jmp     short poke_5
 28654                              <1> poke_4:	; 20/07/2013
 28655                              <1> 	; 17/07/2013
 28656                              <1> 	not 	al 
 28657                              <1> 	and	[active], al ; reset, not busy
 28658                              <1> 	; EBX = system I/O buffer header (queue entry) address
 28659                              <1> seta: ; / I/O queue bookkeeping; set read/write waiting bits.
 28660                              <1> 	mov	ax, [ebx]
 28661                              <1>        		; mov (r1),r3 / move word 1 of I/O queue entry into r3
 28662                              <1>         and	ax, 600h
 28663                              <1> 		; bic $!3000,r3 / clear all bits except 9 and 10
 28664                              <1> 	and 	word [ebx], 0F9FFh
 28665                              <1>        		; bic $3000,(r1) / clear only bits 9 and 10
 28666                              <1> 	shl	ah, 3
 28667                              <1>        		; rol r3
 28668                              <1>                 ; rol r3
 28669                              <1>                 ; rol r3	
 28670                              <1> 	or	[ebx], ax
 28671                              <1> 		; bis r3,(r1) / or old value of bits 9 and 10 with 
 28672                              <1> 			   ; bits 12 and 13
 28673                              <1> 	call	idle ; 18/01/2014
 28674                              <1> 	;; sti
 28675                              <1> 	;hlt 	; wait for a hardware interrupt
 28676                              <1> 	;; cli
 28677                              <1> 	; NOTE: In fact, disk controller's 'disk I/O completed' 
 28678                              <1>         ; interrupt would be used to reset busy bits, but INT 13h
 28679                              <1> 	; returns when disk I/O is completed. So, here, as temporary
 28680                              <1> 	; method, this procedure will wait for a time according to
 28681                              <1> 	; multi tasking and time sharing concept.
 28682                              <1> 	;
 28683                              <1> 	; 24/10/2015
 28684                              <1> 	;not	ax 
 28685                              <1> 	mov 	ax, 0FFh ; 24/10/2015 (temporary)
 28686                              <1> 	and	[ebx], ax ; clear bits 12 and 13
 28687                              <1> poke_5: ;2:
 28688                              <1>         cmp     esi, bufp
 28689                              <1> 		; cmp r2,$bufp / test to see if entire I/O queue 
 28690                              <1>                             ; / has been scanned
 28691                              <1> 	ja      short poke_1
 28692                              <1> 		; bhi 1b
 28693                              <1> 	; 24/03/2013
 28694                              <1>        		; mov (sp)+,r3
 28695                              <1>        		; mov (sp)+,r2
 28696                              <1>        		; mov (sp)+,r1
 28697                              <1>         pop 	eax  ; Physical Block Number (r1) (mget)
 28698                              <1> 	pop 	ebx
 28699                              <1> 	; 02/07/2015 (32 bit modification)
 28700                              <1> 	; 20/07/2013
 28701                              <1> 	;cmp 	dword [ebx+4], 0FFFFFFFFh
 28702                              <1> 	cmp	byte [ebx], 0FFh ; 20/08/2015
 28703                              <1> 	;	
 28704                              <1> 	; 'poke' returns with cf=0 if the requested buffer is read 
 28705                              <1> 	; or written successfully; even if an error occurs while
 28706                              <1> 	; reading to or writing from other buffers. 20/07/2013
 28707                              <1> 	;
 28708                              <1> 	; 09/06/2015
 28709                              <1> 	cmc
 28710                              <1> 	retn
 28711                              <1>                 ; rts r0
 28712                              <1> 
 28713                              <1> %endif
 28714                              <1> 
 28715                              <1> bufaloc:
 28716                              <1> 	; 15/07/2022
 28717                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28718                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 28719                              <1> 	; 20/08/2015
 28720                              <1> 	; 19/08/2015
 28721                              <1> 	; 02/07/2015
 28722                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28723                              <1> 	;	     (32 bit modifications)	
 28724                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 28725                              <1> 	;
 28726                              <1> 	; bufaloc - Block device I/O buffer allocation
 28727                              <1> 	; 
 28728                              <1> 	; INPUTS ->
 28729                              <1> 	;    r1 - block number
 28730                              <1> 	;    cdev - current (block/disk) device number
 28731                              <1> 	;    bufp+(2*n)-2 --- n = 1 ... nbuff
 28732                              <1> 	; OUTPUTS ->
 28733                              <1> 	;    r5 - pointer to buffer allocated
 28734                              <1> 	;    bufp ... bufp+12 --- (bufp), (bufp)+2
 28735                              <1> 	;
 28736                              <1> 	; ((AX = R1)) input/output
 28737                              <1> 	; ((BX = R5)) output
 28738                              <1>         ;    ((Modified registers: DX, CX, BX, SI, DI, BP))
 28739                              <1> 	;    zf=1 -> block already in a I/O buffer
 28740                              <1> 	;    zf=0 -> a new I/O buffer has been allocated
 28741                              <1> 	;    ((DL = Device ID))
 28742                              <1> 	;    (((DH = 0 or 1)))
 28743                              <1> 	;    (((CX = previous value of word ptr [bufp])))
 28744                              <1> 	;    ((CX and DH will not be used after return)))
 28745                              <1> 
 28746                              <1> 	; 15/07/2022
 28747                              <1> 	;	Modified registers: EBX, ECX, EDX, ESI, EDI
 28748                              <1> 
 28749                              <1> 	;;push 	esi ; ***
 28750                              <1> 		; mov r2,-(sp) / save r2 on stack
 28751                              <1>        		; mov $340,*$ps / set processor priority to 7
 28752                              <1> 	; 20/07/2013
 28753                              <1> 	; 26/04/2013
 28754                              <1> 	;movzx	ebx, byte [cdev] ; 0 or 1
 28755                              <1> 	;mov	edi, rdev ; offset mdev = offset rdev + 1
 28756                              <1> 	;add	edi, ebx
 28757                              <1> 	; 09/01/2022
 28758 00005A4B 0FB63D[416C0000]    <1> 	movzx	edi, byte [cdev] ; 0 or 1
 28759 00005A52 81C7[426C0000]      <1> 	add	edi, rdev
 28760                              <1> bufaloc_0: ; 26/04/2013 !! here is called from bread or bwrite !!
 28761                              <1> 			;; EDI points to device id.
 28762 00005A58 0FB61F              <1> 	movzx	ebx, byte [edi] ; [EDI] -> rdev/mdev or brwdev
 28763                              <1> 	; 11/06/2021
 28764 00005A5B 80BB[6E620000]F0    <1> 	cmp 	byte [ebx+drv.status], 0F0h ; Drive not ready !
 28765 00005A62 720F                <1> 	jb	short bufaloc_9
 28766 00005A64 C705[D86C0000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 28767 00005A6C 0000                <1>
 28768 00005A6E E9EED6FFFF          <1> 	jmp	error
 28769                              <1> bufaloc_9:
 28770 00005A73 89DA                <1> 	mov	edx, ebx ; dh = 0, dl = device number (0 to 5)
 28771                              <1> bufaloc_10: ; 02/07/2015
 28772                              <1> 	; 14/07/2022
 28773                              <1> 	;xor 	ebp, ebp ; 0
 28774                              <1> 	;push	ebp ; 0
 28775                              <1>         ;mov	ebp, esp
 28776 00005A75 31FF                <1> 	xor	edi, edi ; 0
 28777 00005A77 57                  <1> 	push	edi
 28778                              <1> bufaloc_1: ;1:
 28779                              <1> 		; clr -(sp) / vacant buffer
 28780 00005A78 BE[F46B0000]        <1>         mov 	esi, bufp
 28781                              <1> 		; mov $bufp,r2 / bufp contains pointers to I/O queue 
 28782                              <1> 			     ; / entrys in buffer area
 28783                              <1> bufaloc_2: ;2:
 28784 00005A7D 8B1E                <1> 	mov	ebx, [esi]
 28785                              <1>        		; mov (r2)+,r5 / move pointer to word 1 of an I/O 
 28786                              <1> 			    ; queue entry into r5
 28787                              <1> 	; 15/07/2022
 28788 00005A7F 8B0B                <1> 	mov	ecx, [ebx]	
 28789                              <1> 	;test	word [ebx], 0F600h
 28790                              <1> 	; 15/07/2022
 28791 00005A81 F6C501              <1> 	test	ch, 1 ; valid buffer (content) ?
 28792                              <1> 		; bit $173000,(r5) / lock+keep+active+outstanding
 28793 00005A84 7505                <1>         jnz	short bufaloc_3 ; yes
 28794                              <1> 		; bne 3f / branch when 
 28795                              <1> 		       ; / any of bits 9,10,12,13,14,15 are set
 28796                              <1>                        ; / (i.e., buffer busy)
 28797                              <1> 	;mov    [ebp], esi ; pointer to I/0 queue entry
 28798                              <1> 	; 15/07/2022
 28799                              <1> 	; save free buffer pointer 
 28800 00005A86 893424              <1> 	mov	[esp], esi
 28801                              <1>                 ; mov r2,(sp) ;/ save pointer to last non-busy buffer
 28802                              <1> 			; / found points to word 2 of I/O queue entry)
 28803                              <1> 	; continue to see if requested sector/block buffer
 28804                              <1> 	;	already is one of existing (valid) buffers
 28805                              <1> 	;jmp	short bufaloc_4
 28806 00005A89 EB0E                <1> 	jmp	short bufaloc_11 ; 15/07/2022
 28807                              <1> bufaloc_3: ;3:
 28808                              <1> 	;mov	dl, [edi] ; 26/04/2013
 28809                              <1> 	;
 28810 00005A8B 38D1                <1> 	cmp	cl, dl ; 15/07/2022
 28811                              <1> 	;cmp	[ebx], dl	
 28812                              <1> 		; cmpb (r5),cdev / is device in I/O queue entry same 
 28813                              <1> 			       ; / as current device
 28814 00005A8D 7508                <1> 	jne	short bufaloc_4
 28815                              <1>        		; bne 3f
 28816 00005A8F 394304              <1> 	cmp	[ebx+4], eax
 28817                              <1>        		; cmp 2(r5),r1 / is block number in I/O queue entry, 
 28818                              <1> 			     ; / same as current block number
 28819 00005A92 7503                <1>        	jne	short bufaloc_4
 28820                              <1> 		; bne 3f
 28821                              <1> 	;add	esp, 4
 28822 00005A94 59                  <1> 	pop	ecx
 28823                              <1>        		; tst (sp)+ / bump stack pointer
 28824 00005A95 EB1D                <1> 	jmp	short bufaloc_7 ; Retro Unix 8086 v1 modification
 28825                              <1> 				; jump to bufaloc_6 in original Unix v1
 28826                              <1>        		; br 1f / use this buffer
 28827                              <1> bufaloc_4: ;3:
 28828                              <1> 	; 15/07/2022
 28829                              <1> 	; save last valid buffer 
 28830                              <1> 	; (will be used if there is not a free buffer)
 28831 00005A97 89F7                <1> 	mov	edi, esi	
 28832                              <1> bufaloc_11:
 28833 00005A99 83C604              <1> 	add	esi, 4 ; 20/08/2015
 28834                              <1> 	;
 28835 00005A9C 81FE[346C0000]      <1> 	cmp	esi, bufp + (nbuf*4)
 28836                              <1> 		; cmp r2,$bufp+nbuf+nbuf
 28837 00005AA2 72D9                <1> 	jb	short bufaloc_2
 28838                              <1> 		; blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
 28839                              <1>                        ; / buffers not checked)
 28840 00005AA4 5E                  <1>         pop	esi
 28841                              <1> 		; mov (sp)+,r2 / once all bufs are examined move pointer
 28842                              <1> 			     ; / to last free block
 28843 00005AA5 09F6                <1>        	or	esi, esi 
 28844 00005AA7 7502                <1> 	jnz	short bufaloc_5
 28845                              <1> 		; bne 2f / if (sp) is non zero, i.e., 
 28846                              <1> 	        ; / if a free buffer is found branch to 2f
 28847                              <1> 
 28848                              <1> 	; 15/07/2022        
 28849                              <1> 	; if there is not a free buffer
 28850                              <1> 	; we can use last valid buffer (the oldest buffer)
 28851                              <1> 	; ((ptr to new buffer is located at head of buff ptr chain))
 28852 00005AA9 89FE                <1> 	mov	esi, edi
 28853                              <1> 
 28854                              <1> 	;;mov  ecx, [s.wait_]
 28855                              <1> 	;call	idle
 28856                              <1> 	;	; jsr r0,idle; s.wait+2 / idle if no free buffers
 28857                              <1> 	;jmp 	short bufaloc_10 ; 02/07/2015
 28858                              <1>        	;	; br 1b
 28859                              <1> bufaloc_5: ;2:
 28860                              <1> 		; tst (r0)+ / skip if warmed over buffer
 28861                              <1> 	; 15/07/2022
 28862                              <1> 	;inc	dh ; Retro UNIX 8086 v1 modification
 28863                              <1> bufaloc_6: ;1:
 28864 00005AAB 8B1E                <1>         mov    	ebx, [esi] 
 28865                              <1> 		; mov -(r2),r5 / put pointer to word 1 of I/O queue 
 28866                              <1> 			     ; / entry in r5
 28867                              <1> 	;; 26/04/2013
 28868                              <1>         ;;mov	dl, [edi] ; byte [rdev] or byte [mdev]
 28869                              <1> 	;mov 	[ebx], dl
 28870                              <1> 		; movb cdev,(r5) / put current device number 
 28871                              <1> 				 ; / in I/O queue entry
 28872                              <1> 	; 15/07/2022
 28873                              <1> 	; invalidate buffer before r/w (new) disk sector/block
 28874                              <1> 	;mov	[ebx+1], dh ; 0
 28875                              <1> 	; 15/07/2022
 28876 00005AAD 8913                <1> 	mov	[ebx], edx  ; dh = 0
 28877                              <1> 	
 28878 00005AAF 894304              <1> 	mov 	[ebx+4], eax
 28879                              <1> 		; mov r1,2(r5) / move block number into word 2
 28880                              <1> 			     ; / of I/O queue entry
 28881                              <1> 	; 15/07/2022
 28882 00005AB2 FEC6                <1> 	inc	dh ; dh = 1
 28883                              <1> bufaloc_7: ;1:
 28884 00005AB4 81FE[F46B0000]      <1>         cmp	esi, bufp
 28885                              <1> 		; cmp r2,$bufp / bump all entrys in bufp 
 28886                              <1> 			     ; / and put latest assigned
 28887 00005ABA 760B                <1> 	jna	short bufaloc_8	
 28888                              <1>        		; blos 1f / buffer on the top 
 28889                              <1> 			; / (this makes if the lowest priority)
 28890                              <1> 	; 15/07/2022
 28891 00005ABC 89F7                <1> 	mov	edi, esi
 28892 00005ABE 83EE04              <1> 	sub	esi, 4
 28893 00005AC1 8B0E                <1> 	mov	ecx, [esi]
 28894 00005AC3 890F                <1> 	mov	[edi], ecx ; 15/07/2022
 28895                              <1> 	;mov	[esi+4], ecx
 28896                              <1> 		; mov -(r2),2(r2) / job for a particular device
 28897 00005AC5 EBED                <1> 	jmp 	short bufaloc_7
 28898                              <1> 		; br 1b
 28899                              <1> bufaloc_8: ;1:
 28900 00005AC7 891E                <1>         mov	[esi], ebx
 28901                              <1> 		; mov r5,(r2)
 28902                              <1> 	;;pop	esi ; ***
 28903                              <1>        		; mov (sp)+,r2 / restore r2
 28904 00005AC9 08F6                <1>        	or 	dh, dh ; 0 or 1 ?
 28905                              <1> 		; Retro UNIX 8086 v1 modification
 28906                              <1> 		; zf=1 --> block already is in an I/O buffer
 28907                              <1> 		; zf=0 --> a new I/O buffer has been allocated
 28908 00005ACB C3                  <1> 	retn
 28909                              <1> 		; rts r0
 28910                              <1> 
 28911                              <1> diskio:
 28912                              <1> 	; 16/07/2022
 28913                              <1> 	; 12/07/2022 - Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28914                              <1> 	; 08/07/2022
 28915                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 28916                              <1> 	;	((simplified and shortened 'diskio.s' code))
 28917                              <1> 	; 12/02/2022
 28918                              <1> 	; 10/02/2022
 28919                              <1> 	; 08/02/2022
 28920                              <1> 	; 09/01/2022 (Retro UNIX 386 v1.2)
 28921                              <1> 	; 28/11/2021
 28922                              <1> 	; 10/07/2015
 28923                              <1> 	; 02/07/2015
 28924                              <1> 	; 16/06/2015
 28925                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 28926                              <1> 	;	     (80386 protected mode modifications)	
 28927                              <1> 	; 15/03/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 28928                              <1> 	;
 28929                              <1> 	; Retro UNIX 8086 v1 feature only !
 28930                              <1> 	;
 28931                              <1> 	; Derived from proc_chs_read procedure of TRDOS DISKIO.ASM (2011)
 28932                              <1> 	; 04/07/2009 - 20/07/2011
 28933                              <1> 	;
 28934                              <1> 	; NOTE: Reads only 1 block/sector (sector/block size is 512 bytes)
 28935                              <1> 	;
 28936                              <1>         ; INPUTS ->
 28937                              <1> 	; 	   ebx = System I/O Buffer header address
 28938                              <1> 	;
 28939                              <1>         ; OUTPUTS -> cf=0 --> done 
 28940                              <1> 	; 	     cf=1 --> error code in AH
 28941                              <1> 	;	     ; 08/02/2022
 28942                              <1> 	;	     cf=1 & [u.brwdev] = 0FFh -->
 28943                              <1> 	;		error code in [u.error]
 28944                              <1> 	;		
 28945                              <1> 	; (Modified registers: eax, ecx, edx)
 28946                              <1> 	
 28947                              <1> ;rw_disk_sector:
 28948                              <1> 	; 16/07/2022
 28949                              <1> 	; 12/07/2022
 28950                              <1> 	;	Retro UNIX 386 v1.2 (Kernel v0.2.2.3)
 28951                              <1> 	;	Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 28952                              <1> 	; 12/02/2022
 28953                              <1> 	; 10/02/2022
 28954                              <1> 	; 08/02/2022
 28955                              <1> 	; 28/11/2021
 28956                              <1> 	; 10/07/2015
 28957                              <1> 	; 02/07/2015
 28958                              <1> 	; 11/06/2015 - Retro UNIX 386 v1 - 'u8.s' 
 28959                              <1> 	; 21/02/2015 ('dsectpm.s', 'read_disk_sector')
 28960                              <1> 	; 16/02/2015 (Retro UNIX 386 v1 test - 'unix386.s')
 28961                              <1> 	; 01/12/2014 - 18/01/2015 ('dsectrm2.s')
 28962                              <1> 	;
 28963                              <1> 	;;mov	dx, 0201h ; Read 1 sector/block
 28964                              <1> 	;mov	dh, 2
 28965                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 28966 00005ACC B602                <1> 	mov	dh, 2 ; Write 1 sector/block
 28967 00005ACE 668B03              <1> 	mov	ax, [ebx] 
 28968                              <1> 	;
 28969 00005AD1 56                  <1> 	push	esi ; ****
 28970 00005AD2 53                  <1> 	push	ebx ; ***
 28971                              <1> 	;
 28972 00005AD3 0FB6C8              <1> 	movzx	ecx, al
 28973                              <1> 	; 28/11/2021
 28974                              <1> 	;mov	ecx, eax
 28975 00005AD6 89CE                <1> 	mov	esi, ecx
 28976                              <1> 	;
 28977 00005AD8 38F1                <1> 	cmp	cl, dh ; 2
 28978 00005ADA 7202                <1> 	jb	short rwdsk0
 28979 00005ADC 047E                <1> 	add	al, 7Eh  ; 80h, 81h, 82h, 83h
 28980                              <1> rwdsk0:
 28981                              <1> 	; 16/07/2022
 28982                              <1> 	; 12/07/2022
 28983                              <1> 	;mov	[drv], al
 28984 00005ADE 81C6[6E620000]      <1> 	add	esi, drv.status
 28985                              <1> 	; 11/06/2015
 28986 00005AE4 803EF0              <1> 	cmp	byte [esi], 0F0h 
 28987 00005AE7 7204                <1> 	jb      short rwdsk1
 28988                              <1> 	; 'drive not ready' error
 28989                              <1> 	; 10/02/2022
 28990                              <1> 	; 08/02/2022
 28991                              <1> 	;mov	byte [u.brwdev], 0FFh ; error code in [u.error]
 28992                              <1> 	;mov	dword [u.error], ERR_DRV_NOT_RDY
 28993                              <1> 	;;jmp	error
 28994                              <1> 	;stc	; cf = 1
 28995                              <1> 	;retn
 28996                              <1> 	; 10/02/2022
 28997 00005AE9 B10F                <1> 	mov	cl, ERR_DRV_NOT_RDY
 28998 00005AEB EB1F                <1> 	jmp	short rwdsk_err1
 28999                              <1> rwdsk1:
 29000                              <1> 	; 16/07/2022
 29001                              <1> 	;test	ah, 2
 29002                              <1> 	;;test	ax, 200h ; Bit 9 of word 0 (status word)
 29003                              <1> 	;		 ; write bit
 29004                              <1> 	;jz	short rwdsk2
 29005                              <1> 	
 29006                              <1> 	;;test	ah, 4
 29007                              <1> 	;;;test	ax, 400h ; Bit 10 of word 0 (status word)
 29008                              <1> 	;;		 ; read bit
 29009                              <1> 	;;jz	short diskio_ret
 29010                              <1> 
 29011                              <1> 	;inc	dh ; 03h = write
 29012                              <1> 
 29013                              <1> 	; 08/07/2022
 29014 00005AED 84F4                <1> 	test	ah, dh ; test ah, 2
 29015 00005AEF 7502                <1> 	jnz	short rwdsk2 ; dh = 02h = write
 29016 00005AF1 FECE                <1> 	dec	dh
 29017                              <1> 		; dh = 01h = read
 29018                              <1> rwdsk2:
 29019 00005AF3 88C2                <1> 	mov	dl, al
 29020 00005AF5 83C304              <1> 	add	ebx, 4 ; sector/block address/number pointer
 29021 00005AF8 8B03                <1> 	mov	eax, [ebx] ; sector/block number (LBA)
 29022 00005AFA C0E102              <1> 	shl	cl, 2
 29023 00005AFD 81C1[52620000]      <1> 	add	ecx, drv.size ; disk size
 29024 00005B03 3B01                <1> 	cmp	eax, [ecx] ; Last sector + 1 (number of secs.)
 29025 00005B05 7214                <1> 	jb      short rwdsk3
 29026                              <1>  	; 'out of volume' error
 29027                              <1> 	; 10/02/2022
 29028                              <1> 	; 08/02/2022
 29029                              <1> 	;mov	byte [u.brwdev], 0FFh ; error code in [u.error]
 29030                              <1> 	;mov 	dword [u.error], ERR_DEV_VOL_SIZE
 29031                              <1> 	;;jmp	error
 29032                              <1> 	;stc	; cf = 1
 29033                              <1> 	;retn
 29034                              <1> 	; 10/02/2022
 29035 00005B07 B910000000          <1> 	mov	ecx, ERR_DEV_VOL_SIZE
 29036                              <1> rwdsk_err1:
 29037 00005B0C C605[D76C0000]FF    <1> 	mov	byte [u.brwdev], 0FFh
 29038 00005B13 890D[D86C0000]      <1> 	mov	[u.error], ecx ; 12/02/2022
 29039 00005B19 EB27                <1> 	jmp	short rwdsk_err2
 29040                              <1> rwdsk3:
 29041                              <1> 	; 11/06/2015
 29042 00005B1B 83C304              <1> 	add	ebx, 4 ; buffer address
 29043 00005B1E C605[FB6C0000]04    <1> 	mov	byte [retry_count], 4
 29044                              <1> 	; 12/07/2022
 29045                              <1> 	;test	byte [esi], 1 ; LBA ready ?
 29046                              <1>         ;jz	short rwdsk_chs
 29047                              <1> rwdsk_lba:
 29048                              <1> 	; LBA read/write (with private LBA function) 
 29049                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 29050 00005B25 83C607              <1>         add     esi, drv.error - drv.status ; 10/07/2015
 29051 00005B28 89C1                <1> 	mov	ecx, eax ; sector number
 29052                              <1> 	; ebx = buffer (data) address
 29053                              <1> 	; dl = physical drive number (0, 1, 80h, 81h, 82h, 83h)
 29054                              <1> rwdsk_lba_retry:
 29055                              <1> 	;mov	dl, [drv]
 29056                              <1> 		; Function 1Bh = LBA read, 1Ch = LBA write
 29057                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29058                              <1> 	;;mov	ah, 1Ch - 03h ; LBA write function number - 3
 29059                              <1> 	;mov	ah, 2 ; LBA write function number - 2
 29060                              <1> 	;add	ah, dh		
 29061                              <1> 	;mov	al, 1
 29062                              <1> 	;int	13h
 29063                              <1> 	;call	int13h
 29064                              <1> 	; 12/07/2022
 29065 00005B2A 88F0                <1> 	mov	al, dh	; function (1 or 2)
 29066                              <1> 			; (1 = read, 2 = write )
 29067                              <1> 	; ecx = disk sector address (LBA)
 29068                              <1> 	; ebx = buffer address
 29069                              <1> 	;  dl = (physical) disk number
 29070                              <1> 	;  al = function (r/w)
 29071 00005B2C E835C4FFFF          <1> 	call	DISK_IO
 29072                              <1> 
 29073 00005B31 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 29074 00005B33 730E                <1> 	jnc	short rwdsk_lba_ok
 29075 00005B35 80FC80              <1> 	cmp	ah, 80h ; time out ?
 29076 00005B38 7408                <1>         je      short rwdsk_lba_fails
 29077 00005B3A FE0D[FB6C0000]      <1> 	dec	byte [retry_count]
 29078 00005B40 7504                <1>         jnz     short rwdsk_lba_reset ; 10/07/2015
 29079                              <1> rwdsk_err2:	; 10/02/2022
 29080                              <1> rwdsk_lba_fails:
 29081 00005B42 F9                  <1> 	stc
 29082                              <1> rwdsk_lba_ok:
 29083 00005B43 5B                  <1> 	pop	ebx ; ***
 29084 00005B44 5E                  <1> 	pop	esi ; ****
 29085 00005B45 C3                  <1> 	retn
 29086                              <1> rwdsk_lba_reset:
 29087                              <1> 	;mov	ah, 0Dh ; Alternate reset
 29088                              <1> 	;int	13h
 29089                              <1> 	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29090                              <1> 	;mov	ah, 5 ; Alternate reset	 
 29091                              <1> 	;call	int13h
 29092                              <1> 	;jnc	short rwdsk_lba_retry
 29093                              <1> 	; 12/07/2022
 29094 00005B46 30C0                <1> 	xor	al, al ; 0 ; reset
 29095 00005B48 E819C4FFFF          <1> 	call	DISK_IO
 29096 00005B4D 73DB                <1> 	jnc	short rwdsk_lba_retry
 29097                              <1> 
 29098 00005B4F 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 29099 00005B51 EBF0                <1> 	jmp	short rwdsk_lba_ok
 29100                              <1> 
 29101                              <1> 	; 12/07/2022 
 29102                              <1> 	;	(CHS Read/Write setup is not needed here.)
 29103                              <1> 	; 	(LBA address will be converted to CHS parameters 
 29104                              <1> 	;	in 'DISK_IO' procedure when/if it is required.)
 29105                              <1>  
 29106                              <1> ;	; CHS read (convert LBA address to CHS values)	
 29107                              <1> ;rwdsk_chs:
 29108                              <1> ;	; 10/07/2015
 29109                              <1> ;	sub	esi, drv.status
 29110                              <1> ;	mov	ecx, esi
 29111                              <1> ;	add 	esi, drv.error
 29112                              <1> ;	; 02/07/2015
 29113                              <1> ;	; 16/06/2015
 29114                              <1> ;	; 11/06/2015 
 29115                              <1> ;	push	ebx ; ** ; buffer
 29116                              <1> ;	shl	ecx, 1
 29117                              <1> ;	push	ecx ; * 
 29118                              <1> ;	;
 29119                              <1> ;	mov	ebx, ecx
 29120                              <1> ;	mov	[rwdsk], dh ; 02/07/2015
 29121                              <1> ;	xor	edx, edx ; 0
 29122                              <1> ;	; 09/01/2022
 29123                              <1> ;	;sub	ecx, ecx 
 29124                              <1> ;       add     ebx, drv.spt
 29125                              <1> ;	mov	cx, [ebx] ; sector per track
 29126                              <1> ;		; EDX:EAX = LBA
 29127                              <1> ;	div	ecx
 29128                              <1> ;	mov	cl, dl	; sector number - 1
 29129                              <1> ;	inc	cl	; sector number (1 based)
 29130                              <1> ;	pop	ebx ; * ; 11/06/2015
 29131                              <1> ;	;push	cx
 29132                              <1> ;	; 09/01/2022
 29133                              <1> ;	push	ecx
 29134                              <1> ;	add     ebx, drv.heads
 29135                              <1> ;	mov	cx, [ebx] ; heads
 29136                              <1> ;	xor	edx, edx
 29137                              <1> ;		; EAX = cylinders * heads + head
 29138                              <1> ;	div	ecx
 29139                              <1> ;	;pop	cx     ; sector number
 29140                              <1> ;	; 09/01/2022
 29141                              <1> ;	pop	ecx
 29142                              <1> ;	mov	dh, dl ; head number
 29143                              <1> ;	mov	dl, [drv]
 29144                              <1> ;	mov	ch, al ; cylinder (bits 0-7)
 29145                              <1> ;	shl	ah, 6
 29146                              <1> ;	or	cl, ah ; cylinder (bits 8-9)
 29147                              <1> ;		       ; sector (bits 0-7)
 29148                              <1> ;	pop	ebx ; ** ; buffer ; 11/06/2015
 29149                              <1> ;		; CL = sector (bits 0-5)
 29150                              <1> ;		;      cylinder (bits 8-9 -> bits 6-7)
 29151                              <1> ;		; CH = cylinder (bits 0-7)
 29152                              <1> ;		; DH = head
 29153                              <1> ;		; DL = drive
 29154                              <1> ;	;
 29155                              <1> ;	mov	byte [retry_count], 4
 29156                              <1> ;rwdsk_retry:	
 29157                              <1> ;	;mov	ah, [rwdsk] ; 02h = read, 03h = write
 29158                              <1> ;	; 08/07/2022
 29159                              <1> ;	mov	ah, [rwdsk] ; 01h = read, 02h = write
 29160                              <1> ;	mov	al, 1 ; sector count	
 29161                              <1> ;	;int	13h
 29162                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29163                              <1> ;	call	int13h
 29164                              <1> ;	mov	[esi], ah ; error code ; 10/07/2015
 29165                              <1> ;	jnc	short rwdsk_ok ; ah = 0
 29166                              <1> ;	cmp	ah, 80h ; time out ?
 29167                              <1> ;	je	short rwdsk_fails
 29168                              <1> ;	dec	byte [retry_count]
 29169                              <1> ;	jnz	short rwdsk_reset
 29170                              <1> ;rwdsk_fails:
 29171                              <1> ;	stc
 29172                              <1> ;rwdsk_ok:
 29173                              <1> ;	pop	ebx ; ***
 29174                              <1> ;	pop	esi ; ****
 29175                              <1> ;	retn
 29176                              <1> ;rwdsk_reset:
 29177                              <1> ;	; 02/02/2015
 29178                              <1> ;	sub	ah, ah
 29179                              <1> ;	cmp	dl, 80h
 29180                              <1> ;	jb	short rwdsk_fd_reset
 29181                              <1> ;	;mov	ah, 0Dh ; Alternate reset
 29182                              <1> ;	; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 29183                              <1> ;	mov	ah, 5  ; Alternate reset
 29184                              <1> ;rwdsk_fd_reset:
 29185                              <1> ;	;int	13h
 29186                              <1> ;	call	int13h
 29187                              <1> ;	jnc	short rwdsk_retry
 29188                              <1> ;	mov	[esi], ah ; error code ; 10/07/2015
 29189                              <1> ;	jmp 	short rwdsk_ok
 29190                              <1> 
 29191                              <1> ; Original UNIX v1 - drum (& disk) interrupt routine
 29192                              <1> ;	(Equivalent to IRQ 14 & IRQ 15 disk/hardware interrupts)
 29193                              <1> ;
 29194                              <1> ; This feature is not used in Retro UNIX 386 (& 8086) for now.
 29195                              <1> ; Because, current Retro UNIX 386 disk I/O -INT13H- routine is 
 29196                              <1> ; derived from IBM PC AT -infact: XT286- BIOS source code, int 13h
 29197                              <1> ; that uses hardware -transfer has been completed- interrupt inside it. 
 29198                              <1> ; In a next Retro UNIX 386 version, these interrupts
 29199                              <1> ; (fdc_int, hdc1_int, hdc2_int) will be handled by a separate routine
 29200                              <1> ; as in original unix v1.
 29201                              <1> ; I am not removing IBM BIOS source code derivatives -compatible code-
 29202                              <1> ; for now, regarding the new/next 32 bit TRDOS project by me
 29203                              <1> ; (to keep source code files easy adaptable to 32 bit TRDOS.)
 29204                              <1> ;
 29205                              <1> ; Erdogan tan (10/07/2015) 
 29206                              <1> 
 29207                              <1> ;drum: / interrupt handler
 29208                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 29209                              <1> ;       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
 29210                              <1> ;                                      / error
 29211                              <1> ;               br 3f / no, error
 29212                              <1> ;       br      2f / error
 29213                              <1> ;
 29214                              <1> ;disk:
 29215                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 29216                              <1> ;       jmp     *$0f
 29217                              <1> ;0:
 29218                              <1> ;       jsr     r0,trapt; rkcs; rkap; 2
 29219                              <1> ;      	        br 3f / no, errors
 29220                              <1> ;       mov     $115,(r2) / drive reset, errbit was set
 29221                              <1> ;       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
 29222                              <1> ;                        / to 1f
 29223                              <1> ;       br      4f
 29224                              <1> ;1:
 29225                              <1> ;       bit     $20000,rkcs
 29226                              <1> ;       beq     4f / wait for seek complete
 29227                              <1> ;       mov     $0b,0b-2
 29228                              <1> ;       mov     rkap,r1
 29229                              <1> ;2:
 29230                              <1> ;       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
 29231                              <1> ;                          / the disk buffer
 29232                              <1> ;       bne     3f / no, branch ignore error if outstanding
 29233                              <1> ;       inc     r1
 29234                              <1> ;       asr     (r1)
 29235                              <1> ;       asr     (r1)
 29236                              <1> ;       asr     (r1) / reissue request
 29237                              <1> ;       dec     r1
 29238                              <1> ;3:
 29239                              <1> ;       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
 29240                              <1> ;       mov     ac,-(sp)
 29241                              <1> ;       mov     mq,-(sp) / put these on the stack
 29242                              <1> ;       mov     sc,-(sp)
 29243                              <1> ;       jsr     r0,poke
 29244                              <1> ;       mov     (sp)+,sc
 29245                              <1> ;       mov     (sp)+,mq / pop them off stack
 29246                              <1> ;       mov     (sp)+,ac
 29247                              <1> ;4:
 29248                              <1> ;       jmp     retisp / u4-3
 29249                              <1> ;
 29250                              <1> ;trapt:                  / r2 points to the
 29251                              <1> ;       mov     (r0)+,r2 / device control register
 29252                              <1> ;       mov     *(r0)+,r1 / transaction pointer points to buffer
 29253                              <1> ;       tst     (sp)+
 29254                              <1> ;       tstb    (r2) / is ready bit of dcs set?
 29255                              <1> ;       bge     4b / device still active so branch
 29256                              <1> ;       bit     (r0),active / was device busy?
 29257                              <1> ;       beq     4b / no, stray interrupt
 29258                              <1> ;       bic     (r0)+,active / yes, set active to zero
 29259                              <1> ;       tst     (r2) / test the err(bit is) of dcs
 29260                              <1> ;       bge     2f / if no error jump to 2f
 29261                              <1> ;       tst     (r0)+ / skip on error
 29262                              <1> ; 2:
 29263                              <1> ;       jmp     (r0)
 29264                              <1> 
 29265                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatibility code
 29266                              <1> get_system_time:
 29267                              <1> 	; 27/10/2021
 29268                              <1> 	; 21/02/2020 - Retro UNIX 386 v2
 29269                              <1> 	; get system time
 29270                              <1> 	;  (from recent value which is saved in RTC interrupt)
 29271                              <1> 	; Input:
 29272                              <1> 	; 	none
 29273                              <1> 	; Return:
 29274                              <1> 	;   	eax = system time in unix epoch format 
 29275                              <1> 	;
 29276                              <1> 	; Modified registers: eax, ecx, edx
 29277                              <1> 	
 29278                              <1> 	; 27/11/2021
 29279 00005B53 53                  <1> 	push	ebx
 29280 00005B54 E8E1D0FFFF          <1> 	call	epoch
 29281 00005B59 5B                  <1> 	pop	ebx
 29282 00005B5A C3                  <1> 	retn
 29283                              <1> 	
 29284                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2)
 29285                              <1> 	;  ('get_serial_number' is not used in v1.2 kernel)
 29286                              <1> ;get_serial_number:
 29287                              <1> 	; temporary - 21/02/2020
 29288                              <1> 	; 26/04/2020 (esi)
 29289                              <1> 	; 25/04/2020
 29290                              <1> 	; (Possible) Modified registers: eax, ecx, edx
 29291                              <1> 	; (edi, ebx & esi registers must be preserved)
 29292                              <1> 	; Return:
 29293                              <1> 	; eax = 32 bit serial number  
 29294                              <1> 	; (edx = high 32 bit of 64 bit serial number)
 29295                              <1> 	; -64 bit serial numbers will not be used in RUNIX 386 v2-
 29296                              <1> 	
 29297                              <1> 	;retn
 29298                                  %include 'u9.s'      ; 29/06/2015
 29299                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 29300                              <1> ; (re-write kernel for test by using previous version without a major defect)
 29301                              <1> ; ****************************************************************************
 29302                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.3) - SYS9.INC
 29303                              <1> ; Last Modification: 08/08/2022 (Previous: 12/06/2022)
 29304                              <1> ; ----------------------------------------------------------------------------
 29305                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 29306                              <1> ; (v0.1 - Beginning: 11/07/2012)
 29307                              <1> ;
 29308                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 29309                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 29310                              <1> ; <Bell Laboratories (17/3/1972)>
 29311                              <1> ; <Preliminary Release of UNIX Implementation Document>
 29312                              <1> ;
 29313                              <1> ; Retro UNIX 8086 v1 - U9.ASM (01/09/2014) //// UNIX v1 -> u9.s
 29314                              <1> ;
 29315                              <1> ; ****************************************************************************
 29316                              <1> 
 29317                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - Printer BIOS (Functions)
 29318                              <1> 
 29319                              <1> getch:
 29320                              <1> 	; 30/06/2015
 29321                              <1> 	; 18/02/2015 - Retro UNIX 386 v1 - feature only!
 29322 00005B5B 28C0                <1> 	sub	al, al ; 0
 29323                              <1> getch_q: ; 06/08/2015
 29324 00005B5D 8A25[56670000]      <1> 	mov 	ah, [ptty] ; active (current) video page
 29325 00005B63 EB06                <1>         jmp     short getc_n
 29326                              <1> 
 29327                              <1> getc: 
 29328                              <1> 	; 12/11/2015
 29329                              <1> 	; 15/09/2015
 29330                              <1> 	; 01/07/2015
 29331                              <1> 	; 30/06/2015
 29332                              <1> 	; 18/02/2015 (Retro UNIX 386 v1 - Beginning)
 29333                              <1> 	; 13/05/2013 - 04/07/2014 (Retro UNIX 8086 v1)
 29334                              <1> 	;
 29335                              <1> 	; Retro UNIX 8086 v1 modification !
 29336                              <1> 	; 
 29337                              <1> 	; 'getc' gets (next) character 
 29338                              <1> 	;	 from requested TTY (keyboard) buffer 
 29339                              <1> 	; INPUTS ->
 29340                              <1> 	;     [u.ttyn] = tty number (0 to 7) (8 is COM1, 9 is COM2)	
 29341                              <1> 	;     AL=0 -> Get (next) character from requested TTY buffer
 29342                              <1> 	;	(Keyboard buffer will point to 
 29343                              <1> 	;			next character at next call)
 29344                              <1> 	;     AL=1 -> Test a key is available in requested TTY buffer
 29345                              <1> 	;	(Keyboard buffer will point to 
 29346                              <1> 	;			current character at next call)
 29347                              <1> 	; OUTPUTS ->
 29348                              <1> 	;     (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 29349                              <1> 	;     			 ZF=0 -> AX has (current) character
 29350                              <1> 	;      AL = ascii code
 29351                              <1> 	;      AH = scan code	(AH = line status for COM1 or COM2)	 			
 29352                              <1> 	; 		        (cf=1 -> error code/flags in AH)
 29353                              <1> 	; Original UNIX V1 'getc': 
 29354                              <1> 	;		get a character off character list
 29355                              <1> 	;
 29356                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))	
 29357                              <1> 	;
 29358                              <1> 	; 30/06/2015 (32 bit modifications)
 29359                              <1> 	; 16/07/2013
 29360                              <1> 	; mov 	[getctty], ah
 29361                              <1> 	;
 29362                              <1> 
 29363 00005B65 8A25[996C0000]      <1> 	mov	ah, [u.ttyn] 	; 28/07/2013
 29364                              <1> getc_n:
 29365                              <1> 	; 30/06/2015
 29366 00005B6B 08E4                <1> 	or	ah, ah
 29367 00005B6D 740D                <1> 	jz	short getc0 
 29368 00005B6F D0E4                <1> 	shl	ah, 1
 29369 00005B71 0FB6DC              <1> 	movzx	ebx, ah
 29370 00005B74 81C3[58670000]      <1> 	add	ebx, ttychr
 29371 00005B7A EB05                <1> 	jmp	short getc1
 29372                              <1> getc0:
 29373 00005B7C BB[58670000]        <1> 	mov	ebx, ttychr
 29374                              <1> getc1:
 29375 00005B81 668B0B              <1> 	mov	cx, [ebx] 	; ascii & scan code
 29376                              <1> 				; (by kb_int)	
 29377 00005B84 6609C9              <1> 	or	cx, cx
 29378 00005B87 7507                <1> 	jnz	short getc2
 29379 00005B89 20C0                <1> 	and 	al, al
 29380 00005B8B 7415                <1> 	jz	short getc_s
 29381                              <1> 	;xor	ax, ax
 29382                              <1> 	; 30/11/2021
 29383 00005B8D 31C0                <1> 	xor	eax, eax
 29384 00005B8F C3                  <1> 	retn
 29385                              <1> getc2:	
 29386 00005B90 20C0                <1> 	and	al, al
 29387 00005B92 6689C8              <1> 	mov	ax, cx
 29388 00005B95 66B90000            <1> 	mov	cx, 0
 29389 00005B99 7506                <1> 	jnz	short getc3
 29390                              <1> getc_sn:
 29391 00005B9B 66890B              <1> 	mov	[ebx], cx ; 0, reset
 29392 00005B9E 6639C8              <1> 	cmp	ax, cx  ; zf = 0
 29393                              <1> getc3:
 29394 00005BA1 C3                  <1> 	retn
 29395                              <1> getc_s:
 29396                              <1> 	; 12/11/2015
 29397                              <1> 	; 15/09/2015
 29398                              <1> 	; 01/07/2015
 29399                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 29400                              <1> 	; 16/07/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 29401                              <1> 	;
 29402                              <1> 	; tty  of the current process is not 
 29403                              <1> 	; current tty (ptty); so, current process only 
 29404                              <1> 	; can use keyboard input when its tty becomes 
 29405                              <1> 	; current tty (ptty).
 29406                              <1> 	; 'sleep' is for preventing an endless lock
 29407                              <1> 	; during this tty input request.
 29408                              <1> 	; (Because, the user is not looking at the video page
 29409                              <1> 	; of the process to undersand there is a keyboard
 29410                              <1> 	; input request.)
 29411                              <1> 	;
 29412                              <1> 	;((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 29413                              <1> 	;
 29414                              <1> 	; 05/10/2013
 29415                              <1> 	; ah = byte ptr [u.ttyn] ; (tty number)
 29416                              <1> 	;
 29417                              <1> 	; 10/10/2013
 29418                              <1> gcw0:
 29419 00005BA2 B10A                <1> 	mov	cl, 10 ; ch = 0
 29420                              <1> gcw1:	
 29421                              <1> 	; 12/11/2015
 29422 00005BA4 E8C5D6FFFF          <1> 	call intract ; jumps to 'sysexit' if [u.quit] = FFFFh
 29423                              <1> 	; 10/10/2013
 29424 00005BA9 E841EBFFFF          <1> 	call	idle
 29425 00005BAE 668B03              <1> 	mov	ax, [ebx] 	; ascii & scan code
 29426                              <1> 				; (by kb_int)
 29427 00005BB1 6609C0              <1> 	or	ax, ax
 29428                              <1> ;	jnz	short gcw3
 29429 00005BB4 7519                <1> 	jnz	short gcw2 ; 15/09/2015
 29430                              <1> 	; 30/06/2015
 29431 00005BB6 FEC9                <1> 	dec	cl
 29432 00005BB8 75EA                <1> 	jnz	short gcw1
 29433                              <1> 	;
 29434 00005BBA 8A25[996C0000]      <1> 	mov	ah, [u.ttyn] 	; 20/10/2013
 29435                              <1> ;	; 10/12/2013
 29436                              <1> ;	cmp 	ah, [ptty]
 29437                              <1> ;	jne	short gcw2
 29438                              <1> ;	; 14/02/2014
 29439                              <1> ;	cmp	byte [u.uno], 1
 29440                              <1> ;	jna	short gcw0		
 29441                              <1> ;gcw2:
 29442 00005BC0 E8B7EBFFFF          <1> 	call	sleep
 29443                              <1> 	;
 29444                              <1> 	; 20/09/2013
 29445 00005BC5 8A25[996C0000]      <1> 	mov	ah, [u.ttyn]
 29446 00005BCB 30C0                <1> 	xor 	al, al
 29447 00005BCD EB9C                <1> 	jmp	short getc_n
 29448                              <1> ;gcw3:
 29449                              <1> gcw2: 	; 15/09/2015
 29450                              <1> 	; 10/10/2013
 29451 00005BCF 30C9                <1> 	xor	cl, cl
 29452 00005BD1 EBC8                <1> 	jmp	short getc_sn
 29453                              <1> 
 29454                              <1> putc:	
 29455                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 29456                              <1> 	; 13/08/2015
 29457                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 29458                              <1> 	; 15/05/2013 - 27/07/2014 (Retro UNIX 8086 v1)
 29459                              <1> 	;
 29460                              <1> 	; Retro UNIX 8086 v1 modification !
 29461                              <1> 	; 
 29462                              <1> 	; 'putc' puts a character 
 29463                              <1> 	;	 onto requested (tty) video page or
 29464                              <1> 	;	 serial port
 29465                              <1> 	; INPUTS ->
 29466                              <1> 	;     AL = ascii code of the character
 29467                              <1> 	;     AH = video page (tty) number (0 to 7)
 29468                              <1> 	;			  (8 is COM1, 9 is COM2)	
 29469                              <1> 	; OUTPUTS ->
 29470                              <1> 	;    (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 29471                              <1> 	;      			ZF=0 -> AX has (current) character
 29472                              <1> 	;     cf=0 and AH = 0 -> no error
 29473                              <1> 	;     cf=1 and AH > 0 -> error (only for COM1 and COM2)
 29474                              <1> 	; 
 29475                              <1> 	; Original UNIX V1 'putc': 
 29476                              <1> 	;     put a character at the end of character list
 29477                              <1> 	;
 29478                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 29479                              <1> 	;
 29480 00005BD3 80FC07              <1> 	cmp	ah, 7
 29481 00005BD6 770A                <1>         ja      short sndc ; 05/12/2021
 29482                              <1> 	; 30/06/2015
 29483 00005BD8 0FB6DC              <1> 	movzx	ebx, ah
 29484                              <1> 	; 13/08/2015
 29485 00005BDB B407                <1> 	mov	ah, 07h ; black background, light gray character color
 29486 00005BDD E9D2B6FFFF          <1> 	jmp	write_tty ; 'video.inc'
 29487                              <1> 
 29488                              <1> sndc:   ; <Send character>
 29489                              <1> 	;
 29490                              <1> 	; 12/01/2022
 29491                              <1> 	; 24/12/2021 (Retro UNIX 386 v1.2)
 29492                              <1> 	; 17/11/2015
 29493                              <1> 	; 16/11/2015
 29494                              <1> 	; 11/11/2015
 29495                              <1> 	; 10/11/2015
 29496                              <1> 	; 09/11/2015
 29497                              <1> 	; 08/11/2015
 29498                              <1> 	; 07/11/2015
 29499                              <1> 	; 06/11/2015 (serial4.asm, 'sendchr')	
 29500                              <1> 	; 29/10/2015
 29501                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 29502                              <1> 	; 14/05/2013 - 28/07/2014 (Retro UNIX 8086 v1)
 29503                              <1> 	;
 29504                              <1> 	; Retro UNIX 8086 v1 feature only !
 29505                              <1> 	;
 29506                              <1> 	; ah = [u.ttyn]
 29507                              <1> 	;
 29508                              <1> 	; 30/06/2015
 29509 00005BE2 80EC08              <1> 	sub	ah, 8 ; ; 0 = tty8 or 1 = tty9
 29510                              <1> 	; 07/11/2015
 29511 00005BE5 0FB6DC              <1> 	movzx	ebx, ah ; serial port index (0 or 1)
 29512                              <1> sndc0:
 29513                              <1> 	; 07/11/2015
 29514 00005BE8 E8DDEBFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 29515 00005BED 7405                <1> 	jz	short sndc1
 29516 00005BEF E87AD6FFFF          <1> 	call	intract ; quit (ctrl+break) check
 29517                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 29518                              <1> sndc1:
 29519                              <1> 	; 16/11/2015
 29520                              <1> 	;mov	cx, ax	; *** al = character (to be sent)
 29521                              <1> 	; 24/12/2021
 29522 00005BF4 89C1                <1> 	mov	ecx, eax ; *** al = character (to be sent)
 29523                              <1> sndcx:
 29524 00005BF6 8A83[9A670000]      <1> 	mov	al, [ebx+schar] ; last sent character
 29525 00005BFC 8AA3[98670000]      <1> 	mov	ah, [ebx+rchar] ; last received character
 29526                              <1> 	;
 29527                              <1> 	; 17/11/2015
 29528                              <1> 	; check 'request for response' status
 29529 00005C02 80BB[94670000]00    <1> 	cmp	byte [ebx+req_resp], 0
 29530 00005C09 740A                <1> 	jz	short query
 29531                              <1> response:
 29532 00005C0B FE05[97670000]      <1> 	inc 	byte [comqr] ; query or response status
 29533 00005C11 B0FF                <1> 	mov	al, 0FFh	 
 29534 00005C13 EB14                <1> 	jmp	short sndc3
 29535                              <1> query:
 29536 00005C15 08C0                <1> 	or 	al, al  ; 0 = query (also end of text)
 29537 00005C17 750E                <1> 	jnz 	short sndc2 ; normal character
 29538                              <1> 	;cmp 	ah, 0FFh     ; is it responded by terminal ?
 29539                              <1> 	;je	short sndc2  ; yes, already responded
 29540                              <1> 	; 16/11/2015
 29541                              <1> 	; query: request for response (again)
 29542 00005C19 8883[98670000]      <1> 	mov	[ebx+rchar], al ; 0 ; reset
 29543 00005C1F FE05[97670000]      <1> 	inc 	byte [comqr] ; query or response status
 29544 00005C25 EB02                <1> 	jmp	short sndc3
 29545                              <1> sndc2:
 29546 00005C27 88C8                <1> 	mov	al, cl 	; *** character (to be sent)
 29547                              <1> sndc3:
 29548 00005C29 8883[9A670000]      <1> 	mov	[ebx+schar], al ; current character (to be sent)
 29549 00005C2F 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 29550                              <1> 	; 30/06/2015
 29551 00005C31 E869CFFFFF          <1> 	call	sp_status ; get serial port status
 29552                              <1> 	; AL = Line status, AH = Modem status
 29553                              <1> 	; 07/11/2015
 29554 00005C36 A880                <1> 	test	al, 80h
 29555 00005C38 7504                <1> 	jnz	short sndc4
 29556 00005C3A A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 29557 00005C3C 751A                <1> 	jnz	short sndc5
 29558                              <1> sndc4: 	; Check line status again
 29559                              <1> 	; 16/11/2015
 29560                              <1> 	;push	cx
 29561                              <1> 	; 24/12/2021
 29562 00005C3E 51                  <1> 	push	ecx
 29563                              <1> 	;mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 29564                              <1> 	; 12/01/2022
 29565 00005C3F 31C9                <1> 	xor	ecx, ecx
 29566 00005C41 B106                <1> 	mov	cl, 6
 29567 00005C43 E863B7FFFF          <1> 	call	WAITF
 29568                              <1> 	;pop	cx
 29569                              <1> 	; 24/12/1021
 29570 00005C48 59                  <1> 	pop	ecx
 29571                              <1> 	;
 29572 00005C49 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 29573 00005C4B E84FCFFFFF          <1> 	call	sp_status ; get serial port status
 29574                              <1> 	; 16/11/2015
 29575                              <1> 	; 09/11/2015
 29576                              <1> 	; 08/11/2015
 29577 00005C50 A880                <1> 	test	al, 80h	; time out error
 29578 00005C52 7565                <1>         jnz     short sndc7
 29579 00005C54 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 29580 00005C56 7461                <1>         jz	short sndc7
 29581                              <1> sndc5:  
 29582 00005C58 8A83[9A670000]      <1> 	mov	al, [ebx+schar] ; character (to be sent)
 29583 00005C5E 66BAF803            <1> 	mov	dx, 3F8h   ; data port (COM2)
 29584 00005C62 28DE                <1> 	sub	dh, bl
 29585 00005C64 EE                  <1> 	out	dx, al	   ; send on serial port
 29586                              <1> 	; 10/11/2015
 29587                              <1> 	; delay for 3*30 (3*(15..80)) micro seconds
 29588                              <1> 	; (to improve text flow to the terminal)
 29589                              <1> 	; ('diskette.inc': 'WAITF')
 29590                              <1> 	; Uses port 61h, bit 4 to have CPU speed independent waiting.
 29591                              <1> 	; (refresh periods = 1 per 30 microseconds on most machines)
 29592                              <1> 	;push	cx
 29593                              <1> 	; 24/12/2021
 29594 00005C65 51                  <1> 	push	ecx
 29595                              <1> 	;mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 29596                              <1> 	; 12/01/2022
 29597 00005C66 29C9                <1> 	sub	ecx, ecx
 29598 00005C68 B106                <1> 	mov	cl, 6
 29599 00005C6A E83CB7FFFF          <1> 	call	WAITF
 29600                              <1> 	;pop	cx
 29601                              <1> 	; 24/12/1021
 29602 00005C6F 59                  <1> 	pop	ecx
 29603                              <1>     	;
 29604                              <1> 	; 07/11/2015
 29605 00005C70 88D8                <1> 	mov	al, bl ; al = 0 (tty8) or 1 (tty9)
 29606                              <1> 	;
 29607 00005C72 E828CFFFFF          <1> 	call	sp_status ; get serial port status
 29608                              <1> 	; AL = Line status, AH = Modem status
 29609                              <1> 	;
 29610 00005C77 E84EEBFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 29611 00005C7C 7405                <1> 	jz	short sndc6
 29612 00005C7E E8EBD5FFFF          <1> 	call	intract ; quit (ctrl+break) check
 29613                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 29614                              <1> sndc6:
 29615 00005C83 3C80                <1> 	cmp	al, 80h
 29616 00005C85 7332                <1> 	jnb	short sndc7		
 29617                              <1> 	;
 29618 00005C87 803D[97670000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 29619 00005C8E 7244                <1> 	jb	short sndc8 	; no, normal character
 29620 00005C90 883D[97670000]      <1> 	mov 	byte [comqr], bh ; 0 ; reset
 29621                              <1> 	; 17/11/2015
 29622 00005C96 E854EAFFFF          <1> 	call	idle
 29623                              <1> 	;
 29624 00005C9B 38BB[9A670000]      <1> 	cmp	[ebx+schar], bh ; 0 ; query ?
 29625                              <1>         ;ja	sndc2       ; response (will be followed by
 29626                              <1> 			    ; a normal character)
 29627                              <1> 	; 24/12/2021
 29628 00005CA1 7602                <1> 	jna	short sndc_10
 29629 00005CA3 EB82                <1> 	jmp	sndc2
 29630                              <1> sndc_10:
 29631                              <1> 	; Query request must be responded by the terminal
 29632                              <1> 	; before sending a normal character !
 29633 00005CA5 53                  <1> 	push	ebx
 29634                              <1> 	;push	cx ; *** cl = character (to be sent)
 29635                              <1> 	; 24/12/2021
 29636 00005CA6 51                  <1> 	push	ecx ; *** cl = character (to be sent)
 29637 00005CA7 8A25[996C0000]      <1> 	mov	ah, [u.ttyn]
 29638 00005CAD E8CAEAFFFF          <1> 	call	sleep ; this process will be awakened by
 29639                              <1> 		      ; received data available interrupt
 29640                              <1> 	;pop	cx ; *** cl = character (to be sent)
 29641                              <1> 	; 24/12/2021
 29642 00005CB2 59                  <1> 	pop	ecx ; *** cl = character (to be sent) 
 29643 00005CB3 5B                  <1> 	pop	ebx
 29644 00005CB4 E93DFFFFFF          <1>         jmp	sndcx
 29645                              <1> sndc7:
 29646                              <1> 	 ; 16/11/2015
 29647 00005CB9 803D[97670000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 29648 00005CC0 7213                <1> 	jb	short sndc9 	; no
 29649                              <1> 	;
 29650 00005CC2 88BB[98670000]      <1> 	mov	[ebx+rchar], bh ; 0 ; reset
 29651 00005CC8 88BB[9A670000]      <1> 	mov	[ebx+schar], bh ; 0 ; reset
 29652                              <1> 	;
 29653 00005CCE 883D[97670000]      <1> 	mov	byte [comqr], bh ; 0 ; reset  
 29654                              <1> sndc8:
 29655 00005CD4 F5                  <1> 	cmc  ; jnc -> jc, jb -> jnb
 29656                              <1> sndc9:
 29657                              <1> 	; AL = Line status, AH = Modem status
 29658 00005CD5 C3                  <1> 	retn
 29659                              <1> 
 29660                              <1> get_cpos:
 29661                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 29662                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 29663                              <1> 	;
 29664                              <1> 	; INPUT -> bl = video page number
 29665                              <1> 	; RETURN -> dx = cursor position
 29666                              <1> 
 29667 00005CD6 53                  <1> 	push	ebx
 29668 00005CD7 83E30F              <1> 	and	ebx, 0Fh ; 07h ; tty0 to tty7
 29669 00005CDA D0E3                <1> 	shl	bl, 1
 29670 00005CDC 81C3[46670000]      <1> 	add	ebx, cursor_posn
 29671 00005CE2 668B13              <1> 	mov	dx, [ebx]
 29672 00005CE5 5B                  <1> 	pop	ebx
 29673 00005CE6 C3                  <1> 	retn
 29674                              <1> 
 29675                              <1> read_ac_current:
 29676                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 29677                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 29678                              <1> 	;
 29679                              <1> 	; INPUT -> bl = video page number
 29680                              <1> 	; RETURN -> ax = character (al) and attribute (ah)
 29681                              <1> 
 29682 00005CE7 E82EB7FFFF          <1> 	call 	find_position ; 'video.inc'
 29683                              <1> 	; dx = status port
 29684                              <1> 	; esi = cursor location/address
 29685 00005CEC 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
 29686 00005CF2 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
 29687 00005CF5 C3                  <1> 	retn
 29688                              <1> 
 29689                              <1> syssleep:
 29690                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
 29691                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
 29692                              <1> 	;
 29693                              <1> 	; Retro UNIX 8086 v1 feature only
 29694                              <1> 	; (INPUT -> none)
 29695                              <1> 	;
 29696 00005CF6 0FB61D[B56C0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 29697 00005CFD 8AA3[63680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 29698 00005D03 E874EAFFFF          <1> 	call	sleep
 29699 00005D08 E974D4FFFF          <1> 	jmp	sysret
 29700                              <1> 
 29701                              <1> vp_clr:
 29702                              <1> 	; Reset/Clear Video Page
 29703                              <1> 	;
 29704                              <1> 	; 05/12/2021 - (Retro UNIX 386 v1.2)
 29705                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
 29706                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
 29707                              <1> 	;
 29708                              <1> 	; Retro UNIX 8086 v1 feature only !
 29709                              <1> 	;
 29710                              <1> 	; INPUTS -> 
 29711                              <1> 	;   BL = video page number	 
 29712                              <1> 	;
 29713                              <1> 	; OUTPUT ->
 29714                              <1> 	;   none
 29715                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
 29716                              <1> 	;
 29717                              <1> 	; 04/12/2013
 29718 00005D0D 28C0                <1> 	sub	al, al
 29719                              <1> 	; al = 0 (clear video page)
 29720                              <1> 	; bl = video page
 29721 00005D0F B407                <1> 	mov	ah, 07h
 29722                              <1> 	; ah = 7 (attribute/color)
 29723                              <1> 	;xor 	cx, cx ; 0, left upper column (cl) & row (cl)
 29724                              <1> 	; 05/12/2021
 29725 00005D11 31C9                <1> 	xor	ecx, ecx
 29726 00005D13 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
 29727 00005D17 E828B7FFFF          <1> 	call	scroll_up
 29728                              <1> 	; bl = video page
 29729                              <1> 	;xor	dx, dx ; 0 (cursor position) 
 29730                              <1> 	; 05/12/2021
 29731 00005D1C 31D2                <1> 	xor	edx, edx
 29732 00005D1E E99BB6FFFF          <1> 	jmp 	set_cpos
 29733                              <1> 
 29734                              <1> sysmsg:
 29735                              <1> 	; 11/12/2021
 29736                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 29737                              <1> 	; 11/11/2015
 29738                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
 29739                              <1> 	; Print user-application message on user's console tty
 29740                              <1> 	;
 29741                              <1> 	; Input -> EBX = Message address
 29742                              <1> 	;	   ECX = Message length (max. 255)
 29743                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
 29744                              <1> 	;
 29745 00005D23 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
 29746                              <1> 	;ja	sysret ; nothing to do with big message size
 29747 00005D29 7779                <1> 	ja	short sysmsg8 ; 11/12/2021
 29748 00005D2B 08C9                <1> 	or	cl, cl
 29749                              <1> 	;jz	sysret
 29750 00005D2D 7475                <1> 	jz	short sysmsg8 ; 11/12/2021
 29751 00005D2F 20D2                <1> 	and	dl, dl
 29752 00005D31 7502                <1> 	jnz	short sysmsg0
 29753 00005D33 B207                <1> 	mov	dl, 07h ; default color
 29754                              <1> 		; (black background, light gray character)
 29755                              <1> sysmsg0:
 29756 00005D35 891D[886C0000]      <1> 	mov	[u.base], ebx
 29757 00005D3B 8815[57670000]      <1> 	mov	[ccolor], dl ; color attributes
 29758 00005D41 89E5                <1> 	mov	ebp, esp
 29759 00005D43 31DB                <1> 	xor	ebx, ebx ; 0
 29760 00005D45 891D[906C0000]      <1> 	mov	[u.nread], ebx ; 0
 29761                              <1> 	;
 29762 00005D4B 381D[D66C0000]      <1> 	cmp	[u.kcall], bl ; 0
 29763 00005D51 7772                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
 29764                              <1> 	;
 29765 00005D53 890D[8C6C0000]      <1> 	mov	[u.count], ecx
 29766 00005D59 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ ; 04/12/2021
 29767                              <1> 	; 04/12/2021
 29768                              <1> 	; (dword alignment for esp)
 29769 00005D5A F6C103              <1> 	test	cl, 3
 29770 00005D5D 7404                <1> 	jz	short sysmsg_7
 29771 00005D5F 80C903              <1> 	or	cl, 3
 29772 00005D62 41                  <1> 	inc	ecx
 29773                              <1> sysmsg_7:
 29774 00005D63 29CC                <1> 	sub	esp, ecx
 29775 00005D65 89E7                <1> 	mov	edi, esp
 29776 00005D67 89E6                <1> 	mov	esi, esp
 29777 00005D69 66891D[D06C0000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
 29778                              <1> 	; 11/11/2015 
 29779 00005D70 8A25[9A6C0000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
 29780                              <1> 	; 0 = none
 29781 00005D76 FECC                <1> 	dec	ah
 29782 00005D78 790C                <1> 	jns	short sysmsg1 
 29783 00005D7A 8A1D[B56C0000]      <1> 	mov	bl, [u.uno] ; process number	
 29784 00005D80 8AA3[63680000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
 29785                              <1> sysmsg1:
 29786 00005D86 8825[996C0000]      <1> 	mov	[u.ttyn], ah
 29787                              <1> sysmsg2:
 29788 00005D8C E898F5FFFF          <1> 	call	cpass
 29789 00005D91 7416                <1> 	jz	short sysmsg5
 29790 00005D93 AA                  <1> 	stosb
 29791 00005D94 20C0                <1> 	and	al, al
 29792 00005D96 75F4                <1> 	jnz	short sysmsg2
 29793                              <1> sysmsg3:
 29794 00005D98 80FC07              <1> 	cmp	ah, 7 ; tty number
 29795 00005D9B 7711                <1> 	ja	short sysmsg6 ; serial port
 29796 00005D9D E83E000000          <1> 	call	print_cmsg
 29797                              <1> sysmsg4:
 29798 00005DA2 89EC                <1> 	mov	esp, ebp
 29799                              <1> sysmsg8: ; 11/12/2021	
 29800 00005DA4 E9D8D3FFFF          <1> 	jmp	sysret
 29801                              <1> sysmsg5:
 29802 00005DA9 C60700              <1> 	mov	byte [edi], 0
 29803 00005DAC EBEA                <1> 	jmp	short sysmsg3
 29804                              <1> sysmsg6:
 29805 00005DAE 8A06                <1> 	mov	al, [esi]
 29806 00005DB0 E82DFEFFFF          <1> 	call	sndc
 29807 00005DB5 72EB                <1> 	jc	short sysmsg4
 29808 00005DB7 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
 29809 00005DBA 76E6                <1> 	jna	short sysmsg4
 29810 00005DBC 46                  <1> 	inc 	esi
 29811 00005DBD 8A25[996C0000]      <1> 	mov	ah, [u.ttyn]
 29812 00005DC3 EBE9                <1> 	jmp	short sysmsg6
 29813                              <1> 
 29814                              <1> sysmsgk: ; Temporary (01/07/2015)
 29815                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
 29816                              <1> 	; (ECX -character count- will not be considered)
 29817 00005DC5 8B35[886C0000]      <1> 	mov	esi, [u.base]
 29818 00005DCB 8A25[56670000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
 29819 00005DD1 8825[996C0000]      <1> 	mov	[u.ttyn], ah
 29820 00005DD7 C605[D66C0000]00    <1> 	mov	byte [u.kcall], 0
 29821 00005DDE EBB8                <1> 	jmp	short sysmsg3
 29822                              <1> 	
 29823                              <1> print_cmsg: 
 29824                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
 29825                              <1> 	;
 29826                              <1> 	; print message (on user's console tty) 
 29827                              <1> 	;	with requested color
 29828                              <1> 	;
 29829                              <1> 	; INPUTS:
 29830                              <1> 	;	esi = message address
 29831                              <1> 	;	[u.ttyn] = tty number (0 to 7)
 29832                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
 29833                              <1> 	;
 29834 00005DE0 AC                  <1> 	lodsb
 29835                              <1> pcmsg1:
 29836 00005DE1 56                  <1> 	push 	esi
 29837 00005DE2 0FB61D[996C0000]    <1>         movzx   ebx, byte [u.ttyn]
 29838 00005DE9 8A25[57670000]      <1> 	mov	ah, [ccolor]
 29839 00005DEF E8C0B4FFFF          <1> 	call 	write_tty
 29840 00005DF4 5E                  <1> 	pop	esi
 29841 00005DF5 AC                  <1> 	lodsb
 29842 00005DF6 20C0                <1> 	and 	al, al  ; 0
 29843 00005DF8 75E7                <1> 	jnz 	short pcmsg1
 29844 00005DFA C3                  <1> 	retn
 29845                              <1> 
 29846                              <1> sysgeterr:
 29847                              <1> 	; 16/02/2022 - Retro UNIX 386 v1.2
 29848                              <1> 	; 09/12/2015
 29849                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
 29850                              <1> 	; Get last error number or page fault count
 29851                              <1> 	; (for debugging)
 29852                              <1> 	;
 29853                              <1> 	; Input -> EBX = return type
 29854                              <1> 	;	   0 = last error code (which is in 'u.error')	
 29855                              <1> 	;	   FFFFFFFFh = page fault count for running process
 29856                              <1> 	;	   FFFFFFFEh = total page fault count
 29857                              <1> 	;	   1 .. FFFFFFFDh = undefined 
 29858                              <1> 	;
 29859                              <1> 	; Output -> EAX = last error number or page fault count
 29860                              <1> 	;	   (depending on EBX input)
 29861                              <1> 	; 	
 29862 00005DFB 21DB                <1> 	and 	ebx, ebx
 29863 00005DFD 750F                <1> 	jnz	short glerr_2
 29864                              <1> glerr_0:
 29865 00005DFF A1[D86C0000]        <1> 	mov	eax, [u.error]
 29866                              <1> glerr_1:
 29867 00005E04 A3[646C0000]        <1> 	mov	[u.r0], eax
 29868                              <1> 	;retn
 29869                              <1>  	; 16/02/2022 (BugFix)
 29870 00005E09 E973D3FFFF          <1> 	jmp	sysret
 29871                              <1> glerr_2:
 29872 00005E0E 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
 29873 00005E0F 74FD                <1> 	jz	short glerr_2 ; page fault count for process
 29874 00005E11 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
 29875 00005E12 75EB                <1> 	jnz	short glerr_0
 29876 00005E14 A1[DC670000]        <1> 	mov	eax, [PF_Count] ; total page fault count
 29877 00005E19 EBE9                <1>         jmp     short glerr_1
 29878                              <1> glerr_3:
 29879 00005E1B A1[DC6C0000]        <1> 	mov 	eax, [u.pfcount]
 29880 00005E20 EBE2                <1> 	jmp	short glerr_1
 29881                              <1> 
 29882                              <1> ; 12/06/2022 - Retro UNIX 386 v1.2 - PRINTER BIOS (Functions)		
 29883                              <1> 
 29884                              <1> ;;; IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985 ;;; 
 29885                              <1> ;
 29886                              <1> ;--- INT 17 H ------------------------------------------------------------------
 29887                              <1> ; PRINTER_IO								       :
 29888                              <1> ;	THIS ROUTINE PROVIDES COMMUNICATION WITH THE PRINTER		       :
 29889                              <1> ; INPUT 								       :
 29890                              <1> ;	(AH)= 00H  PRINT THE CHARACTER IN (AL)				       :
 29891                              <1> ;		    ON RETURN, (AH)= 1 IF CHARACTER NOT BE PRINTED (TIME OUT)  :
 29892                              <1> ;		    OTHER BITS SET AS ON NORMAL STATUS CALL		       :
 29893                              <1> ;	(AH)= 01H  INITIALIZE THE PRINTER PORT				       :
 29894                              <1> ;		    RETURNS WITH (AH) SET WITH PRINTER STATUS		       :
 29895                              <1> ;	(AH)= 02H  READ THE PRINTER STATUS INTO (AH)			       :
 29896                              <1> ;		   7	   6	   5	   4	   3	   2-1	   0	       :
 29897                              <1> ;		   |	   |	   |	   |	   |	   |	   |_TIME OUT  :
 29898                              <1> ;		   |	   |	   |	   |	   |	   |		       :
 29899                              <1> ;		   |	   |	   |	   |	   |	   |_ UNUSED	       :
 29900                              <1> ;		   |	   |	   |	   |	   |			       :
 29901                              <1> ;		   |	   |	   |	   |	   |_ 1 = I/O ERROR	       :
 29902                              <1> ;		   |	   |	   |	   |				       :
 29903                              <1> ;		   |	   |	   |	   |_ 1 = SELECTED		       :
 29904                              <1> ;		   |	   |	   |					       :
 29905                              <1> ;		   |	   |	   |_ 1 = OUT OF PAPER			       :
 29906                              <1> ;		   |	   |						       :
 29907                              <1> ;		   |	   |_ 1 = ACKNOWLEDGE				       :
 29908                              <1> ;		   |							       :
 29909                              <1> ;		   |_ 1 = NOT BUSY					       :
 29910                              <1> ;									       :
 29911                              <1> ;	(DX) = PRINTER TO BE USED (0,1,2) CORRESPONDING TO ACTUAL VALUES       :
 29912                              <1> ;		IN @PRINTER_BASE AREA					       :
 29913                              <1> ; DATA AREA @PRINTER_BASE CONTAINS THE BASE ADDRESS OF THE PRINTER CARD(S)     :
 29914                              <1> ; AVAILABLE (LOCATED AT BEGINNING OF DATA SEGMENT, 408H ABSOLUTE, 3 WORDS)     :
 29915                              <1> ;									       :
 29916                              <1> ; DATA AREA @PRINT_TIM_OUT (BYTE) MAY BE CHANGED TO CAUSE DIFFERENT	       :
 29917                              <1> ; TIME OUT WAITS. DEFAULT=20 * 4					       :
 29918                              <1> ;									       :
 29919                              <1> ; REGISTERS	(AH) IS MODIFIED WITH STATUS INFORMATION		       :
 29920                              <1> ;		ALL OTHERS UNCHANGED					       :
 29921                              <1> ;-------------------------------------------------------------------------------
 29922                              <1> 
 29923                              <1> int17h:
 29924                              <1> 	; 12/06/2022 - Retro UNIX 386 v1.2
 29925                              <1> 	; (Derived from: IBM PC-AT BIOS v3 - PRT.ASM - 15/11/1985)
 29926                              <1> 	;
 29927                              <1> 	; (Default printer port: 378h) ; LPT1
 29928                              <1> 	; (Number of printers = 1)
 29929                              <1> 	
 29930                              <1> 	PRINTER_BASE equ 378h ; LPT1
 29931                              <1> 	;PRINT_TIM_OUT equ 4*80*65536 
 29932                              <1> 			; (Ref: IBM PC-AT BIOS v2 PRT.ASM)	 
 29933                              <1> 
 29934                              <1> 	PRINT_TIM_OUT equ 36000 ; WAIT_PRN_NBUSY
 29935                              <1> 			; (Ref: AWARD BIOS 1999 ATORGS.ASM)		
 29936                              <1> 
 29937                              <1> 	; INPUT:
 29938                              <1> 	;	ah = 0 -> print the character in AL 
 29939                              <1> 	;		 (sys write with write count >0)
 29940                              <1> 	;	ah = 1 -> initialize printer port
 29941                              <1> 	;		 (sys open)	
 29942                              <1> 	;	ah = 2 -> read the printer status 
 29943                              <1> 	;		 (sys write with write count = 0)
 29944                              <1> 	; OUTPUT:
 29945                              <1> 	;	ah = printer status
 29946                              <1> 
 29947                              <1> 	; Modified registers: eax, ecx, edx
 29948                              <1> 
 29949                              <1> PRINTER_IO_1:
 29950 00005E22 08E4                <1> 	or	ah, ah
 29951 00005E24 7417                <1> 	jz	short _b20
 29952 00005E26 FECC                <1> 	dec	ah
 29953 00005E28 7444                <1> 	jz	short _b80
 29954                              <1> 	;dec 	ah
 29955                              <1> 	;jz	short _b50
 29956                              <1> _b50:
 29957                              <1> 	;-----	PRINTER STATUS
 29958                              <1> B50:
 29959 00005E2A 50                  <1> 	push	eax		; SAVE (AL) REGISTER
 29960                              <1> B60:
 29961 00005E2B 66BA7903            <1> 	mov	dx, PRINTER_BASE+1
 29962                              <1> 				; GET PRINTER ATTACHMENT BASE ADDRESS
 29963                              <1> 				; POINT TO CONTROL PORT
 29964 00005E2F EC                  <1> 	in	al, dx		; PRE-CHARGE +BUSY LINE IF FLOATING
 29965 00005E30 EC                  <1> 	in	al, dx		; GET PRINTER STATUS HARDWARE BITS
 29966 00005E31 88C4                <1> 	mov	ah, al		; SAVE
 29967 00005E33 80E4F8              <1> 	and	ah, 0F8h	; TURN OFF UNUSED BITS
 29968                              <1> B70:
 29969 00005E36 5A                  <1> 	pop	edx		; RECOVER (AL) REGISTER
 29970 00005E37 88D0                <1> 	mov	al, dl		; MOVE CHARACTER INTO (AL)
 29971 00005E39 80F448              <1> 	xor	ah, 48h		; FLIP A COUPLE OF BITS
 29972                              <1> B10:
 29973 00005E3C C3                  <1> 	retn			; RETURN FROM ROUTINE WITH STATUS IN AH
 29974                              <1> _b20:
 29975                              <1> 	;-----	PRINT THE CHARACTER IN (AL)
 29976 00005E3D B9A08C0000          <1> 	mov	ecx, PRINT_TIM_OUT ; (1 second)
 29977                              <1> B20:
 29978 00005E42 50                  <1> 	push	eax		; SAVE VALUE TO PRINT
 29979 00005E43 66BA7803            <1> 	mov	dx, PRINTER_BASE
 29980 00005E47 EE                  <1> 	out	dx, al		; OUTPUT CHARACTER TO DATA PORT
 29981 00005E48 FEC2                <1> 	inc	dl		; POINT TO STATUS PORT
 29982                              <1> 
 29983                              <1> 	;-----	CHECK FOR PRINTER BUSY
 29984                              <1> B25:
 29985                              <1> 	;-----	WAIT BUSY
 29986                              <1> B35:
 29987 00005E4A EC                  <1> 	in	al, dx		; GET STATUS
 29988 00005E4B 88C4                <1> 	mov	ah, al		; STATUS TO (AH) ALSO
 29989 00005E4D A880                <1> 	test	al, 80h		; IS THE PRINTER CURRENTLY BUSY? (*)
 29990 00005E4F 750F                <1> 	jnz	short B40	; GO TO OUTPUT STROBE
 29991 00005E51 E831000000          <1> 	call	WAIT_REFRESH	; (wait for 30 micro seconds)
 29992 00005E56 E2F2                <1> 	loop	B35		; LOOP IF YES (*)
 29993                              <1> 
 29994 00005E58 80CC01              <1> 	or	ah, 1		; SET ERROR FLAG
 29995 00005E5B 80E4F9              <1> 	and	ah, 0F9h	; TURN OFF THE UNUSED BITS
 29996 00005E5E EBD6                <1> 	jmp	short B70	; RETURN WITH ERROR FLAG SET
 29997                              <1> 
 29998                              <1> B40:				; SEND STROBE PULSE
 29999 00005E60 B00D                <1> 	mov	al, 0Dh		; SET THE STROBE LOW (BIT ON)
 30000 00005E62 6642                <1> 	inc	dx		; OUTPUT STROBE TO CONTROL PORT
 30001 00005E64 FA                  <1> 	cli			; PREVENT INTERRUPT PULSE STRETCHING
 30002 00005E65 EE                  <1> 	out	dx, al		; OUTPUT STROBE BIT > 1us < 5us
 30003                              <1> 	; IODELAY
 30004                              <1> 	;jmp	short $+2	; I/O DELAY TO ALLOW FOR LINE LOADING
 30005                              <1> 	;jmp	short $+2	; AND FOR CORRECT PULSE WIDTH
 30006                              <1> 	; NEWIODELAY
 30007 00005E66 E6EB                <1> 	out	0EBh, al
 30008                              <1> 
 30009 00005E68 B00C                <1> 	mov	al, 0Ch		; SET THE -STROBE HIGH
 30010 00005E6A EE                  <1> 	out	dx, al
 30011 00005E6B FB                  <1> 	sti			; INTERRUPTS BACK ON
 30012                              <1> 	;pop	eax		; RECOVER THE OUTPUT CHAR
 30013                              <1> 	;jmp	short B50
 30014 00005E6C EBBD                <1> 	jmp	short B60
 30015                              <1> 
 30016                              <1> _b80:
 30017                              <1> 	;-----	INITIALIZE THE PRINTER PORT
 30018                              <1> B80:
 30019 00005E6E 50                  <1> 	push	eax		; SAVE (AL)
 30020 00005E6F 66BA7A03            <1> 	mov	dx, PRINTER_BASE+2 ; POINT TO OUTPUT PORT
 30021 00005E73 B008                <1> 	mov	al, 8		; SET INIT LINE LOW
 30022 00005E75 EE                  <1> 	out	dx, al
 30023                              <1> 	;mov	eax, 1000*4	; ADJUST FOR INITIALIZATION DELAY LOOP
 30024 00005E76 B989080000          <1> 	mov	ecx, WAIT_PRN_INIT ; (65536 micro seconds)
 30025                              <1> B90:				; INIT_LOOP
 30026                              <1> 	;dec	eax		; LOOP FOR RESET TO TAKE
 30027                              <1> 	;jnz	short B90	; INIT_LOOP
 30028 00005E7B E807000000          <1> 	call	WAIT_REFRESH	; (wait for 30 micro seconds)
 30029 00005E80 E2F9                <1> 	loop	B90	
 30030 00005E82 B00C                <1> 	mov	al, 0Ch		; NO INTERRUPTS, NON AUTO LF, INIT HIGH
 30031 00005E84 EE                  <1> 	out	dx, al
 30032 00005E85 EBA4                <1> 	jmp	short B60	; EXIT THROUGH STATUS ROUTINE
 30033                              <1> 
 30034                              <1> 
 30035                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
 30036                              <1> ; -------------------------------------------------------------------
 30037                              <1> ;
 30038                              <1> ;;Wait while printer initializes should be 65,536 microseconds.
 30039                              <1> ;;65536/30 = 2185
 30040                              <1> ;			PUBLIC	WAIT_PRN_INIT_LO
 30041                              <1> ;WAIT_PRN_INIT_LO	DW	2185
 30042                              <1> ;			PUBLIC	WAIT_PRN_INIT_HI
 30043                              <1> ;WAIT_PRN_INIT_HI	DW	0
 30044                              <1> ;
 30045                              <1> WAIT_PRN_INIT equ 2185 ; 12/06/2022
 30046                              <1> ;
 30047                              <1> ;;Wait for printer not busy should be 1,080,000 microseconds.
 30048                              <1> ;;Memory refresh =15 us, therefore memory refresh period = 30 Us.
 30049                              <1> ;;1,080,000 / 30 = 36,000
 30050                              <1> ;			PUBLIC	WAIT_PRN_NBUSY_LO
 30051                              <1> ;WAIT_PRN_NBUSY_LO	DW	36000
 30052                              <1> ;			PUBLIC	WAIT_PRN_NBUSY_HI
 30053                              <1> ;WAIT_PRN_NBUSY_HI	DB	0
 30054                              <1> ;
 30055                              <1> ;WAIT_PRN_NBUSY	equ 36000 ; 12/06/2022
 30056                              <1> 
 30057                              <1> ; AWARD BIOS - 1999 - ATORGS.ASM (27/5/1999)
 30058                              <1> ; ------------------------------------------
 30059                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
 30060                              <1> ;   	INPUT: BX:CX = number of refresh periods to wait
 30061                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
 30062                              <1> ;	OUTPUT: BX:CX destroyed.
 30063                              <1> ;
 30064                              <1> ;	SAVES:	AX (except when NO STACK)
 30065                              <1> ;
 30066                              <1> ;	NOTES:	This routine can be (and is) used with no stack. When
 30067                              <1> ;		used this way, AX is assumed to be destroyed.
 30068                              <1> 
 30069                              <1> WAIT_REFRESH:
 30070                              <1> 	; 08/08/2022
 30071                              <1> 	; 12/06/2022
 30072                              <1> 	; Modified for Retro UNIX 386 v1.2
 30073                              <1> 	
 30074                              <1> 	; (wait for 30 micro seconds)
 30075                              <1> 
 30076                              <1> 	; 08/08/2022
 30077                              <1> 	;SYS1	equ 61h ; PORT_B
 30078                              <1> 
 30079                              <1> WR_SHORT:
 30080 00005E87 50                  <1> 	push	eax
 30081                              <1> WR_STAT_0:
 30082 00005E88 E461                <1> 	in	al, SYS1	; wait for high to low
 30083 00005E8A A810                <1> 	test	al, 10h		; transition on memory
 30084 00005E8C 75FA                <1> 	jnz	short WR_STAT_0 
 30085                              <1> WR_STAT_1:
 30086 00005E8E E461                <1> 	in	al, SYS1
 30087 00005E90 A810                <1> 	test	al, 10h
 30088 00005E92 74FA                <1> 	jz	short WR_STAT_1
 30089 00005E94 58                  <1> 	pop	eax
 30090 00005E95 C3                  <1> 	retn
 30091                                  
 30092                                  ; 07/03/2015
 30093                                  ; Temporary Code
 30094                                  display_disks:
 30095 00005E96 803D[4C620000]00        	cmp 	byte [fd0_type], 0
 30096 00005E9D 7605                    	jna 	short ddsks1
 30097 00005E9F E87D000000              	call	pdskm
 30098                                  ddsks1:
 30099 00005EA4 803D[4D620000]00        	cmp	byte [fd1_type], 0
 30100 00005EAB 760C                    	jna	short ddsks2
 30101 00005EAD C605[13640000]31        	mov	byte [dskx], '1'
 30102 00005EB4 E868000000              	call	pdskm
 30103                                  ddsks2:
 30104 00005EB9 803D[4E620000]00        	cmp	byte [hd0_type], 0
 30105 00005EC0 7654                    	jna	short ddsk6
 30106 00005EC2 66C705[11640000]68-     	mov	word [dsktype], 'hd'
 30107 00005ECA 64                 
 30108 00005ECB C605[13640000]30        	mov	byte [dskx], '0'
 30109 00005ED2 E84A000000              	call	pdskm
 30110                                  ddsks3:
 30111 00005ED7 803D[4F620000]00        	cmp	byte [hd1_type], 0
 30112 00005EDE 7636                    	jna	short ddsk6
 30113 00005EE0 C605[13640000]31        	mov	byte [dskx], '1'
 30114 00005EE7 E835000000              	call	pdskm
 30115                                  ddsks4:
 30116 00005EEC 803D[50620000]00        	cmp	byte [hd2_type], 0
 30117 00005EF3 7621                    	jna	short ddsk6
 30118 00005EF5 C605[13640000]32        	mov	byte [dskx], '2'
 30119 00005EFC E820000000              	call	pdskm
 30120                                  ddsks5:
 30121 00005F01 803D[51620000]00        	cmp	byte [hd3_type], 0
 30122 00005F08 760C                    	jna	short ddsk6
 30123 00005F0A C605[13640000]33        	mov	byte [dskx], '3'
 30124 00005F11 E80B000000              	call	pdskm
 30125                                  ddsk6:
 30126 00005F16 BE[22640000]            	mov	esi, nextline
 30127 00005F1B E806000000              	call	pdskml
 30128                                  pdskm_ok:
 30129 00005F20 C3                      	retn
 30130                                  pdskm:
 30131 00005F21 BE[0F640000]            	mov	esi, dsk_ready_msg
 30132                                  pdskml:	
 30133 00005F26 AC                      	lodsb
 30134 00005F27 08C0                    	or	al, al
 30135 00005F29 74F5                    	jz	short pdskm_ok
 30136 00005F2B 56                      	push	esi
 30137 00005F2C 31DB                    	xor	ebx, ebx ; 0
 30138                                  			; Video page 0 (bl=0)
 30139 00005F2E B407                    	mov	ah, 07h ; Black background, 
 30140                                  			; light gray forecolor
 30141 00005F30 E87FB3FFFF              	call	write_tty
 30142 00005F35 5E                      	pop	esi
 30143 00005F36 EBEE                    	jmp	short pdskml
 30144                                  
 30145 00005F38 90<rept>                align 16
 30146                                  
 30147                                  gdt:	; Global Descriptor Table
 30148                                  	; (30/07/2015, conforming cs)
 30149                                  	; (26/03/2015)
 30150                                  	; (24/03/2015, tss)
 30151                                  	; (19/03/2015)
 30152                                  	; (29/12/2013)
 30153                                  	;
 30154 00005F40 0000000000000000        	dw 0, 0, 0, 0	; NULL descriptor
 30155                                  	; 18/08/2014
 30156                                  			; 08h kernel code segment, base = 00000000h		
 30157 00005F48 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
 30158                                  			; 10h kernel data segment, base = 00000000h	
 30159 00005F50 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
 30160                                  			; 1Bh user code segment, base address = 400000h ; CORE
 30161 00005F58 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
 30162                                  			; 23h user data segment, base address = 400000h ; CORE
 30163 00005F60 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
 30164                                  			; Task State Segment
 30165 00005F68 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
 30166                                  			       ;  no IO permission in ring 3)
 30167                                  gdt_tss0:
 30168 00005F6A 0000                    	dw 0 ; TSS base address, bits 0-15 
 30169                                  gdt_tss1:
 30170 00005F6C 00                      	db 0 ; TSS base address, bits 16-23 
 30171                                  	      		; 49h	
 30172 00005F6D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
 30173 00005F6E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
 30174                                  gdt_tss2:
 30175 00005F6F 00                      	db 0 ; TSS base address, bits 24-31 
 30176                                  
 30177                                  gdt_end:
 30178                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 30179                                  					;; Type= 1 (code)/C=0/R=1/A=0
 30180                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 30181                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 30182                                  
 30183                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 30184                                  					;; Type= 0 (data)/E=0/W=1/A=0
 30185                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 30186                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 30187                                  		; W= Writeable, A= Accessed
 30188                                  	
 30189                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
 30190                                  					;; Type= 1 (code)/C=0/R=1/A=0
 30191                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 30192                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 30193                                  
 30194                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
 30195                                  					;; Type= 0 (data)/E=0/W=1/A=0
 30196                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 30197                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 30198                                  	
 30199                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
 30200                                  
 30201                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
 30202                                  		;	 = 100000h * 1000h (G=1) = 4GB
 30203                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
 30204                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
 30205                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
 30206                                  		; AVL= Available to programmers	
 30207                                  
 30208                                  gdtd:
 30209 00005F70 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
 30210 00005F72 [405F0000]                      dd gdt			; Address of the GDT
 30211                                  
 30212                                  	; 20/08/2014
 30213                                  idtd:
 30214 00005F76 FF01                            dw idt_end - idt - 1    ; Limit (size)
 30215 00005F78 [C0640000]                      dd idt			; Address of the IDT
 30216                                  
 30217                                  align 4
 30218                                  	; 21/08/2014
 30219                                  ilist:
 30220                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
 30221                                  	;
 30222                                  	; Exception list
 30223                                  	; 25/08/2014	
 30224 00005F7C [1D080000]              	dd	exc0	; 0h,  Divide-by-zero Error
 30225 00005F80 [24080000]              	dd	exc1	
 30226 00005F84 [2B080000]              	dd 	exc2	
 30227 00005F88 [32080000]              	dd	exc3	
 30228 00005F8C [36080000]              	dd	exc4	
 30229 00005F90 [3A080000]              	dd	exc5	
 30230 00005F94 [3E080000]              	dd 	exc6	; 06h,  Invalid Opcode
 30231 00005F98 [42080000]              	dd	exc7	
 30232 00005F9C [46080000]              	dd	exc8	
 30233 00005FA0 [4A080000]              	dd	exc9	
 30234 00005FA4 [4E080000]              	dd 	exc10	
 30235 00005FA8 [52080000]              	dd	exc11
 30236 00005FAC [56080000]              	dd	exc12
 30237 00005FB0 [5A080000]              	dd	exc13	; 0Dh, General Protection Fault
 30238 00005FB4 [5E080000]              	dd 	exc14	; 0Eh, Page Fault
 30239 00005FB8 [62080000]              	dd	exc15
 30240 00005FBC [66080000]              	dd	exc16
 30241 00005FC0 [6A080000]              	dd	exc17
 30242 00005FC4 [6E080000]              	dd 	exc18
 30243 00005FC8 [72080000]              	dd	exc19
 30244 00005FCC [76080000]              	dd 	exc20
 30245 00005FD0 [7A080000]              	dd	exc21
 30246 00005FD4 [7E080000]              	dd	exc22
 30247 00005FD8 [82080000]              	dd	exc23
 30248 00005FDC [86080000]              	dd 	exc24
 30249 00005FE0 [8A080000]              	dd	exc25
 30250 00005FE4 [8E080000]              	dd	exc26
 30251 00005FE8 [92080000]              	dd	exc27
 30252 00005FEC [96080000]              	dd 	exc28
 30253 00005FF0 [9A080000]              	dd	exc29
 30254 00005FF4 [9E080000]              	dd 	exc30
 30255 00005FF8 [A2080000]              	dd	exc31
 30256                                  	; Interrupt list
 30257 00005FFC [58060000]              	dd	timer_int	; INT 20h
 30258                                  		;dd	irq0	
 30259 00006000 [5C0B0000]              	dd	keyb_int	; 27/08/2014
 30260                                  		;dd	irq1
 30261 00006004 [77070000]              	dd	irq2
 30262                                  		; COM2 int
 30263 00006008 [7B070000]              	dd	irq3
 30264                                  		; COM1 int
 30265 0000600C [86070000]              	dd	irq4
 30266 00006010 [91070000]              	dd	irq5
 30267                                  ;DISKETTE_INT: ;06/02/2015
 30268 00006014 [C81E0000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
 30269                                  		;dd	irq6
 30270                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
 30271                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 30272 00006018 [0D0B0000]              	dd	default_irq7	; 25/02/2015
 30273                                  		;dd	irq7
 30274                                  ; Real Time Clock Interrupt
 30275 0000601C [AB090000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
 30276                                  		;dd	irq8	; INT 28h
 30277 00006020 [A1070000]              	dd	irq9
 30278 00006024 [A5070000]              	dd	irq10
 30279 00006028 [A9070000]              	dd	irq11
 30280 0000602C [AD070000]              	dd	irq12
 30281 00006030 [B1070000]              	dd	irq13
 30282                                  ;HDISK_INT1:  ;06/02/2015 	
 30283 00006034 [98230000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
 30284                                  		;dd	irq14
 30285                                  ;HDISK_INT2:  ;06/02/2015
 30286 00006038 [BB230000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
 30287                                  		;dd	irq15	; INT 2Fh
 30288                                  		; 14/08/2015
 30289 0000603C [5D300000]              	dd	sysent		; INT 30h (system calls)
 30290                                  	
 30291                                  	;dd	ignore_int
 30292 00006040 00000000                	dd	0
 30293                                  
 30294                                  ;;;
 30295                                  ;;; 11/03/2015
 30296                                  %include 'kybdata.s'	; KEYBOARD (BIOS) DATA
 30297                              <1> ; Retro UNIX 386 v1 Kernel (v0.2.2.2) - KYBDATA.INC
 30298                              <1> ; Last Modification: 11/06/2022
 30299                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
 30300                              <1> ;
 30301                              <1> ; ///////// KEYBOARD DATA ///////////////
 30302                              <1> 
 30303                              <1> ; 11/03/2015
 30304                              <1> ; 05/12/2014
 30305                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
 30306                              <1> ; 03/06/86  KEYBOARD BIOS
 30307                              <1> 
 30308                              <1> ;---------------------------------------------------------------------------------
 30309                              <1> ;	KEY IDENTIFICATION SCAN TABLES
 30310                              <1> ;---------------------------------------------------------------------------------
 30311                              <1> 
 30312                              <1> ;-----	TABLES FOR ALT CASE ------------
 30313                              <1> ;-----	ALT-INPUT-TABLE 
 30314 00006044 524F50514B          <1> K30:	db	82,79,80,81,75
 30315 00006049 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
 30316                              <1> ;-----	SUPER-SHIFT-TABLE 
 30317 0000604E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
 30318 00006054 161718191E1F        <1> 	db	22,23,24,25,30,31
 30319 0000605A 202122232425        <1> 	db	32,33,34,35,36,37
 30320 00006060 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
 30321 00006066 3132                <1> 	db	49,50
 30322                              <1> 
 30323                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
 30324                              <1> ;-----	KEY_TABLE 
 30325 00006068 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
 30326 00006069 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
 30327 0000606E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
 30328                              <1> _K6L    equ     $-_K6
 30329                              <1> 
 30330                              <1> ;-----	MASK_TABLE
 30331 00006070 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
 30332 00006071 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
 30333 00006076 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
 30334                              <1> 
 30335                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
 30336 00006078 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
 30337 0000607E 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
 30338                              <1> 	;db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
 30339 00006084 FF7F94111705        <1> 	db	-1,127,148,17,23,5 ; 11/06/2022
 30340 0000608A 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
 30341 00006090 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
 30342 00006096 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
 30343 0000609C 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
 30344 000060A2 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
 30345 000060A8 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
 30346 000060AE 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
 30347                              <1> 	;				;----- FUNCTIONS ------		
 30348 000060B2 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
 30349 000060B8 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
 30350 000060BE 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
 30351 000060C4 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
 30352 000060CA 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
 30353                              <1> 
 30354                              <1> ;-----	TABLES FOR LOWER CASE ----------
 30355 000060D0 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
 30356 000060D9 39302D3D0809        <1>
 30357 000060DF 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
 30358 000060E8 705B5D0DFF61736466- <1>
 30359 000060F1 67686A6B6C3B27      <1>
 30360 000060F8 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
 30361 00006101 6D2C2E2FFF2AFF20FF  <1>
 30362                              <1> ;-----	LC TABLE SCAN
 30363 0000610A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
 30364 0000610F 4041424344          <1> 	db	64,65,66,67,68
 30365 00006114 FFFF                <1> 	db	-1,-1			; NL, SL
 30366                              <1> 
 30367                              <1> ;-----	KEYPAD TABLE
 30368 00006116 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
 30369 0000611C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
 30370 00006123 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
 30371                              <1> 
 30372                              <1> ;-----	TABLES FOR UPPER CASE ----------
 30373 00006128 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
 30374 00006131 28295F2B0800        <1>
 30375 00006137 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
 30376 00006140 507B7D0DFF41534446- <1>
 30377 00006149 47484A4B4C3A22      <1>
 30378 00006150 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
 30379 00006159 4D3C3E3FFF2AFF20FF  <1>
 30380                              <1> ;-----	UC TABLE SCAN
 30381 00006162 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
 30382 00006167 595A5B5C5D          <1> 	db	89,90,91,92,93
 30383 0000616C FFFF                <1> 	db	-1,-1			; NL, SL
 30384                              <1> 
 30385                              <1> ;-----	NUM STATE TABLE
 30386 0000616E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
 30387 00006177 3233302E            <1>
 30388                              <1> 	;
 30389 0000617B FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
 30390                              <1> 
 30391                              <1> Align	4
 30392                              <1> ;----------------------------------------
 30393                              <1> ;	VIDEO DISPLAY DATA AREA		;
 30394                              <1> ;----------------------------------------
 30395 00006180 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
 30396 00006181 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
 30397                              <1> 				; (29h default setting for video mode 3)
 30398                              <1> 				; Mode Select register Bits
 30399                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
 30400                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
 30401                              <1> 				;   BIT 2 - COLOR (0), BW (1)
 30402                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
 30403                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
 30404                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
 30405                              <1> 				;   BIT 6, 7 - Not Used
 30406                              <1> 
 30407                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
 30408                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
 30409                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
 30410                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
 30411                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
 30412                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
 30413                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
 30414                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
 30415                              <1> ; Mode & 37h = Video signal OFF
 30416                              <1> 			
 30417                              <1> 
 30418                              <1> ; 26/08/2014
 30419                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
 30420                              <1> ; Derived from IBM "pc-at" 
 30421                              <1> ; rombios source code (06/10/1985)
 30422                              <1> ; 'dseg.inc'
 30423                              <1> 
 30424                              <1> ;---------------------------------------;
 30425                              <1> ;	SYSTEM DATA AREA		;
 30426                              <1> ;----------------------------------------
 30427 00006182 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
 30428                              <1> 
 30429                              <1> ;----------------------------------------
 30430                              <1> ;	KEYBOARD DATA AREAS		;
 30431                              <1> ;----------------------------------------
 30432                              <1> 
 30433 00006183 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
 30434 00006184 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
 30435 00006185 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
 30436 00006186 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
 30437 00006187 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
 30438 00006188 [98610000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
 30439 0000618C [B8610000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
 30440 00006190 [98610000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
 30441 00006194 [98610000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
 30442                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
 30443 00006198 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
 30444                              <1> 
 30445                              <1> ; /// End Of KEYBOARD DATA ///
 30446                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
 30447                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.INC
 30448                              <1> ; Last Modification: 11/03/2015
 30449                              <1> ;		    (Data section for 'VIDEO.INC')	
 30450                              <1> ;
 30451                              <1> ; ///////// VIDEO DATA ///////////////
 30452                              <1> 
 30453                              <1> video_params:
 30454                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
 30455                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
 30456                              <1> 	; VIDEO MODE 3
 30457 000061B8 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
 30458 000061BF 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
 30459 000061C4 00000000            <1> 	db	0,0,0,0
 30460                              <1> 
 30461                              <1> ; /// End Of VIDEO DATA ///
 30462                                  %include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
 30463                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKBSS.INC
 30464                              <1> ; Last Modification: 12/07/2022 
 30465                              <1> ; *****************************************************************************
 30466                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
 30467                              <1> ; *****************************************************************************
 30468                              <1> ; Ref: Retro UNIX 386 v1 Kernel (v0.2.1.5) - DISKDATA.INC - 11/07/2022
 30469                              <1> 
 30470                              <1> ;----------------------------------------
 30471                              <1> ;	80286 INTERRUPT LOCATIONS	:
 30472                              <1> ;	REFERENCED BY POST & BIOS	:
 30473                              <1> ;----------------------------------------
 30474                              <1> 
 30475 000061C8 [2B620000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
 30476                              <1> 
 30477                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
 30478                              <1> ;----------------------------------------------------------------
 30479                              <1> ; DISK_BASE							:
 30480                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
 30481                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
 30482                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
 30483                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
 30484                              <1> ;----------------------------------------------------------------
 30485                              <1> 
 30486                              <1> ;DISK_BASE:	
 30487                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30488                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30489                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30490                              <1> ;	DB	2		; 512 BYTES/SECTOR
 30491                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
 30492                              <1> ;	db	18		; (EOT for 1.44MB diskette)
 30493                              <1> ;	DB	01BH		; GAP LENGTH
 30494                              <1> ;	DB	0FFH		; DTL
 30495                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
 30496                              <1> ;	db	06ch		; (for 1.44MB dsikette)
 30497                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
 30498                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30499                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30500                              <1> 
 30501                              <1> ;----------------------------------------
 30502                              <1> ;	ROM BIOS DATA AREAS		:
 30503                              <1> ;----------------------------------------
 30504                              <1> 
 30505                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 30506                              <1> 
 30507                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
 30508                              <1> 
 30509                              <1> ;----------------------------------------
 30510                              <1> ;	DISKETTE DATA AREAS		:
 30511                              <1> ;----------------------------------------
 30512                              <1> 
 30513                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
 30514                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
 30515                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
 30516                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
 30517                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
 30518                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
 30519                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
 30520                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
 30521                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
 30522                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
 30523                              <1> 
 30524                              <1> ;----------------------------------------
 30525                              <1> ;	POST AND BIOS WORK DATA AREA	:
 30526                              <1> ;----------------------------------------
 30527                              <1> 
 30528                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
 30529                              <1> 
 30530                              <1> ;----------------------------------------
 30531                              <1> ;	TIMER DATA AREA 		:
 30532                              <1> ;----------------------------------------
 30533                              <1> 
 30534                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
 30535                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
 30536                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
 30537                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
 30538                              <1> 
 30539                              <1> ;----------------------------------------
 30540                              <1> ;	ADDITIONAL MEDIA DATA		:
 30541                              <1> ;----------------------------------------
 30542                              <1> 
 30543                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 30544                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 30545                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 30546                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 30547                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 30548                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 30549                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 30550                              <1> 
 30551                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 30552                              <1> 
 30553                              <1> ;--------------------------------------------------------
 30554                              <1> ;	DRIVE TYPE TABLE				:
 30555                              <1> ;--------------------------------------------------------
 30556                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
 30557                              <1> DR_TYPE:
 30558 000061CC 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
 30559                              <1>                 ;DW	MD_TBL1
 30560 000061CD [EA610000]          <1> 		dd	MD_TBL1
 30561 000061D1 82                  <1> 		DB	02+BIT7ON
 30562                              <1> 		;DW	MD_TBL2
 30563 000061D2 [F7610000]          <1>                 dd      MD_TBL2
 30564 000061D6 02                  <1> DR_DEFAULT:	DB	02
 30565                              <1>                 ;DW	MD_TBL3
 30566 000061D7 [04620000]          <1> 		dd      MD_TBL3
 30567 000061DB 03                  <1> 		DB	03
 30568                              <1>                 ;DW	MD_TBL4
 30569 000061DC [11620000]          <1> 		dd      MD_TBL4
 30570 000061E0 84                  <1> 		DB	04+BIT7ON
 30571                              <1>                 ;DW	MD_TBL5
 30572 000061E1 [1E620000]          <1> 		dd      MD_TBL5
 30573 000061E5 04                  <1> 		DB	04
 30574                              <1>                 ;DW	MD_TBL6
 30575 000061E6 [2B620000]          <1> 		dd      MD_TBL6
 30576                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
 30577                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
 30578                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
 30579                              <1> ;--------------------------------------------------------
 30580                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
 30581                              <1> ;--------------------------------------------------------
 30582                              <1> ;--------------------------------------------------------
 30583                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
 30584                              <1> ;--------------------------------------------------------
 30585                              <1> MD_TBL1:        
 30586 000061EA DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30587 000061EB 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30588 000061EC 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30589 000061ED 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30590 000061EE 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30591 000061EF 2A                  <1> 	DB	02AH		; GAP LENGTH
 30592 000061F0 FF                  <1> 	DB	0FFH		; DTL
 30593 000061F1 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30594 000061F2 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30595 000061F3 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30596 000061F4 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30597 000061F5 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 30598 000061F6 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 30599                              <1> ;--------------------------------------------------------
 30600                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
 30601                              <1> ;--------------------------------------------------------
 30602                              <1> MD_TBL2:        
 30603 000061F7 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30604 000061F8 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30605 000061F9 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30606 000061FA 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30607 000061FB 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30608 000061FC 2A                  <1> 	DB	02AH		; GAP LENGTH
 30609 000061FD FF                  <1> 	DB	0FFH		; DTL
 30610 000061FE 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30611 000061FF F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30612 00006200 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30613 00006201 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30614 00006202 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 30615 00006203 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
 30616                              <1> ;--------------------------------------------------------
 30617                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
 30618                              <1> ;--------------------------------------------------------
 30619                              <1> MD_TBL3:
 30620 00006204 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30621 00006205 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30622 00006206 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30623 00006207 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30624 00006208 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
 30625 00006209 1B                  <1> 	DB	01BH		; GAP LENGTH
 30626 0000620A FF                  <1> 	DB	0FFH		; DTL
 30627 0000620B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
 30628 0000620C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30629 0000620D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30630 0000620E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30631 0000620F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30632 00006210 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 30633                              <1> ;--------------------------------------------------------
 30634                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
 30635                              <1> ;--------------------------------------------------------
 30636                              <1> MD_TBL4:
 30637 00006211 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30638 00006212 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30639 00006213 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30640 00006214 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30641 00006215 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30642 00006216 2A                  <1> 	DB	02AH		; GAP LENGTH
 30643 00006217 FF                  <1> 	DB	0FFH		; DTL
 30644 00006218 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30645 00006219 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30646 0000621A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30647 0000621B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30648 0000621C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30649 0000621D 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 30650                              <1> ;--------------------------------------------------------
 30651                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
 30652                              <1> ;--------------------------------------------------------
 30653                              <1> MD_TBL5:
 30654 0000621E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30655 0000621F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30656 00006220 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30657 00006221 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30658 00006222 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 30659 00006223 2A                  <1> 	DB	02AH		; GAP LENGTH
 30660 00006224 FF                  <1> 	DB	0FFH		; DTL
 30661 00006225 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 30662 00006226 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30663 00006227 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30664 00006228 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30665 00006229 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30666 0000622A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 30667                              <1> ;--------------------------------------------------------
 30668                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
 30669                              <1> ;--------------------------------------------------------
 30670                              <1> MD_TBL6:
 30671 0000622B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
 30672 0000622C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 30673 0000622D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 30674 0000622E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 30675 0000622F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
 30676 00006230 1B                  <1> 	DB	01BH		; GAP LENGTH
 30677 00006231 FF                  <1> 	DB	0FFH		; DTL
 30678 00006232 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
 30679 00006233 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 30680 00006234 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 30681 00006235 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 30682 00006236 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 30683 00006237 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 30684                              <1> 
 30685                              <1> 
 30686                              <1> ; << diskette.inc >>
 30687                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 30688                              <1> ;
 30689                              <1> ;----------------------------------------
 30690                              <1> ;	ROM BIOS DATA AREAS		:
 30691                              <1> ;----------------------------------------
 30692                              <1> 
 30693                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 30694                              <1> 
 30695                              <1> ;----------------------------------------
 30696                              <1> ;	FIXED DISK DATA AREAS		:
 30697                              <1> ;----------------------------------------
 30698                              <1> 
 30699                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
 30700                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
 30701                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
 30702                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
 30703                              <1> 
 30704                              <1> ;----------------------------------------
 30705                              <1> ;	ADDITIONAL MEDIA DATA		:
 30706                              <1> ;----------------------------------------
 30707                              <1> 
 30708                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 30709                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
 30710                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
 30711                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
 30712                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
 30713                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 30714                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 30715                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 30716                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 30717                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 30718                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 30719                              <1> 
 30720                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 30721                              <1> ;
 30722                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 30723                              <1> 
 30724                              <1> ERR_TBL:
 30725 00006238 E0                  <1> 	db	NO_ERR
 30726 00006239 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
 30727 0000623D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
 30728                              <1> 
 30729                              <1> ; 11/07/2022
 30730                              <1> ; 17/12/2014 (mov ax, [cfd])
 30731                              <1> ; 11/12/2014
 30732                              <1> ;cfd:		db 0			; current floppy drive (for GET_PARM)
 30733                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
 30734                              <1> ;pfd:		db 1			; previous floppy drive (for GET_PARM)
 30735                              <1> 					; (initial value of 'pfd 
 30736                              <1> 					; must be different then 'cfd' value
 30737                              <1> 					; to force updating/initializing
 30738                              <1> 					; current drive parameters) 
 30739                              <1> 
 30740                              <1> ;; 11/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 30741 00006241 FF                  <1> pfd:		db 0FFh
 30742                              <1> 
 30743                              <1> align 2
 30744                              <1> 
 30745 00006242 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
 30746                              <1> 			      ; (170h)
 30747 00006244 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
 30748                              <1> 
 30749                              <1> ; 05/01/2015 
 30750 00006246 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
 30751                              <1> 
 30752                              <1> ; *****************************************************************************
 30753                                  ;;;
 30754                                  
 30755 00006247 90                      align 2
 30756                                  
 30757                                  ; 12/11/2014 (Retro UNIX 386 v1)
 30758 00006248 00                      boot_drv:    db 0  ; boot drive number (physical)
 30759                                  ; 24/11/2014
 30760 00006249 00                      drv:	     db 0 
 30761 0000624A 00                      last_drv:    db 0  ; last hdd
 30762 0000624B 00                      hdc:         db 0  ; number of hard disk drives
 30763                                  		     ; (present/detected)
 30764                                  ;
 30765                                  ; 24/11/2014 (Retro UNIX 386 v1)
 30766                                  ; Physical drive type & flags
 30767 0000624C 00                      fd0_type:    db 0  ; floppy drive type
 30768 0000624D 00                      fd1_type:    db 0    ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
 30769                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
 30770                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
 30771                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
 30772                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
 30773 0000624E 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 - present flag)
 30774 0000624F 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 - present flag)
 30775 00006250 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 - present flag)
 30776 00006251 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 - present flag)
 30777                                  		     ; bit 0 - Fixed disk access subset supported
 30778                                  		     ; bit 1 - Drive locking and ejecting
 30779                                  		     ; bit 2 - Enhanced disk drive support
 30780                                  		     ; bit 3 - Reserved (64 bit EDD support)
 30781                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
 30782                                  		     ; will interpret it as 'LBA ready'!)		
 30783                                  
 30784                                  ; 12/07/2022
 30785                                  ; (drv.cylinders, drv.spt, drv.spt will not be used now on)
 30786                                  ; ('diskio.inc')
 30787                                  ; ((spt and heads and cylinder counts will be taken from DPT))
 30788                                  
 30789                                  ; 11/03/2015 - 10/07/2015
 30790                                  ;drv.cylinders: dw 0,0,0,0,0,0,0
 30791                                  ;drv.heads:     dw 0,0,0,0,0,0,0
 30792                                  ;drv.spt:       dw 0,0,0,0,0,0,0
 30793                                  ; 12/07/2022 - 11/03/2015
 30794 00006252 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
 30795 0000625B 000000000000000000-
 30796 00006264 000000000000000000-
 30797 0000626D 00                 
 30798 0000626E 00000000000000          drv.status:    db 0,0,0,0,0,0,0
 30799 00006275 00000000000000          drv.error:     db 0,0,0,0,0,0,0
 30800                                  ;
 30801                                  
 30802                                  ; 27/08/2014
 30803                                  scr_row:
 30804 0000627C E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
 30805                                  scr_col:
 30806 00006280 00000000                	dd 0
 30807                                  
 30808                                  ;; 14/08/2015
 30809                                  ;;msgPM:
 30810                                  ;;      db "Protected mode and paging are ENABLED ... ", 0
 30811                                  msgKVER:
 30812                                  	;;;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.0 [18/04/2022]", 0
 30813                                  	;;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.1 [08/06/2022]", 0
 30814                                  	;db "Retro UNIX 386 v1.2 - Kernel v0.2.2.2 [14/06/2022]", 0
 30815 00006284 526574726F20554E49-     	db "Retro UNIX 386 v1.2 - Kernel v0.2.2.3 [08/08/2022]", 0
 30816 0000628D 58203338362076312E-
 30817 00006296 32202D204B65726E65-
 30818 0000629F 6C2076302E322E322E-
 30819 000062A8 33205B30382F30382F-
 30820 000062B1 323032325D00       
 30821                                  
 30822 000062B7 90                      align 2
 30823                                  
 30824                                  ; 20/08/2014
 30825                                    ; /* This is the default interrupt "handler" :-) */ 
 30826                                    ; Linux v0.12 (head.s)
 30827                                  int_msg:
 30828 000062B8 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
 30829 000062C1 6E7465727275707420-
 30830 000062CA 212000             
 30831                                  
 30832 000062CD 90                      align 2  
 30833                                  
 30834                                  ; 21/08/2014
 30835                                  timer_msg:
 30836 000062CE 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
 30837 000062D7 542032306829202120-
 30838 000062E0 54696D657220496E74-
 30839 000062E9 657272757074203A20 
 30840                                  tcountstr:
 30841 000062F2 303030303020            	db "00000 "
 30842 000062F8 00                      	db 0
 30843                                  
 30844 000062F9 90                      align 2
 30845                                  	; 21/08/2014
 30846                                  exc_msg:
 30847 000062FA 435055206578636570-     	db "CPU exception ! "
 30848 00006303 74696F6E202120     
 30849                                  excnstr: 		; 25/08/2014
 30850 0000630A 3F3F68202045495020-     	db "??h", "  EIP : "
 30851 00006313 3A20               
 30852                                  EIPstr: ; 29/08/2014
 30853 00006315 00<rept>                	times 12 db 0
 30854                                  rtc_msg:
 30855 00006321 5265616C2054696D65-     	db "Real Time Clock - "
 30856 0000632A 20436C6F636B202D20 
 30857                                  datestr:
 30858 00006333 30302F30302F303030-     	db "00/00/0000"
 30859 0000633C 30                 
 30860 0000633D 20                      	db " "
 30861                                  daystr:
 30862 0000633E 44415920                	db "DAY "
 30863                                  timestr:	
 30864 00006342 30303A30303A3030                db "00:00:00"
 30865 0000634A 20                      	db " "
 30866 0000634B 00                      	db 0 
 30867                                  
 30868                                  daytmp:
 30869                                  	; 28/02/2015
 30870 0000634C 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
 30871 00006355 4F4E20545545205745-
 30872 0000635E 442054485520465249-
 30873 00006367 2053415420         
 30874                                  
 30875 0000636C FF                      ptime_seconds: db 0FFh
 30876                                  
 30877                                  	; 23/02/2015
 30878                                  	; 25/08/2014
 30879                                  ;scounter:
 30880                                  ;	db 5
 30881                                  ;	db 19
 30882                                  
 30883                                  ; 28/11/2021
 30884                                  ;; 05/11/2014
 30885                                  ;msg_out_of_memory:
 30886                                  ;	db 	07h, 0Dh, 0Ah
 30887                                  ;	db	'Insufficient memory ! (Minimum 2 MB memory is needed.)'
 30888                                  ; 	db	0Dh, 0Ah, 0
 30889                                  	;
 30890                                  setup_error_msg:
 30891 0000636D 0D0A                    	db 0Dh, 0Ah
 30892 0000636F 4469736B2053657475-     	db 'Disk Setup Error!' 
 30893 00006378 70204572726F7221   
 30894 00006380 0D0A00                  	db 0Dh, 0Ah,0
 30895                                  
 30896                                  ; 02/09/2014 (Retro UNIX 386 v1)
 30897                                  ;crt_ulc: db 0 ; upper left column (for scroll) 
 30898                                  ;	  db 0 ; upper left row (for scroll)	
 30899                                  
 30900                                  ;crt_lrc: db 79 ; lower right column (for scroll) 
 30901                                  ;	  db 24 ; lower right row (for scroll)
 30902                                  
 30903                                  ; 06/11/2014 (Temporary Data)
 30904                                  ; Memory Information message
 30905                                  ; 14/08/2015
 30906                                  msg_memory_info:
 30907 00006383 07                      	db	07h
 30908 00006384 0D0A                    	db	0Dh, 0Ah
 30909                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
 30910 00006386 546F74616C206D656D-     	db	"Total memory : "
 30911 0000638F 6F7279203A20       
 30912                                  mem_total_b_str: ; 10 digits
 30913 00006395 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
 30914 0000639E 302062797465730D0A 
 30915 000063A7 202020202020202020-     	db	"               ", 20h, 20h, 20h
 30916 000063B0 202020202020202020 
 30917                                  mem_total_p_str: ; 7 digits
 30918 000063B9 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
 30919 000063C2 616765730D0A       
 30920 000063C8 0D0A                    	db 	0Dh, 0Ah
 30921 000063CA 46726565206D656D6F-     	db	"Free memory  : "
 30922 000063D3 727920203A20       
 30923                                  free_mem_b_str:  ; 10 digits
 30924 000063D9 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
 30925 000063E2 3F2062797465730D0A 
 30926 000063EB 202020202020202020-     	db	"               ", 20h, 20h, 20h
 30927 000063F4 202020202020202020 
 30928                                  free_mem_p_str:  ; 7 digits
 30929 000063FD 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
 30930 00006406 616765730D0A       
 30931 0000640C 0D0A00                  	db	0Dh, 0Ah, 0
 30932                                  
 30933                                  dsk_ready_msg:
 30934 0000640F 0D0A                    	db 	0Dh, 0Ah
 30935                                  dsktype:
 30936 00006411 6664                    	db	'fd'
 30937                                  dskx:
 30938 00006413 30                      	db	'0'
 30939 00006414 20                      	db	20h
 30940 00006415 697320524541445920-     	db 	'is READY ...'
 30941 0000641E 2E2E2E             
 30942 00006421 00                      	db 	0
 30943                                  nextline:
 30944 00006422 0D0A00                  	db 	0Dh, 0Ah, 0
 30945                                  
 30946                                  ; KERNEL - SYSINIT Messages
 30947                                  ; 24/08/2015
 30948                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
 30949                                  ; 14/07/2013
 30950                                  ;kernel_init_err_msg:
 30951                                  ;	db 0Dh, 0Ah
 30952                                  ;	db 07h
 30953                                  ;	db 'Kernel initialization ERROR !'
 30954                                  ;	db 0Dh, 0Ah, 0 
 30955                                  ; 24/08/2015
 30956                                  ;;; (temporary kernel init message has been removed
 30957                                  ;;;  from 'sys_init' code)
 30958                                  ;kernel_init_ok_msg: 
 30959                                  ;	db 0Dh, 0Ah
 30960                                  ;	db 07h
 30961                                  ;	db 'Welcome to Retro UNIX 386 v1.1 Operating System !'
 30962                                  ;	db 0Dh, 0Ah
 30963                                  ;       db 'by Erdogan Tan - 04/02/2016 (v0.2.1.0)'
 30964                                  ;	db 0Dh, 0Ah, 0
 30965                                  panic_msg:
 30966 00006425 0D0A07                  	db 0Dh, 0Ah, 07h
 30967 00006428 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
 30968 00006431 726E656C2050616E69-
 30969 0000643A 632021             
 30970 0000643D 0D0A00                  	db 0Dh, 0Ah, 0
 30971                                  etc_init_err_msg:
 30972 00006440 0D0A                    	db 0Dh, 0Ah
 30973 00006442 07                      	db 07h
 30974 00006443 4552524F523A202F65-     	db 'ERROR: /etc/init !?'
 30975 0000644C 74632F696E69742021-
 30976 00006455 3F                 
 30977 00006456 0D0A00                  	db 0Dh, 0Ah, 0
 30978                                  
 30979                                  ; 10/05/2015
 30980                                  badsys_msg:
 30981 00006459 0D0A                    	db 0Dh, 0Ah
 30982 0000645B 07                      	db 07h
 30983 0000645C 496E76616C69642053-     	db 'Invalid System Call !'
 30984 00006465 797374656D2043616C-
 30985 0000646E 6C2021             
 30986 00006471 0D0A                    	db 0Dh, 0Ah
 30987 00006473 4541583A20              	db 'EAX: '
 30988                                  bsys_msg_eax:
 30989 00006478 303030303030303068      	db '00000000h'
 30990 00006481 0D0A                    	db 0Dh, 0Ah
 30991 00006483 4549503A20              	db 'EIP: '
 30992                                  bsys_msg_eip:
 30993 00006488 303030303030303068      	db '00000000h' 
 30994 00006491 0D0A00                  	db 0Dh, 0Ah, 0
 30995                                  
 30996                                  BSYS_M_SIZE equ $ - badsys_msg
 30997                                  
 30998                                  align 2
 30999                                  
 31000                                  ; EPOCH Variables
 31001                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
 31002                                  ; 09/04/2013 epoch variables
 31003                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
 31004                                  ;
 31005 00006494 B207                    year: 	dw 1970
 31006                                  ;month: dw 1
 31007                                  ;day: 	dw 1
 31008                                  ;hour: 	dw 0
 31009                                  ;minute: dw 0
 31010                                  ;second: dw 0
 31011                                  ; 02/06/2022
 31012 00006496 01                      month:	db 1
 31013 00006497 01                      day:	db 1
 31014 00006498 01                      hour:	db 1
 31015 00006499 01                      minute: db 1
 31016 0000649A 01                      second:	db 1
 31017 0000649B 01                      	db 1
 31018                                  
 31019                                  DMonth:
 31020 0000649C 0000                    	dw 0
 31021 0000649E 1F00                    	dw 31
 31022 000064A0 3B00                    	dw 59
 31023 000064A2 5A00                    	dw 90
 31024 000064A4 7800                    	dw 120
 31025 000064A6 9700                    	dw 151
 31026 000064A8 B500                    	dw 181
 31027 000064AA D400                    	dw 212
 31028 000064AC F300                    	dw 243
 31029 000064AE 1101                    	dw 273
 31030 000064B0 3001                    	dw 304
 31031 000064B2 4E01                    	dw 334
 31032                                  
 31033                                  ; 02/01/2022 (Retro UNIX 386 v1.2)
 31034                                  ; 04/11/2014 (Retro UNIX 386 v1)
 31035 000064B4 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
 31036                                  		   ;   1 and 16 MB, max. 3C00h = 15 MB.
 31037 000064B6 0000                    	     dw 0  ; 02/01/2022 (Retro UNIX 386 v1.2)
 31038 000064B8 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
 31039                                  		   ;   between 16 MB and 4 GB.
 31040 000064BA 0000                    	     dw 0  ; 02/01/2022 (Retro UNIX 386 v1.2)
 31041                                  
 31042                                  ; 01/01/2022
 31043                                  KEND:
 31044                                  
 31045 000064BC 90<rept>                align 16
 31046                                  
 31047                                  bss_start:
 31048                                  
 31049                                  ABSOLUTE bss_start
 31050                                  
 31051                                  	; 11/03/2015
 31052                                  	; Interrupt Descriptor Table (20/08/2014)
 31053                                  idt:
 31054 000064C0 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
 31055                                  idt_end:
 31056                                  
 31057                                  ;alignb 4
 31058                                  
 31059                                  task_state_segment:
 31060                                  	; 24/03/2015
 31061 000066C0 <res 00000002>          tss.link:   resw 1
 31062 000066C2 <res 00000002>          	    resw 1
 31063                                  ; tss offset 4	
 31064 000066C4 <res 00000004>          tss.esp0:   resd 1
 31065 000066C8 <res 00000002>          tss.ss0:    resw 1
 31066 000066CA <res 00000002>          	    resw 1	
 31067 000066CC <res 00000004>          tss.esp1:   resd 1
 31068 000066D0 <res 00000002>          tss.ss1:    resw 1
 31069 000066D2 <res 00000002>          	    resw 1 	
 31070 000066D4 <res 00000004>          tss.esp2:   resd 1
 31071 000066D8 <res 00000002>          tss.ss2:    resw 1
 31072 000066DA <res 00000002>          	    resw 1
 31073                                  ; tss offset 28
 31074 000066DC <res 00000004>          tss.CR3:    resd 1
 31075 000066E0 <res 00000004>          tss.eip:    resd 1
 31076 000066E4 <res 00000004>          tss.eflags: resd 1
 31077                                  ; tss offset 40
 31078 000066E8 <res 00000004>          tss.eax:    resd 1		 		
 31079 000066EC <res 00000004>          tss.ecx:    resd 1
 31080 000066F0 <res 00000004>          tss.edx:    resd 1
 31081 000066F4 <res 00000004>          tss.ebx:    resd 1
 31082 000066F8 <res 00000004>          tss.esp:    resd 1
 31083 000066FC <res 00000004>          tss.ebp:    resd 1
 31084 00006700 <res 00000004>          tss.esi:    resd 1
 31085 00006704 <res 00000004>          tss.edi:    resd 1
 31086                                  ; tss offset 72
 31087 00006708 <res 00000002>          tss.ES:     resw 1
 31088 0000670A <res 00000002>          	    resw 1	
 31089 0000670C <res 00000002>          tss.CS:	    resw 1
 31090 0000670E <res 00000002>          	    resw 1
 31091 00006710 <res 00000002>          tss.SS:	    resw 1
 31092 00006712 <res 00000002>          	    resw 1
 31093 00006714 <res 00000002>          tss.DS:	    resw 1
 31094 00006716 <res 00000002>          	    resw 1
 31095 00006718 <res 00000002>          tss.FS:	    resw 1
 31096 0000671A <res 00000002>          	    resw 1
 31097 0000671C <res 00000002>          tss.GS:	    resw 1
 31098 0000671E <res 00000002>          	    resw 1		
 31099 00006720 <res 00000002>          tss.LDTR:   resw 1
 31100 00006722 <res 00000002>          	    resw 1
 31101                                  ; tss offset 100		
 31102 00006724 <res 00000002>          	    resw 1		
 31103 00006726 <res 00000002>          tss.IOPB:   resw 1
 31104                                  ; tss offset 104 
 31105                                  tss_end:
 31106                                  
 31107 00006728 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
 31108                                  		    ;  (Physical address = Virtual address)	 	
 31109 0000672C <res 00000004>          memory_size: resd 1 ; memory size in pages
 31110 00006730 <res 00000004>          free_pages:  resd 1 ; number of free pages		
 31111 00006734 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
 31112                                  		    ;   first free page search
 31113 00006738 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
 31114                                  		    ;   next free page search will be
 31115                                  		    ;   stopped after it. (end of M.A.T.)
 31116 0000673C <res 00000004>          first_page:  resd 1 ;   offset value in M.A.T. which
 31117                                  		    ; first free page search
 31118                                  		    ;   will be started on it. (for user)
 31119 00006740 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
 31120                                  
 31121                                  ;;;
 31122                                  ; 02/09/2014 (Retro UNIX 386 v1)
 31123                                  ; 04/12/2013 (Retro UNIX 8086 v1)
 31124 00006744 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
 31125                                  			  ; NOTE: active page only
 31126 00006746 <res 00000010>          cursor_posn: resw 8 	  ; cursor positions for video pages
 31127                                  active_page: 
 31128 00006756 <res 00000001>          ptty: 	     resb 1 	  ; current tty
 31129                                  ; 01/07/2015
 31130 00006757 <res 00000001>          ccolor:	     resb 1	  ; current color attributes ('sysmsg')	
 31131                                  ; 26/10/2015
 31132                                  ; 07/09/2014
 31133 00006758 <res 00000014>          ttychr:      resw ntty+2  ; Character buffer (multiscreen)
 31134                                  
 31135                                  ; 21/08/2014
 31136 0000676C <res 00000004>          tcount:	     resd 1
 31137                                  
 31138                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
 31139 00006770 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
 31140                                  
 31141                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
 31142                                  ; (open mode locks for pseudo TTYs)
 31143                                  ; [ major tty locks (return error in any conflicts) ]
 31144 00006774 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
 31145                                  
 31146                                  ; 15/04/2015 (Retro UNIX 386 v1)
 31147                                  ; 22/09/2013 (Retro UNIX 8086 v1)
 31148 00006788 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
 31149                                  ; 15/04/2015 (Retro UNIX 386 v1)
 31150                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
 31151                                  ;; 0 means serial port is not available 
 31152                                  ;;comprm: ; 25/06/2014
 31153 00006792 <res 00000001>          com1p:       resb 1  ;;0E3h
 31154 00006793 <res 00000001>          com2p:       resb 1  ;;0E3h
 31155                                  
 31156                                  ; 17/11/2015
 31157                                  ; request for response (from the terminal)	
 31158 00006794 <res 00000002>          req_resp:    resw 1 			
 31159                                  ; 07/11/2015
 31160 00006796 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
 31161                                  		    ; (0= COM1, 1= COM2)
 31162                                  ; 09/11/2015
 31163 00006797 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
 31164                                  ; 07/11/2015
 31165 00006798 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
 31166 0000679A <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
 31167                                  
 31168                                  ; 23/10/2015
 31169                                  ; SERIAL PORTS - COMMUNICATION MODES
 31170                                  ; (Retro UNIX 386 v1 feature only!)
 31171                                  ; 0 - command mode (default/initial mode)
 31172                                  ; 1 - terminal mode (Retro UNIX 386 v1 terminal, ascii chars)
 31173                                  ;;; communication modes for future versions:  
 31174                                  ; // 2 - keyboard mode (ascii+scancode input)
 31175                                  ; // 3 - mouse mode
 31176                                  ; // 4 - device control (output) mode
 31177                                  ; VALID COMMANDS for current version:
 31178                                  ; 	'LOGIN'
 31179                                  ;  Login request: db 0FFh, 'LOGIN', 0 
 31180                                  ;	 ("Retro UNIX 386 v1 terminal requests login")
 31181                                  ;  Login response: db 0FFh, 'login', 0
 31182                                  ;	 ("login request accepted, wait for login prompt") 
 31183                                  ; When a login requests is received and acknowledged (by
 31184                                  ; serial port interrupt handler (communication procedure),
 31185                                  ; Retro UNIX 386 v1 operating system will start terminal mode
 31186                                  ; (login procedure) by changing comm. mode to 1 (terminal mode)
 31187                                  ; and then running 'etc/getty' for tty8 (COM1) or tty9 (COM2)
 31188                                  ; 
 31189                                  ; 'sys connect' system call is used to change communication mode
 31190                                  ; except 'LOGIN' command which is used to start terminal mode
 31191                                  ; by using (COM port) terminal.
 31192                                  
 31193                                  ;com1own:     resb 1 ; COM1 owner (u.uno)
 31194                                  ;com2own:     resb 1 ; COM2 owner (u.uno)
 31195                                  ;com1mode:    resb 1 ; communication mode for COM1
 31196                                  ;com1com:     resb 1 ; communication command for COM1
 31197                                  ;com2mode:    resb 1 ; communication mode for COM1
 31198                                  ;com2com      resb 1 ; communication command for COM1
 31199                                  ;com1cbufp:   resb 8 ; COM1 command buffer char pointer	
 31200                                  ;com2cbufp:   resb 8 ; COM2 command buffer char pointer	
 31201                                  ;com1cbuf:    resb 8 ; COM2 command buffer
 31202                                  ;com2cbuf:    resb 8 ; COM2 command buffer
 31203                                  
 31204                                  ; 22/08/2014 (RTC)
 31205                                  ; (Packed BCD)
 31206 0000679C <res 00000001>          time_seconds: resb 1
 31207 0000679D <res 00000001>          time_minutes: resb 1
 31208 0000679E <res 00000001>          time_hours:   resb 1
 31209 0000679F <res 00000001>          date_wday:    resb 1
 31210 000067A0 <res 00000001>          date_day:     resb 1
 31211 000067A1 <res 00000001>          date_month:   resb 1			
 31212 000067A2 <res 00000001>          date_year:    resb 1
 31213 000067A3 <res 00000001>          date_century: resb 1
 31214                                  
 31215                                  %include 'diskbss.s' ; UNINITIALIZED DISK (BIOS) DATA
 31216                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - DISKBSS.INC
 31217                              <1> ; Last Modification: 12/07/2022 
 31218                              <1> ; *****************************************************************************
 31219                              <1> ;	(Uninitialized Disk Parameters Data section for 'DISKIO.INC')
 31220                              <1> ; *****************************************************************************
 31221                              <1> ; Ref: Retro UNIX 386 v1 Kernel (v0.2.1.5) - DISKBSS.INC - 10/07/2022
 31222                              <1>  
 31223                              <1> 
 31224                              <1> alignb 2
 31225                              <1> 
 31226                              <1> ;----------------------------------------
 31227                              <1> ;	TIMER DATA AREA 		:
 31228                              <1> ;----------------------------------------
 31229                              <1> 
 31230                              <1> TIMER_LH:	; 16/02/2015
 31231 000067A4 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
 31232 000067A6 <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
 31233 000067A8 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
 31234                              <1> 
 31235                              <1> ;----------------------------------------
 31236                              <1> ;	DISKETTE DATA AREAS		:
 31237                              <1> ;----------------------------------------
 31238                              <1> 
 31239 000067A9 <res 00000001>      <1> SEEK_STATUS:	resb	1
 31240 000067AA <res 00000001>      <1> MOTOR_STATUS:	resb	1
 31241 000067AB <res 00000001>      <1> MOTOR_COUNT:	resb	1
 31242 000067AC <res 00000001>      <1> DSKETTE_STATUS:	resb	1
 31243 000067AD <res 00000007>      <1> NEC_STATUS:	resb	7
 31244                              <1> 
 31245                              <1> ;----------------------------------------
 31246                              <1> ;	ADDITIONAL MEDIA DATA		:
 31247                              <1> ;----------------------------------------
 31248                              <1> 
 31249 000067B4 <res 00000001>      <1> LASTRATE:	resb 	1
 31250 000067B5 <res 00000001>      <1> HF_STATUS:	resb 	1
 31251                              <1> ;HF_ERROR:	resb 	1  ; 10/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)	
 31252 000067B6 <res 00000001>      <1> HF_INT_FLAG:	resb	1
 31253                              <1> ;HF_CNTRL:	resb 	1  ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 31254                              <1> ;DSK_STATE:	resb 	4
 31255 000067B7 <res 00000002>      <1> DSK_STATE:	resb 	2  ; 08/07/2022 - Retro UNIX 386 v1.1 (Kernel v0.2.1.5)
 31256 000067B9 <res 00000002>      <1> DSK_TRK:	resb 	2
 31257                              <1> 
 31258                              <1> ;----------------------------------------
 31259                              <1> ;	FIXED DISK DATA AREAS		:
 31260                              <1> ;----------------------------------------
 31261                              <1> 
 31262 000067BB <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
 31263 000067BC <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
 31264 000067BD <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
 31265                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
 31266                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
 31267                              <1> ;port2_off	resb	1		; Hard disk controller 2 - port offset
 31268                              <1> 
 31269 000067BE <res 00000002>      <1> alignb 4
 31270                              <1> 
 31271                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 31272                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 31273                              <1> HF_TBL_VEC: ; 22/12/2014	
 31274 000067C0 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 31275 000067C4 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 31276 000067C8 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
 31277 000067CC <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
 31278                              <1> 
 31279                              <1> ; 03/01/2015
 31280 000067D0 <res 00000001>      <1> LBAMode:     	resb	1
 31281                              <1> 
 31282                              <1> ; *****************************************************************************
 31283                                  
 31284                                  ;;; Real Mode Data (10/07/2015 - BSS)
 31285                                  
 31286                                  ;alignb 2
 31287                                  
 31288                                  ; 02/01/2022
 31289                                  ;%include 'ux.s' ; 12/04/2015 (unix system/user/process data)
 31290                                  
 31291                                  ; 17/04/2021
 31292                                  ; (memory page swap parameters are disabled as temporary)
 31293                                  ;
 31294                                  ;; Memory (swap) Data (11/03/2015)
 31295                                  ; 09/03/2015
 31296                                  ;swpq_count: resw 1 ; count of pages on the swap que
 31297                                  ;swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
 31298                                  ;swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes).	
 31299                                  ;swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 31300                                  ;swpd_next:  resd 1 ; next free page block
 31301                                  ;swpd_last:  resd 1 ; last swap page block	
 31302                                  
 31303 000067D1 <res 00000003>          alignb 4
 31304                                  
 31305                                  ; 10/07/2015
 31306                                  ; 28/08/2014
 31307 000067D4 <res 00000004>          error_code:  resd 1
 31308                                  ; 29/08/2014
 31309 000067D8 <res 00000004>          FaultOffset: resd 1
 31310                                  ; 21/09/2015
 31311 000067DC <res 00000004>          PF_Count:    resd 1 ; total page fault count
 31312                                  		    ; (for debugging - page fault analyze)
 31313                                  		    ; 'page _fault_handler' (memory.s)
 31314                                  		    ; 'sysgeterr' (u9.s)
 31315                                  ; 23/02/2022
 31316 000067E0 <res 00000004>          rtc_ticks:  resd 1  ; (temporary! this rtc counter value may be used 
 31317                                  		    ;  for a system call in next retro unix 386 version)
 31318                                  		    ; -2 ticks per second-
 31319                                  ;; 21/08/2015
 31320                                  ;;buffer: resb (nbuf*520) ;; sysdefs.s, ux.s
 31321                                  
 31322                                  ; 02/01/2022
 31323                                  %include 'ux.s'	; 12/04/2015 (unix system/user/process data)
 31324                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 31325                              <1> ; (re-write kernel for test by using previous version without a major defect)
 31326                              <1> ; ****************************************************************************
 31327                              <1> ; Retro UNIX 386 v1.2 Kernel (v0.2.2.3) - ux.s 
 31328                              <1> ; Last Modification: 15/07/2022
 31329                              <1> ;
 31330                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 31331                              <1> ; (Modified from 
 31332                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 31333                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 31334                              <1> ; ----------------------------------------------------------------------------
 31335                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 31336                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 31337                              <1> ; <Bell Laboratories (17/3/1972)>
 31338                              <1> ; <Preliminary Release of UNIX Implementation Document>
 31339                              <1> ; (Section E10 (17/3/1972) - ux.s)
 31340                              <1> ; ****************************************************************************
 31341                              <1> 
 31342                              <1> ; 15/07/2022
 31343                              <1> ; 08/06/2022
 31344                              <1> ; 15/05/2022
 31345                              <1> ; 21/03/2022
 31346                              <1> ; 27/02/2022
 31347                              <1> ; 12/01/2022
 31348                              <1> ; 22/11/2021 (Modification in Runix v1.1 'ux.s' for runix v2 fs compatibility)
 31349                              <1> ; 18/07/2021
 31350                              <1> ; 15/07/2021
 31351                              <1> ; 12/05/2021
 31352                              <1> ; 09/05/2021
 31353                              <1> ; 06/05/2021
 31354                              <1> ; 02/05/2021
 31355                              <1> ; 26/01/2020 (NASM version of SuperBlock structure in UNIXHDCP.ASM)
 31356                              <1> 
 31357                              <1> ; 21/12/2019 (UNIXCOPY.COM, UNIXCOPY.ASM, UNIXHDCP.COM, UNIXHDCP.ASM)
 31358                              <1> ; 19/12/2019 (UNIXHDFS.COM, RUFSHDI.ASM)
 31359                              <1> ; 01/09/2019 - Retro UNIX 386 v2 SuperBlock
 31360                              <1> 
 31361                              <1> ; 14/01/2020 - Super Block modification:
 31362                              <1> ;	     - Extended sections/divisions (consequental sectors)
 31363                              <1> ;	     - (for swapping, configuration, boot space etc.)	
 31364                              <1> 
 31365                              <1> ; 26/01/2020 (unix386.s, ux.s)
 31366                              <1> ; 14/01/2020
 31367                              <1> SB.HiddenSects	equ SB.BootSectAddr
 31368                              <1> SB.TotalSects	equ SB.VolumeSize
 31369                              <1> 
 31370                              <1> ; 11/05/2021 (Retro UNIX 386 v2)
 31371                              <1> ; Super block status byte (byte 0 of SB.status dword)
 31372                              <1> ; 	bit 0 - superblock modified flag
 31373                              <1> ; 	bit 1 - inode map modified flag
 31374                              <1> ; 	bit 2 - free blocks map modified flag
 31375                              <1> ; 	bit 3 - inode table modified flag
 31376                              <1> ;; 	bit 4 - boot sector modified flag ; 17/08/2021
 31377                              <1> ; 17/08/2021
 31378                              <1> ;	bit 4 - file data write error (for SB.LastInode)
 31379                              <1> ;	bit 5 - inode table write error (for SB.LastInode)
 31380                              <1> ;	bit 6 - inode map write error (for SB.LastInode)
 31381                              <1> ;	bit 7 - free blocks map write error (for SB.LastInode)
 31382                              <1> 	
 31383                              <1> ; 21/12/2019
 31384                              <1> ; 19/12/2019 - Retro UNIX 386 v2 HD (071h) partition boot sector 
 31385                              <1> ;	       (UNIXHDFS.ASM)
 31386                              <1> ; 04/12/2015 (14 byte file names - Retro UNIX 386 v1.1)
 31387                              <1> ; 14/07/2015 (8 byte file names - Retro UNIX 8086 v1 & Retro UNIX 386 v1.0)
 31388                              <1> 
 31389                              <1> bsFSystemID 	equ 2  ; db 'RUFS'	
 31390                              <1> bsVolumeSerial 	equ 6  ; dd 0 ; (4 bytes)
 31391                              <1> bsFDSign	equ 10 ; db 'fd'
 31392                              <1> bsDriveNumber 	equ 12 ; db 0 ; fd0 or fd1 (0 or 1)
 31393                              <1> bsReserved 	equ 13 ; db 0 ; (512 bytes per sector)	
 31394                              <1> bsSecPerTrack	equ 14 ; db 18 ; (9 or 15)	
 31395                              <1> bsHeads		equ 15 ; db  ; 2
 31396                              <1> bsTracks	equ 16 ; dw 80 ; bsCylinders
 31397                              <1> bs_bf_inode_number equ 18 ; dw 0 ; 0 or Boot/Startup File I-Number
 31398                              <1> bsInfoEndsign	equ 20 ; db '@'
 31399                              <1> ; 21/12/2019
 31400                              <1> bsMagic		equ 20 ; db '@'
 31401                              <1> bsPartitionID	equ 21 ; db 0 ; db 71h
 31402                              <1> bsHiddenSects	equ 22 ; dd 0 ; Hidden sectors (Boot Sector LBA)
 31403                              <1> 
 31404                              <1> ; 22/11/2021 - Retro UNIX v2 I-node Flags
 31405                              <1> ; ------------------------------------------------------------------
 31406                              <1> ; UINSTALL.ASM (included in UNIXFDFS.ASM) - 23/01/2020
 31407                              <1> ; ------------------------------------------------------------------
 31408                              <1> 
 31409                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
 31410                              <1> ; 1000000000000000b 	IFREG - 1 = regular file (8000h)
 31411                              <1> ; 0100000000000000b	IFDIR - 1 = directory (4000h)
 31412                              <1> ; 0010000000000000b	IRSVD - 0 = reserved bit (2000h) ; Mounted flag
 31413                              <1> ; 0001000000000000b	ILARG - large file addressing bit (1000h)
 31414                              <1> ; 0000100000000000b	ISUID - set user id on exec (800h)
 31415                              <1> ; 0000010000000000b	ISGID - set group id on exec (400h)
 31416                              <1> ; 0000001000000000b	IEXTT - 1 = use extents (200h)
 31417                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 31418                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 31419                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 31420                              <1> ; 0000000000100000b	read, group (20h)
 31421                              <1> ; 0000000000010000b	write, group (10h)
 31422                              <1> ; 0000000000001000b	execute, group (08h)
 31423                              <1> ; 0000000000000100b	read, others (04h)
 31424                              <1> ; 0000000000000010b	write, others (02h)
 31425                              <1> ; 0000000000000001b	execute, others (01h)
 31426                              <1> 
 31427                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
 31428                              <1> ; 1000000000000000b 	IFREG - 0 = device file (8000h)
 31429                              <1> ; 0100000000000000b	IFBLK - 1 = block device (4000h)
 31430                              <1> ; 0010000000000000b	IFCHR - character special (2000h) -always 1-
 31431                              <1> ; 0001000000000000b	IFIFO - fifo special (1000h)
 31432                              <1> ; 0000100000000000b	IPIPE - pipe special (800h) ; 07/02/2020
 31433                              <1> ; 0000010000000000b	IREDIR - redirected (400h)  ; 07/02/2020
 31434                              <1> ; 0000001000000000b	IEXTR - 1 = external device driver (200h)
 31435                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 31436                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 31437                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 31438                              <1> ; 0000000000100000b	read, group (20h)
 31439                              <1> ; 0000000000010000b	write, group (10h)
 31440                              <1> ; 0000000000001000b	execute, group (08h)
 31441                              <1> ; 0000000000000100b	read, others (04h)
 31442                              <1> ; 0000000000000010b	write, others (02h)
 31443                              <1> ; 0000000000000001b	execute, others (01h)
 31444                              <1> 
 31445                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 31446                              <1> ; (SB structure has been moved from here to 'sysdefs.s'
 31447                              <1> ;	to overcome NASM's bss addressing bug !!!)
 31448                              <1> ; (('ux.s' bss section addresses are being overlapped
 31449                              <1> ;    when SB structure is defined in 'ux.s'))
 31450                              <1> 
 31451                              <1> %if 0
 31452                              <1> 
 31453                              <1> struc SB ; SuperBlock
 31454                              <1> 
 31455                              <1> .Header:	resd 1
 31456                              <1> ;.HiddenSects:
 31457                              <1> .BootSectAddr:	resd 1	; Hidden Sectors
 31458                              <1> ;.TotalSects:
 31459                              <1> .VolumeSize:	resd 1	; Entire Volume/Partition Size (includes ext. volume)
 31460                              <1> .Version:	resd 1	
 31461                              <1> .BlockSize:	resd 1	
 31462                              <1> .InodeCount:	resd 1	
 31463                              <1> .FreeMapAddr:	resd 1	
 31464                              <1> .FreeMapSize:	resd 1	
 31465                              <1> .InodeMapAddr:	resd 1	
 31466                              <1> .InodeMapSize:	resd 1	
 31467                              <1> .InodeTblAddr:	resd 1	
 31468                              <1> .InodeTblSize:	resd 1	
 31469                              <1> .FreeInodes:	resd 1	
 31470                              <1> .FirstFreeIno:	resd 1	
 31471                              <1> .FreeBlocks:	resd 1	
 31472                              <1> .FirstFreeBlk:	resd 1	
 31473                              <1> .BootSecParms:	resb 19	; v1
 31474                              <1> .BSExtension:	resb 5	; v2 HDFS
 31475                              <1> .Status:	resb 1	; 12/05/2021 (system modification status) (*)
 31476                              <1> .Pdrv:		resb 1  ; Physical disk number (index) ; 12/05/2021 (*) 
 31477                              <1> .Uno:		resw 1	; user/process number ; 12/05/2021 (*)
 31478                              <1> .ModifTime:	resd 1	; (last) modification time (*)
 31479                              <1> .ExtdVolTbl:	resd 1	; Extended Volume Start/Table Address
 31480                              <1> .ExtdVolSize:	resd 1	; Extended Volume (swap section etc.) Size	
 31481                              <1> .LBA_rw:	resb 1
 31482                              <1> .ClusterSize:	resb 1
 31483                              <1> .ReadOnly:	resb 1	; (SB will not be written to disk if bit 0 is 1)
 31484                              <1> .Mounted:	resb 1
 31485                              <1> .MountInode:	resd 1  ; double word
 31486                              <1> .DevMajor:	resb 1
 31487                              <1> .DevMinor:	resb 1
 31488                              <1> .LongName:	resb 1
 31489                              <1> .Direntry32:	resb 1
 31490                              <1> ; 18/07/2021
 31491                              <1> .FileBuffer:	resd 1
 31492                              <1> .ItabBuffer:	resd 1
 31493                              <1> .ImapBuffer:	resd 1
 31494                              <1> .FmapBuffer:	resd 1
 31495                              <1>  ; 15/07/2021
 31496                              <1> .LastInode:	resd 1
 31497                              <1> ; 02/05/2021
 31498                              <1> .FmapIndex:	resd 1
 31499                              <1> .ImapIndex:	resd 1
 31500                              <1> .ItableIndex:	resd 1
 31501                              <1> .Reserved:	resb 508-148 ; 18/07/2021
 31502                              <1> .Footer:	resd 1
 31503                              <1> 
 31504                              <1> endstruc
 31505                              <1> 
 31506                              <1> %endif
 31507                              <1> 
 31508                              <1> alignb 2
 31509                              <1> 
 31510                              <1> inode:
 31511                              <1> 	;; 11/03/2013. 
 31512                              <1> 	;;Derived from UNIX v1 source code 'inode' structure (ux).
 31513                              <1> 	;;i.
 31514                              <1> 	;
 31515                              <1> 	;i.flgs: resw 1
 31516                              <1> 	;i.nlks: resb 1
 31517                              <1> 	;i.uid:	 resb 1
 31518                              <1>         ;i.size: resw 1 ; size
 31519                              <1> 	;i.dskp: resw 8 ; 16 bytes
 31520                              <1> 	;i.ctim: resd 1
 31521                              <1> 	;i.mtim: resd 1
 31522                              <1> 	;i.rsvd: resw 1 ; Reserved (ZERO/Undefined word for UNIX v1)
 31523                              <1> 
 31524                              <1> 	; 26/01/2020
 31525                              <1> 	; Retro UNIX 386 v2.0 - Modified UNIX v7 inode model
 31526                              <1> 	;	(15/09/2029 .. 18/12/2019)
 31527                              <1> 
 31528 000067E4 <res 00000002>      <1> 	i.flgs:   resw 1	; /* mode and type of file */
 31529 000067E6 <res 00000002>      <1> 	i.nlks:	  resw 1	; /* number of links to file */
 31530 000067E8 <res 00000002>      <1> 	i.uid:	  resw 1	; /* owner's user id */  - 0 to 65535 -
 31531 000067EA <res 00000001>      <1> 	i.gid:	  resb 1	; /* owner's group id */ - o to 255 -
 31532 000067EB <res 00000001>      <1> 	i.size_h: resb 1	; /* number of bytes in file */ ; byte 5
 31533 000067EC <res 00000004>      <1> 	i.size:	  resd 1 ; size	; /* number of bytes in file */
 31534 000067F0 <res 00000028>      <1> 	i.dskp:	  resd 10 ; 40 bytes ; /* disk block addresses */
 31535 00006818 <res 00000004>      <1> 	i.atim:	  resd 1	; /* time last accessed */
 31536 0000681C <res 00000004>      <1> 	i.mtim:	  resd 1	; /* time last modified */
 31537 00006820 <res 00000004>      <1> 	i.ctim:	  resd 1	; /* time created */
 31538                              <1> 
 31539                              <1> I_SIZE	equ $ - inode
 31540                              <1> 
 31541                              <1> process:
 31542                              <1> 	; 27/02/2022
 31543                              <1> 	; 12/01/2022 (Retro UNIX 386 v1.2) 
 31544                              <1> 	; 06/05/2015
 31545                              <1> 	; 11/03/2013 - 05/02/2014
 31546                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
 31547                              <1> 	;p.
 31548                              <1> 	
 31549 00006824 <res 00000020>      <1>         p.pid:   resw nproc
 31550 00006844 <res 00000020>      <1>         p.ppid:  resw nproc
 31551                              <1> 	;p.break: resw nproc ; 12/01/2022 (p.break is not used)
 31552 00006864 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
 31553                              <1> 	; 27/02/2022 (p.waitc is not used)
 31554                              <1> 	;p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
 31555 00006874 <res 00000010>      <1> 	p.link:	 resb nproc
 31556 00006884 <res 00000010>      <1> 	p.stat:	 resb nproc
 31557                              <1> 
 31558                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 feature only !) 
 31559 00006894 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
 31560                              <1> 			    ; 'user' structure	
 31561                              <1> 
 31562                              <1> P_SIZE	equ $ - process
 31563                              <1> 
 31564                              <1> ; fsp table (original UNIX v1)
 31565                              <1> ;
 31566                              <1> ;Entry
 31567                              <1> ;          15                                      0
 31568                              <1> ;  1     |---|---------------------------------------|
 31569                              <1> ;        |r/w|       i-number of open file           |
 31570                              <1> ;        |---|---------------------------------------| 
 31571                              <1> ;        |               device number               |
 31572                              <1> ;        |-------------------------------------------|
 31573                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
 31574                              <1> ;        |-------------------------------------------| 
 31575                              <1> ;        |  flag that says    | number of processes  |
 31576                              <1> ;        |   file deleted     | that have file open  |
 31577                              <1> ;        |-------------------------------------------| 
 31578                              <1> ;  2     |                                           |
 31579                              <1> ;        |-------------------------------------------| 
 31580                              <1> ;        |                                           |
 31581                              <1> ;        |-------------------------------------------|
 31582                              <1> ;        |                                           |
 31583                              <1> ;        |-------------------------------------------|
 31584                              <1> ;        |                                           |
 31585                              <1> ;        |-------------------------------------------| 
 31586                              <1> ;  3     |                                           | 
 31587                              <1> ;        |                                           |  
 31588                              <1> ;
 31589                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
 31590                              <1> 
 31591                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
 31592                              <1> 
 31593                              <1> ;Entry
 31594                              <1> ;         15                    7                   0
 31595                              <1> ;  1     |-------------------------------------------|
 31596                              <1> ;        |   	     i-number of open file           |
 31597                              <1> ;        |-------------------------------------------| 
 31598                              <1> ;        |        high word of 32 bit i-number       |
 31599                              <1> ;        |-------------------------------------------|
 31600                              <1> ;        | open mode & status  |   device number     |
 31601                              <1> ;        |-------------------------------------------|
 31602                              <1> ;        |    reserved byte    |     open count      |
 31603                              <1> ;        |-------------------------------------------| 
 31604                              <1> ;        | offset pointer, i.e., r/w pointer to file |
 31605                              <1> ;        |-------------------------------------------|
 31606                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
 31607                              <1> ;        |-------------------------------------------|
 31608                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
 31609                              <1> ;        |-------------------------------------------|
 31610                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
 31611                              <1> ;        |-------------------------------------------|
 31612                              <1> ;  2     |                                           |
 31613                              <1> ;        |-------------------------------------------| 
 31614                              <1> ;        |                                           |
 31615                              <1> ;        |-------------------------------------------|
 31616                              <1> ;        |                                           |
 31617                              <1> ;        |-------------------------------------------|
 31618                              <1> ;        |                                           |
 31619                              <1> ;        |-------------------------------------------| 
 31620                              <1> ;        |                                           | 
 31621                              <1> 
 31622                              <1> ; 10/01/2022 - Retro UNIX 386 v1.2
 31623                              <1> ; (file structure has been moved from here to 'sysdefs.s'
 31624                              <1> ;	to overcome NASM's bss addressing bug !!!)
 31625                              <1> ; (('ux.s' bss section addresses are being overlapped
 31626                              <1> ;    when file file structure is defined in 'ux.s'))
 31627                              <1> 
 31628                              <1> %if 0
 31629                              <1> 
 31630                              <1> ; 22/11/2021
 31631                              <1> ; 21/07/2021 - Retro UNIX 386 v2 open file structure revision
 31632                              <1> 
 31633                              <1> struc file	; open files (fsp) structure
 31634                              <1>   .inode:  resw 1  ; inode number of open file (32 bit)
 31635                              <1>   .i32:	   resw 1  ; higher word of inode number (reserved)
 31636                              <1>   .drive:  resb 1  ; logical drive (disk) number
 31637                              <1>   .flags:  resb 1  ; open mode and status
 31638                              <1>   .count:  resb 1  ; number of processes that have file open
 31639                              <1>   ;.rsvd:  resb 1  ; reserved byte (for next versions)
 31640                              <1>   .mnt:    resb 1  ; mnttab index+1 (0 = not mounted)
 31641                              <1>   .offset: resd 1  ; file offset/pointer (64 bit) 
 31642                              <1>   .o64:	   resd 1  ; higher 32 bit of file offset
 31643                              <1>  .size:  ; = 16		
 31644                              <1> endstruc
 31645                              <1> 
 31646                              <1> %endif
 31647                              <1> 
 31648                              <1> ; 01/01/2022
 31649                              <1> ; 22/11/2021
 31650                              <1> ;fp.size equ file.size
 31651                              <1> 
 31652                              <1> ; 02/01/2022
 31653 000068D4 <res 00000320>      <1> fsp:	resb nfiles*16 ; (NFILES*fp.size)
 31654                              <1> ; 01/01/2022
 31655                              <1> ; 22/11/2021 (16/05/2021)
 31656                              <1> ;fsp:	resb NFILES*16 ; (NFILES*fp.size)
 31657                              <1> ; 15/04/2015
 31658                              <1> ;fsp:	resb nfiles*10 ; 11/05/2015 (8 -> 10)
 31659                              <1> 
 31660 00006BF4 <res 00000048>      <1> bufp:	resd (nbuf+2) ; will be initialized 
 31661 00006C3C <res 00000004>      <1> ii:	resd 1 ; 22/11/2021 ; 32 bit inode number (high word is 0)
 31662                              <1> ; 22/11/2021
 31663 00006C40 <res 00000001>      <1> idev:	resb 1 ; logical drive number of current inode, [ii]
 31664 00006C41 <res 00000001>      <1> cdev:	resb 1 ; current logical drive number for current user
 31665                              <1> 
 31666                              <1> ; 18/05/2015
 31667                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
 31668                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
 31669                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
 31670                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
 31671                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
 31672                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
 31673                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
 31674                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
 31675                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
 31676                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
 31677                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
 31678 00006C42 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
 31679                              <1> 	        ; as above, for physical drives numbers in following table
 31680 00006C43 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
 31681                              <1> ; 15/04/2015
 31682                              <1> ;active: resb 1 ; 15/07/2022
 31683                              <1> ;	 resb 1 ; 09/06/2015
 31684 00006C44 <res 00000002>      <1> mpid:	 resw 1
 31685                              <1> ; 22/11/2021 (32 bit inode numbers)
 31686 00006C46 <res 00000004>      <1> rootdir: resd 1
 31687 00006C4A <res 00000004>      <1> mnti:	 resd 1
 31688                              <1> ; 15/05/2022 ; (parent dir inumber of [mnti])
 31689 00006C4E <res 00000004>      <1> mntp:	 resd 1 
 31690                              <1> 
 31691                              <1> ; 14/02/2014
 31692                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
 31693                              <1> ;		      Single level run queue
 31694                              <1> ;		      (in order to solve sleep/wakeup lock)
 31695 00006C52 <res 00000002>      <1> runq:	resw 1
 31696 00006C54 <res 00000001>      <1> imod:	resb 1
 31697 00006C55 <res 00000001>      <1> imodx:	resb 1 ; 09/01/2022 - Retro UNIX 386 v1.2
 31698 00006C56 <res 00000001>      <1> smod:	resb 1
 31699 00006C57 <res 00000001>      <1> mmod:	resb 1
 31700                              <1> ;	resb 1 ; 09/01/2022 
 31701 00006C58 <res 00000001>      <1> sysflg:	resb 1
 31702                              <1> 
 31703 00006C59 <res 00000003>      <1> alignb 4
 31704                              <1> 
 31705                              <1> user:
 31706                              <1> 	; 01/01/2022
 31707                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 31708                              <1> 	; 24/10/2021
 31709                              <1> 	; 18/10/2021
 31710                              <1> 	; 10/06/2021
 31711                              <1> 	; 30/05/2021
 31712                              <1> 	; 29/05/2021
 31713                              <1> 	; 21/05/2021
 31714                              <1> 	; 20/05/2021
 31715                              <1> 	; 16/05/2021
 31716                              <1> 	; 01/05/2021
 31717                              <1> 	; 27/03/2021
 31718                              <1> 	; 17/04/2020, 28/04/2020
 31719                              <1> 	; 25/03/2020, 28/03/2020
 31720                              <1> 	; 20/03/2020, 22/03/2020, 23/03/2020
 31721                              <1> 	; 05/03/2020, 08/03/2020, 14/03/2020
 31722                              <1> 	; 07/02/2020 - Retro UNIX 386 v2
 31723                              <1> 	;
 31724                              <1> 	; 27/02/2017 - TRDOS 386
 31725                              <1> 	; 13/01/2017 - TRDOS 386
 31726                              <1> 	; 10/01/2017 - TRDOS 386
 31727                              <1> 	; 19/12/2016 - TRDOS 386	
 31728                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0) 
 31729                              <1> 	; 	       [u.pri] usage method modification
 31730                              <1> 	;
 31731                              <1> 	; 04/12/2015 - Retro UNIX 386 v1.1 (14 byte file/directory names)
 31732                              <1> 	; 18/10/2015
 31733                              <1> 	; 12/10/2015
 31734                              <1> 	; 21/09/2015
 31735                              <1> 	; 24/07/2015
 31736                              <1> 	; 16/06/2015
 31737                              <1> 	; 09/06/2015
 31738                              <1> 	; 11/05/2015
 31739                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 31740                              <1> 	; 10/10/2013
 31741                              <1> 	; 11/03/2013. 
 31742                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
 31743                              <1> 	;u.
 31744                              <1> 
 31745 00006C5C <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
 31746 00006C60 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
 31747 00006C64 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
 31748 00006C68 <res 00000002>      <1> 	u.cdir:	  resw 1
 31749 00006C6A <res 00000002>      <1> 		  resw 1 ; 28/03/2020 - reserved for 32 bit inode number
 31750                              <1> 	;u.cdrv:  resw 1 ; 17/04/2020 (dword alignment) 
 31751 00006C6C <res 00000001>      <1> 	u.cdrv:   resb 1 ; 01/05/2021
 31752 00006C6D <res 00000001>      <1> 		  resb 1 ; 01/05/2021 (dword alignment)
 31753 00006C6E <res 0000000A>      <1> 	u.fp:	  resb 10 ; Retro UNIX 386 v1
 31754                              <1> 	;u.fp:	  resb OPENFILES ; Retro UNIX 386 v2 ; 28/03/2020 
 31755                              <1> 	u.fsp:	  ; 16/05/2021
 31756 00006C78 <res 00000004>      <1> 	u.fofp:	  resd 1 ; 16/05/2021 (pointer to fsp entry)
 31757 00006C7C <res 00000004>      <1> 	u.dirp:	  resd 1
 31758 00006C80 <res 00000004>      <1> 	u.namep:  resd 1
 31759 00006C84 <res 00000004>      <1> 	u.off:	  resd 1
 31760                              <1> 	;	  resd 1 ; 08/03/2020 - Retro UNIX 386 v2 - 64 bit fptr
 31761 00006C88 <res 00000004>      <1> 	u.base:	  resd 1
 31762 00006C8C <res 00000004>      <1> 	u.count:  resd 1
 31763 00006C90 <res 00000004>      <1> 	u.nread:  resd 1
 31764 00006C94 <res 00000004>      <1> 	u.break:  resd 1 ; break
 31765                              <1> 	; 16/05/2021 (Retro UNIX 386 v2)
 31766 00006C98 <res 00000001>      <1> 	u.mode:   resb 1 ; 16/05/2021 (sysread, syswrite, 'rdwr' file mode)
 31767                              <1> 	; 10/01/2017 (TRDOS 386, relocation and dword alignment)
 31768                              <1> 	; tty number (rtty, rcvt, wtty)
 31769 00006C99 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
 31770 00006C9A <res 00000002>      <1> 	u.ttyp:	  resw 1 
 31771 00006C9C <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
 31772                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
 31773 00006CAC <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
 31774 00006CAD <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 31775 00006CAE <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
 31776 00006CAF <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 31777                              <1> 	; 10/06/2021
 31778                              <1> 	;u.signal: resw 1 ; 21/05/2021 - Retro UNIX 386 v2
 31779                              <1> 	;	  resw 1 ; reserved ; 21/05/2021	
 31780 00006CB0 <res 00000002>      <1> 	u.intr:	  resw 1
 31781 00006CB2 <res 00000002>      <1> 	u.quit:	  resw 1
 31782                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
 31783                              <1> 	;u.ilgins: resw 1 ; 10/01/2017
 31784                              <1> 	;u.cdrv:  resw 1 ; cdev ; 17/04/2020 (moved to up)
 31785                              <1> 	;u.uid:	  resb 1 ; uid
 31786                              <1> 	;u.ruid:  resb 1
 31787 00006CB4 <res 00000001>      <1> 	u.bsys:	  resb 1
 31788 00006CB5 <res 00000001>      <1> 	u.uno:	  resb 1
 31789 00006CB6 <res 00000002>      <1>         u.uid:	  resw 1 ; uid	; 27/03/2021 - Retro UNIX 386 v2
 31790 00006CB8 <res 00000002>      <1> 	u.ruid:	  resw 1	; 16 bit uid
 31791 00006CBA <res 00000001>      <1> 	u.gid:	  resb 1 ; gid 	; 27/03/2021 - Retro UNIX 386 v2
 31792 00006CBB <res 00000001>      <1> 	u.rgid:	  resb 1
 31793                              <1> 	; 20/05/2021 - Retro UNIX 386 v2
 31794 00006CBC <res 00000004>      <1> 	u.procp:  resd 1 ; /* pointer to proc structure */		
 31795 00006CC0 <res 00000004>      <1> 	u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
 31796 00006CC4 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
 31797 00006CC8 <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
 31798 00006CCC <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
 31799                              <1> 		; 24/10/2021 (32 bit value for Retro UNIX 386 v2)
 31800 00006CD0 <res 00000004>      <1> 	u.pcount: resd 1 ; 20/05/2015 (byte -transfer- count for page)
 31801                              <1> 	;u.pncount: resw 1 
 31802                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
 31803                              <1> 	;u.pnbase:  resd 1 
 31804                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
 31805 00006CD4 <res 00000002>      <1> 	u.rsvd:	  resw 1 ; 04/12/2021 (dword alignment)
 31806                              <1> 			 ; 09/06/2015
 31807 00006CD6 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign
 31808                              <1> 		; 08/03/2020 (block device read/write flag for 'sioreg')		
 31809 00006CD7 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
 31810                              <1> 			 ; 24/07/2015 - 24/06/2015
 31811                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
 31812                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
 31813                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
 31814                              <1>  			 ; 24/06/2015	  	
 31815                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
 31816                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
 31817                              <1> 	; last error number
 31818 00006CD8 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
 31819                              <1> 			; Retro UNIX 8086/386 v1 feature only!
 31820                              <1> 			; 21/09/2015 (debugging - page fault analyze)
 31821 00006CDC <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
 31822                              <1> 		; 29/05/2021 - Retro UNIX 386 v2, 2021 (sleep, psig)
 31823                              <1> ;	u.signal: resd 1 ; unix signal recognition (enabling, accepting) bits	
 31824                              <1> ;	u.srb:	  resb 1 ; signal handling/responding method
 31825                              <1> ;	u.snum:	  resb 1 ; signal number (last signal number)
 31826                              <1> ;	u.exit:	  resb 1 ; exit code ; 30/05/2021 - Retro UNIX 386 v2
 31827                              <1> ;	u.s_lock: resb 1 ; signal handling (phase) lock	
 31828                              <1> ;	u.s_addr: resd 1 ; Signal Response Byte or signal handler (callback) address
 31829                              <1> ;	u.s_time: resd 1 ; signal time in unix epoch format		
 31830                              <1> 		; 19/12/2016 (TRDOS 386)	
 31831                              <1> ;	u.tcb:	  resd 1 ; Timer callback address/flag which will be used by timer int
 31832                              <1> 		; 13/01/2017 (TRDOS 386)
 31833                              <1> ;	u.t_lock: resb 1 ; Timer interrupt (callback) lock (unlocked by 'sysrele')
 31834                              <1> ;	u.t_mode: resb 1 ; running mode during timer interrupt (0= system, 0FFh= user)
 31835                              <1> 		; 26/02/2017 (TRDOS 386)
 31836                              <1> ;	u.irqc:	  resb 1  ; Count of IRQ callback services (IRQs in use)
 31837                              <1> 		; 28/02/2017 (TRDOS 386) 
 31838                              <1> ;	u.irqwait: resb 1 ; IRQ waiting for callback service flag (IRQ number, If > 0)
 31839                              <1> ;	u.r_lock:  resb 1 ; 'IRQ callback service is in progress' flag (IRQ lock)
 31840                              <1> ;	u.r_mode:  resb 1 ; running mode during hardware interrupt
 31841                              <1> 		; 07/02/2020 - Retro UNIX 386 v2
 31842                              <1> ;	u.redir:  resb 1 ; device func redirection permitted by user (if u.redir > 0)
 31843                              <1> 		; 26/02/2020 - Retro UNIX 386 v2
 31844                              <1> ;	u.rwm:	  resb 1  ; read & write mode for devices/drives, 0 = direct, 1 = fs r/w 
 31845                              <1> 		; 24/02/2020 - Retro UNIX 386 v2
 31846                              <1> 		; 24/10/2021 (32 bit value)
 31847                              <1> ;	u.scount: resd 1 ; sub byte count ; 22/03/2020 
 31848                              <1> 		; 07/03/2020 - Retro UNIX 386 v2
 31849                              <1> ;	u.bps:	  resw 1 ; u.bps = bytes per sector, for readi and writei
 31850                              <1> ;		  resw 1 ; 24/10/2021 (32 bit value for using with 32 bit registers)	
 31851                              <1> 		; 23/03/2020 - Retro UNIX 386 v2
 31852                              <1> ;	u.timeout: resw 1 ; timeout setting (seconds) -for 'sleep'-
 31853                              <1> 		; 28/04/2020 - Retro UNIX 386 v2
 31854                              <1> ;	u.lock:	  resb 1 ; Device lock flag (bit 0 is for device/disk read/write)
 31855                              <1> 		; 24/04/2020
 31856                              <1> 		; 17/04/2020 - Retro UNIX 386 v2
 31857                              <1> ;	u.ifs:	  resb 1 ; (current) installable file system driver index number
 31858                              <1> 		; 25/03/2020
 31859                              <1> 		; 20/03/2020
 31860                              <1> 	;u.lcount: resd 1 ; last byte count for 'writei' (for restoring write count)	
 31861                              <1> 
 31862                              <1> 		; 08/03/2020 - Retro UNIX 386 v2 ('sioreg, 'readi')
 31863                              <1> 	;u.limit: resd 1  ; disk/file size limit for block device read/write ('sioreg')			
 31864                              <1> 	;	  resd 1  ; 08/03/2020 - 64 bit limit (disk size in bytes)
 31865                              <1> 	;	; 26/02/2020 - Retro UNIX 386 v2
 31866                              <1> 	;u.sector: resd 1  ; current sector (for readi and writei, device r/w)  		
 31867                              <1> 	;u.buffer: resd 1  ; current buffer (for readi and writei, device r/w) 
 31868                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 31869                              <1> 	;u.devmm: resw 1 ; device major (hb) and minor (lb) numbers
 31870                              <1> 	;u.zero:  resw 1 ; 14/03/2020 - Must be ZERO for current version
 31871                              <1> 		; 22/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 31872                              <1> ;	u.device: resd 1 ; (blk, chr) device description table (entry) address 	
 31873                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 31874                              <1> ;	u.function: resd 1 ; device function (read, write)
 31875                              <1> 		; 22/03/2020 - Retro UNIX 386 v2, 2020 (readi, writei)
 31876                              <1> ;	u.buffer: resd 1  ; for saving buffer header address for 'poke'
 31877                              <1> ;	u.inode:  resw 1  ; for saving inode number of current (device) inode
 31878                              <1> ;		  resw 1  ; 18/10/2021 Retro UNIX 386 v2 - 32 bit inode number			
 31879                              <1> ;	u.idev:	  resb 1  ; for saving logical drv number of current (dev) inode
 31880                              <1> 		; 04/12/2021
 31881                              <1> ;	u.rsvd2:  resw 1  ; (for dword alignment)	
 31882                              <1> 		; 27/02/2017 (TRDOS 386) 
 31883                              <1> ;; 31/12/2021 - temporary !
 31884                              <1> ;	u.fpsave: resb 1  ; TRDOS 386, 'save/restore FPU registers' flag
 31885                              <1> alignb 4
 31886                              <1> 	; !! wrong sizing in TRDOS 386 v2.0.4 (in 'ubss.s', 28/02/2017) !! 
 31887                              <1> 	;u.fpregs: resb 94 ; 94 byte area for saving and restoring FPU registers
 31888                              <1> 	; 30/05/2021 - Retro UNIX 386 v2
 31889                              <1> ;	u.fpregs: resb 108 ; 108 byte area for saving and restoring FPU registers	
 31890                              <1> alignb 4
 31891                              <1> 
 31892                              <1> U_SIZE	equ $ - user
 31893                              <1> 
 31894                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
 31895 00006CE0 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
 31896 00006CE4 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
 31897 00006CE8 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
 31898                              <1> ;ncount: resw 1 ; remain byte count in page for 'namei' & 'sysexec'
 31899                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'ncount')
 31900 00006CEC <res 00000004>      <1> ncount: resd 1	; remain byte count in page for 'namei' & 'sysexec'
 31901                              <1> ;argc:	resw 1	; argument count for 'sysexec'
 31902                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'argc')
 31903 00006CF0 <res 00000004>      <1> argc:	resd 1	; argument count for 'sysexec'
 31904 00006CF4 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
 31905                              <1> 
 31906                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
 31907                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
 31908 00006CF8 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
 31909 00006CF9 <res 00000001>      <1> rwdsk:	 resb 1 ;; Read/Write function number (diskio) - 16/06/2015
 31910 00006CFA <res 00000001>      <1> mget_rw: resb 1 ; 22/11/2021 
 31911 00006CFB <res 00000001>      <1> retry_count: resb 1 ; Disk I/O retry count - 11/06/2015
 31912                              <1> 
 31913                              <1> ; 08/06/2022 - (BugFix) ! (level: resd 0) !
 31914                              <1> ; 22/11/2021 - Retro UNIX 386 v2 compatibility
 31915 00006CFC <res 00000004>      <1> level:	resd 1  ; level, level+1, level+2, level+3  ; for 'mget' procedure
 31916                              <1> 
 31917                              <1> ; (02/01/2022)
 31918                              <1> ; 27/11/2021
 31919                              <1> ; these are will be used for disk block allocation ('alloc' proc)
 31920                              <1> free_map_offset: 
 31921 00006D00 <res 00000004>      <1> 		resd 1
 31922 00006D04 <res 00000004>      <1> free_map_index:	resd 1
 31923                              <1> free_map_sector:
 31924 00006D08 <res 00000004>      <1> 		resd 1
 31925                              <1> ;free_map_buffer:
 31926                              <1> ;		resd 1
 31927                              <1> 
 31928                              <1> ; 12/01/2022
 31929                              <1> ; 27/11/2021 - temporary !
 31930                              <1> ;s.time:	resd 1
 31931                              <1> 
 31932                              <1> ;alignb 4
 31933                              <1> 
 31934                              <1> ; (02/01/2022)
 31935                              <1> ; 22/08/2015
 31936                              <1> ;buffer: resb nbuf * 520
 31937                              <1> 
 31938 00006D0C <res 00000008>      <1> sb0:	resd 2
 31939                              <1> ;s:
 31940                              <1> ; (root disk) super block buffer
 31941                              <1> systm:
 31942                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatible super block
 31943                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
 31944                              <1> 	; 11/03/2013. 
 31945                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
 31946                              <1> 	;s.
 31947                              <1> 
 31948                              <1> 	;resw 1
 31949                              <1> 	;resb 360 ; 2880 sectors ; original UNIX v1 value: 128
 31950                              <1> 	;resw 1
 31951                              <1> 	;resb 32 ; 256+40 inodes ; original UNIX v1 value: 64
 31952                              <1> 	;s.time: resd 1
 31953                              <1> 	;s.syst: resd 1
 31954                              <1>         ;s.wait_: resd 1 ; wait
 31955                              <1> 	;s.idlet: resd 1
 31956                              <1> 	;s.chrgt: resd 1
 31957                              <1> 	;s.drerr: resw 1
 31958                              <1> 
 31959                              <1> 	; 27/11/2021
 31960 00006D14 <res 00000200>      <1> 	resb 512	
 31961                              <1> 
 31962                              <1> ;S_SIZE	equ $ - systm
 31963                              <1> 
 31964                              <1> 	;resb 512-S_SIZE ; 03/06/2015
 31965                              <1> 
 31966 00006F14 <res 00000008>      <1> sb1:	resd 2
 31967                              <1> ; (mounted disk) super block buffer
 31968                              <1> mount:	
 31969 00006F1C <res 00000200>      <1> 	resb 512  ; 03/06/2015
 31970                              <1> 
 31971                              <1> ; 21/03/2022
 31972                              <1> ; hard disk masterboot sector buffer
 31973 0000711C <res 00000008>      <1> mbrbuf: resd 2
 31974 00007124 <res 00000200>      <1> 	resb 512
 31975                              <1> 
 31976                              <1> ; 10/01/2022
 31977 00007324 <res 00000200>      <1> dbli_buf: resb 512  ; double indir ptr buff for 'itrunc', 'tloop'
 31978 00007524 <res 00000200>      <1> trpi_buf: resb 512  ; triple indir ptr buff for 'itrunc', 'tloop'
 31979                              <1> 
 31980                              <1> ;/ ux -- unix
 31981                              <1> ;
 31982                              <1> ;systm:
 31983                              <1> ;
 31984                              <1> ;	.=.+2
 31985                              <1> ;	.=.+128.
 31986                              <1> ;	.=.+2
 31987                              <1> ;	.=.+64.
 31988                              <1> ;	s.time: .=.+4
 31989                              <1> ;	s.syst: .=.+4
 31990                              <1> ;	s.wait: .=.+4
 31991                              <1> ;	s.idlet:.=.+4
 31992                              <1> ;	s.chrgt:.=.+4
 31993                              <1> ;	s.drerr:.=.+2
 31994                              <1> ;inode:
 31995                              <1> ;	i.flgs: .=.+2
 31996                              <1> ;	i.nlks: .=.+1
 31997                              <1> ;	i.uid:  .=.+1
 31998                              <1> ;	i.size: .=.+2
 31999                              <1> ;	i.dskp: .=.+16.
 32000                              <1> ;	i.ctim: .=.+4
 32001                              <1> ;	i.mtim: .=.+4
 32002                              <1> ;	. = inode+32.
 32003                              <1> ;mount:	.=.+1024.
 32004                              <1> ;proc:
 32005                              <1> ;	p.pid:  .=.+[2*nproc]
 32006                              <1> ;	p.dska: .=.+[2*nproc]
 32007                              <1> ;	p.ppid: .=.+[2*nproc]
 32008                              <1> ;	p.break:.=.+[2*nproc]
 32009                              <1> ;	p.link: .=.+nproc
 32010                              <1> ;	p.stat: .=.+nproc
 32011                              <1> ;tty:
 32012                              <1> ;	. = .+[ntty*8.]
 32013                              <1> ;fsp:	.=.+[nfiles*8.]
 32014                              <1> ;bufp:	.=.+[nbuf*2]+6
 32015                              <1> ;sb0:	.=.+8
 32016                              <1> ;sb1:	.=.+8
 32017                              <1> ;swp:	.=.+8
 32018                              <1> ;ii:	.=.+2
 32019                              <1> ;idev:	.=.+2
 32020                              <1> ;cdev:	.=.+2
 32021                              <1> ;deverr: .=.+12.
 32022                              <1> ;active: .=.+2
 32023                              <1> ;rfap:	.=.+2
 32024                              <1> ;rkap:	.=.+2
 32025                              <1> ;tcap:	.=.+2
 32026                              <1> ;tcstate:.=.+2
 32027                              <1> ;tcerrc: .=.+2
 32028                              <1> ;mnti:	.=.+2
 32029                              <1> ;mntd:	.=.+2
 32030                              <1> ;mpid:	.=.+2
 32031                              <1> ;clockp: .=.+2
 32032                              <1> ;rootdir:.=.+2
 32033                              <1> ;toutt:	.=.+16.
 32034                              <1> ;touts: .=.+32.
 32035                              <1> ;runq:	.=.+6
 32036                              <1> ;
 32037                              <1> ;wlist:	.=.+40.
 32038                              <1> ;cc:	.=.+30.
 32039                              <1> ;cf:	.=.+31.
 32040                              <1> ;cl:	.=.+31.
 32041                              <1> ;clist:	.=.+510.
 32042                              <1> ;imod:	.=.+1
 32043                              <1> ;smod:	.=.+1
 32044                              <1> ;mmod:	.=.+1
 32045                              <1> ;uquant: .=.+1
 32046                              <1> ;sysflg: .=.+1
 32047                              <1> ;pptiflg:.=.+1
 32048                              <1> ;ttyoch: .=.+1
 32049                              <1> ; .even
 32050                              <1> ; .=.+100.; sstack:
 32051                              <1> ;buffer: .=.+[ntty*140.]
 32052                              <1> ;	.=.+[nbuf*520.]
 32053                              <1> ;
 32054                              <1> ; . = core-64.
 32055                              <1> ;user:
 32056                              <1> ;	u.sp:    .=.+2
 32057                              <1> ;	u.usp:   .=.+2
 32058                              <1> ;	u.r0:    .=.+2
 32059                              <1> ;	u.cdir:  .=.+2
 32060                              <1> ;	u.fp:    .=.+10.
 32061                              <1> ;	u.fofp:  .=.+2
 32062                              <1> ;	u.dirp:  .=.+2
 32063                              <1> ;	u.namep: .=.+2
 32064                              <1> ;	u.off:   .=.+2
 32065                              <1> ;	u.base:  .=.+2
 32066                              <1> ;	u.count: .=.+2
 32067                              <1> ;	u.nread: .=.+2
 32068                              <1> ;	u.break: .=.+2
 32069                              <1> ;	u.ttyp:  .=.+2
 32070                              <1> ;	u.dirbuf:.=.+10.
 32071                              <1> ;	u.pri:   .=.+2
 32072                              <1> ;	u.intr:  .=.+2
 32073                              <1> ;	u.quit:  .=.+2
 32074                              <1> ;	u.emt:   .=.+2
 32075                              <1> ;	u.ilgins:.=.+2
 32076                              <1> ;	u.cdev:  .=.+2
 32077                              <1> ;	u.uid:   .=.+1
 32078                              <1> ;	u.ruid:  .=.+1
 32079                              <1> ;	u.bsys:  .=.+1
 32080                              <1> ;	u.uno:   .=.+1
 32081                              <1> ;. = core
 32082                                  
 32083                                  ; 27/12/2021
 32084 00007724 <res 00002080>          buffer:	resb (nbuf*520)
 32085                                  
 32086                                  bss_end:
 32087                                  
 32088                                  ; 12/12/2021
 32089                                  BSS_SIZE equ bss_end - bss_start
 32090                                  
 32091                                  ; 27/12/2013
 32092                                  _end: ; end of kernel code (and read only data, just before bss)
