     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.0
     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: 12/12/2021 ]
    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                                  ; 27/12/2013
    62                                  KEND    equ KLOAD + 65536 ; (28/12/2013) (end of kernel space)
    63                                  
    64                                  ; IBM PC/AT BIOS ----- 10/06/85 (postequ.inc)
    65                                  ;--------- CMOS TABLE LOCATION ADDRESS'S -------------------------------------
    66                                  CMOS_SECONDS	EQU	00H		; SECONDS (BCD)
    67                                  CMOS_MINUTES	EQU	02H		; MINUTES (BCD)	
    68                                  CMOS_HOURS	EQU	04H		; HOURS (BCD)
    69                                  CMOS_DAY_WEEK	EQU	06H		; DAY OF THE WEEK  (BCD)
    70                                  CMOS_DAY_MONTH	EQU	07H		; DAY OF THE MONTH (BCD) 
    71                                  CMOS_MONTH	EQU	08H		; MONTH (BCD)
    72                                  CMOS_YEAR	EQU	09H		; YEAR (TWO DIGITS) (BCD)
    73                                  CMOS_CENTURY	EQU	32H		; DATE CENTURY BYTE (BCD)
    74                                  CMOS_REG_A	EQU	0AH		; STATUS REGISTER A
    75                                  CMOS_REG_B	EQU	00BH		; STATUS REGISTER B  ALARM
    76                                  CMOS_REG_C	EQU	00CH		; STATUS REGISTER C  FLAGS
    77                                  CMOS_REG_D	EQU	0DH		; STATUS REGISTER D  BATTERY
    78                                  CMOS_SHUT_DOWN	EQU	0FH		; SHUTDOWN STATUS COMMAND BYTE
    79                                  ;----------------------------------------
    80                                  ;	CMOS EQUATES FOR THIS SYSTEM	;
    81                                  ;-----------------------------------------------------------------------------
    82                                  CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
    83                                  CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
    84                                  NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
    85                                  					; HIGH BIT OF CMOS LOCATION ADDRESS
    86                                  
    87                                  ; Memory Allocation Table Address
    88                                  ; 05/11/2014
    89                                  ; 31/10/2014
    90                                  MEM_ALLOC_TBL	equ	100000h		; Memory Allocation Table at the end of
    91                                  					; the 1st 1 MB memory space.
    92                                  					; (This address must be aligned
    93                                  					;  on 128 KB boundary, if it will be
    94                                  					;  changed later.)
    95                                  					; ((lower 17 bits of 32 bit M.A.T.
    96                                  					;   address must be ZERO)).
    97                                  					; ((((Reason: 32 bit allocation 
    98                                  					;     instructions, dword steps)))
    99                                  					; (((byte >> 12 --> page >> 5)))  
   100                                  ;04/11/2014	
   101                                  PDE_A_PRESENT	equ	1		; Present flag for PDE
   102                                  PDE_A_WRITE	equ 	2		; Writable (write permission) flag
   103                                  PDE_A_USER	equ	4		; User (non-system/kernel) page flag
   104                                  ;
   105                                  PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
   106                                  PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
   107                                  PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
   108                                  PTE_A_ACCESS    equ	32		; Accessed flag (bit 5) ; 09/03/2015
   109                                  
   110                                  ; 17/02/2015 (unix386.s)
   111                                  ; 10/12/2014 - 30/12/2014 (0B000h -> 9000h) (dsectrm2.s)
   112                                  DPT_SEGM equ 09000h  ; FDPT segment (EDD v1.1, EDD v3)
   113                                  ;
   114                                  HD0_DPT	 equ 0	    ; Disk parameter table address for hd0
   115                                  HD1_DPT	 equ 32	    ; Disk parameter table address for hd1
   116                                  HD2_DPT	 equ 64	    ; Disk parameter table address for hd2
   117                                  HD3_DPT	 equ 96	    ; Disk parameter table address for hd3
   118                                  
   119                                  
   120                                  ; FDPT (Phoenix, Enhanced Disk Drive Specification v1.1, v3.0)
   121                                  ;      (HDPT: Programmer's Guide to the AMIBIOS, 1993)
   122                                  ;
   123                                  FDPT_CYLS	equ 0 ; 1 word, number of cylinders
   124                                  FDPT_HDS	equ 2 ; 1 byte, number of heads
   125                                  FDPT_TT		equ 3 ; 1 byte, A0h = translated FDPT with logical values
   126                                  		      ; otherwise it is standard FDPT with physical values 	
   127                                  FDPT_PCMP	equ 5 ; 1 word, starting write precompensation cylinder
   128                                  		      ; (obsolete for IDE/ATA drives)
   129                                  FDPT_CB		equ 8 ; 1 byte, drive control byte
   130                                  			; Bits 7-6 : Enable or disable retries (00h = enable)
   131                                  			; Bit 5	: 1 = Defect map is located at last cyl. + 1
   132                                  			; Bit 4 : Reserved. Always 0
   133                                  			; Bit 3 : Set to 1 if more than 8 heads
   134                                  			; Bit 2-0 : Reserved. Alsways 0
   135                                  FDPT_LZ		equ 12 ; 1 word, landing zone (obsolete for IDE/ATA drives)
   136                                  FDPT_SPT	equ 14 ; 1 byte, sectors per track
   137                                  
   138                                  ; Floppy Drive Parameters Table (Programmer's Guide to the AMIBIOS, 1993)
   139                                  ; (11 bytes long) will be used by diskette handler/bios
   140                                  ; which is derived from IBM PC-AT BIOS (DISKETTE.ASM, 21/04/1986).						 	  		 	  
   141                                  
   142                                  [BITS 16]       ; We need 16-bit intructions for Real mode
   143                                  
   144                                  [ORG 0] 
   145                                  	; 12/11/2014
   146                                  	; Save boot drive number (that is default root drive)
   147 00000000 8816[AA6A]              	mov	[boot_drv], dl ; physical drv number
   148                                  
   149                                  	; Determine installed memory
   150                                  	; 31/10/2014
   151                                  	;
   152 00000004 B801E8                  	mov	ax, 0E801h ; Get memory size 
   153 00000007 CD15                    	int	15h	   ; for large configurations
   154 00000009 7308                    	jnc	short chk_ms
   155 0000000B B488                    	mov	ah, 88h    ; Get extended memory size 
   156 0000000D CD15                    	int	15h
   157                                  	;	   
   158                                  	;mov	al, 17h	; Extended memory (1K blocks) low byte
   159                                  	;out	70h, al ; select CMOS register
   160                                  	;in	al, 71h ; read data (1 byte)
   161                                  	;mov	cl, al
   162                                  	;mov	al, 18h ; Extended memory (1K blocks) high byte
   163                                  	;out	70h, al ; select CMOS register
   164                                  	;in	al, 71h ; read data (1 byte)
   165                                  	;mov	ch, al
   166                                   	;      
   167 0000000F 89C1                    	mov	cx, ax
   168 00000011 31D2                    	xor	dx, dx
   169                                  chk_ms:
   170 00000013 890E[446D]              	mov	[mem_1m_1k], cx
   171 00000017 8916[466D]              	mov	[mem_16m_64k], dx
   172                                  	; 05/11/2014
   173                                  	;and	dx, dx
   174                                  	;jz	short L2
   175 0000001B 81F90004                        cmp     cx, 1024
   176 0000001F 7351                    	jnb	short L0
   177                                  		 ; insufficient memory_error	
   178                                  		 ; Minimum 2 MB memory is needed... 
   179                                  	; 05/11/2014
   180                                  	; (real mode error printing)
   181 00000021 FB                      	sti
   182 00000022 BE[3600]                	mov	si, msg_out_of_memory
   183 00000025 BB0700                  	mov	bx, 7
   184 00000028 B40E                    	mov	ah, 0Eh	; write tty
   185                                  oom_1:
   186 0000002A AC                      	lodsb
   187 0000002B 08C0                    	or	al, al
   188 0000002D 7404                    	jz	short oom_2
   189 0000002F CD10                    	int	10h
   190 00000031 EBF7                    	jmp	short oom_1
   191                                  oom_2:
   192 00000033 F4                              hlt
   193 00000034 EBFD                    	jmp	short oom_2
   194                                  
   195                                  ; 28/11/2021 - Retro UNIX 386 v2 compatibility modification (on v1.1)
   196                                  ; 11/04/2021 - Retro UNIX 386 v2
   197                                  ; ((Real mode messages and buffers must be in the 1st 64K of the kernel))
   198                                  ; 20/02/2017 (TRDOS 386 v2)
   199                                  ; 05/11/2014
   200                                  msg_out_of_memory:
   201 00000036 070D0A                  	db 	07h, 0Dh, 0Ah
   202 00000039 496E73756666696369-             db      'Insufficient memory !'
   203 00000042 656E74206D656D6F72-
   204 0000004B 792021             
   205 0000004E 0D0A                    	db	0Dh, 0Ah
   206                                  _int13h_48h_buffer: ; 07/07/2016
   207 00000050 284D696E696D756D20-     	db	'(Minimum 2MB memory is needed.)'
   208 00000059 324D42206D656D6F72-
   209 00000062 79206973206E656564-
   210 0000006B 65642E29           
   211 0000006F 0D0A00                   	db	0Dh, 0Ah, 0
   212                                  
   213                                  L0:
   214                                  %include 'diskinit.s' ; 07/03/2015
   215                              <1> ; Retro UNIX 386 v1 Kernel - DISKINIT.INC
   216                              <1> ; Last Modification: 04/02/2016
   217                              <1> 
   218                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
   219                              <1> 
   220                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
   221                              <1> 
   222                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
   223                              <1> ;L0:
   224                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
   225                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
   226 00000072 BA7F00              <1> 	mov	dx, 7Fh
   227                              <1> L1:	
   228 00000075 FEC2                <1> 	inc	dl
   229 00000077 B441                <1> 	mov	ah, 41h ; Check extensions present
   230                              <1> 			; Phoenix EDD v1.1 - EDD v3
   231 00000079 BBAA55              <1> 	mov	bx, 55AAh
   232 0000007C CD13                <1> 	int 	13h
   233 0000007E 721A                <1> 	jc	short L2
   234                              <1> 
   235 00000080 81FB55AA            <1> 	cmp	bx, 0AA55h
   236 00000084 7514                <1> 	jne	short L2
   237 00000086 FE06[AD6A]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
   238 0000008A 8816[AC6A]          <1>         mov     [last_drv], dl  ; last hard disk number
   239 0000008E BB[306A]            <1> 	mov	bx, hd0_type - 80h
   240 00000091 01D3                <1> 	add	bx, dx	 
   241 00000093 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
   242                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
   243                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
   244                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
   245                              <1>                          ;            (EDD) ready (DPTE ready)
   246                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
   247                              <1>                          ;            (EDD-3)
   248                              <1> 			 ; Bit 4 to 15 - 0, Reserved
   249 00000095 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
   250 00000098 72DB                <1> 	jb	short L1
   251                              <1> L2:
   252                              <1> 	; 23/11/2014
   253                              <1> 	; 19/11/2014
   254 0000009A 30D2                <1> 	xor	dl, dl  ; 0
   255                              <1> 	; 04/02/2016 (esi -> si)
   256 0000009C BE[AE6A]            <1> 	mov	si, fd0_type
   257                              <1> L3:
   258                              <1> 	; 14/01/2015
   259 0000009F 8816[AB6A]          <1> 	mov	[drv], dl
   260                              <1> 	;
   261 000000A3 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   262 000000A5 CD13                <1> 	int	13h	
   263 000000A7 7210                <1> 	jc	short L4
   264                              <1> 		; BL = drive type (for floppy drives)
   265                              <1> 		; DL = number of floppy drives
   266                              <1> 		;		
   267                              <1> 		; ES:DI = Address of DPT from BIOS
   268                              <1> 		;
   269 000000A9 881C                <1> 	mov	[si], bl ;  Drive type
   270                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
   271                              <1> 	; 14/01/2015
   272 000000AB E8A202              <1> 	call	set_disk_parms
   273                              <1> 	; 10/12/2014
   274 000000AE 81FE[AE6A]          <1> 	cmp	si, fd0_type
   275 000000B2 7705                <1> 	ja	short L4
   276 000000B4 46                  <1> 	inc	si ; fd1_type
   277 000000B5 B201                <1> 	mov	dl, 1
   278 000000B7 EBE6                <1> 	jmp	short L3
   279                              <1> L4:
   280                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   281 000000B9 B27F                <1> 	mov	dl, 7Fh
   282                              <1> 	; 24/12/2014 (Temporary)
   283 000000BB 803E[AD6A]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
   284 000000C0 0F879000            <1>         ja      L10       ; yes, all fixed disk operations
   285                              <1> 			  ; will be performed according to
   286                              <1> 			  ; present EDD specification
   287                              <1> L6:
   288 000000C4 FEC2                <1> 	inc 	dl
   289 000000C6 8816[AB6A]          <1>         mov     [drv], dl
   290 000000CA 8816[AC6A]          <1>         mov     [last_drv], dl ; 14/01/2015
   291 000000CE B408                <1> 	mov 	ah, 08h ; Return drive parameters
   292 000000D0 CD13                <1> 	int	13h	; (conventional function)
   293 000000D2 0F828201            <1>         jc      L13	; fixed disk drive not ready
   294 000000D6 8816[AD6A]          <1>         mov     [hdc], dl ; number of drives
   295                              <1> 	;; 14/01/2013
   296                              <1> 	;;push	cx
   297 000000DA E87302              <1> 	call	set_disk_parms
   298                              <1> 	;;pop	cx
   299                              <1> 	;
   300                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   301 000000DD 8A16[AB6A]          <1>         mov     dl, [drv]
   302 000000E1 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   303 000000E4 80FA80              <1> 	cmp	dl, 80h
   304 000000E7 7603                <1> 	jna	short L7
   305 000000E9 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   306                              <1> L7:	
   307 000000EC 31C0                <1> 	xor	ax, ax
   308 000000EE 8ED8                <1> 	mov	ds, ax
   309 000000F0 8B37                <1>         mov     si, [bx]
   310 000000F2 8B4702              <1>         mov     ax, [bx+2] 
   311 000000F5 8ED8                <1> 	mov	ds, ax
   312 000000F7 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   313 000000FA 0F855601            <1>         jne     L12 ; invalid FDPT
   314 000000FE BF0000              <1> 	mov	di, HD0_DPT
   315 00000101 80FA80              <1> 	cmp	dl, 80h
   316 00000104 7603                <1> 	jna	short L8
   317 00000106 BF2000              <1> 	mov	di, HD1_DPT 
   318                              <1> L8:
   319                              <1> 	; 30/12/2014
   320 00000109 B80090              <1> 	mov	ax, DPT_SEGM
   321 0000010C 8EC0                <1> 	mov	es, ax
   322                              <1> 	; 24/12/2014
   323 0000010E B90800              <1> 	mov	cx, 8
   324 00000111 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   325 00000113 8CC8                <1> 	mov	ax, cs
   326 00000115 8ED8                <1> 	mov	ds, ax
   327                              <1> 	; 02/02/2015
   328 00000117 8A0E[AB6A]          <1>         mov     cl, [drv]
   329 0000011B 88CB                <1> 	mov	bl, cl
   330 0000011D B8F001              <1> 	mov	ax, 1F0h
   331 00000120 80E301              <1> 	and	bl, 1
   332 00000123 7406                <1> 	jz	short L9
   333 00000125 C0E304              <1> 	shl	bl, 4
   334 00000128 2D8000              <1> 	sub	ax, 1F0h-170h
   335                              <1> L9:
   336 0000012B AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   337 0000012C 050602              <1> 	add	ax, 206h
   338 0000012F AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   339 00000130 88D8                <1> 	mov	al, bl
   340 00000132 04A0                <1> 	add	al, 0A0h
   341 00000134 AA                  <1> 	stosb	; Device/Head Register upper nibble
   342                              <1> 	;
   343 00000135 FE06[AB6A]          <1> 	inc	byte [drv]
   344 00000139 BB[306A]            <1> 	mov	bx, hd0_type - 80h
   345 0000013C 01CB                <1> 	add	bx, cx
   346 0000013E 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   347 00000141 A0[AD6A]            <1> 	mov	al, [hdc]
   348 00000144 FEC8                <1> 	dec	al
   349 00000146 0F840E01            <1>         jz      L13
   350 0000014A 80FA80              <1> 	cmp	dl, 80h
   351 0000014D 0F8673FF            <1>         jna     L6
   352 00000151 E90401              <1>         jmp     L13
   353                              <1> L10:
   354 00000154 FEC2                <1> 	inc 	dl
   355                              <1> 	; 25/12/2014
   356 00000156 8816[AB6A]          <1> 	mov	[drv], dl
   357 0000015A B408                <1> 	mov 	ah, 08h ; Return drive parameters
   358 0000015C CD13                <1> 	int	13h	; (conventional function)
   359 0000015E 0F82F600            <1>         jc      L13
   360                              <1> 	; 14/01/2015
   361 00000162 8A16[AB6A]          <1> 	mov	dl, [drv]
   362 00000166 52                  <1> 	push	dx
   363 00000167 51                  <1> 	push	cx
   364 00000168 E8E501              <1> 	call	set_disk_parms
   365 0000016B 59                  <1> 	pop	cx
   366 0000016C 5A                  <1> 	pop	dx
   367                              <1> 	; 04/02/2016 (esi -> si)
   368 0000016D BE[5482]            <1> 	mov	si, _end ; 30 byte temporary buffer address 	
   369                              <1> 			 ; at the '_end' of kernel.
   370 00000170 C7041E00            <1> 	mov	word [si], 30
   371 00000174 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   372 00000176 CD13                <1> 	int	13h
   373 00000178 0F82DC00            <1>         jc      L13
   374                              <1> 	; 04/02/2016 (ebx -> bx)
   375                              <1> 	; 14/01/2015
   376 0000017C 29DB                <1> 	sub	bx, bx
   377 0000017E 88D3                <1> 	mov	bl, dl
   378 00000180 80EB80              <1> 	sub	bl, 80h
   379 00000183 81C3[B06A]          <1> 	add	bx, hd0_type
   380 00000187 8A07                <1> 	mov 	al, [bx]
   381 00000189 0C80                <1> 	or	al, 80h
   382 0000018B 8807                <1> 	mov 	[bx], al	
   383 0000018D 81EB[AE6A]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   384 00000191 81C3[FA6A]          <1> 	add	bx, drv.status
   385 00000195 8807                <1> 	mov	[bx], al
   386                              <1> 	; 04/02/2016 (eax -> ax)
   387 00000197 8B4410              <1> 	mov	ax, [si+16]
   388 0000019A 854412              <1> 	test	ax, [si+18]
   389 0000019D 7412                <1> 	jz	short L10_A0h 
   390                              <1> 			; 'CHS only' disks on EDD system 
   391                              <1> 			;  are reported with ZERO disk size
   392 0000019F 81EB[FA6A]          <1> 	sub	bx, drv.status
   393 000001A3 C1E302              <1> 	shl	bx, 2
   394 000001A6 81C3[DE6A]          <1> 	add	bx, drv.size ; disk size (in sectors)
   395 000001AA 8907                <1> 	mov	[bx], ax
   396 000001AC 8B4412              <1> 	mov	ax, [si+18]
   397 000001AF 8907                <1> 	mov	[bx], ax
   398                              <1> 
   399                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   400                              <1> 	 ; for CHS disks (28/02/2015)
   401                              <1> 	; 30/12/2014
   402 000001B1 BF0000              <1> 	mov	di, HD0_DPT
   403 000001B4 88D0                <1> 	mov	al, dl
   404 000001B6 83E003              <1> 	and 	ax, 3
   405 000001B9 C0E005              <1> 	shl	al, 5 ; *32
   406 000001BC 01C7                <1> 	add 	di, ax
   407 000001BE B80090              <1> 	mov	ax, DPT_SEGM
   408 000001C1 8EC0                <1> 	mov	es, ax
   409                              <1> 	;
   410 000001C3 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   411 000001C5 88CC                <1> 	mov	ah, cl	
   412 000001C7 C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   413 000001CA 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   414 000001CB AB                  <1> 	stosw		
   415 000001CC 88F0                <1> 	mov	al, dh	; max. head number
   416 000001CE FEC0                <1> 	inc	al
   417 000001D0 AA                  <1> 	stosb		; logical heads (limits 256)
   418 000001D1 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   419 000001D3 AA                  <1> 	stosb
   420 000001D4 8A440C              <1> 	mov	al, [si+12]
   421 000001D7 AA                  <1> 	stosb		 ; physical sectors per track
   422 000001D8 31C0                <1>  	xor	ax, ax
   423                              <1> 	;dec	ax	 ; 02/01/2015 
   424 000001DA AB                  <1> 	stosw		 ; precompensation (obsolete)
   425                              <1> 	;xor	al, al	 ; 02/01/2015	
   426 000001DB AA                  <1> 	stosb		 ; reserved
   427 000001DC B008                <1> 	mov	al, 8	 ; drive control byte
   428                              <1> 		         ; (do not disable retries, 
   429                              <1> 			 ; more than 8 heads)
   430 000001DE AA                  <1> 	stosb
   431 000001DF 8B4404              <1> 	mov	ax, [si+4]
   432 000001E2 AB                  <1> 	stosw		 ; physical number of cylinders	
   433                              <1> 	;push	ax	 ; 02/01/2015
   434 000001E3 8A4408              <1> 	mov	al, [si+8]
   435 000001E6 AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   436 000001E7 29C0                <1> 	sub 	ax, ax
   437                              <1> 	;pop	ax	 ; 02/01/2015	
   438 000001E9 AB                  <1> 	stosw		 ; landing zone (obsolete)
   439 000001EA 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   440 000001EC 243F                <1> 	and 	al, 3Fh	
   441 000001EE AA                  <1> 	stosb
   442                              <1> 	;sub	al, al	 ; checksum
   443                              <1> 	;stosb
   444                              <1> 	;
   445 000001EF 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   446 000001F2 AD                  <1> 	lodsw
   447 000001F3 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   448 000001F4 AD                  <1> 	lodsw
   449 000001F5 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   450                              <1> 	;
   451                              <1> 	; checksum calculation
   452 000001F6 89FE                <1> 	mov	si, di
   453 000001F8 06                  <1> 	push	es
   454 000001F9 1F                  <1> 	pop	ds
   455                              <1> 	;mov	cx, 16
   456 000001FA B90F00              <1> 	mov 	cx, 15
   457 000001FD 29CE                <1> 	sub	si, cx
   458 000001FF 30E4                <1> 	xor	ah, ah
   459                              <1> 	;del	cl
   460                              <1> L11:		
   461 00000201 AC                  <1> 	lodsb
   462 00000202 00C4                <1> 	add	ah, al
   463 00000204 E2FB                <1> 	loop	L11
   464                              <1> 	;
   465 00000206 88E0                <1> 	mov	al, ah
   466 00000208 F6D8                <1> 	neg	al	; -x+x = 0
   467 0000020A AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   468                              <1> 	;
   469 0000020B 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   470 0000020C 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   471                              <1> 	;
   472                              <1> 	; 23/02/2015
   473 0000020D 57                  <1> 	push	di
   474                              <1> 	; ES:DI points to DPTE (FDPTE) location
   475                              <1> 	;mov	cx, 8
   476 0000020E B108                <1> 	mov	cl, 8
   477 00000210 F3A5                <1> 	rep	movsw	
   478                              <1> 	;
   479                              <1> 	; 23/02/2015
   480                              <1> 	; (P)ATA drive and LBA validation
   481                              <1> 	; (invalidating SATA drives and setting
   482                              <1> 	; CHS type I/O for old type fixed disks)
   483 00000212 5B                  <1> 	pop	bx
   484 00000213 8CC8                <1> 	mov	ax, cs
   485 00000215 8ED8                <1> 	mov	ds, ax
   486 00000217 268B07              <1> 	mov	ax, [es:bx]
   487 0000021A 3DF001              <1> 	cmp	ax, 1F0h
   488 0000021D 7418                <1> 	je	short L11a
   489 0000021F 3D7001              <1> 	cmp	ax, 170h
   490 00000222 7413                <1> 	je	short L11a
   491                              <1> 	; invalidation 
   492                              <1> 	; (because base port address is not 1F0h or 170h)
   493 00000224 30FF                <1> 	xor	bh, bh
   494 00000226 88D3                <1> 	mov	bl, dl
   495 00000228 80EB80              <1> 	sub	bl, 80h
   496 0000022B C687[B06A]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   497 00000230 808F[FC6A]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   498 00000235 EB14                <1> 	jmp	short L11b
   499                              <1> L11a:	
   500                              <1> 	; LBA validation
   501 00000237 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   502 0000023B A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   503 0000023D 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   504                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   505 0000023F 28FF                <1> 	sub	bh, bh
   506 00000241 88D3                <1> 	mov	bl, dl
   507 00000243 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   508 00000246 80A7[FC6A]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   509                              <1> 				; bit 0 = LBA ready bit
   510                              <1> 	; 'diskio' procedure will check this bit !
   511                              <1> L11b:
   512 0000024B 3A16[AC6A]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   513 0000024F 7307                <1>         jnb     short L13
   514 00000251 E900FF              <1>         jmp     L10
   515                              <1> L12:
   516                              <1> 	; Restore data registers
   517 00000254 8CC8                <1> 	mov	ax, cs
   518 00000256 8ED8                <1> 	mov	ds, ax	
   519                              <1> L13:
   520                              <1> 	; 13/12/2014
   521 00000258 0E                  <1> 	push	cs
   522 00000259 07                  <1> 	pop	es
   523                              <1> L14:
   524 0000025A B411                <1> 	mov 	ah, 11h
   525 0000025C CD16                <1> 	int 	16h
   526 0000025E 7406                <1> 	jz 	short L15 ; no keys in keyboard buffer
   527 00000260 B010                <1> 	mov	al, 10h
   528 00000262 CD16                <1> 	int 	16h
   529 00000264 EBF4                <1> 	jmp 	short L14
   530                              <1> L15:
   531                              <1> ; //////
   532                              <1> 	; 24/11/2014
   533                              <1> 	; 19/11/2014
   534                              <1> 	; 14/11/2014
   535                              <1> 	; Temporary code for disk searching code check
   536                              <1> 	;
   537                              <1> 	; This code will show existing (usable) drives and also
   538                              <1> 	; will show EDD interface support status for hard disks		
   539                              <1> 	; (If status bit 7 is 1, Identify Device info is ready,
   540                              <1> 	; no need to get it again in protected mode...) 
   541                              <1> 	;	
   542                              <1> 	; 13/11/2014
   543 00000266 BB0700              <1> 	mov	bx, 7
   544 00000269 B40E                <1> 	mov	ah, 0Eh
   545 0000026B A0[AE6A]            <1> 	mov	al, [fd0_type]
   546 0000026E 20C0                <1> 	and	al, al
   547 00000270 743D                <1> 	jz	short L15a
   548 00000272 88C2                <1> 	mov	dl, al
   549 00000274 B046                <1> 	mov	al, 'F'
   550 00000276 CD10                <1> 	int 	10h
   551 00000278 B044                <1> 	mov	al, 'D'
   552 0000027A CD10                <1> 	int 	10h
   553 0000027C B030                <1> 	mov	al, '0'
   554 0000027E CD10                <1> 	int 	10h
   555 00000280 B020                <1> 	mov	al, ' '
   556 00000282 CD10                <1> 	int	10h
   557 00000284 E8B200              <1> 	call	L15c
   558 00000287 B020                <1> 	mov	al, ' '
   559 00000289 CD10                <1> 	int	10h
   560                              <1> 	;
   561 0000028B A0[AF6A]            <1> 	mov	al, [fd1_type]
   562 0000028E 20C0                <1> 	and	al, al
   563 00000290 741D                <1> 	jz	short L15a
   564 00000292 88C2                <1> 	mov	dl, al
   565 00000294 B046                <1> 	mov	al, 'F'
   566 00000296 CD10                <1> 	int 	10h
   567 00000298 B044                <1> 	mov	al, 'D'
   568 0000029A CD10                <1> 	int 	10h
   569 0000029C B031                <1> 	mov	al, '1'
   570 0000029E CD10                <1> 	int 	10h
   571 000002A0 B020                <1> 	mov	al, ' '
   572 000002A2 CD10                <1> 	int	10h
   573 000002A4 E89200              <1> 	call	L15c
   574 000002A7 B020                <1> 	mov	al, ' '
   575 000002A9 CD10                <1> 	int	10h
   576 000002AB B020                <1> 	mov	al, ' '
   577 000002AD CD10                <1> 	int	10h
   578                              <1> L15a:
   579 000002AF A0[B06A]            <1> 	mov	al, [hd0_type]
   580 000002B2 20C0                <1> 	and	al, al
   581 000002B4 7479                <1> 	jz	short L15b
   582 000002B6 88C2                <1> 	mov	dl, al
   583 000002B8 B048                <1> 	mov	al, 'H'
   584 000002BA CD10                <1> 	int 	10h
   585 000002BC B044                <1> 	mov	al, 'D'
   586 000002BE CD10                <1> 	int 	10h
   587 000002C0 B030                <1> 	mov	al, '0'
   588 000002C2 CD10                <1> 	int 	10h
   589 000002C4 B020                <1> 	mov	al, ' '
   590 000002C6 CD10                <1> 	int 	10h
   591 000002C8 E86E00              <1> 	call	L15c
   592 000002CB B020                <1> 	mov	al, ' '
   593 000002CD CD10                <1> 	int	10h
   594                              <1> 	;
   595 000002CF A0[B16A]            <1> 	mov	al, [hd1_type]
   596 000002D2 20C0                <1> 	and	al, al
   597 000002D4 7459                <1> 	jz	short L15b
   598 000002D6 88C2                <1> 	mov	dl, al
   599 000002D8 B048                <1> 	mov	al, 'H'
   600 000002DA CD10                <1> 	int 	10h
   601 000002DC B044                <1> 	mov	al, 'D'
   602 000002DE CD10                <1> 	int 	10h
   603 000002E0 B031                <1> 	mov	al, '1'
   604 000002E2 CD10                <1> 	int 	10h
   605 000002E4 B020                <1> 	mov	al, ' '
   606 000002E6 CD10                <1> 	int 	10h
   607 000002E8 E84E00              <1> 	call	L15c
   608 000002EB B020                <1> 	mov	al, ' '
   609 000002ED CD10                <1> 	int	10h
   610                              <1> 	;
   611 000002EF A0[B26A]            <1> 	mov	al, [hd2_type]
   612 000002F2 20C0                <1> 	and	al, al
   613 000002F4 7439                <1> 	jz	short L15b
   614 000002F6 88C2                <1> 	mov	dl, al
   615 000002F8 B048                <1> 	mov	al, 'H'
   616 000002FA CD10                <1> 	int 	10h
   617 000002FC B044                <1> 	mov	al, 'D'
   618 000002FE CD10                <1> 	int 	10h
   619 00000300 B032                <1> 	mov	al, '2'
   620 00000302 CD10                <1> 	int 	10h
   621 00000304 B020                <1> 	mov	al, ' '
   622 00000306 CD10                <1> 	int 	10h
   623 00000308 E82E00              <1> 	call	L15c
   624 0000030B B020                <1> 	mov	al, ' '
   625 0000030D CD10                <1> 	int	10h
   626                              <1> 	;
   627 0000030F A0[B36A]            <1> 	mov	al, [hd3_type]
   628 00000312 20C0                <1> 	and	al, al
   629 00000314 7419                <1> 	jz	short L15b
   630 00000316 88C2                <1> 	mov	dl, al
   631 00000318 B048                <1> 	mov	al, 'H'
   632 0000031A CD10                <1> 	int 	10h
   633 0000031C B044                <1> 	mov	al, 'D'
   634 0000031E CD10                <1> 	int 	10h
   635 00000320 B033                <1> 	mov	al, '3'
   636 00000322 CD10                <1> 	int 	10h
   637 00000324 B020                <1> 	mov	al, ' '
   638 00000326 CD10                <1> 	int 	10h
   639 00000328 E80E00              <1> 	call	L15c
   640 0000032B B020                <1> 	mov	al, ' '
   641 0000032D CD10                <1> 	int	10h
   642                              <1> 	;
   643                              <1> L15b:
   644 0000032F B00D                <1> 	mov	al, 0Dh
   645 00000331 CD10                <1> 	int 	10h	
   646 00000333 B00A                <1> 	mov	al, 0Ah
   647 00000335 CD10                <1> 	int 	10h
   648                              <1> 	;;xor	ah, ah
   649                              <1> 	;;int 	16h	
   650                              <1> 	;
   651 00000337 EB77                <1>         jmp     L16  ; jmp short L16
   652                              <1>         ;
   653                              <1> L15c:
   654 00000339 88D6                <1> 	mov	dh, dl
   655 0000033B C0EE04              <1> 	shr	dh, 4
   656 0000033E 80C630              <1> 	add	dh, 30h
   657 00000341 80E20F              <1> 	and	dl, 15
   658 00000344 80C230              <1> 	add	dl, 30h
   659 00000347 88F0                <1> 	mov	al, dh
   660 00000349 CD10                <1> 	int	10h
   661 0000034B 88D0                <1> 	mov	al, dl
   662 0000034D CD10                <1> 	int	10h
   663 0000034F C3                  <1> 	retn
   664                              <1> 	;
   665                              <1> 	; end of temporary code for disk searching code check
   666                              <1> 
   667                              <1> ; //////
   668                              <1> 
   669                              <1> set_disk_parms:
   670                              <1> 	; 04/02/2016 (ebx -> bx)
   671                              <1> 	; 10/07/2015
   672                              <1> 	; 14/01/2015
   673                              <1> 	;push	bx
   674 00000350 28FF                <1> 	sub	bh, bh
   675 00000352 8A1E[AB6A]          <1> 	mov	bl, [drv]
   676 00000356 80FB80              <1> 	cmp	bl, 80h
   677 00000359 7203                <1> 	jb	short sdp0
   678 0000035B 80EB7E              <1> 	sub	bl, 7Eh
   679                              <1> sdp0:	
   680 0000035E 81C3[FA6A]          <1> 	add	bx, drv.status
   681 00000362 C60780              <1>   	mov	byte [bx], 80h ; 'Present' flag
   682                              <1> 	;
   683 00000365 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   684 00000367 88CC                <1> 	mov	ah, cl ; 
   685 00000369 C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   686 0000036C 81EB[FA6A]          <1> 	sub	bx, drv.status
   687 00000370 D0E3                <1> 	shl	bl, 1
   688 00000372 81C3[B46A]          <1> 	add	bx, drv.cylinders
   689 00000376 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   690 00000377 8907                <1> 	mov	[bx], ax
   691 00000379 50                  <1> 	push	ax ; ** cylinders
   692 0000037A 81EB[B46A]          <1> 	sub	bx, drv.cylinders
   693 0000037E 81C3[C26A]          <1> 	add	bx, drv.heads
   694 00000382 30E4                <1> 	xor	ah, ah
   695 00000384 88F0                <1> 	mov	al, dh ; heads
   696 00000386 40                  <1> 	inc	ax
   697 00000387 8907                <1> 	mov	[bx], ax
   698 00000389 81EB[C26A]          <1>         sub     bx, drv.heads
   699 0000038D 81C3[D06A]          <1>         add     bx, drv.spt
   700 00000391 30ED                <1> 	xor	ch, ch
   701 00000393 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   702 00000396 890F                <1> 	mov	[bx], cx
   703 00000398 81EB[D06A]          <1>         sub     bx, drv.spt
   704 0000039C D1E3                <1> 	shl	bx, 1
   705 0000039E 81C3[DE6A]          <1> 	add	bx, drv.size ; disk size (in sectors)
   706                              <1> 	; LBA size = cylinders * heads * secpertrack
   707 000003A2 F7E1                <1> 	mul	cx 
   708 000003A4 89C2                <1> 	mov	dx, ax	; heads*spt					
   709 000003A6 58                  <1> 	pop	ax ; ** cylinders
   710 000003A7 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   711 000003A8 F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   712 000003AA 8907                <1> 	mov	[bx], ax
   713 000003AC 895702              <1> 	mov	[bx+2], dx
   714                              <1> 	;
   715                              <1> 	;pop	bx
   716 000003AF C3                  <1> 	retn
   717                              <1> 
   718                              <1> ;align 2
   719                              <1> 
   720                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   721                              <1> ;heads	  :  dw 0, 0, 0, 0, 0, 0
   722                              <1> ;spt	  :  dw 0, 0, 0, 0, 0, 0
   723                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   724                              <1> 
   725                              <1> ;last_drv:
   726                              <1> ;	db  0
   727                              <1> ;drv_status:
   728                              <1> ;	db  0,0,0,0,0,0
   729                              <1> ;	db 0
   730                              <1> 
   731                              <1> 
   732                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   733                              <1> 
   734                              <1> L16:
   735                                  _L0:	
   736                                  	; 10/11/2014
   737 000003B0 FA                           	cli	; Disable interrupts (clear interrupt flag)
   738                                  		; Reset Interrupt MASK Registers (Master&Slave)
   739                                  	;mov	al, 0FFh	; mask off all interrupts
   740                                  	;out	21h, al		; on master PIC (8259)
   741                                  	;jmp 	$+2  ; (delay)
   742                                  	;out	0A1h, al	; on slave PIC (8259)
   743                                  	;
   744                                  	; Disable NMI 
   745 000003B1 B080                    	mov   	al, 80h 
   746 000003B3 E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   747                                  	;23/02/2015
   748 000003B5 90                      	nop			;
   749                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   750                                  				; for preventing unknown state (!?)
   751                                  	;
   752                                   	; 20/08/2014
   753                                  	; Moving the kernel 64 KB back (to physical address 0)
   754                                  	; DS = CS = 1000h
   755                                  	; 05/11/2014
   756 000003B6 31C0                    	xor	ax, ax
   757 000003B8 8EC0                    	mov	es, ax ; ES = 0
   758                                  	;
   759 000003BA B90040                  	mov	cx, (KEND - KLOAD)/4
   760 000003BD 31F6                    	xor	si, si
   761 000003BF 31FF                    	xor	di, di
   762 000003C1 F366A5                  	rep	movsd
   763                                  	;
   764 000003C4 06                      	push	es ; 0
   765 000003C5 68[C903]                	push	L17
   766 000003C8 CB                      	retf
   767                                  	;
   768                                  L17:
   769                                  	; Turn off the floppy drive motor
   770 000003C9 BAF203                          mov     dx, 3F2h
   771 000003CC EE                              out     dx, al ; 0 ; 31/12/2013
   772                                  
   773                                  	; Enable access to memory above one megabyte
   774                                  L18:
   775 000003CD E464                    	in	al, 64h
   776 000003CF A802                    	test	al, 2
   777 000003D1 75FA                            jnz     short L18
   778 000003D3 B0D1                    	mov	al, 0D1h	; Write output port
   779 000003D5 E664                    	out	64h, al
   780                                  L19:
   781 000003D7 E464                    	in	al, 64h
   782 000003D9 A802                    	test	al, 2
   783 000003DB 75FA                            jnz     short L19
   784 000003DD B0DF                    	mov	al, 0DFh	; Enable A20 line
   785 000003DF E660                    	out	60h, al
   786                                  ;L20:
   787                                  	;
   788                                  	; Load global descriptor table register
   789                                  
   790                                          ;mov     ax, cs
   791                                          ;mov     ds, ax
   792                                  
   793 000003E1 2E0F0116[D067]                  lgdt    [cs:gdtd]
   794                                  
   795 000003E7 0F20C0                          mov     eax, cr0
   796                                  	; or 	eax, 1
   797 000003EA 40                      	inc     ax
   798 000003EB 0F22C0                  	mov     cr0, eax
   799                                  
   800                                  	; Jump to 32 bit code
   801                                  	
   802 000003EE 66                      	db	66h 		; Prefix for 32-bit
   803 000003EF EA                      	db	0EAh 		; Opcode for far jump
   804 000003F0 [F6030000]              	dd	StartPM 	; Offset to start, 32-bit
   805                                  				; (1000h:StartPM = StartPM + 10000h)
   806 000003F4 0800                    	dw	KCODE		; This is the selector for CODE32_DESCRIPTOR,
   807                                  				; assuming that StartPM resides in code32
   808                                  
   809                                  [BITS 32] 
   810                                  
   811                                  StartPM:
   812                                  	; Kernel Base Address = 0 ; 30/12/2013
   813 000003F6 66B81000                	mov	ax, KDATA	; Save data segment identifier
   814 000003FA 8ED8                            mov	ds, ax		; Move a valid data segment into DS register
   815 000003FC 8EC0                           	mov	es, ax		; Move data segment into ES register
   816 000003FE 8EE0                           	mov	fs, ax		; Move data segment into FS register
   817 00000400 8EE8                          	mov	gs, ax		; Move data segment into GS register
   818 00000402 8ED0                            mov	ss, ax		; Move data segment into SS register
   819 00000404 BC00000900                      mov	esp, 90000h	; Move the stack pointer to 090000h
   820                                  
   821                                  clear_bss: ; Clear uninitialized data area
   822                                  	; 11/03/2015
   823 00000409 31C0                    	xor	eax, eax ; 0
   824                                  	;mov	ecx, (bss_end - bss_start)/4
   825                                  	;;shr	ecx, 2 ; bss section is already aligned for double words
   826                                  	; 12/12/2021
   827 0000040B B941050000              	mov	ecx, BSS_SIZE/4
   828 00000410 BF[506D0000]            	mov	edi, bss_start	
   829 00000415 F3AB                    	rep	stosd  		
   830                                  
   831                                  memory_init:
   832                                  	; Initialize memory allocation table and page tables
   833                                  	; 16/11/2014
   834                                  	; 15/11/2014
   835                                  	; 07/11/2014
   836                                  	; 06/11/2014
   837                                  	; 05/11/2014
   838                                  	; 04/11/2014
   839                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   840                                  	;
   841                                  ;	xor	eax, eax
   842                                  ;	xor 	ecx, ecx
   843 00000417 B108                    	mov	cl, 8
   844 00000419 BF00001000              	mov	edi, MEM_ALLOC_TBL	
   845 0000041E F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   846                                  				   ; for the first 1 MB memory
   847                                  	;
   848 00000420 668B0D[446D0000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   849                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   850 00000427 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   851 0000042B 890D[C06F0000]          	mov	[free_pages], ecx
   852 00000431 668B15[466D0000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   853                                  				   ; between 16 MB and 4 GB.	
   854 00000438 6609D2                  	or	dx, dx
   855 0000043B 7413                    	jz	short mi_0
   856                                  	;
   857 0000043D 6689D0                  	mov	ax, dx
   858 00000440 C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   859 00000443 0105[C06F0000]          	add	[free_pages], eax
   860 00000449 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   861 0000044E EB07                    	jmp	short mi_1
   862                                  mi_0:
   863 00000450 6689C8                  	mov	ax, cx
   864 00000453 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   865                                  mi_1:
   866 00000457 A3[BC6F0000]            	mov	[memory_size], eax ; Total available memory in pages
   867                                  				   ; 1 alloc. tbl. bit = 1 memory page
   868                                  				   ; 32 allocation bits = 32 mem. pages   
   869                                  	;
   870 0000045C 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   871 00000461 C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   872                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   873                                  				   ;  --> x M.A.T. pages, if y = 0
   874 00000464 66A3[D06F0000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   875 0000046A C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   876                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   877 0000046D 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   878                                  	; Set/Calculate Kernel's Page Directory Address
   879 0000046F 81C300001000            	add	ebx, MEM_ALLOC_TBL
   880 00000475 891D[B86F0000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   881                                  				   ; just after the last M.A.T. page
   882                                  	;
   883 0000047B 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   884 0000047E A3[C86F0000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   885                                  	;			   ; (allocation status search must be 
   886                                  				   ; stopped after here)	
   887 00000483 31C0                    	xor	eax, eax
   888 00000485 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   889 00000486 6651                    	push	cx
   890 00000488 C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   891                                  				   ; count of 32 allocation bits
   892 0000048B F3AB                    	rep	stosd
   893 0000048D 6659                    	pop	cx
   894 0000048F 40                      	inc	eax		   ; 0	
   895 00000490 80E11F                  	and	cl, 31		   ; remain bits
   896 00000493 7412                    	jz	short mi_4
   897 00000495 8907                    	mov	[edi], eax	   ; reset	
   898                                  mi_2:
   899 00000497 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   900 0000049A FEC9                    	dec	cl
   901 0000049C 7404                    	jz	short mi_3
   902 0000049E FEC0                    	inc	al
   903 000004A0 EBF5                    	jmp	short mi_2
   904                                  mi_3:
   905 000004A2 28C0                    	sub	al, al	   	   ; 0
   906 000004A4 83C704                  	add	edi, 4		   ; 15/11/2014
   907                                  mi_4:
   908 000004A7 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   909 000004AA 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   910                                  	;	
   911 000004AC B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   912                                  	;	
   913 000004B1 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   914 000004B3 7406                    	jz	short mi_5	  ; jump if EDI points to 
   915                                  				  ;         end of first 16 MB	
   916 000004B5 D1E9                    	shr	ecx, 1		  ; convert to dword count
   917 000004B7 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   918 000004B9 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   919                                  				  ; (memory hole under 16 MB)
   920                                  mi_5:
   921 000004BB 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   922 000004BE D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   923 000004C0 9C                      	pushf			  ; 16/11/2014		
   924 000004C1 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   925 000004C2 F3AB                    	rep	stosd
   926 000004C4 40                      	inc	eax		  ; 0
   927 000004C5 9D                      	popf			  ; 16/11/2014
   928 000004C6 7305                    	jnc	short mi_6
   929 000004C8 6648                    	dec	ax		  ; eax = 0000FFFFh
   930 000004CA AB                      	stosd
   931 000004CB 6640                    	inc	ax		  ; 0		
   932                                  mi_6:
   933 000004CD 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   934 000004CF 730A                    	jnb	short mi_7	  ; end of memory allocation table
   935                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   936 000004D1 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   937 000004D3 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   938 000004D5 D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   939 000004D7 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   940 000004D9 F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   941                                  mi_7:
   942                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   943 000004DB BA00001000              	mov	edx, MEM_ALLOC_TBL
   944                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   945                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   946 000004E0 668B0D[D06F0000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   947 000004E7 89D7                    	mov	edi, edx
   948 000004E9 C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   949                                  				  ; byte offset in M.A.T.
   950                                  				  ; (1 M.A.T. byte points to 
   951                                  				  ;	      32768 bytes)
   952                                  				  ; Note: MEM_ALLOC_TBL address 
   953                                  				  ; must be aligned on 128 KB 
   954                                  				  ; boundary!
   955 000004EC 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   956                                  	; eax = 0
   957 000004EE 290D[C06F0000]          	sub	[free_pages], ecx ; 07/11/2014
   958                                  mi_8:
   959 000004F4 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   960                                  	;dec	bl
   961 000004F7 FEC9                    	dec	cl
   962 000004F9 7404                    	jz	short mi_9
   963 000004FB FEC0                    	inc	al
   964 000004FD EBF5                    	jmp	short mi_8
   965                                  mi_9:
   966                                  	;
   967                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   968                                  	;		(allocate pages for system page tables)
   969                                  
   970                                  	; edx = MEM_ALLOC_TBL
   971 000004FF 8B0D[BC6F0000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   972 00000505 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   973 0000050B C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   974                                  				 ; page table count (PDE count)
   975                                  	;
   976 0000050E 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   977                                  	;
   978 0000050F 41                      	inc	ecx		 ; +1 for kernel page directory	
   979                                  	;
   980 00000510 290D[C06F0000]          	sub	[free_pages], ecx ; 07/11/2014
   981                                  	;
   982 00000516 8B35[B86F0000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   983 0000051C C1EE0C                  	shr	esi, 12		 ; convert to page number
   984                                  mi_10:
   985 0000051F 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   986 00000521 89C3                    	mov	ebx, eax
   987 00000523 C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   988 00000526 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   989                                  				 ;   to align on dword boundary
   990 00000529 83E01F                  	and	eax, 31		 ; set allocation bit position 
   991                                  				 ;  (bit 0 to bit 31)
   992                                  	;
   993 0000052C 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   994                                  	;
   995 0000052E 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   996                                  	;
   997 00000531 46                      	inc	esi		 ; next page table
   998 00000532 E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   999                                  				 ; (ecx = page table count + 1)		
  1000                                  	;
  1001 00000534 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
  1002                                  	;
  1003                                  	; Initialize Kernel Page Directory and Kernel Page Tables
  1004                                  	;
  1005                                  	; Initialize Kernel's Page Directory
  1006 00000535 8B3D[B86F0000]          	mov	edi, [k_page_dir]
  1007 0000053B 89F8                    	mov	eax, edi
  1008 0000053D 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
  1009                                  		     	      ; supervisor + read&write + present
  1010 0000053F 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
  1011                                  mi_11:
  1012 00000541 0500100000              	add	eax, 4096	; Add page size (PGSZ)
  1013                                  			        ; EAX points to next page table
  1014 00000546 AB                      	stosd
  1015 00000547 E2F8                    	loop	mi_11
  1016 00000549 29C0                    	sub	eax, eax	; Empty PDE
  1017 0000054B 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
  1018 0000054F 29D1                    	sub	ecx, edx
  1019 00000551 7402                    	jz	short mi_12
  1020 00000553 F3AB                    	rep	stosd 		; clear remain (empty) PDEs
  1021                                  	;
  1022                                  	; Initialization of Kernel's Page Directory is OK, here.
  1023                                  mi_12:
  1024                                  	; Initialize Kernel's Page Tables
  1025                                  	;
  1026                                  	; (EDI points to address of page table 0)
  1027                                  	; eax = 0
  1028 00000555 8B0D[BC6F0000]          	mov	ecx, [memory_size] ; memory size in pages
  1029 0000055B 89CA                    	mov	edx, ecx	; (***)
  1030 0000055D B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
  1031                                  			     ; supervisor + read&write + present 	
  1032                                  mi_13:
  1033 0000055F AB                      	stosd
  1034 00000560 0500100000              	add	eax, 4096	
  1035 00000565 E2F8                    	loop	mi_13	
  1036 00000567 6681E2FF03              	and	dx, 1023	; (***)
  1037 0000056C 740B                    	jz	short mi_14
  1038 0000056E 66B90004                	mov	cx, 1024	
  1039 00000572 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
  1040 00000575 31C0                    	xor	eax, eax
  1041 00000577 F3AB                    	rep	stosd		; clear remain (empty) PTEs 
  1042                                  				; of the last page table
  1043                                  mi_14:
  1044                                  	;  Initialization of Kernel's Page Tables is OK, here.
  1045                                  	;
  1046 00000579 89F8                    	mov	eax, edi	; end of the last page table page
  1047                                  			        ; (beginging of user space pages)
  1048 0000057B C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
  1049 0000057E 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
  1050                                  				; aligning on dword boundary	
  1051                                  	 
  1052 00000580 A3[CC6F0000]            	mov	[first_page], eax
  1053 00000585 A3[C46F0000]            	mov	[next_page], eax ; The first free page pointer
  1054                                  				 ; for user programs
  1055                                  				 ; (Offset in Mem. Alloc. Tbl.)	
  1056                                  	;
  1057                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
  1058                                  	;
  1059                                  	
  1060                                  	; Enable paging
  1061                                  	;
  1062 0000058A A1[B86F0000]                    mov     eax, [k_page_dir]
  1063 0000058F 0F22D8                  	mov	cr3, eax
  1064 00000592 0F20C0                  	mov	eax, cr0
  1065 00000595 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
  1066 0000059A 0F22C0                  	mov	cr0, eax
  1067                                          ;jmp    KCODE:StartPMP
  1068                                  
  1069 0000059D EA                      	db 0EAh 		; Opcode for far jump
  1070 0000059E [A4050000]                      dd StartPMP		; 32 bit offset
  1071 000005A2 0800                    	dw KCODE		; kernel code segment descriptor
  1072                                  
  1073                                  
  1074                                  StartPMP:
  1075                                  	; 06/11//2014
  1076                                  	; Clear video page 0
  1077                                  	;
  1078                                  	; Temporary Code
  1079                                  	;
  1080 000005A4 B9E8030000              	mov	ecx, 80*25/2
  1081 000005A9 BF00800B00              	mov	edi, 0B8000h
  1082 000005AE 31C0                    	xor	eax, eax	; black background, black fore color
  1083 000005B0 F3AB                    	rep	stosd
  1084                                  	
  1085                                  	; 19/08/2014
  1086                                  	; Kernel Base Address = 0
  1087                                  	; It is mapped to (physically) 0 in the page table.
  1088                                  	; So, here is exactly 'StartPMP' address.
  1089                                  	;
  1090                                  	;;mov	ah, 4Eh	; Red background, yellow forecolor
  1091                                  	;;mov	esi, msgPM
  1092                                  	;; 14/08/2015 (kernel version message will appear
  1093                                  	;;	       when protected mode and paging is enabled)
  1094 000005B2 B40B                    	mov	ah, 0Bh ; Black background, light cyan forecolor
  1095 000005B4 BE[106B0000]            	mov	esi, msgKVER
  1096 000005B9 BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
  1097                                  	; 20/08/2014
  1098 000005BE E893010000              	call	printk
  1099                                  
  1100                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
  1101                                  	; // Set IRQ offsets
  1102                                  	;
  1103                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
  1104                                  	;
  1105                                  					;; ICW1
  1106 000005C3 B011                    	mov	al, 11h			; Initialization sequence
  1107 000005C5 E620                    	out	20h, al			; 	8259A-1
  1108                                  	; jmp 	$+2
  1109 000005C7 E6A0                    	out	0A0h, al		; 	8259A-2
  1110                                  					;; ICW2
  1111 000005C9 B020                    	mov	al, 20h			; Start of hardware ints (20h)
  1112 000005CB E621                    	out	21h, al			;	for 8259A-1
  1113                                  	; jmp 	$+2
  1114 000005CD B028                    	mov	al, 28h			; Start of hardware ints (28h)
  1115 000005CF E6A1                    	out	0A1h, al		; 	for 8259A-2
  1116                                  					;
  1117 000005D1 B004                    	mov	al, 04h			;; ICW3
  1118 000005D3 E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
  1119                                  	; jmp 	$+2
  1120 000005D5 B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
  1121 000005D7 E6A1                    	out	0A1h, al		;
  1122                                  					;; ICW4
  1123 000005D9 B001                    	mov	al, 01h	 		;
  1124 000005DB E621                    	out	21h, al			; 	8086 mode, normal EOI	
  1125                                  	; jmp 	$+2
  1126 000005DD E6A1                    	out	0A1h, al		;	for both chips.
  1127                                  
  1128                                  	;mov	al, 0FFh	; mask off all interrupts for now
  1129                                  	;out	21h, al
  1130                                  	;; jmp 	$+2
  1131                                  	;out	0A1h, al
  1132                                  
  1133                                  	; 02/04/2015
  1134                                  	; 26/03/2015 System call (INT 30h) modification
  1135                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
  1136                                  	;
  1137                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
  1138                                  	;  setup_idt:
  1139                                  	;
  1140                                          ;; 16/02/2015
  1141                                  	;;mov	dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1142                                  	; 21/08/2014 (timer_int)
  1143 000005DF BE[DC670000]            	mov	esi, ilist
  1144 000005E4 8D3D[506D0000]          	lea	edi, [idt]
  1145                                  	; 26/03/2015
  1146 000005EA B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
  1147                                  	; 02/04/2015
  1148 000005EF BB00000800              	mov	ebx, 80000h
  1149                                  rp_sidt1:
  1150 000005F4 AD                      	lodsd
  1151 000005F5 89C2                    	mov	edx, eax
  1152 000005F7 66BA008E                	mov	dx, 8E00h
  1153 000005FB 6689C3                  	mov	bx, ax
  1154 000005FE 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
  1155                                         			        ; /* interrupt gate - dpl=0, present */
  1156 00000600 AB                      	stosd	; selector & offset bits 0-15 	
  1157 00000601 89D0                    	mov	eax, edx
  1158 00000603 AB                      	stosd	; attributes & offset bits 16-23
  1159 00000604 E2EE                    	loop	rp_sidt1
  1160 00000606 B110                    	mov	cl, 16		; 16 software interrupts (INT 30h to INT 3Fh)
  1161                                  rp_sidt2:
  1162 00000608 AD                      	lodsd
  1163 00000609 21C0                    	and	eax, eax
  1164 0000060B 7413                    	jz	short rp_sidt3
  1165 0000060D 89C2                    	mov	edx, eax
  1166 0000060F 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1167 00000613 6689C3                  	mov	bx, ax
  1168 00000616 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1169 00000618 AB                      	stosd
  1170 00000619 89D0                    	mov	eax, edx
  1171 0000061B AB                      	stosd
  1172 0000061C E2EA                    	loop	rp_sidt2
  1173 0000061E EB16                    	jmp	short sidt_OK
  1174                                  rp_sidt3:
  1175 00000620 B8[770A0000]            	mov	eax, ignore_int
  1176 00000625 89C2                    	mov	edx, eax
  1177 00000627 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
  1178 0000062B 6689C3                  	mov	bx, ax
  1179 0000062E 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
  1180                                  rp_sidt4:
  1181 00000630 AB                      	stosd
  1182 00000631 92                      	xchg	eax, edx
  1183 00000632 AB                      	stosd
  1184 00000633 92                      	xchg	edx, eax
  1185 00000634 E2FA                    	loop	rp_sidt4
  1186                                  sidt_OK: 
  1187 00000636 0F011D[D6670000]        	lidt 	[idtd]
  1188                                  	;
  1189                                  	; TSS descriptor setup ; 24/03/2015
  1190 0000063D B8[506F0000]            	mov	eax, task_state_segment
  1191 00000642 66A3[CA670000]          	mov	[gdt_tss0], ax
  1192 00000648 C1C010                  	rol	eax, 16
  1193 0000064B A2[CC670000]            	mov	[gdt_tss1], al
  1194 00000650 8825[CF670000]          	mov	[gdt_tss2], ah
  1195 00000656 66C705[B66F0000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
  1196 0000065E 00                 
  1197                                  		; 
  1198                                  		; IO Map Base address (When this address points
  1199                                  		; to end of the TSS, CPU does not use IO port 
  1200                                  		; permission bit map for RING 3 IO permissions, 
  1201                                  		; access to any IO ports in ring 3 will be forbidden.)
  1202                                   		;
  1203                                  	;mov	[tss.esp0], esp ; TSS offset 4
  1204                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
  1205 0000065F 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
  1206                                  			 ; occurs (or a system call -software INT- is requested)
  1207                                  			 ; while cpu running in ring 3 (in user mode).				
  1208                                  			 ; (Kernel stack pointer and segment will be loaded
  1209                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
  1210 00000663 0F00D8                  	ltr	ax  ; Load task register
  1211                                  	;
  1212                                  esp0_set0:
  1213                                  	; 30/07/2015
  1214 00000666 8B0D[BC6F0000]          	mov 	ecx, [memory_size] ; memory size in pages
  1215 0000066C C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
  1216 0000066F 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
  1217                                  			  ; (kernel mode virtual address)
  1218 00000675 7605                    	jna	short esp0_set1
  1219                                  	;
  1220                                  	; If available memory > CORE (end of the 1st 4 MB)
  1221                                  	; set stack pointer to CORE
  1222                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
  1223                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
  1224 00000677 B900004000              	mov	ecx, CORE
  1225                                  esp0_set1:
  1226 0000067C 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
  1227                                  esp0_set_ok:
  1228                                  	; 30/07/2015 (**tss.esp0**) 
  1229 0000067E 8925[546F0000]          	mov	[tss.esp0], esp
  1230 00000684 66C705[586F0000]10-             mov     word [tss.ss0], KDATA
  1231 0000068C 00                 
  1232                                  	; 14/08/2015
  1233                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
  1234                                  	;
  1235                                  	;cli	; Disable interrupts (for CPU)
  1236                                  	;    (CPU will not handle hardware interrupts, except NMI!)
  1237                                  	;
  1238 0000068D 30C0                    	xor	al, al		; Enable all hardware interrupts!
  1239 0000068F E621                    	out	21h, al		; (IBM PC-AT compatibility)
  1240 00000691 EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
  1241 00000693 E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
  1242                                  				; (Even if related hardware component
  1243                                  				;  does not exist!)
  1244                                  	; Enable NMI 
  1245 00000695 B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
  1246 00000697 E670                    	out  	70h, al
  1247                                  	; 23/02/2015
  1248 00000699 90                      	nop
  1249 0000069A E471                    	in	al, 71h		; read in 71h just after writing out to 70h
  1250                                  				; for preventing unknown state (!?)
  1251                                  	;
  1252                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
  1253                                  	;
  1254                                  	; 02/09/2014
  1255 0000069C 6631DB                  	xor	bx, bx
  1256 0000069F 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
  1257 000006A3 E83A0F0000              	call	set_cpos
  1258                                  	;
  1259                                  	; 06/11/2014
  1260                                  	; Temporary Code
  1261                                  	;
  1262 000006A8 E857110000              	call	memory_info
  1263                                  	; 14/08/2015
  1264                                  	;call	getch ; 28/02/2015
  1265                                  drv_init:
  1266 000006AD FB                      	sti	; Enable Interrupts 
  1267                                  	; 06/02/2015
  1268 000006AE 8B15[B06A0000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1269 000006B4 668B1D[AE6A0000]        	mov	bx, [fd0_type] ; fd0, fd1
  1270                                  	; 22/02/2015
  1271 000006BB 6621DB                  	and	bx, bx
  1272 000006BE 751B                    	jnz	short di1
  1273                                  	;
  1274 000006C0 09D2                    	or 	edx, edx
  1275 000006C2 7529                    	jnz	short di2
  1276                                  	;
  1277                                  setup_error:
  1278 000006C4 BE[F96B0000]            	mov 	esi, setup_error_msg
  1279                                  psem:	
  1280 000006C9 AC                      	lodsb
  1281 000006CA 08C0                    	or	al, al
  1282                                  	;jz	short haltx ; 22/02/2015
  1283 000006CC 7426                    	jz	short di3
  1284 000006CE 56                      	push	esi
  1285 000006CF 31DB                    	xor	ebx, ebx ; 0
  1286                                  			; Video page 0 (bl=0)
  1287 000006D1 B407                    	mov	ah, 07h ; Black background, 
  1288                                  			; light gray forecolor
  1289 000006D3 E8E80D0000              	call	write_tty
  1290 000006D8 5E                      	pop	esi
  1291 000006D9 EBEE                    	jmp	short psem
  1292                                  
  1293                                  di1:
  1294                                  	; supress 'jmp short T6'
  1295                                  	;  (activate fdc motor control code)
  1296 000006DB 66C705[D7070000]90-     	mov	word [T5], 9090h ; nop
  1297 000006E3 90                 
  1298                                  	;
  1299                                  	;mov	ax, int_0Eh	; IRQ 6 handler
  1300                                  	;mov	di, 0Eh*4	; IRQ 6 vector
  1301                                  	;stosw
  1302                                  	;mov 	ax, cs
  1303                                  	;stosw
  1304                                  	;; 16/02/2015
  1305                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1306                                  	;
  1307 000006E4 E831200000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
  1308                                  	;
  1309 000006E9 09D2                    	or	edx, edx
  1310 000006EB 7407                            jz      short di3
  1311                                  di2:
  1312 000006ED E86E200000              	call   	DISK_SETUP	; Initialize Fixed Disks
  1313 000006F2 72D0                            jc      short setup_error
  1314                                  di3:
  1315 000006F4 E8DF100000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
  1316                                  	;
  1317 000006F9 E8F55F0000              	call	display_disks ; 07/03/2015  (Temporary)
  1318                                  ;haltx:
  1319                                  	; 14/08/2015
  1320                                  	;call	getch ; 22/02/2015
  1321 000006FE FB                      	sti	; Enable interrupts (for CPU)
  1322                                  	; 14/08/2015
  1323                                  	;mov 	ecx, 0FFFFFFFh
  1324                                  	; 22/11/2021
  1325 000006FF B9FFFF2F00              	mov 	ecx, 02FFFFFh	
  1326                                  md_info_msg_wait:
  1327 00000704 51                      	push 	ecx
  1328 00000705 B001                    	mov	al, 1
  1329 00000707 8A25[E66F0000]          	mov 	ah, [ptty] ; active (current) video page
  1330 0000070D E8235D0000              	call	getc_n
  1331 00000712 59                      	pop	ecx
  1332 00000713 7502                    	jnz	short md_info_msg_ok
  1333 00000715 E2ED                    	loop	md_info_msg_wait
  1334                                  md_info_msg_ok:
  1335                                  	; 30/06/2015
  1336 00000717 E8502D0000              	call	sys_init
  1337                                  	;
  1338                                  	;jmp 	cpu_reset ; 22/02/2015
  1339                                  hang:
  1340                                  	; 04/12/2021
  1341 0000071C 29C0                    	sub	eax, eax
  1342                                  _hang:	
  1343                                  	; 23/02/2015
  1344                                  	;sti			; Enable interrupts
  1345 0000071E F4                      	hlt
  1346                                  	;
  1347                                  	;nop
  1348                                  	;; 03/12/2014
  1349                                  	;; 28/08/2014
  1350                                  	;mov	ah, 11h
  1351                                  	;call	getc
  1352                                  	;jz      _c8
  1353                                  	;
  1354                                  	; 23/02/2015
  1355                                  	; 06/02/2015
  1356                                  	; 07/09/2014
  1357 0000071F 31DB                    	xor	ebx, ebx
  1358 00000721 8A1D[E66F0000]          	mov	bl, [ptty]	; active_page
  1359 00000727 89DE                    	mov	esi, ebx
  1360 00000729 66D1E6                  	shl 	si, 1
  1361 0000072C 81C6[E86F0000]          	add	esi, ttychr
  1362 00000732 668B06                  	mov	ax, [esi]
  1363                                  	;and	ax, ax
  1364                                  	;;jz	short _c8
  1365                                  	;jz	short hang
  1366                                  	; 04/12/2021
  1367 00000735 21C0                    	and	eax, eax
  1368 00000737 74E5                    	jz	short _hang
  1369 00000739 66C7060000              	mov	word [esi], 0
  1370 0000073E 80FB03                  	cmp	bl, 3		; Video page 3
  1371                                  	;jb	short _c8
  1372 00000741 72D9                    	jb	short hang
  1373                                  	;	
  1374                                  	; 02/09/2014
  1375 00000743 B40E                    	mov	ah, 0Eh		; Yellow character 
  1376                                  				; on black background
  1377                                  	; 30/11/2021 (32 bit reg push-pop)
  1378                                  	; 07/09/2014
  1379                                  nxtl:
  1380 00000745 53                      	push	ebx
  1381                                  	;
  1382                                  	;xor	ebx, ebx	; bl = 0 (video page 0)
  1383                                  				; bh = 0 (video mode)
  1384                                  				; Retro UNIX 386 v1 - Video Mode 0
  1385                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
  1386 00000746 50                      	push	eax
  1387 00000747 E8740D0000              	call 	write_tty
  1388 0000074C 58                      	pop	eax
  1389                                  	;pop	bx
  1390 0000074D 5B                      	pop	ebx
  1391 0000074E 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
  1392                                  	;jne	short _c8
  1393 00000750 75CA                    	jne	short hang
  1394 00000752 B00A                    	mov	al, 0Ah		; next line
  1395 00000754 EBEF                    	jmp	short nxtl
  1396                                  	
  1397                                  ;_c8:
  1398                                  ;	; 25/08/2014
  1399                                  ;	cli			; Disable interrupts
  1400                                  ;	mov	al, [scounter + 1]
  1401                                  ;	and	al, al
  1402                                  ;	jnz	hang
  1403                                  ;	call	rtc_p
  1404                                  ;	jmp     hang
  1405                                  
  1406                                  
  1407                                  	; 27/08/2014
  1408                                  	; 20/08/2014
  1409                                  printk:
  1410                                          ;mov    edi, [scr_row]
  1411                                  pkl:
  1412 00000756 AC                      	lodsb
  1413 00000757 08C0                    	or 	al, al
  1414 00000759 7404                    	jz	short pkr
  1415 0000075B 66AB                    	stosw
  1416 0000075D EBF7                    	jmp	short pkl
  1417                                  pkr:
  1418 0000075F C3                      	retn
  1419                                  
  1420                                  ; 25/07/2015
  1421                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
  1422                                  ; 17/02/2015
  1423                                  ; 06/02/2015 (unix386.s)
  1424                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
  1425                                  ;
  1426                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
  1427                                  ;
  1428                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
  1429                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
  1430                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
  1431                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
  1432                                  ;									       :
  1433                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
  1434                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
  1435                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
  1436                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
  1437                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
  1438                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
  1439                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
  1440                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
  1441                                  ;-------------------------------------------------------------------------------
  1442                                  ;
  1443                                  
  1444                                  timer_int:	; IRQ 0
  1445                                  ;int_08h:	; Timer
  1446                                  	; 14/10/2015
  1447                                  	; Here, we are simulating system call entry (for task switch)
  1448                                  	; (If multitasking is enabled, 
  1449                                  	; 'clock' procedure may jump to 'sysrelease')
  1450 00000760 1E                      	push	ds
  1451 00000761 06                      	push	es
  1452 00000762 0FA0                    	push	fs
  1453 00000764 0FA8                    	push	gs
  1454 00000766 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1455 00000767 66B91000                	mov     cx, KDATA
  1456 0000076B 8ED9                            mov     ds, cx
  1457 0000076D 8EC1                            mov     es, cx
  1458 0000076F 8EE1                            mov     fs, cx
  1459 00000771 8EE9                            mov     gs, cx
  1460                                  	;
  1461 00000773 0F20D9                  	mov	ecx, cr3
  1462 00000776 890D[15080000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1463                                  	;
  1464 0000077C 3B0D[B86F0000]          	cmp 	ecx, [k_page_dir]
  1465 00000782 741F                    	je	short T3
  1466                                  	;
  1467                                  	; timer interrupt has been occurred while OS is in user mode
  1468 00000784 A3[B4700000]            	mov 	[u.r0], eax
  1469 00000789 89E1                    	mov	ecx, esp
  1470 0000078B 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1471 0000078E 890D[AC700000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1472 00000794 8925[B0700000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1473                                  	;
  1474 0000079A 8B0D[B86F0000]          	mov	ecx, [k_page_dir]
  1475 000007A0 0F22D9                  	mov	cr3, ecx
  1476                                  T3:
  1477 000007A3 FB                      	sti				; INTERRUPTS BACK ON
  1478 000007A4 66FF05[34700000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1479 000007AB 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1480 000007AD 66FF05[36700000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1481                                  T4:					; TEST_DAY
  1482 000007B4 66833D[36700000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
  1483 000007BC 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1484 000007BE 66813D[34700000]B0-     	CMP	word [TIMER_LOW],0B0H
  1485 000007C6 00                 
  1486 000007C7 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1487                                  
  1488                                  ;-----	TIMER HAS GONE 24 HOURS
  1489                                  	;;SUB	AX,AX
  1490                                  	;MOV	[TIMER_HIGH],AX
  1491                                  	;MOV	[TIMER_LOW],AX
  1492 000007C9 29C0                    	sub	eax, eax
  1493 000007CB A3[34700000]            	mov	[TIMER_LH], eax
  1494                                  	;	
  1495 000007D0 C605[38700000]01        	MOV	byte [TIMER_OFL],1
  1496                                  
  1497                                  ;-----	TEST FOR DISKETTE TIME OUT
  1498                                  
  1499                                  T5:
  1500                                  	; 23/12/2014
  1501 000007D7 EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1502                                  					; (9090h) if a floppy disk
  1503                                  					; is detected.
  1504                                  	;mov	al,[CS:MOTOR_COUNT]
  1505 000007D9 A0[3B700000]            	mov	al, [MOTOR_COUNT]
  1506 000007DE FEC8                    	dec	al
  1507                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1508 000007E0 A2[3B700000]            	mov	[MOTOR_COUNT], al
  1509                                  	;mov	[ORG_MOTOR_COUNT], al
  1510 000007E5 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1511 000007E7 B0F0                    	mov 	al,0F0h
  1512                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1513 000007E9 2005[3A700000]          	and	[MOTOR_STATUS], al
  1514                                  	;and	[ORG_MOTOR_STATUS], al
  1515 000007EF B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1516                                  					; bit 2 = enable controller
  1517                                  					;	1 = normal operation
  1518                                  					;	0 = reset	
  1519                                  					; bit 0, 1 = drive select
  1520                                  					; bit 4-7 = motor running bits 
  1521 000007F1 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1522 000007F5 EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1523                                  T6:	
  1524                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1525                                  					; TIMER TICK INTERRUPT
  1526                                  	;;inc	word [wait_count] ;;27/02/2015
  1527                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1528                                  	;;;;cli
  1529                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1530 000007F6 FF15[11080000]          	call	[x_timer] ; 14/05/2015
  1531                                  T7:
  1532                                  	; 14/10/2015
  1533 000007FC B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1534 000007FE FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1535 000007FF E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1536                                  	;
  1537 00000801 A1[15080000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1538 00000806 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1539                                  	;
  1540 00000809 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1541                                  	;
  1542 0000080A 0FA9                    	pop	gs
  1543 0000080C 0FA1                    	pop	fs
  1544 0000080E 07                      	pop	es
  1545 0000080F 1F                      	pop	ds
  1546 00000810 CF                      	iretd	; return from interrupt
  1547                                  
  1548                                  
  1549                                  ; ////////////////
  1550                                  
  1551                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1552                                  x_timer:
  1553 00000811 [19080000]              	dd 	u_timer			; 14/05/2015
  1554                                  	;dd	clock
  1555                                  
  1556                                  ; 14/10/2015
  1557 00000815 00000000                cr3reg: dd 0
  1558                                  
  1559                                  	; 04/12/2021 - Retro UNIX 386 v1.2
  1560                                  	; 06/02/2015
  1561                                  	; 07/09/2014
  1562                                  	; 21/08/2014
  1563                                  u_timer:
  1564                                  ;timer_int:	; IRQ 0
  1565                                  	; 06/02/2015
  1566                                  	;push	eax
  1567                                  	;push	edx
  1568                                  	;push	ecx
  1569                                  	;push	ebx
  1570                                  	;push	ds
  1571                                  	;push	es
  1572                                  	;mov	eax, KDATA
  1573                                  	;mov	ds, ax
  1574                                  	;mov	es, ax
  1575 00000819 FF05[FC6F0000]          	inc	dword [tcount]
  1576 0000081F BB[826B0000]            	mov	ebx, tcountstr + 4
  1577                                  	;mov	ax, [tcount]
  1578                                  	; 04/12/2021
  1579 00000824 A1[FC6F0000]            	mov	eax, [tcount]
  1580 00000829 B90A000000              	mov	ecx, 10
  1581                                  rp_divtcnt:
  1582 0000082E 31D2                    	xor	edx, edx
  1583 00000830 F7F1                    	div	ecx
  1584 00000832 80C230                  	add	dl, 30h
  1585 00000835 8813                    	mov	[ebx], dl
  1586                                  	;or	ax, ax
  1587                                  	; 04/12/2021
  1588 00000837 09C0                    	or	eax, eax
  1589 00000839 7403                    	jz	short print_lzero
  1590 0000083B 4B                      	dec	ebx
  1591 0000083C EBF0                    	jmp	short rp_divtcnt
  1592                                  print_lzero:
  1593 0000083E 81FB[7E6B0000]          	cmp	ebx, tcountstr
  1594 00000844 7606                    	jna	short print_tcount
  1595 00000846 4B                      	dec	ebx
  1596 00000847 C60330                   	mov	byte [ebx], 30h
  1597 0000084A EBF2                    	jmp	short print_lzero
  1598                                  print_tcount:
  1599 0000084C 56                      	push	esi
  1600 0000084D 57                      	push	edi
  1601 0000084E BE[5A6B0000]            	mov	esi, timer_msg ; Timer interrupt message
  1602                                  	; 07/09/2014
  1603                                  	;mov	bx, 1		; Video page 1
  1604                                  	; 04/12/2021
  1605 00000853 29DB                    	sub	ebx, ebx
  1606 00000855 FEC3                    	inc	bl ; ebx = 1
  1607                                  ptmsg:
  1608 00000857 AC                      	lodsb
  1609 00000858 08C0                    	or	al, al
  1610 0000085A 740D                    	jz	short ptmsg_ok
  1611 0000085C 56                      	push	esi
  1612                                  	;push	bx
  1613                                  	; 04/12/2021
  1614 0000085D 53                              push	ebx
  1615 0000085E B42F                    	mov     ah, 2Fh ; Green background, white forecolor
  1616 00000860 E85B0C0000              	call 	write_tty
  1617                                  	;pop	bx
  1618                                  	; 04/12/2021
  1619 00000865 5B                      	pop	ebx
  1620 00000866 5E                      	pop	esi
  1621 00000867 EBEE                    	jmp	short ptmsg
  1622                                  	;; 27/08/2014
  1623                                  	;mov	edi, 0B8000h + 0A0h ; Row 1
  1624                                  	;call	printk
  1625                                  	;
  1626                                  ptmsg_ok:
  1627                                  	; 07/09/2014
  1628                                  	;xor	dx, dx		; column 0, row 0
  1629                                  	; 04/12/2021
  1630 00000869 31D2                    	xor	edx, edx
  1631 0000086B E8720D0000              	call	set_cpos	; set cursor position to 0,0 
  1632                                  	; 23/02/2015
  1633                                  	; 25/08/2014
  1634                                  	;mov	ebx, scounter		; (seconds counter)
  1635                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1636                                  ;	dec	byte [scounter+1]
  1637                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1638                                  ;	jns	short u_timer_retn
  1639                                  	; 26/02/2015
  1640                                  ;	call	rtc_p
  1641                                  ;	mov	ebx, scounter		; (seconds counter)
  1642                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1643                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1644                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1645                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1646                                  ;	mov	byte [ebx], 5
  1647                                  ;	inc	byte [ebx+1] ; 19
  1648                                  ;;timer_eoi:
  1649                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1650                                  ;;	out	20h, al	; 8259 PORT
  1651                                  	;
  1652                                  ;u_timer_retn:  ; 06/02/2015
  1653 00000870 5F                      	pop	edi
  1654 00000871 5E                      	pop	esi
  1655                                  	;pop	es
  1656                                  	;pop	ds
  1657                                  	;pop	ebx
  1658                                  	;pop	ecx
  1659                                  	;pop	edx
  1660                                  	;pop	eax
  1661                                  	;iret
  1662 00000872 C3                      	retn	; 06/02/2015
  1663                                  
  1664                                  	; 28/08/2014
  1665                                  irq0:
  1666 00000873 6A00                            push 	dword 0
  1667 00000875 EB48                    	jmp	short which_irq
  1668                                  irq1:
  1669 00000877 6A01                            push 	dword 1
  1670 00000879 EB44                    	jmp	short which_irq
  1671                                  irq2:
  1672 0000087B 6A02                            push 	dword 2
  1673 0000087D EB40                    	jmp	short which_irq
  1674                                  irq3:
  1675                                  	; 20/11/2015
  1676                                  	; 24/10/2015
  1677 0000087F 2EFF15[D33B0000]        	call	dword [cs:com2_irq3]
  1678 00000886 6A03                    	push 	dword 3
  1679 00000888 EB35                    	jmp	short which_irq
  1680                                  irq4:
  1681                                  	; 20/11/2015
  1682                                  	; 24/10/2015
  1683 0000088A 2EFF15[CF3B0000]        	call	dword [cs:com1_irq4]
  1684 00000891 6A04                            push 	dword 4
  1685 00000893 EB2A                    	jmp	short which_irq
  1686                                  irq5:
  1687 00000895 6A05                            push 	dword 5
  1688 00000897 EB26                    	jmp	short which_irq
  1689                                  irq6:
  1690 00000899 6A06                            push 	dword 6
  1691 0000089B EB22                    	jmp	short which_irq
  1692                                  irq7:
  1693 0000089D 6A07                            push 	dword 7
  1694 0000089F EB1E                    	jmp	short which_irq
  1695                                  irq8:
  1696 000008A1 6A08                            push 	dword 8
  1697 000008A3 EB1A                    	jmp	short which_irq
  1698                                  irq9:
  1699 000008A5 6A09                            push 	dword 9
  1700 000008A7 EB16                    	jmp	short which_irq
  1701                                  irq10:
  1702 000008A9 6A0A                            push 	dword 10
  1703 000008AB EB12                    	jmp	short which_irq
  1704                                  irq11:
  1705 000008AD 6A0B                            push 	dword 11
  1706 000008AF EB0E                    	jmp	short which_irq
  1707                                  irq12:
  1708 000008B1 6A0C                            push 	dword 12
  1709 000008B3 EB0A                    	jmp	short which_irq
  1710                                  irq13:
  1711 000008B5 6A0D                            push 	dword 13
  1712 000008B7 EB06                    	jmp	short which_irq
  1713                                  irq14:
  1714 000008B9 6A0E                            push 	dword 14
  1715 000008BB EB02                    	jmp	short which_irq
  1716                                  irq15:
  1717 000008BD 6A0F                            push 	dword 15
  1718                                  	;jmp	short which_irq
  1719                                  
  1720                                  	; 19/10/2015
  1721                                  	; 29/08/2014
  1722                                  	; 21/08/2014
  1723                                  which_irq:
  1724 000008BF 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1725 000008C2 53                      	push	ebx
  1726 000008C3 56                      	push	esi
  1727 000008C4 57                      	push	edi
  1728 000008C5 1E                      	push 	ds
  1729 000008C6 06                      	push 	es
  1730                                  	;
  1731 000008C7 88C3                    	mov	bl, al
  1732                                  	;
  1733 000008C9 B810000000              	mov	eax, KDATA
  1734 000008CE 8ED8                    	mov	ds, ax
  1735 000008D0 8EC0                    	mov	es, ax
  1736                                  	; 19/10/2015
  1737 000008D2 FC                      	cld
  1738                                          ; 27/08/2014
  1739 000008D3 8105[086B0000]A000-             add     dword [scr_row], 0A0h
  1740 000008DB 0000               
  1741                                  	;
  1742 000008DD B417                    	mov	ah, 17h	; blue (1) background, 
  1743                                  			; light gray (7) forecolor
  1744 000008DF 8B3D[086B0000]                  mov     edi, [scr_row]
  1745 000008E5 B049                    	mov	al, 'I'
  1746 000008E7 66AB                    	stosw
  1747 000008E9 B052                    	mov	al, 'R'
  1748 000008EB 66AB                    	stosw
  1749 000008ED B051                    	mov	al, 'Q'
  1750 000008EF 66AB                    	stosw
  1751 000008F1 B020                    	mov	al, ' '
  1752 000008F3 66AB                    	stosw
  1753 000008F5 88D8                    	mov	al, bl
  1754 000008F7 3C0A                    	cmp	al, 10
  1755 000008F9 7208                    	jb	short iix
  1756 000008FB B031                    	mov	al, '1'
  1757 000008FD 66AB                    	stosw
  1758 000008FF 88D8                    	mov	al, bl
  1759 00000901 2C0A                    	sub	al, 10
  1760                                  iix:
  1761 00000903 0430                    	add	al, '0'
  1762 00000905 66AB                    	stosw
  1763 00000907 B020                    	mov	al, ' '
  1764 00000909 66AB                    	stosw
  1765 0000090B B021                    	mov	al, '!'
  1766 0000090D 66AB                    	stosw
  1767 0000090F B020                    	mov	al, ' '
  1768 00000911 66AB                    	stosw
  1769                                  	; 23/02/2015
  1770 00000913 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1771                                  	;jna	iiret
  1772                                  	; 04/12/2021
  1773 00000916 7604                    	jna	short iiz
  1774                                  iiy:
  1775 00000918 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1776 0000091A E6A0                    	out	0A0h, al ; the 2nd 8259
  1777                                  iiz:
  1778 0000091C E984010000              	jmp     iiret
  1779                                  	;
  1780                                  	; 22/08/2014
  1781                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1782                                  	;out	20h, al	; 8259 PORT
  1783                                  	;
  1784                                  	;pop	es
  1785                                  	;pop	ds
  1786                                  	;pop	edi
  1787                                  	;pop	esi
  1788                                  	;pop	ebx
  1789                                  	;pop 	eax
  1790                                  	;iret
  1791                                  
  1792                                  	; 02/04/2015
  1793                                  	; 25/08/2014
  1794                                  exc0:
  1795 00000921 6A00                            push 	dword 0
  1796 00000923 E990000000                      jmp     cpu_except
  1797                                  exc1:
  1798 00000928 6A01                            push 	dword 1
  1799 0000092A E989000000                      jmp     cpu_except
  1800                                  exc2:
  1801 0000092F 6A02                            push 	dword 2
  1802 00000931 E982000000                      jmp     cpu_except
  1803                                  exc3:
  1804 00000936 6A03                            push 	dword 3
  1805 00000938 EB7E                            jmp     cpu_except
  1806                                  exc4:
  1807 0000093A 6A04                            push 	dword 4
  1808 0000093C EB7A                            jmp     cpu_except
  1809                                  exc5:
  1810 0000093E 6A05                            push 	dword 5
  1811 00000940 EB76                            jmp     cpu_except
  1812                                  exc6:
  1813 00000942 6A06                            push 	dword 6
  1814 00000944 EB72                            jmp     cpu_except
  1815                                  exc7:
  1816 00000946 6A07                            push 	dword 7
  1817 00000948 EB6E                            jmp     cpu_except
  1818                                  exc8:
  1819                                  	; [esp] = Error code
  1820 0000094A 6A08                            push 	dword 8
  1821 0000094C EB5C                            jmp     cpu_except_en
  1822                                  exc9:
  1823 0000094E 6A09                            push 	dword 9
  1824 00000950 EB66                            jmp     cpu_except
  1825                                  exc10:
  1826                                  	; [esp] = Error code
  1827 00000952 6A0A                            push 	dword 10
  1828 00000954 EB54                            jmp     cpu_except_en
  1829                                  exc11:
  1830                                  	; [esp] = Error code
  1831 00000956 6A0B                            push 	dword 11
  1832 00000958 EB50                            jmp     cpu_except_en
  1833                                  exc12:
  1834                                  	; [esp] = Error code
  1835 0000095A 6A0C                            push 	dword 12
  1836 0000095C EB4C                            jmp     cpu_except_en
  1837                                  exc13:
  1838                                  	; [esp] = Error code
  1839 0000095E 6A0D                            push 	dword 13
  1840 00000960 EB48                            jmp     cpu_except_en
  1841                                  exc14:
  1842                                  	; [esp] = Error code
  1843 00000962 6A0E                            push 	dword 14
  1844 00000964 EB44                    	jmp	short cpu_except_en
  1845                                  exc15:
  1846 00000966 6A0F                            push 	dword 15
  1847 00000968 EB4E                            jmp     cpu_except
  1848                                  exc16:
  1849 0000096A 6A10                            push 	dword 16
  1850 0000096C EB4A                            jmp     cpu_except
  1851                                  exc17:
  1852                                  	; [esp] = Error code
  1853 0000096E 6A11                            push 	dword 17
  1854 00000970 EB38                    	jmp	short cpu_except_en
  1855                                  exc18:
  1856 00000972 6A12                            push 	dword 18
  1857 00000974 EB42                    	jmp	short cpu_except
  1858                                  exc19:
  1859 00000976 6A13                            push 	dword 19
  1860 00000978 EB3E                    	jmp	short cpu_except
  1861                                  exc20:
  1862 0000097A 6A14                            push 	dword 20
  1863 0000097C EB3A                    	jmp	short cpu_except
  1864                                  exc21:
  1865 0000097E 6A15                            push 	dword 21
  1866 00000980 EB36                    	jmp	short cpu_except
  1867                                  exc22:
  1868 00000982 6A16                            push 	dword 22
  1869 00000984 EB32                    	jmp	short cpu_except
  1870                                  exc23:
  1871 00000986 6A17                            push 	dword 23
  1872 00000988 EB2E                    	jmp	short cpu_except
  1873                                  exc24:
  1874 0000098A 6A18                            push 	dword 24
  1875 0000098C EB2A                    	jmp	short cpu_except
  1876                                  exc25:
  1877 0000098E 6A19                            push 	dword 25
  1878 00000990 EB26                    	jmp	short cpu_except
  1879                                  exc26:
  1880 00000992 6A1A                            push 	dword 26
  1881 00000994 EB22                    	jmp	short cpu_except
  1882                                  exc27:
  1883 00000996 6A1B                            push 	dword 27
  1884 00000998 EB1E                    	jmp	short cpu_except
  1885                                  exc28:
  1886 0000099A 6A1C                            push 	dword 28
  1887 0000099C EB1A                    	jmp	short cpu_except
  1888                                  exc29:
  1889 0000099E 6A1D                            push 	dword 29
  1890 000009A0 EB16                    	jmp	short cpu_except
  1891                                  exc30:
  1892 000009A2 6A1E                            push 	dword 30
  1893 000009A4 EB04                    	jmp	short cpu_except_en
  1894                                  exc31:
  1895 000009A6 6A1F                            push 	dword 31
  1896 000009A8 EB0E                            jmp     short cpu_except
  1897                                  
  1898                                  	; 19/10/2015
  1899                                  	; 19/09/2015
  1900                                  	; 01/09/2015
  1901                                  	; 28/08/2015
  1902                                  	; 28/08/2014
  1903                                  cpu_except_en:
  1904 000009AA 87442404                	xchg	eax, [esp+4] ; Error code
  1905 000009AE 36A3[48820000]          	mov	[ss:error_code], eax
  1906 000009B4 58                      	pop	eax  ; Exception number
  1907 000009B5 870424                  	xchg	eax, [esp]
  1908                                  		; eax = eax before exception
  1909                                  		; [esp] -> exception number
  1910                                  		; [esp+4] -> EIP to return
  1911                                  	; 19/10/2015
  1912                                  	; 19/09/2015
  1913                                  	; 01/09/2015
  1914                                  	; 28/08/2015
  1915                                  	; 29/08/2014
  1916                                  	; 28/08/2014
  1917                                  	; 25/08/2014
  1918                                  	; 21/08/2014
  1919                                  cpu_except:	; CPU Exceptions
  1920 000009B8 FC                      	cld
  1921 000009B9 870424                  	xchg	eax, [esp] 
  1922                                  		; eax = Exception number
  1923                                  		; [esp] = eax (before exception)	
  1924 000009BC 53                      	push	ebx
  1925 000009BD 56                      	push	esi
  1926 000009BE 57                      	push	edi
  1927 000009BF 1E                      	push 	ds
  1928 000009C0 06                      	push 	es
  1929                                  	; 28/08/2015
  1930 000009C1 66BB1000                	mov	bx, KDATA
  1931 000009C5 8EDB                    	mov	ds, bx
  1932 000009C7 8EC3                    	mov	es, bx
  1933 000009C9 0F20DB                  	mov	ebx, cr3
  1934 000009CC 53                      	push	ebx ; (*) page directory
  1935                                  	; 19/10/2015
  1936 000009CD FC                      	cld
  1937                                  	; 25/03/2015
  1938 000009CE 8B1D[B86F0000]          	mov	ebx, [k_page_dir]
  1939 000009D4 0F22DB                  	mov	cr3, ebx
  1940                                  	; 28/08/2015
  1941 000009D7 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1942 000009DA 7512                    	jne	short cpu_except_nfp
  1943 000009DC E841280000              	call	page_fault_handler
  1944 000009E1 21C0                    	and 	eax, eax
  1945 000009E3 0F84B8000000                    jz	iiretp ; 01/09/2015
  1946 000009E9 B80E000000              	mov	eax, 0Eh ; 14
  1947                                  cpu_except_nfp:
  1948                                  	; 02/04/2015
  1949 000009EE BB[1C070000]            	mov	ebx, hang
  1950 000009F3 875C241C                	xchg	ebx, [esp+28]
  1951                                  		; EIP (points to instruction which faults)
  1952                                  	  	; New EIP (hang)
  1953 000009F7 891D[4C820000]          	mov	[FaultOffset], ebx
  1954 000009FD C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1955 00000A05 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1956                                  	;
  1957 00000A0D 88C4                    	mov	ah, al
  1958 00000A0F 240F                    	and	al, 0Fh
  1959 00000A11 3C09                    	cmp	al, 9
  1960 00000A13 7602                    	jna	short h1ok
  1961 00000A15 0407                    	add	al, 'A'-':'
  1962                                  h1ok:
  1963 00000A17 D0EC                    	shr	ah, 1
  1964 00000A19 D0EC                    	shr	ah, 1
  1965 00000A1B D0EC                    	shr	ah, 1
  1966 00000A1D D0EC                    	shr	ah, 1
  1967 00000A1F 80FC09                  	cmp	ah, 9
  1968 00000A22 7603                    	jna	short h2ok
  1969 00000A24 80C407                  	add	ah, 'A'-':'
  1970                                  h2ok:	
  1971 00000A27 86E0                    	xchg 	ah, al	
  1972 00000A29 66053030                	add	ax, '00'
  1973 00000A2D 66A3[966B0000]          	mov	[excnstr], ax
  1974                                  	;
  1975                                  	; 29/08/2014
  1976 00000A33 A1[4C820000]            	mov	eax, [FaultOffset]
  1977 00000A38 51                      	push	ecx
  1978 00000A39 52                      	push	edx
  1979 00000A3A 89E3                    	mov	ebx, esp
  1980                                  	; 28/08/2015
  1981 00000A3C B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1982                                  			  ; to hexadecimal string
  1983                                  	;mov	ecx, 10	    ; divisor to convert	
  1984                                  			    ; binary number to decimal string
  1985                                  b2d1:
  1986 00000A41 31D2                    	xor	edx, edx
  1987 00000A43 F7F1                    	div	ecx
  1988 00000A45 6652                    	push	dx
  1989 00000A47 39C8                    	cmp	eax, ecx
  1990 00000A49 73F6                    	jnb	short b2d1
  1991 00000A4B BF[A16B0000]            	mov	edi, EIPstr ; EIP value
  1992                                  			    ; points to instruction which faults	
  1993                                  	; 28/08/2015
  1994 00000A50 89C2                    	mov	edx, eax
  1995                                  b2d2:
  1996                                  	;add	al, '0'
  1997 00000A52 8A82[C0180000]          	mov	al, [edx+hexchrs]
  1998 00000A58 AA                      	stosb		    ; write hexadecimal digit to its place	
  1999 00000A59 39E3                    	cmp	ebx, esp
  2000 00000A5B 7606                    	jna	short b2d3
  2001 00000A5D 6658                    	pop	ax
  2002 00000A5F 88C2                    	mov	dl, al
  2003 00000A61 EBEF                    	jmp	short b2d2
  2004                                  b2d3:
  2005 00000A63 B068                    	mov 	al, 'h' ; 28/08/2015
  2006 00000A65 AA                      	stosb
  2007 00000A66 B020                    	mov	al, 20h	    ; space
  2008 00000A68 AA                      	stosb
  2009 00000A69 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  2010 00000A6B AA                      	stosb
  2011                                  	;
  2012 00000A6C 5A                      	pop	edx
  2013 00000A6D 59                      	pop	ecx
  2014                                  	;
  2015 00000A6E B44F                    	mov	ah, 4Fh	; red (4) background, 
  2016                                  			; white (F) forecolor
  2017 00000A70 BE[866B0000]            	mov	esi, exc_msg ; message offset
  2018                                  	;
  2019 00000A75 EB11                    	jmp	short piemsg
  2020                                  	;
  2021                                          ;add    dword [scr_row], 0A0h
  2022                                          ;mov    edi, [scr_row]
  2023                                          ;
  2024                                  	;call 	printk
  2025                                  	;
  2026                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2027                                  	;out	20h, al	; 8259 PORT
  2028                                  	;
  2029                                  	;pop	es
  2030                                  	;pop	ds
  2031                                  	;pop	edi
  2032                                  	;pop	esi
  2033                                  	;pop 	eax
  2034                                  	;iret
  2035                                  	
  2036                                  	; 28/08/2015
  2037                                  	; 23/02/2015
  2038                                  	; 20/08/2014
  2039                                  ignore_int:
  2040 00000A77 50                      	push	eax
  2041 00000A78 53                      	push	ebx ; 23/02/2015
  2042 00000A79 56                      	push	esi
  2043 00000A7A 57                      	push	edi
  2044 00000A7B 1E                      	push 	ds
  2045 00000A7C 06                      	push 	es
  2046                                  	; 28/08/2015
  2047 00000A7D 0F20D8                  	mov	eax, cr3
  2048 00000A80 50                      	push	eax ; (*) page directory
  2049                                  	;
  2050 00000A81 B467                    	mov	ah, 67h	; brown (6) background, 
  2051                                  			; light gray (7) forecolor
  2052 00000A83 BE[446B0000]            	mov	esi, int_msg ; message offset
  2053                                  piemsg:
  2054                                          ; 27/08/2014
  2055 00000A88 8105[086B0000]A000-             add     dword [scr_row], 0A0h
  2056 00000A90 0000               
  2057 00000A92 8B3D[086B0000]                  mov     edi, [scr_row]
  2058                                          ;
  2059 00000A98 E8B9FCFFFF              	call 	printk
  2060                                  	;
  2061                                  	; 23/02/2015
  2062 00000A9D B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2063 00000A9F E6A0                    	out	0A0h, al ; the 2nd 8259
  2064                                  iiretp: ; 01/09/2015
  2065                                  	; 28/08/2015
  2066 00000AA1 58                      	pop	eax ; (*) page directory
  2067 00000AA2 0F22D8                  	mov	cr3, eax
  2068                                  	;
  2069                                  iiret:
  2070                                  	; 22/08/2014
  2071 00000AA5 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2072 00000AA7 E620                    	out	20h, al	; 8259 PORT
  2073                                  	;
  2074 00000AA9 07                      	pop	es
  2075 00000AAA 1F                      	pop	ds
  2076 00000AAB 5F                      	pop	edi
  2077 00000AAC 5E                      	pop	esi
  2078 00000AAD 5B                      	pop	ebx ; 29/08/2014
  2079 00000AAE 58                      	pop 	eax
  2080 00000AAF CF                      	iretd
  2081                                  
  2082                                  	; 26/02/2015
  2083                                  	; 07/09/2014
  2084                                  	; 25/08/2014
  2085                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  2086                                  	; 22/08/2014
  2087 00000AB0 50                      	push	eax
  2088 00000AB1 53                      	push	ebx ; 29/08/2014
  2089 00000AB2 56                      	push	esi
  2090 00000AB3 57                      	push	edi
  2091 00000AB4 1E                      	push 	ds
  2092 00000AB5 06                      	push 	es
  2093                                  	;
  2094 00000AB6 B810000000              	mov	eax, KDATA
  2095 00000ABB 8ED8                    	mov	ds, ax
  2096 00000ABD 8EC0                    	mov	es, ax
  2097                                  	;
  2098                                  	; 25/08/2014
  2099 00000ABF E884000000              	call	rtc_p
  2100                                  	;
  2101                                  	; 22/02/2015 - dsectpm.s
  2102                                  	; [ source: http://wiki.osdev.org/RTC ]
  2103                                  	; read status register C to complete procedure
  2104                                  	;(it is needed to get a next IRQ 8) 
  2105 00000AC4 B00C                    	mov	al, 0Ch ; 
  2106 00000AC6 E670                    	out	70h, al ; select register C
  2107 00000AC8 90                      	nop
  2108 00000AC9 E471                    	in	al, 71h ; just throw away contents
  2109                                  	; 22/02/2015
  2110 00000ACB B020                    	MOV	AL,EOI		; END OF INTERRUPT
  2111 00000ACD E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  2112                                  	;
  2113 00000ACF EBD4                    	jmp	short iiret	
  2114                                  
  2115                                  	; 22/08/2014
  2116                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  2117                                  	; (INT 1Ah)
  2118                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  2119                                  time_of_day:
  2120 00000AD1 E862010000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  2121 00000AD6 726F                            jc      short rtc_retn 
  2122 00000AD8 B000                    	mov	al, CMOS_SECONDS
  2123 00000ADA E843010000              	call	CMOS_READ
  2124 00000ADF A2[2C700000]            	mov	[time_seconds], al 
  2125 00000AE4 B002                    	mov	al, CMOS_MINUTES
  2126 00000AE6 E837010000              	call	CMOS_READ
  2127 00000AEB A2[2D700000]            	mov	[time_minutes], al 
  2128 00000AF0 B004                    	mov	al, CMOS_HOURS
  2129 00000AF2 E82B010000              	call	CMOS_READ
  2130 00000AF7 A2[2E700000]                    mov     [time_hours], al
  2131 00000AFC B006                    	mov	al, CMOS_DAY_WEEK 
  2132 00000AFE E81F010000              	call	CMOS_READ
  2133 00000B03 A2[2F700000]            	mov	[date_wday], al
  2134 00000B08 B007                     	mov	al, CMOS_DAY_MONTH
  2135 00000B0A E813010000              	call	CMOS_READ
  2136 00000B0F A2[30700000]            	mov	[date_day], al
  2137 00000B14 B008                    	mov	al, CMOS_MONTH
  2138 00000B16 E807010000              	call	CMOS_READ
  2139 00000B1B A2[31700000]            	mov	[date_month], al
  2140 00000B20 B009                    	mov	al, CMOS_YEAR
  2141 00000B22 E8FB000000              	call	CMOS_READ
  2142 00000B27 A2[32700000]            	mov	[date_year], al
  2143 00000B2C B032                    	mov	al, CMOS_CENTURY
  2144 00000B2E E8EF000000              	call	CMOS_READ
  2145 00000B33 A2[33700000]            	mov	[date_century], al
  2146                                  	;
  2147 00000B38 B000                    	mov	al, CMOS_SECONDS
  2148 00000B3A E8E3000000              	call 	CMOS_READ
  2149 00000B3F 3A05[2C700000]          	cmp	al, [time_seconds]
  2150 00000B45 758A                    	jne	short time_of_day
  2151                                  
  2152                                  rtc_retn:
  2153 00000B47 C3                      	retn
  2154                                  
  2155                                  rtc_p:	
  2156                                  	; 07/09/2014
  2157                                  	; 29/08/2014
  2158                                  	; 27/08/2014
  2159                                  	; 25/08/2014
  2160                                   	; Print Real Time Clock content
  2161                                  	;
  2162                                  	;
  2163 00000B48 E884FFFFFF              	call	time_of_day
  2164 00000B4D 72F8                    	jc	short rtc_retn
  2165                                  	;
  2166 00000B4F 3A05[F86B0000]          	cmp	al, [ptime_seconds]
  2167 00000B55 74F0                            je      short rtc_retn ; 29/08/2014
  2168                                  	;
  2169 00000B57 A2[F86B0000]            	mov	[ptime_seconds], al
  2170                                  	;
  2171 00000B5C A0[33700000]            	mov	al, [date_century]
  2172 00000B61 E8ED000000              	call	bcd_to_ascii
  2173 00000B66 66A3[C56B0000]          	mov	[datestr+6], ax
  2174 00000B6C A0[32700000]            	mov	al, [date_year]
  2175 00000B71 E8DD000000              	call	bcd_to_ascii
  2176 00000B76 66A3[C76B0000]          	mov	[datestr+8], ax
  2177 00000B7C A0[31700000]            	mov	al, [date_month]
  2178 00000B81 E8CD000000              	call	bcd_to_ascii
  2179 00000B86 66A3[C26B0000]          	mov	[datestr+3], ax
  2180 00000B8C A0[30700000]            	mov	al, [date_day]
  2181 00000B91 E8BD000000              	call	bcd_to_ascii
  2182 00000B96 66A3[BF6B0000]          	mov	[datestr], ax
  2183                                  	;
  2184 00000B9C 0FB61D[2F700000]        	movzx	ebx, byte [date_wday]
  2185 00000BA3 C0E302                  	shl 	bl, 2
  2186 00000BA6 81C3[D86B0000]          	add	ebx, daytmp
  2187 00000BAC 8B03                    	mov	eax, [ebx]
  2188 00000BAE A3[CA6B0000]            	mov	[daystr], eax
  2189                                  	;
  2190 00000BB3 A0[2E700000]            	mov	al, [time_hours]
  2191 00000BB8 E896000000              	call	bcd_to_ascii
  2192 00000BBD 66A3[CE6B0000]          	mov	[timestr], ax
  2193 00000BC3 A0[2D700000]            	mov	al, [time_minutes]
  2194 00000BC8 E886000000              	call	bcd_to_ascii
  2195 00000BCD 66A3[D16B0000]          	mov	[timestr+3], ax
  2196 00000BD3 A0[2C700000]            	mov	al, [time_seconds]
  2197 00000BD8 E876000000              	call	bcd_to_ascii
  2198 00000BDD 66A3[D46B0000]          	mov	[timestr+6], ax
  2199                                  	;		
  2200 00000BE3 BE[AD6B0000]            	mov	esi, rtc_msg ; message offset
  2201                                  	; 23/02/2015
  2202 00000BE8 52                      	push	edx
  2203 00000BE9 51                      	push	ecx
  2204                                  	; 07/09/2014
  2205 00000BEA 66BB0200                	mov	bx, 2		; Video page 2
  2206                                  prtmsg:
  2207 00000BEE AC                      	lodsb
  2208 00000BEF 08C0                    	or	al, al
  2209 00000BF1 740F                    	jz	short prtmsg_ok
  2210 00000BF3 56                      	push	esi
  2211 00000BF4 6653                    	push	bx
  2212 00000BF6 B43F                            mov	ah, 3Fh	; cyan (6) background, 
  2213                                  			; white (F) forecolor
  2214 00000BF8 E8C3080000              	call 	write_tty
  2215 00000BFD 665B                    	pop	bx
  2216 00000BFF 5E                      	pop	esi
  2217 00000C00 EBEC                    	jmp	short prtmsg
  2218                                  	;
  2219                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  2220                                  	;call	printk
  2221                                  prtmsg_ok:
  2222                                  	; 07/09/2014
  2223 00000C02 6631D2                  	xor	dx, dx		; column 0, row 0
  2224 00000C05 E8D8090000              	call	set_cpos	; set curspor position to 0,0 
  2225                                  	; 23/02/2015
  2226 00000C0A 59                      	pop	ecx
  2227 00000C0B 5A                      	pop	edx
  2228 00000C0C C3                      	retn
  2229                                  
  2230                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2231                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2232                                  default_irq7:
  2233                                  	; 04/12/2021
  2234                                  	;push	ax
  2235 00000C0D 50                      	push	eax
  2236 00000C0E B00B                    	mov	al, 0Bh  ; In-Service register
  2237 00000C10 E620                    	out	20h, al
  2238 00000C12 EB00                            jmp short $+2
  2239 00000C14 EB00                    	jmp short $+2
  2240 00000C16 E420                    	in	al, 20h
  2241 00000C18 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  2242 00000C1A 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  2243 00000C1C B020                            mov     al, 20h ; EOI
  2244 00000C1E E620                    	out	20h, al 
  2245                                  irq7_iret:
  2246                                  	;pop	ax
  2247                                  	; 04/12/2021
  2248 00000C20 58                      	pop	eax
  2249 00000C21 CF                      	iretd
  2250                                  	
  2251                                  	; 04/12/2021
  2252                                  	; 22/08/2014
  2253                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
  2254                                  CMOS_READ:
  2255 00000C22 9C                      	pushf		; SAVE INTERRUPT ENABLE STATUS AND FLAGS
  2256 00000C23 D0C0                    	rol	al, 1	; MOVE NMI BIT TO LOW POSITION
  2257 00000C25 F9                      	stc		; FORCE NMI BIT ON IN CARRY FLAG
  2258 00000C26 D0D8                    	rcr	al, 1	; HIGH BIT ON TO DISABLE NMI - OLD IN CY
  2259 00000C28 FA                      	cli		; DISABLE INTERRUPTS
  2260 00000C29 E670                    	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
  2261 00000C2B 90                      	nop		; I/O DELAY
  2262 00000C2C E471                    	in	al, CMOS_DATA	; READ THE REQUESTED CMOS LOCATION
  2263                                  	;push	ax	; SAVE (AH) REGISTER VALUE AND CMOS BYTE
  2264                                  	; 04/12/2021
  2265 00000C2E 50                      	push	eax
  2266                                  	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
  2267                                  		     ; ----- 10/06/85 (test4.asm)
  2268 00000C2F B01E                    	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
  2269                                  	;mov	al, CMOS_REG_D*2 ; GET ADDRESS OF DEFAULT LOCATION
  2270 00000C31 D0D8                    	rcr	al, 1	; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
  2271 00000C33 E670                    	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
  2272                                  	;pop	ax	; RESTORE (AH) AND (AL), CMOS BYTE
  2273                                  	; 04/12/2021
  2274 00000C35 58                      	pop	eax
  2275 00000C36 9D                      	popf	
  2276 00000C37 C3                      	retn		; RETURN WITH FLAGS RESTORED
  2277                                  
  2278                                  	; 22/08/2014
  2279                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
  2280                                  UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
  2281 00000C38 51                      	push	ecx
  2282 00000C39 B9FFFF0000              	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
  2283                                  		; mov cx, 800	
  2284                                  UPD_10:
  2285 00000C3E B00A                    	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
  2286 00000C40 FA                      	cli				; NO TIMER INTERRUPTS DURING UPDATES
  2287 00000C41 E8DCFFFFFF              	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
  2288 00000C46 A880                    	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
  2289 00000C48 7406                    	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
  2290 00000C4A FB                      	sti				; ALLOW INTERRUPTS WHILE WAITING
  2291 00000C4B E2F1                    	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
  2292 00000C4D 31C0                    	xor	eax, eax		; CLEAR RESULTS IF ERROR
  2293                                  		; xor ax, ax
  2294 00000C4F F9                      	stc				; SET CARRY FOR ERROR
  2295                                  UPD_90:
  2296 00000C50 59                      	pop	ecx			; RESTORE CALLERS REGISTER
  2297 00000C51 FA                      	cli				; INTERRUPTS OFF DURING SET
  2298 00000C52 C3                      	retn				; RETURN WITH CY FLAG SET
  2299                                  
  2300                                  bcd_to_ascii:
  2301                                  	; 25/08/2014
  2302                                  	; INPUT ->
  2303                                  	;	al = Packed BCD number
  2304                                  	; OUTPUT ->
  2305                                  	;	ax  = ASCII word/number
  2306                                  	;
  2307                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  2308                                  	;
  2309 00000C53 D410                    	db	0D4h, 10h		; Undocumented inst. AAM
  2310                                  					; AH = AL / 10h
  2311                                  					; AL = AL MOD 10h
  2312 00000C55 660D3030                	or	ax, '00'		; Make it ASCII based
  2313                                  
  2314 00000C59 86E0                            xchg	ah, al 
  2315                                  	
  2316 00000C5B C3                      	retn	
  2317                                  	
  2318                                  
  2319                                  %include 'keyboard.s' ; 07/03/2015
  2320                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  2321                              <1> ; (re-write kernel for test by using previous version without a major defect)
  2322                              <1> ; ****************************************************************************
  2323                              <1> ; Retro UNIX 386 v1 Kernel - KEYBOARD.INC
  2324                              <1> ; Last Modification: 05/12/2021
  2325                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
  2326                              <1> ;
  2327                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
  2328                              <1> 
  2329                              <1> ; 05/12/2021 (Retro UNIX 386 v1.2)
  2330                              <1> ; 30/06/2015
  2331                              <1> ; 11/03/2015
  2332                              <1> ; 28/02/2015
  2333                              <1> ; 25/02/2015
  2334                              <1> ; 20/02/2015
  2335                              <1> ; 18/02/2015
  2336                              <1> ; 03/12/2014
  2337                              <1> ; 07/09/2014
  2338                              <1> ; KEYBOARD INTERRUPT HANDLER
  2339                              <1> ; (kb_int - Retro UNIX 8086 v1 - U0.ASM, 30/06/2014)
  2340                              <1> 
  2341                              <1> ;getch:
  2342                              <1> ;	; 18/02/2015
  2343                              <1> ;	; This routine will be replaced with Retro UNIX 386
  2344                              <1> ;	; version of Retro UNIX 8086 getch (tty input)
  2345                              <1> ;	; routine, later... (multi tasking ability)
  2346                              <1> ;	; 28/02/2015
  2347                              <1> ;	sti	; enable interrupts
  2348                              <1> ;	;
  2349                              <1> ;	;push	esi
  2350                              <1> ;	;push	ebx
  2351                              <1> ;	;xor	ebx, ebx
  2352                              <1> ;	;mov	bl, [ptty]  ; active_page
  2353                              <1> ;	;mov	esi, ebx
  2354                              <1> ;	;shl 	si, 1
  2355                              <1> ;	;add	esi, ttychr
  2356                              <1> ;getch_1:
  2357                              <1> ;	;mov	ax, [esi]
  2358                              <1> ;	mov	ax, [ttychr] ; video page 0 (tty0)
  2359                              <1> ;	and	ax, ax
  2360                              <1> ;	jz	short getch_2
  2361                              <1> ;	mov	word [ttychr], 0
  2362                              <1> ;	;mov	word [esi], 0
  2363                              <1> ;	;pop	ebx
  2364                              <1> ;	;pop	esi
  2365                              <1> ;	retn
  2366                              <1> ;getch_2:
  2367                              <1> ;	hlt	; not proper for multi tasking!
  2368                              <1> ;		; (temporary halt for now)
  2369                              <1> ;		; 'sleep' on tty 
  2370                              <1> ;		; will (must) be located here		
  2371                              <1> ;	nop
  2372                              <1> ;	jmp	short getch_1
  2373                              <1> 
  2374                              <1> keyb_int:
  2375                              <1> 	; 30/06/2015
  2376                              <1> 	; 25/02/2015
  2377                              <1> 	; 20/02/2015
  2378                              <1> 	; 03/12/2014 (getc_int - INT 16h modifications)
  2379                              <1> 	; 07/09/2014 - Retro UNIX 386 v1
  2380                              <1> 	; 30/06/2014
  2381                              <1> 	; 10/05/2013	
  2382                              <1>       	; Retro Unix 8086 v1 feature only!
  2383                              <1> 	; 03/03/2014
  2384                              <1> 	
  2385 00000C5C 1E                  <1> 	push	ds
  2386 00000C5D 53                  <1> 	push	ebx
  2387 00000C5E 50                  <1> 	push	eax
  2388                              <1> 	;
  2389 00000C5F 66B81000            <1> 	mov	ax, KDATA
  2390 00000C63 8ED8                <1> 	mov	ds, ax
  2391                              <1> 	;
  2392 00000C65 9C                  <1> 	pushfd
  2393 00000C66 0E                  <1> 	push	cs
  2394 00000C67 E812020000          <1> 	call	kb_int  ; int_09h
  2395                              <1> 	;
  2396 00000C6C B411                <1> 	mov	ah, 11h	 ; 03/12/2014	
  2397                              <1> 	;call	getc
  2398 00000C6E E856000000          <1> 	call	int_16h ; 30/06/2015
  2399 00000C73 7450                <1> 	jz	short keyb_int4
  2400                              <1> 	;
  2401 00000C75 B410                <1> 	mov	ah, 10h	 ; 03/12/2014
  2402                              <1> 	;call	getc
  2403 00000C77 E84D000000          <1> 	call	int_16h ; 30/06/2015
  2404                              <1> 	;
  2405                              <1> 	; 20/02/2015
  2406 00000C7C 0FB61D[E66F0000]    <1>         movzx   ebx, byte [ptty]  ; active_page
  2407                              <1> 	;
  2408 00000C83 20C0                <1> 	and 	al, al
  2409 00000C85 751E                <1> 	jnz	short keyb_int1
  2410                              <1> 	;
  2411 00000C87 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  2412 00000C8A 7219                <1> 	jb	short keyb_int1
  2413 00000C8C 80FC6F              <1> 	cmp	ah, 6Fh  ; ALT + F8 key	
  2414 00000C8F 7714                <1> 	ja	short keyb_int1
  2415                              <1> 	;
  2416 00000C91 88D8                <1> 	mov	al, bl
  2417 00000C93 0468                <1> 	add	al, 68h
  2418 00000C95 38E0                <1> 	cmp	al, ah
  2419 00000C97 7409                <1> 	je	short keyb_int0
  2420 00000C99 88E0                <1> 	mov	al, ah
  2421 00000C9B 2C68                <1> 	sub	al, 68h
  2422 00000C9D E8FB0A0000          <1> 	call	tty_sw
  2423                              <1> 	;movzx	ebx, [ptty]  ; active_page
  2424                              <1> keyb_int0: ; 30/06/2015
  2425 00000CA2 6631C0              <1> 	xor	ax, ax
  2426                              <1> keyb_int1:
  2427 00000CA5 D0E3                <1> 	shl	bl, 1
  2428 00000CA7 81C3[E86F0000]      <1> 	add	ebx, ttychr
  2429                              <1> 	;
  2430 00000CAD 6609C0              <1> 	or	ax, ax
  2431 00000CB0 7406                <1> 	jz	short keyb_int2
  2432                              <1> 	;
  2433 00000CB2 66833B00            <1> 	cmp 	word [ebx], 0
  2434 00000CB6 7703                <1>         ja      short keyb_int3 
  2435                              <1> keyb_int2:
  2436 00000CB8 668903              <1>         mov	[ebx], ax  ; Save ascii code
  2437                              <1> 			   ; and scan code of the character
  2438                              <1> 			   ; for current tty (or last tty
  2439                              <1> 			   ; just before tty switch).
  2440                              <1> keyb_int3:
  2441 00000CBB A0[E66F0000]        <1>         mov     al, [ptty]
  2442 00000CC0 E8C0440000          <1> 	call	wakeup
  2443                              <1> 	;
  2444                              <1> keyb_int4:
  2445 00000CC5 58                  <1> 	pop	eax
  2446 00000CC6 5B                  <1> 	pop	ebx
  2447 00000CC7 1F                  <1> 	pop	ds
  2448 00000CC8 CF                  <1> 	iret
  2449                              <1> 
  2450                              <1> ; 18/02/2015
  2451                              <1> ; REMINDER: Only 'keyb_int' (IRQ 9) must call getc.
  2452                              <1> ; 'keyb_int' always handles 'getc' at 1st and puts the
  2453                              <1> ; scancode and ascii code of the character 
  2454                              <1> ; in the tty input (ttychr) buffer. 
  2455                              <1> ; Test procedures must call 'getch' for tty input
  2456                              <1> ; otherwise, 'getc' will not be able to return to the caller
  2457                              <1> ; due to infinite (key press) waiting loop.
  2458                              <1> ; 
  2459                              <1> ; 03/12/2014
  2460                              <1> ; 26/08/2014
  2461                              <1> ; KEYBOARD I/O
  2462                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
  2463                              <1> 
  2464                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
  2465                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
  2466                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
  2467                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
  2468                              <1> 
  2469                              <1> int_16h: ; 30/06/2015
  2470                              <1> ;getc:
  2471 00000CC9 9C                  <1> 	pushfd	; 28/08/2014
  2472 00000CCA 0E                  <1> 	push 	cs
  2473 00000CCB E826000000          <1> 	call 	getc_int
  2474 00000CD0 C3                  <1> 	retn
  2475                              <1> 
  2476                              <1> ; 05/12/2021
  2477                              <1> 
  2478                              <1> 	;-----	SHIFT STATUS
  2479                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
  2480 00000CD1 8A25[E4690000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2481 00000CD7 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2482                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2483                              <1> 	;shl	ah, cl			; BIT 7 POSITION
  2484 00000CDA C0E405              <1>         shl	ah, 5
  2485 00000CDD A0[E4690000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2486 00000CE2 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2487 00000CE4 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2488 00000CE6 A0[E6690000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2489 00000CEB 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2490 00000CED 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2491                              <1> _K3:
  2492 00000CEF A0[E3690000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2493 00000CF4 EB2B                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2494                              <1> 
  2495                              <1> getc_int:
  2496                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  2497                              <1> 	; 28/02/2015
  2498                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2499                              <1> 	;	      instead of pc-at bios - 1985-)
  2500                              <1> 	; 28/08/2014 (_k1d)
  2501                              <1> 	; 30/06/2014
  2502                              <1> 	; 03/03/2014
  2503                              <1> 	; 28/02/2014
  2504                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
  2505                              <1> 	; rombios source code (21/04/1986)
  2506                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
  2507                              <1> 	;
  2508                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
  2509                              <1> 	;
  2510                              <1> 	;--- INT 16 H -----------------------------------------------------------------
  2511                              <1> 	; KEYBOARD I/O								      :
  2512                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
  2513                              <1> 	; INPUT									      :
  2514                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
  2515                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
  2516                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
  2517                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
  2518                              <1> 	;-----------------------------------------------------------------------------:
  2519                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
  2520                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
  2521                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
  2522                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
  2523                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
  2524                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
  2525                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
  2526                              <1> 	;-----------------------------------------------------------------------------:	
  2527                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
  2528                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
  2529                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
  2530                              <1> 	;-----------------------------------------------------------------------------:	
  2531                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
  2532                              <1> 	;	      (AL) = 05H                                                      :
  2533                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
  2534                              <1> 	;		       							      :
  2535                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
  2536                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
  2537                              <1> 	;                     --------------------------------------------            :
  2538                              <1> 	;			00H        30.0        10H        7.5                 :
  2539                              <1> 	;			01H        26.7        11H        6.7                 :
  2540                              <1> 	;			02H        24.0        12H        6.0                 :
  2541                              <1> 	;			03H        21.8        13H        5.5                 :
  2542                              <1> 	;			04H        20.0        14H        5.0                 :
  2543                              <1> 	;			05H        18.5        15H        4.6                 :
  2544                              <1> 	;			06H        17.1        16H        4.3                 :
  2545                              <1> 	;			07H        16.0        17H        4.0                 :
  2546                              <1> 	;			08H        15.0        18H        3.7                 :
  2547                              <1> 	;			09H        13.3        19H        3.3                 :
  2548                              <1> 	;			0AH        12.0        1AH        3.0                 :
  2549                              <1> 	;			0BH        10.9        1BH        2.7                 :
  2550                              <1>         ;			0CH        10.0        1CH        2.5                 :
  2551                              <1> 	;			0DH         9.2        1DH        2.3                 :
  2552                              <1> 	;			0EH         8.6        1EH        2.1                 :
  2553                              <1> 	;			0FH         8.0        1FH        2.0                 :
  2554                              <1> 	;									      :
  2555                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
  2556                              <1> 	;		       							      :
  2557                              <1> 	;                     REGISTER     DELAY                                      :
  2558                              <1> 	;                      VALUE       VALUE                                      :
  2559                              <1> 	;                     ------------------                                      :
  2560                              <1> 	;			00H        250 ms                                     :
  2561                              <1> 	;			01H        500 ms                                     :
  2562                              <1> 	;			02H        750 ms                                     :
  2563                              <1> 	;			03H       1000 ms                                     :
  2564                              <1> 	;-----------------------------------------------------------------------------:
  2565                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
  2566                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
  2567                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
  2568                              <1> 	;		           (CH) = SCAN CODE                                   :
  2569                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
  2570                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
  2571                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
  2572                              <1> 	;-----------------------------------------------------------------------------:		
  2573                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
  2574                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
  2575                              <1> 	;-----------------------------------------------------------------------------:
  2576                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
  2577                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
  2578                              <1> 	;-----------------------------------------------------------------------------:	
  2579                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
  2580                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
  2581                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
  2582                              <1> 	; OUTPUT					                              :
  2583                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
  2584                              <1> 	;	ALL REGISTERS RETAINED		                                      :
  2585                              <1> 	;------------------------------------------------------------------------------
  2586                              <1> 	
  2587 00000CF6 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2588 00000CF7 1E                  <1> 	push	ds			; SAVE CURRENT DS
  2589 00000CF8 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
  2590                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
  2591 00000CF9 66BB1000            <1>         mov     bx, KDATA 
  2592 00000CFD 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
  2593 00000CFF 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
  2594 00000D01 742D                <1> 	jz	short _K1		; ASCII_READ
  2595 00000D03 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
  2596 00000D05 7446                <1>         jz      short _K2               ; ASCII_STATUS
  2597 00000D07 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
  2598 00000D09 74E4                <1>         jz      short _K3               ; SHIFT STATUS
  2599 00000D0B FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
  2600 00000D0D 745B                <1>         jz      short _K300             ; SET TYPAMATIC RATE/DELAY
  2601 00000D0F 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
  2602 00000D12 7479                <1>         jz      short _K500             ; KEYBOARD WRITE         
  2603                              <1> _KIO1:	
  2604 00000D14 80EC0B              <1> 	sub	ah, 11			; AH =  10H
  2605 00000D17 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
  2606 00000D19 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
  2607 00000D1B 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
  2608 00000D1D FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
  2609 00000D1F 74B0                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
  2610                              <1> _KIO_EXIT:
  2611                              <1> 	;pop	ecx			; RECOVER REGISTER
  2612 00000D21 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2613 00000D22 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2614 00000D23 CF                  <1> 	iretd				; INVALID COMMAND, EXIT
  2615                              <1> 
  2616                              <1> 	;-----	ASCII CHARACTER
  2617                              <1> _K1E:	
  2618 00000D24 E891000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
  2619 00000D29 E804010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2620 00000D2E EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
  2621                              <1> _K1:	
  2622 00000D30 E885000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
  2623 00000D35 E803010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2624 00000D3A 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
  2625                              <1> _K1A:
  2626 00000D3C EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
  2627                              <1> 
  2628                              <1> 	;-----	ASCII STATUS
  2629                              <1> _K2E:	
  2630 00000D3E E8C2000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
  2631 00000D43 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2632 00000D45 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2633 00000D46 E8E7000000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
  2634 00000D4B EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
  2635                              <1> _K2:	
  2636 00000D4D E8B3000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
  2637 00000D52 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
  2638 00000D54 9C                  <1> 	pushf				; SAVE ZF FROM TEST
  2639 00000D55 E8E3000000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
  2640 00000D5A 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
  2641 00000D5C 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
  2642 00000D5D E858000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
  2643 00000D62 EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
  2644                              <1> _K2A:
  2645 00000D64 9D                  <1> 	popf				; RESTORE ZF FROM TEST
  2646                              <1> _K2B:
  2647                              <1> 	;pop	ecx			; RECOVER REGISTER
  2648 00000D65 5B                  <1> 	pop	ebx			; RECOVER REGISTER
  2649 00000D66 1F                  <1> 	pop	ds			; RECOVER SEGMENT
  2650 00000D67 CA0400              <1> 	retf	4			; THROW AWAY (e)FLAGS
  2651                              <1> 
  2652                              <1> ; 05/12/2021
  2653                              <1> ;	;-----	SHIFT STATUS
  2654                              <1> ;_K3E:                                  ; GET THE EXTENDED SHIFT STATUS FLAGS
  2655                              <1> ;	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
  2656                              <1> ;	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
  2657                              <1> ;	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
  2658                              <1> ;	;shl	ah, cl			; BIT 7 POSITION
  2659                              <1> ;       shl	ah, 5
  2660                              <1> ;	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
  2661                              <1> ;	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
  2662                              <1> ;	or	ah, al                  ; MERGE REMAINING BITS INTO AH
  2663                              <1> ;	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
  2664                              <1> ;	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
  2665                              <1> ;	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
  2666                              <1> ;_K3:
  2667                              <1> ;	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
  2668                              <1> ;	jmp	short _KIO_EXIT		; RETURN TO CALLER
  2669                              <1> 
  2670                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
  2671                              <1> _K300:
  2672 00000D6A 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
  2673 00000D6C 75B3                <1> 	jne	short _KIO_EXIT		; NO, RETURN
  2674 00000D6E F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
  2675 00000D71 75AE                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2676 00000D73 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
  2677 00000D76 75A9                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
  2678 00000D78 B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
  2679 00000D7A E880060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2680                              <1> 	;mov	cx, 5			; SHIFT COUNT
  2681                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
  2682 00000D7F C0E705              <1> 	shl	bh, 5
  2683 00000D82 88D8                <1> 	mov	al, bl			; PUT IN RATE
  2684 00000D84 08F8                <1> 	or	al, bh			; AND DELAY
  2685 00000D86 E874060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
  2686 00000D8B EB94                <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
  2687                              <1> 
  2688                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
  2689                              <1> _K500:
  2690 00000D8D 56                  <1> 	push	esi			; SAVE SI (esi)
  2691 00000D8E FA                  <1> 	cli				; 
  2692 00000D8F 8B1D[F4690000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
  2693 00000D95 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
  2694 00000D97 E8D1000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
  2695 00000D9C 3B1D[F0690000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
  2696 00000DA2 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
  2697 00000DA4 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
  2698 00000DA7 891D[F4690000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
  2699 00000DAD 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
  2700 00000DAF EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
  2701                              <1> _K502:
  2702 00000DB1 B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
  2703                              <1> _K504:
  2704 00000DB3 FB                  <1> 	sti				
  2705 00000DB4 5E                  <1> 	pop	esi			; RECOVER SI (esi)
  2706 00000DB5 E967FFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
  2707                              <1> 
  2708                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
  2709                              <1> _K1S:
  2710 00000DBA FA                  <1> 	cli	; 03/12/2014
  2711 00000DBB 8B1D[F0690000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2712 00000DC1 3B1D[F4690000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2713                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
  2714 00000DC7 750F                <1> 	jne	short _k1x ; 03/12/2014
  2715                              <1> 	;
  2716                              <1> 	; 03/12/2014
  2717                              <1> 	; 28/08/2014
  2718                              <1> 	; PERFORM OTHER FUNCTION ?? here !
  2719                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
  2720                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
  2721                              <1> _K1T:                                   ; ASCII READ
  2722 00000DC9 FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
  2723 00000DCA 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
  2724                              <1> _K1U:	
  2725 00000DCB FA                  <1> 	cli				; INTERRUPTS BACK OFF
  2726 00000DCC 8B1D[F0690000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
  2727 00000DD2 3B1D[F4690000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
  2728                              <1> _k1x:
  2729 00000DD8 53                  <1> 	push	ebx			; SAVE ADDRESS		
  2730 00000DD9 9C                  <1> 	pushf				; SAVE FLAGS
  2731 00000DDA E8D4060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2732 00000DDF 8A1D[E5690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2733 00000DE5 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2734 00000DE7 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
  2735 00000DEA 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
  2736 00000DEC E86E060000          <1> 	call	SND_LED1
  2737 00000DF1 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2738                              <1> _K1V:
  2739 00000DF2 9D                  <1> 	popf				; RESTORE FLAGS
  2740 00000DF3 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
  2741 00000DF4 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
  2742                              <1> 	;
  2743 00000DF6 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
  2744 00000DF9 E86F000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
  2745 00000DFE 891D[F0690000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
  2746 00000E04 C3                  <1> 	retn				; RETURN
  2747                              <1> 
  2748                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
  2749                              <1> _K2S:
  2750 00000E05 FA                  <1> 	cli				; INTERRUPTS OFF
  2751 00000E06 8B1D[F0690000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
  2752 00000E0C 3B1D[F4690000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
  2753 00000E12 668B03              <1> 	mov	ax, [ebx]
  2754 00000E15 9C                  <1> 	pushf				; SAVE FLAGS
  2755                              <1> 	;push	ax			; SAVE CODE
  2756                              <1> 	; 05/12/2021
  2757 00000E16 50                  <1> 	push	eax
  2758 00000E17 E897060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  2759 00000E1C 8A1D[E5690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  2760 00000E22 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  2761 00000E24 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
  2762 00000E27 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
  2763 00000E29 E81A060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  2764                              <1> _K2T:
  2765                              <1> 	;pop	ax			; RESTORE CODE
  2766                              <1> 	; 05/12/2021
  2767 00000E2E 58                  <1> 	pop	eax
  2768 00000E2F 9D                  <1> 	popf				; RESTORE FLAGS
  2769 00000E30 FB                  <1> 	sti				; INTERRUPTS BACK ON
  2770 00000E31 C3                  <1> 	retn				; RETURN
  2771                              <1> 
  2772                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
  2773                              <1> _KIO_E_XLAT:
  2774 00000E32 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2775 00000E34 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
  2776 00000E36 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
  2777 00000E38 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
  2778 00000E3A 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
  2779                              <1> _KIO_E_RET:				
  2780 00000E3C C3                  <1> 	retn				; GO BACK
  2781                              <1> 
  2782                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
  2783                              <1> _KIO_S_XLAT:
  2784 00000E3D 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
  2785 00000E40 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
  2786 00000E42 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
  2787 00000E44 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
  2788 00000E46 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
  2789 00000E48 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
  2790 00000E4A B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
  2791                              <1> _kio_ret: ; 03/12/2014
  2792 00000E4C F8                  <1> 	clc
  2793 00000E4D C3                  <1> 	retn
  2794                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2795                              <1> _KIO_S1:				
  2796 00000E4E B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
  2797                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
  2798 00000E50 C3                  <1> 	retn
  2799                              <1> _KIO_S2:		
  2800 00000E51 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
  2801 00000E54 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
  2802 00000E56 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
  2803 00000E58 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
  2804 00000E5A 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2805 00000E5C 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
  2806 00000E5E EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
  2807                              <1> _KIO_S3:
  2808 00000E60 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
  2809                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
  2810 00000E62 75E8                <1> 	jne	short _kio_ret
  2811 00000E64 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
  2812 00000E66 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
  2813 00000E68 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
  2814                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
  2815                              <1> _KIO_USE:
  2816                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
  2817 00000E6A C3                  <1> 	retn				; RETURN	
  2818                              <1> _KIO_DIS:
  2819 00000E6B F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
  2820 00000E6C C3                  <1> 	retn				; RETURN
  2821                              <1> 
  2822                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
  2823                              <1> _K4:    
  2824 00000E6D 43                  <1> 	inc     ebx
  2825 00000E6E 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
  2826 00000E6F 3B1D[EC690000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
  2827                              <1>         ;jne    short _K5               ; NO, CONTINUE
  2828 00000E75 7206                <1> 	jb	short _K5
  2829 00000E77 8B1D[E8690000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
  2830                              <1> _K5:
  2831 00000E7D C3                  <1> 	retn
  2832                              <1> 
  2833                              <1> ; 20/02/2015
  2834                              <1> ; 05/12/2014
  2835                              <1> ; 26/08/2014
  2836                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
  2837                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
  2838                              <1> ;
  2839                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
  2840                              <1> ; rombios source code (06/10/1985)
  2841                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
  2842                              <1> 
  2843                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
  2844                              <1> ENA_KBD		equ	0AEh	; ENABLE KEYBOARD COMMAND
  2845                              <1> DIS_KBD		equ	0ADh	; DISABLE KEYBOARD COMMAND
  2846                              <1> SHUT_CMD	equ	0FEh	; CAUSE A SHUTDOWN COMMAND
  2847                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  2848                              <1> STATUS_PORT	equ	064h	; 8042 STATUS PORT
  2849                              <1> INPT_BUF_FULL	equ	00000010b ; 1 = +INPUT BUFFER FULL
  2850                              <1> PORT_A		equ	060h	; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  2851                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
  2852                              <1> KB_ACK		equ	0FAh	; ACKNOWLEDGE PROM TRANSMISSION
  2853                              <1> KB_RESEND	equ	0FEh	; RESEND REQUEST
  2854                              <1> KB_OVER_RUN	equ	0FFh	; OVER RUN SCAN CODE
  2855                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
  2856                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
  2857                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
  2858                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
  2859                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
  2860                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
  2861                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
  2862                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
  2863                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
  2864                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
  2865                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
  2866                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
  2867                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
  2868                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
  2869                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
  2870                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
  2871                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
  2872                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
  2873                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
  2874                              <1> F11_M		equ	87		; F11 KEY MAKE
  2875                              <1> F12_M		equ	88		; F12 KEY MAKE
  2876                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
  2877                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
  2878                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
  2879                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
  2880                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
  2881                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
  2882                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
  2883                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
  2884                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
  2885                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
  2886                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
  2887                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
  2888                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
  2889                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
  2890                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
  2891                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
  2892                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
  2893                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
  2894                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
  2895                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
  2896                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
  2897                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
  2898                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
  2899                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
  2900                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
  2901                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
  2902                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
  2903                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
  2904                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
  2905                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
  2906                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
  2907                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
  2908                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
  2909                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
  2910                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
  2911                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
  2912                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
  2913                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
  2914                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
  2915                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
  2916                              <1> ;
  2917                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
  2918                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
  2919                              <1> INTA00		equ	020h		; 8259 PORT
  2920                              <1> 
  2921                              <1> 
  2922                              <1> kb_int:
  2923                              <1> 
  2924                              <1> ; 05/12/2021 (Retro UNIX 386 v1.2)
  2925                              <1> ; 17/10/2015 ('ctrlbrk') 
  2926                              <1> ; 05/12/2014
  2927                              <1> ; 04/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
  2928                              <1> 	;	      instead of pc-at bios - 1985-)
  2929                              <1> ; 26/08/2014
  2930                              <1> ;
  2931                              <1> ; 03/06/86  KEYBOARD BIOS
  2932                              <1> ;
  2933                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
  2934                              <1> ;										;
  2935                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
  2936                              <1> ;										;
  2937                              <1> ;--------------------------------------------------------------------------------
  2938                              <1> 
  2939                              <1> KB_INT_1:
  2940 00000E7E FB                  <1> 	sti				; ENABLE INTERRUPTS
  2941                              <1> 	;push	ebp
  2942 00000E7F 50                  <1> 	push	eax
  2943 00000E80 53                  <1> 	push	ebx
  2944 00000E81 51                  <1> 	push	ecx
  2945 00000E82 52                  <1> 	push	edx
  2946 00000E83 56                  <1> 	push	esi
  2947 00000E84 57                  <1> 	push	edi
  2948 00000E85 1E                  <1> 	push	ds
  2949 00000E86 06                  <1> 	push	es
  2950 00000E87 FC                  <1> 	cld				; FORWARD DIRECTION
  2951 00000E88 66B81000            <1> 	mov	ax, KDATA
  2952 00000E8C 8ED8                <1> 	mov	ds, ax
  2953 00000E8E 8EC0                <1> 	mov	es, ax
  2954                              <1> 	;
  2955                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
  2956 00000E90 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
  2957 00000E92 E856050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
  2958 00000E97 FA                  <1> 	cli				; DISABLE INTERRUPTS
  2959 00000E98 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
  2960                              <1> KB_INT_01:
  2961 00000E9D E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
  2962 00000E9F A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
  2963 00000EA1 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
  2964                              <1> 	;
  2965                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
  2966 00000EA3 E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
  2967                              <1> 	;
  2968                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
  2969                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
  2970                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
  2971                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
  2972                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
  2973                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
  2974                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
  2975                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
  2976                              <1> 	;
  2977                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
  2978                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
  2979 00000EA5 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  2980 00000EA6 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
  2981 00000EA8 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
  2982                              <1> 	;
  2983                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
  2984 00000EAA 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
  2985 00000EAC 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
  2986                              <1> 	;
  2987                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
  2988 00000EAE FA                  <1> 	cli				; DISABLE INTERRUPTS
  2989 00000EAF 800D[E5690000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
  2990 00000EB6 E963020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
  2991                              <1> 	;
  2992                              <1> 	;-----	RESEND THE LAST BYTE
  2993                              <1> KB_INT_4:
  2994 00000EBB FA                  <1> 	cli				; DISABLE INTERRUPTS
  2995 00000EBC 800D[E5690000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
  2996 00000EC3 E956020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
  2997                              <1> 	;
  2998                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
  2999                              <1> KB_INT_2:
  3000                              <1> 	;push 	ax			; SAVE DATA IN
  3001                              <1> 	; 05/12/2021
  3002 00000EC8 50                  <1> 	push	eax
  3003 00000EC9 E8E5050000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
  3004 00000ECE 8A1D[E5690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
  3005 00000ED4 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
  3006 00000ED6 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
  3007 00000ED9 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
  3008 00000EDB E868050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
  3009                              <1> UP0:
  3010                              <1> 	;pop	ax			; RESTORE DATA IN
  3011                              <1> 	; 05/12/2021
  3012 00000EE0 58                  <1> 	pop	eax
  3013                              <1> ;------------------------------------------------------------------------
  3014                              <1> ;	START OF KEY PROCESSING						;
  3015                              <1> ;------------------------------------------------------------------------
  3016 00000EE1 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
  3017                              <1> 	;
  3018                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
  3019 00000EE3 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
  3020                              <1>         ;je	K62			; BUFFER_FULL_BEEP
  3021                              <1> 	; 05/12/2021
  3022 00000EE5 7505                <1> 	jne	short K16
  3023 00000EE7 E9ED040000          <1> 	jmp	K62
  3024                              <1> K16:	
  3025 00000EEC 8A3D[E6690000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
  3026                              <1> 	;
  3027                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
  3028 00000EF2 F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
  3029 00000EF5 7442                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
  3030 00000EF7 7914                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
  3031 00000EF9 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
  3032 00000EFB 7507                <1> 	jne	short RST_RD_ID
  3033 00000EFD 800D[E6690000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
  3034                              <1> RST_RD_ID:
  3035 00000F04 8025[E6690000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
  3036 00000F0B EB27                <1>         jmp    short ID_EX		; AND EXIT
  3037                              <1> 	; 05/12/2021
  3038                              <1> 	;jmp	K26
  3039                              <1> 	;
  3040                              <1> TST_ID_2:
  3041 00000F0D 8025[E6690000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
  3042 00000F14 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
  3043 00000F16 7415                <1>         je	short KX_BIT		; JUMP IF SO
  3044 00000F18 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
  3045 00000F1A 7518                <1>         jne	short ID_EX		; LEAVE IF NOT
  3046                              <1> 	; 05/12/2021
  3047                              <1> 	;jne	K26
  3048                              <1> 	;
  3049                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
  3050 00000F1C F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
  3051 00000F1F 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
  3052 00000F21 800D[E3690000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
  3053 00000F28 E81B050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
  3054                              <1> KX_BIT:
  3055 00000F2D 800D[E6690000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
  3056 00000F34 E9E5010000          <1> ID_EX:	jmp     K26			; EXIT
  3057                              <1> 	;
  3058                              <1> NOT_ID:
  3059 00000F39 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
  3060 00000F3B 750E                <1> 	jne	short TEST_E1
  3061 00000F3D 800D[E6690000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
  3062 00000F44 EB10                <1> 	jmp	short EXIT		; THROW AWAY THIS CODE
  3063                              <1> 	; 05/12/2021
  3064 00000F46 E9DA010000          <1> 	jmp	K26A	
  3065                              <1> TEST_E1:	
  3066 00000F4B 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
  3067 00000F4D 750C                <1> 	jne	short NOT_HC
  3068 00000F4F 800D[E6690000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
  3069 00000F56 E9CA010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
  3070                              <1> 	;
  3071                              <1> NOT_HC:
  3072 00000F5B 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
  3073 00000F5D F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
  3074 00000F60 740D                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
  3075                              <1> 	;
  3076 00000F62 BF[CE680000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
  3077 00000F67 AE                  <1> 	scasb
  3078                              <1> 	;je	K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
  3079                              <1> 	; 05/12/2021
  3080 00000F68 7458                <1> 	je	short K16B
  3081 00000F6A AE                  <1> 	scasb
  3082 00000F6B 756A                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
  3083 00000F6D EB53                <1> 	jmp	short K16B		; YES, THROW AWAY & RESET FLAG
  3084                              <1> 	; 05/12/2021
  3085                              <1> 	;jmp	K26
  3086                              <1> 	;
  3087                              <1> NOT_LC_E0:
  3088 00000F6F F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
  3089 00000F72 7425                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
  3090 00000F74 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
  3091 00000F79 BF[CC680000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
  3092 00000F7E F2AE                <1> 	repne	scasb			; CHECK IT
  3093 00000F80 74D4                <1> 	je	short EXIT		; THROW AWAY IF SO
  3094                              <1> 	; 05/12/2021
  3095                              <1> 	;je	K26A			
  3096                              <1> 	;
  3097 00000F82 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
  3098 00000F84 753C                <1> 	jne	short K16B		; NO, THROW AWAY & RESET FLAG
  3099                              <1> 	; 05/12/2021
  3100                              <1> 	;jne	K26
  3101 00000F86 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
  3102 00000F89 7537                <1> 	jnz	short K16B		; YES, THROW THIS AWAY, TOO	
  3103                              <1> 	; 05/12/2021
  3104                              <1> 	;jnz	K26
  3105                              <1>         ; 20/02/2015 
  3106 00000F8B F605[E4690000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ; NO, ARE WE PAUSED ALREADY?
  3107 00000F92 752E                <1> 	jnz	short K16B		; YES, THROW AWAY
  3108                              <1> 	; 05/12/2021
  3109                              <1> 	;jnz	K26
  3110 00000F94 E9D6020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
  3111                              <1> 	;
  3112                              <1> 	;-----	TEST FOR SYSTEM KEY
  3113                              <1> T_SYS_KEY:
  3114 00000F99 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
  3115 00000F9B 753A                <1> 	jnz	short K16A		; CONTINUE IF NOT
  3116                              <1> 	;
  3117 00000F9D F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
  3118 00000FA0 7525                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
  3119                              <1> 	;
  3120 00000FA2 F605[E4690000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
  3121 00000FA9 7517                <1> 	jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
  3122                              <1> 	;jnz	K26			
  3123                              <1> 	;
  3124 00000FAB 800D[E4690000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
  3125 00000FB2 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3126 00000FB4 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3127                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3128 00000FB6 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3129 00000FB8 E830040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3130                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
  3131                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
  3132                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3133                              <1> 	;INT	15H			; USER INTERRUPT	
  3134 00000FBD E96F010000          <1>         jmp     K27A                    ; END PROCESSING
  3135                              <1> 	;
  3136 00000FC2 E957010000          <1> K16B:	jmp	K26			; IGNORE SYSTEM KEY
  3137                              <1> 	;
  3138                              <1> K16C:
  3139 00000FC7 8025[E4690000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
  3140 00000FCE B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3141 00000FD0 E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
  3142                              <1> 					; INTERRUPT-RETURN-NO-EOI
  3143                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3144                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3145                              <1> 	;
  3146                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
  3147                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
  3148                              <1> 	;INT	15H			; USER INTERRUPT
  3149                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
  3150                              <1> 	;
  3151 00000FD2 E953010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
  3152                              <1> 	;
  3153                              <1> 	;-----	TEST FOR SHIFT KEYS
  3154                              <1> K16A:
  3155 00000FD7 8A1D[E3690000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
  3156 00000FDD BF[C8680000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
  3157 00000FE2 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
  3158 00000FE7 F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
  3159 00000FE9 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
  3160                              <1>         ;jne    K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
  3161                              <1> 	; 05/12/2021
  3162 00000FEB 7405                <1> 	je	short K17
  3163 00000FED E914010000          <1> 	jmp	K25
  3164                              <1> 	;
  3165                              <1> 	;------	SHIFT KEY FOUND
  3166                              <1> K17:
  3167 00000FF2 81EF[C9680000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
  3168 00000FF8 8AA7[D0680000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
  3169 00000FFE B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
  3170 00001000 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
  3171                              <1>         ;jnz	K23                     ; JUMP OF BREAK
  3172                              <1> 	; 05/12/2021
  3173 00001002 7405                <1> 	jz	short K17C
  3174 00001004 E999000000          <1> 	jmp	K23
  3175                              <1> 	;
  3176                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
  3177                              <1> K17C:
  3178 00001009 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
  3179 0000100C 732C                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
  3180                              <1> 	;
  3181                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
  3182 0000100E 0825[E3690000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
  3183 00001014 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
  3184 00001016 7505                <1> 	jnz	short K17D		; YES, MORE FLAGS TO SET
  3185                              <1> 	;jz	K26			; NO, INTERRUPT RETURN
  3186                              <1> 	; 05/12/2021
  3187 00001018 E901010000          <1> 	jmp	K26
  3188                              <1> K17D:
  3189 0000101D F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
  3190 00001020 740B                <1> 	jz 	short K17E		; NO, JUMP
  3191 00001022 0825[E6690000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
  3192 00001028 E9F1000000          <1> 	jmp	K26			; INTERRUPT RETURN
  3193                              <1> K17E:
  3194 0000102D D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
  3195 0000102F 0825[E4690000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
  3196 00001035 E9E4000000          <1> 	jmp	K26
  3197                              <1> 	;
  3198                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
  3199                              <1> K18:					; SHIFT-TOGGLE
  3200 0000103A F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
  3201 0000103D 7405                <1>         jz    	short K18A              ; JUMP IF NOT CTL STATE
  3202                              <1>         ;jnz	K25                     ; JUMP IF CTL STATE
  3203                              <1> 	; 05/12/2021
  3204 0000103F E9C2000000          <1> 	jmp	K25
  3205                              <1> K18A:
  3206 00001044 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
  3207 00001046 7525                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
  3208 00001048 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
  3209 0000104B 7405                <1>       	jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
  3210                              <1> 	;jnz	K25                     ; JUMP IF ALTERNATE SHIFT
  3211                              <1> 	; 05/12/2021
  3212 0000104D E9B4000000          <1> 	jmp	K25
  3213                              <1> K18B:
  3214 00001052 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
  3215 00001055 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
  3216                              <1> K19:	
  3217 00001057 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
  3218 0000105A 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
  3219 0000105C F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
  3220 0000105F 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
  3221                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
  3222 00001061 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
  3223 00001063 E99E000000          <1>         jmp	K25               	; NUMERAL '0', STNDRD. PROCESSING
  3224                              <1> K21:					; MIGHT BE NUMERIC
  3225 00001068 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
  3226 0000106B 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
  3227                              <1> 	;
  3228                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
  3229 0000106D 8425[E4690000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
  3230                              <1> 	;jnz	K26
  3231                              <1> 	; 05/12/2021
  3232 00001073 7405                <1> 	jz	short K22A
  3233 00001075 E9A4000000          <1> 	jmp	K26			; JUMP IF KEY ALREADY DEPRESSED
  3234                              <1> K22A:
  3235 0000107A 0825[E4690000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
  3236 00001080 3025[E3690000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
  3237                              <1> 	;
  3238                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
  3239 00001086 F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
  3240 00001089 7407                <1> 	jz	short K22B		; GO IF NOT
  3241                              <1> 	;
  3242                              <1> 	; 05/12/2021
  3243                              <1> 	;push	ax			; SAVE SCAN CODE AND SHIFT MASK
  3244 0000108B 50                  <1> 	push	eax
  3245 0000108C E8B7030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
  3246                              <1> 	;pop	ax			; RESTORE SCAN CODE
  3247 00001091 58                  <1> 	pop	eax
  3248                              <1> K22B:
  3249 00001092 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
  3250                              <1>         ;jne	K26			; JUMP IF NOT INSERT KEY
  3251                              <1> 	; 05/12/2021
  3252 00001094 7405                <1> 	je	short K22C
  3253 00001096 E983000000          <1> 	jmp	K26			; JUMP IF NOT INSERT KEY
  3254                              <1> K22C:
  3255 0000109B 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
  3256 0000109D E999000000          <1>         jmp	K28			; FLAGS UPDATED, PROC. FOR BUFFER
  3257                              <1> 	;
  3258                              <1> 	;-----	BREAK SHIFT FOUND
  3259                              <1> K23:					; BREAK-SHIFT-FOUND
  3260 000010A2 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
  3261 000010A5 F6D4                <1> 	not	ah			; INVERT MASK
  3262 000010A7 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
  3263 000010A9 2025[E3690000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
  3264 000010AF 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
  3265 000010B2 7730                <1> 	ja	short K23D		; NO, ALL DONE
  3266                              <1> 	;
  3267 000010B4 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
  3268 000010B7 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
  3269 000010B9 2025[E6690000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
  3270 000010BF EB08                <1> 	jmp	short K23B		; CONTINUE
  3271                              <1> K23A:
  3272 000010C1 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
  3273 000010C3 2025[E4690000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
  3274                              <1> K23B:
  3275 000010C9 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
  3276 000010CB A0[E6690000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
  3277 000010D0 D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
  3278 000010D2 0A05[E4690000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
  3279 000010D8 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
  3280 000010DA 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
  3281 000010DC 0805[E3690000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
  3282 000010E2 88E0                <1> 	mov	al, ah
  3283                              <1> K23D:
  3284 000010E4 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
  3285 000010E6 7536                <1> 	jne	short K26		; INTERRUPT RETURN
  3286                              <1> 	;	
  3287                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
  3288 000010E8 A0[E7690000]        <1> 	mov	al, [ALT_INPUT]
  3289 000010ED B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
  3290 000010EF 8825[E7690000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
  3291 000010F5 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
  3292 000010F7 7425                <1> 	je	short K26		; INTERRUPT_RETURN
  3293 000010F9 E9B8020000          <1>         jmp     K61                     ; IT WASN'T, SO PUT IN BUFFER
  3294                              <1> 	;
  3295                              <1> K24:					; BREAK-TOGGLE
  3296 000010FE 2025[E4690000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
  3297 00001104 EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
  3298                              <1> 	;
  3299                              <1> 	;-----	TEST FOR HOLD STATE
  3300                              <1> 					; AL, AH = SCAN CODE
  3301                              <1> K25:					; NO-SHIFT-FOUND
  3302 00001106 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
  3303 00001108 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
  3304 0000110A F605[E4690000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
  3305 00001111 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
  3306 00001113 3C45                <1> 	cmp	al, NUM_KEY
  3307 00001115 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
  3308 00001117 8025[E4690000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
  3309                              <1> 	;
  3310                              <1> K26:
  3311 0000111E 8025[E6690000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3312                              <1> K26A:					; INTERRUPT-RETURN
  3313 00001125 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3314 00001126 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3315 00001128 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3316                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
  3317 0000112A B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3318 0000112C E8BC020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3319                              <1> K27A:
  3320 00001131 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3321 00001132 07                  <1> 	pop	es			; RESTORE REGISTERS
  3322 00001133 1F                  <1> 	pop	ds
  3323 00001134 5F                  <1> 	pop	edi
  3324 00001135 5E                  <1> 	pop	esi
  3325 00001136 5A                  <1> 	pop	edx
  3326 00001137 59                  <1> 	pop	ecx
  3327 00001138 5B                  <1> 	pop	ebx
  3328 00001139 58                  <1> 	pop	eax
  3329                              <1> 	;pop	ebp
  3330 0000113A CF                  <1> 	iret				; RETURN
  3331                              <1> 
  3332                              <1> 	;-----	NOT IN	HOLD STATE
  3333                              <1> K28:					; NO-HOLD-STATE
  3334 0000113B 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
  3335 0000113D 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
  3336                              <1> 	;
  3337 0000113F F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
  3338 00001142 740E                <1>         jz	short K28A		; IF NOT ALTERNATE
  3339                              <1>         ; 05/12/2021
  3340                              <1> 	;jz      K38
  3341                              <1> 	;
  3342 00001144 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
  3343 00001147 740E                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3344                              <1> 	; 28/02/2015
  3345 00001149 F605[E4690000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
  3346 00001150 7405                <1> 	jz	short K29		; NO, ALT STATE IS REAL
  3347                              <1> 	; 05/12/2021
  3348                              <1> 	;jnz	K38			; YES, THIS IS PHONY ALT STATE 
  3349                              <1>         ;				; DUE TO PRESSING SYSREQ	
  3350 00001152 E9D1000000          <1> K28A:	jmp	K38
  3351                              <1> 	;
  3352                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
  3353                              <1> K29:					; TEST-RESET
  3354 00001157 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
  3355 0000115A 740B                <1> 	jz	short K31		; NO_RESET
  3356 0000115C 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
  3357 0000115E 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
  3358                              <1> 	;
  3359                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
  3360                              <1>  	; 26/08/2014
  3361                              <1> cpu_reset:
  3362                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
  3363                              <1> 	; Send FEh (system reset command) to the keyboard controller.
  3364 00001160 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
  3365 00001162 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
  3366                              <1> khere:
  3367 00001164 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
  3368 00001165 EBFD                <1> 	jmp 	short khere		; INSURE HALT
  3369                              <1> 
  3370                              <1> 	;
  3371                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
  3372                              <1> K31:					; NO-RESET
  3373 00001167 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
  3374 00001169 7507                <1> 	jne	short K311		; NOT THERE
  3375 0000116B B020                <1> 	mov	al, ' '			; SET SPACE CHAR
  3376 0000116D E936020000          <1>         jmp     K57                     ; BUFFER_FILL
  3377                              <1> K311:
  3378 00001172 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
  3379 00001174 7509                <1> 	jne	short K312		; NOT THERE
  3380 00001176 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
  3381 0000117A E929020000          <1>         jmp     K57                     ; BUFFER_FILL
  3382                              <1> K312:
  3383 0000117F 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
  3384 00001181 7471                <1>         je	short K37B              ; GO PROCESS
  3385 00001183 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
  3386 00001185 746D                <1>         je	short K37B              ; GO PROCESS
  3387                              <1> 	;
  3388                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
  3389                              <1> K32:					; ALT-KEY-PAD
  3390 00001187 BF[A4680000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
  3391 0000118C B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
  3392 00001191 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
  3393 00001193 7523                <1> 	jne	short K33		; NO_ALT_KEYPAD
  3394 00001195 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
  3395                              <1>         ;jnz	short K37C		; YES, JUMP, NOT NUMPAD KEY
  3396                              <1> 	; 05/12/2021
  3397 00001198 751C                <1> 	jnz	short K32B
  3398 0000119A 81EF[A5680000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
  3399 000011A0 A0[E7690000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
  3400 000011A5 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
  3401 000011A7 F6E4                <1> 	mul	ah
  3402 000011A9 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
  3403 000011AC A2[E7690000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
  3404                              <1> K32A:
  3405 000011B1 E968FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
  3406                              <1> K32B:
  3407                              <1> 	; 05/12/2021
  3408 000011B6 EB6A                <1> 	jmp	K37C
  3409                              <1> 	;
  3410                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
  3411                              <1> K33:					; NO-ALT-KEYPAD
  3412 000011B8 C605[E7690000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
  3413 000011BF B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
  3414 000011C4 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
  3415 000011C6 7453                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
  3416                              <1> 	;
  3417                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
  3418                              <1> K34:					; ALT-TOP-ROW
  3419 000011C8 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
  3420 000011CA 7228                <1> 	jb	short K37B		; MUST BE ESCAPE
  3421 000011CC 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
  3422 000011CE 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
  3423 000011D0 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
  3424 000011D3 EB46                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3425                              <1> 	;
  3426                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
  3427                              <1> K35:					; ALT-FUNCTION
  3428 000011D5 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
  3429 000011D7 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
  3430 000011D9 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
  3431 000011DB 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
  3432 000011DD 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
  3433 000011E0 EB39                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  3434                              <1> K35A:
  3435 000011E2 F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  3436 000011E5 7425                <1> 	jz	short K37		; NO, JUMP
  3437 000011E7 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  3438 000011E9 7510                <1>         jne     short K35B              ; NOT THERE
  3439 000011EB 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  3440 000011EF E9B4010000          <1> 	jmp	K57			; BUFFER FILL
  3441                              <1> K37B:
  3442 000011F4 B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  3443 000011F6 E9AD010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  3444                              <1> K35B:
  3445 000011FB 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  3446 000011FD 7423                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  3447 000011FF 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  3448 00001201 75AE                <1> 	jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  3449                              <1>         ; 05/12/2021
  3450                              <1> 	;jne	K26
  3451 00001203 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  3452 00001207 E99C010000          <1> 	jmp	K57			; BUFFER FILL
  3453                              <1> K37:
  3454 0000120C 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  3455 0000120E 72E4                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  3456 00001210 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  3457                              <1>         ;ja	short K32A		; IF SO, IGNORE
  3458 00001212 0F8706FFFFFF        <1>         ja      K26
  3459 00001218 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  3460                              <1> K37A:
  3461 0000121B B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  3462 0000121D E986010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  3463                              <1> K37C:
  3464 00001222 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  3465 00001224 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  3466 00001226 EBF3                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  3467                              <1> 	;
  3468                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  3469                              <1> K38:					; NOT-ALT-SHIFT
  3470                              <1> 					; BL STILL HAS SHIFT FLAGS
  3471 00001228 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  3472 0000122B 7505                <1> 	jnz	short K38A		; YES, START PROCESSING	
  3473                              <1>         ;jz	K44                     ; NOT-CTL-SHIFT
  3474                              <1> 	; 05/12/2021
  3475 0000122D E9AB000000          <1> 	jmp	K44
  3476                              <1> 	;
  3477                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  3478                              <1> 	;-----	TEST FOR BREAK
  3479                              <1> K38A:
  3480 00001232 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  3481 00001234 7530                <1> 	jne	short K39		; JUMP, NO-BREAK
  3482 00001236 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3483 00001239 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  3484 0000123B F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3485 0000123E 7426                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  3486                              <1> K38B:
  3487 00001240 8B1D[F0690000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  3488 00001246 891D[F4690000]      <1> 	mov	[BUFFER_TAIL], ebx
  3489 0000124C C605[E2690000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  3490                              <1> 	;
  3491                              <1> 	;-----	ENABLE KEYBOARD
  3492 00001253 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3493 00001255 E893010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3494                              <1> 	;
  3495                              <1> 	; CTRL+BREAK code here !!!
  3496                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  3497                              <1> 	; 17/10/2015	
  3498 0000125A E833230000          <1> 	call	ctrlbrk ; control+break subroutine
  3499                              <1> 	;
  3500                              <1> 	;sub	ax, ax			; PUT OUT DUMMY CHARACTER
  3501                              <1> 	; 05/12/2021
  3502 0000125F 29C0                <1> 	sub	eax, eax
  3503 00001261 E942010000          <1> 	jmp     K57                     ; BUFFER_FILL
  3504                              <1> 	;
  3505                              <1> 	;-----	TEST FOR PAUSE
  3506                              <1> K39:					; NO_BREAK
  3507 00001266 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3508 00001269 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  3509 0000126B 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  3510 0000126D 7533                <1> 	jne	short K41		; NO-PAUSE
  3511                              <1> K39P:
  3512 0000126F 800D[E4690000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  3513                              <1> 	;
  3514                              <1> 	;-----	ENABLE KEYBOARD
  3515 00001276 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  3516 00001278 E870010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3517                              <1> K39A:
  3518 0000127D B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  3519 0000127F E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  3520                              <1> 	;
  3521                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  3522 00001281 803D[E0690000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  3523 00001288 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  3524 0000128A 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  3525 0000128E A0[E1690000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  3526 00001293 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  3527                              <1> 	;
  3528                              <1> K40:					; PAUSE-LOOP
  3529 00001294 F605[E4690000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  3530 0000129B 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  3531                              <1> 	;
  3532 0000129D E988FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  3533                              <1>         ;
  3534                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  3535                              <1> K41:					; NO-PAUSE
  3536 000012A2 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  3537 000012A4 7513                <1> 	jne	short K42		; NOT-KEY-55
  3538 000012A6 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  3539 000012A9 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  3540 000012AB F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  3541 000012AE 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  3542                              <1> K41A:	
  3543 000012B0 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  3544 000012B4 E9EF000000          <1>         jmp     K57                     ; BUFFER_FILL
  3545                              <1> 	;
  3546                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  3547                              <1> K42:					; NOT-KEY-55
  3548 000012B9 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  3549 000012BB 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  3550 000012BD 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  3551 000012BF 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  3552 000012C1 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  3553 000012C4 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  3554 000012C6 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  3555 000012CA E9D9000000          <1> 	jmp	K57			; BUFFER FILL	
  3556                              <1> K42A:
  3557                              <1> 	;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3558 000012CF 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  3559                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  3560                              <1> 	;;jb	K56 ; 20/02/2015
  3561                              <1> 	;;jmp	K64 ; 20/02/2015
  3562                              <1> K42B:
  3563 000012D1 BB[D8680000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  3564                              <1> 	;;jmp	K64
  3565                              <1> 	;jb	K56 ;; 20/02/2015	
  3566                              <1> 	; 05/12/2021
  3567 000012D6 7267                <1> 	jb	short K45F
  3568 000012D8 E9B9000000          <1> 	jmp	K64	
  3569                              <1>         ;
  3570                              <1> 	;-----	NOT IN CONTROL SHIFT
  3571                              <1> K44:					; NOT-CTL-SHIFT
  3572 000012DD 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  3573 000012DF 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  3574 000012E1 F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  3575 000012E4 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  3576 000012E6 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  3577 000012E9 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  3578 000012EB EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3579                              <1> K44A:
  3580 000012ED F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  3581 000012F0 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  3582                              <1> 	;
  3583                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  3584                              <1> K44B:
  3585 000012F2 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3586 000012F4 E8F4000000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  3587 000012F9 B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  3588 000012FB E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  3589                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  3590                              <1> 	;PUSH 	BP			; SAVE POINTER
  3591                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  3592                              <1> 	;POP	BP			; RESTORE POINTER
  3593 000012FD 8025[E6690000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  3594 00001304 E921FEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  3595                              <1> 	;
  3596                              <1> 	;-----	HANDLE IN-CORE KEYS
  3597                              <1> K45:					; NOT-PRINT-SCREEN
  3598 00001309 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  3599 0000130B 7734                <1> 	ja	short K46		; JUMP IF NOT
  3600 0000130D 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  3601 0000130F 7505                <1> 	jne	short K45A		; NO, JUMP
  3602 00001311 F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  3603 00001314 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  3604                              <1> K45A:
  3605 00001316 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  3606 0000131B BF[AE680000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  3607 00001320 F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  3608                              <1> 		; 20/02/2015
  3609 00001322 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  3610                              <1> 	;
  3611 00001324 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  3612 00001327 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  3613                              <1> K45B:
  3614 00001329 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3615 0000132C 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  3616                              <1> 					; NO, LOWERCASE
  3617                              <1> K45C:
  3618 0000132E BB[30690000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  3619 00001333 EB51                <1> 	jmp	short K56	
  3620                              <1> K45D:					; ALMOST-CAPS-STATE
  3621 00001335 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  3622 00001338 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  3623                              <1> K45E:
  3624 0000133A BB[88690000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  3625 0000133F EB45                <1> K45F:	jmp	short K56
  3626                              <1> 	;
  3627                              <1> 	;-----	TEST FOR KEYS F1 - F10
  3628                              <1> K46:					; NOT IN-CORE AREA
  3629 00001341 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  3630                              <1> 	;ja	short K47		; JUMP IF NOT
  3631                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  3632 00001343 7635                <1> 	jna	short K53		
  3633                              <1> 	;
  3634                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  3635                              <1> K47:					; NOT F1 - F10
  3636 00001345 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  3637 00001347 772D                <1> 	ja	short K52		; JUMP IF NOT
  3638                              <1> 	;
  3639                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  3640                              <1> K48:
  3641 00001349 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  3642 0000134B 74ED                <1> 	je	short K45E		; GO TRANSLATE
  3643 0000134D 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  3644 0000134F 74E9                <1> 	je	short K45E		; GO TRANSLATE
  3645 00001351 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  3646 00001354 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  3647                              <1> 	;		
  3648 00001356 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  3649 00001359 7514                <1> 	jnz	short K50		; TEST FOR SURE
  3650 0000135B F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  3651                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  3652 0000135E 75DA                <1> 	jnz	short K45E
  3653                              <1> 	;
  3654                              <1> 	;-----	BASE CASE FOR KEYPAD
  3655                              <1> K49:					
  3656 00001360 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  3657 00001362 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  3658 00001364 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  3659 00001366 EB40                <1> 	jmp	short K57		; BUFFER FILL
  3660                              <1> K49A:
  3661 00001368 BB[30690000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  3662 0000136D EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  3663                              <1> 	;
  3664                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  3665                              <1> K50:					; ALMOST-NUM-STATE
  3666 0000136F F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  3667 00001372 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  3668 00001374 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  3669                              <1> 	;
  3670                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  3671                              <1> K52:					; NOT A NUMPAD KEY
  3672 00001376 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  3673                              <1> 	;jne	short K53		; JUMP IF NOT
  3674                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  3675 00001378 74AF                <1> 	je	short K45B		
  3676                              <1> 	;
  3677                              <1> 	;-----	MUST BE F11 OR F12 
  3678                              <1> K53:					; F1 - F10 COME HERE, TOO
  3679 0000137A F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  3680 0000137D 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  3681                              <1> 		; 20/02/2015 
  3682 0000137F BB[88690000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  3683 00001384 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  3684                              <1> 	;
  3685                              <1> 	;-----	TRANSLATE THE CHARACTER
  3686                              <1> K56:					; TRANSLATE-CHAR
  3687 00001386 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3688 00001388 D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  3689 00001389 F605[E6690000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3690 00001390 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3691 00001392 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  3692 00001394 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  3693                              <1> 	;
  3694                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  3695                              <1> K64:					; TRANSLATE-SCAN-ORGD
  3696 00001396 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  3697 00001398 D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  3698 00001399 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  3699 0000139B B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  3700 0000139D F605[E6690000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  3701 000013A4 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  3702 000013A6 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  3703                              <1> 	;
  3704                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  3705                              <1> K57:					; BUFFER_FILL
  3706 000013A8 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  3707 000013AA 7405                <1>         je	short K59		; YES, DO NOTHING WITH IT
  3708                              <1> 	; 05/12/2021
  3709                              <1> 	;je	K26			; YES, DO NOTHING WITH IT
  3710 000013AC 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  3711                              <1> 	; 05/12/2021
  3712 000013AF 7505                <1>         jne	short K61		; NEAR_INTERRUPT_RETURN
  3713                              <1> 	;je	K26			; INTERRUPT_RETURN
  3714                              <1> K59:					; NEAR_INTERRUPT_RETURN
  3715 000013B1 E968FDFFFF          <1> 	jmp	K26			; INTERRUPT_RETURN
  3716                              <1> K61:					; NOT-CAPS-STATE
  3717 000013B6 8B1D[F4690000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  3718 000013BC 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  3719 000013BE E8AAFAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  3720 000013C3 3B1D[F0690000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  3721 000013C9 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  3722 000013CB 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  3723 000013CE 891D[F4690000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  3724 000013D4 E945FDFFFF          <1> 	jmp	K26
  3725                              <1> 	;;cli				; TURN OFF INTERRUPTS
  3726                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  3727                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  3728                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  3729                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  3730                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  3731                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  3732                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  3733                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  3734                              <1> 	;;jmp   K27                    
  3735                              <1> 	;
  3736                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  3737                              <1> K62:
  3738 000013D9 B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  3739 000013DB E620                <1> 	out	INTA00, al
  3740 000013DD 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  3741 000013E1 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  3742 000013E3 E89B010000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  3743 000013E8 E93DFDFFFF          <1> 	jmp     K27			; EXIT   
  3744                              <1> 
  3745                              <1> SHIP_IT:
  3746                              <1> 	;---------------------------------------------------------------------------------
  3747                              <1> 	; SHIP_IT
  3748                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3749                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  3750                              <1> 	;---------------------------------------------------------------------------------
  3751                              <1> 	;
  3752                              <1> 	;push	ax			; SAVE DATA TO SEND
  3753                              <1> 	; 05/12/2021
  3754 000013ED 50                  <1> 	push	eax
  3755                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  3756 000013EE FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  3757                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  3758 000013EF B900000100          <1> 	mov	ecx, 10000h			
  3759                              <1> S10:
  3760 000013F4 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  3761 000013F6 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  3762 000013F8 E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  3763                              <1> 
  3764                              <1> 	;pop	ax			; GET DATA TO SEND
  3765                              <1> 	; 05/12/2021
  3766 000013FA 58                  <1> 	pop	eax
  3767 000013FB E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  3768 000013FD FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  3769 000013FE C3                  <1> 	retn				; RETURN TO CALLER
  3770                              <1> 
  3771                              <1> SND_DATA:
  3772                              <1> 	; ---------------------------------------------------------------------------------
  3773                              <1> 	; SND_DATA
  3774                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  3775                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  3776                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  3777                              <1> 	; ---------------------------------------------------------------------------------
  3778                              <1> 	;
  3779                              <1> 	;push	ax			; SAVE REGISTERS
  3780                              <1> 	;push	bx
  3781                              <1> 	; 05/12/2021
  3782 000013FF 50                  <1> 	push	eax
  3783 00001400 53                  <1> 	push	ebx
  3784 00001401 51                  <1> 	push	ecx
  3785 00001402 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  3786 00001404 B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  3787                              <1> SD0:
  3788 00001406 FA                  <1> 	cli				; DISABLE INTERRUPTS
  3789 00001407 8025[E5690000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  3790                              <1> 	;
  3791                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  3792 0000140E B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  3793                              <1> SD5:
  3794 00001413 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  3795 00001415 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  3796 00001417 E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  3797                              <1> 	;
  3798 00001419 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  3799 0000141B E660                <1> 	out	PORT_A, al		; SEND BYTE
  3800 0000141D FB                  <1> 	sti				; ENABLE INTERRUPTS
  3801                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  3802 0000141E B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  3803                              <1> SD1:
  3804 00001423 F605[E5690000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  3805 0000142A 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  3806 0000142C E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  3807                              <1> SD2:
  3808 0000142E FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  3809 00001430 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  3810 00001432 800D[E5690000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  3811 00001439 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  3812                              <1> SD3:
  3813 0000143B F605[E5690000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  3814 00001442 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  3815                              <1> SD4:	
  3816 00001444 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  3817                              <1> 	;pop	bx
  3818                              <1> 	;pop	ax
  3819                              <1> 	; 05/12/2021
  3820 00001445 5B                  <1> 	pop	ebx
  3821 00001446 58                  <1> 	pop	eax
  3822 00001447 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  3823                              <1> 
  3824                              <1> SND_LED:
  3825                              <1> 	; ---------------------------------------------------------------------------------
  3826                              <1> 	; SND_LED
  3827                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  3828                              <1> 	;
  3829                              <1> 	;----------------------------------------------------------------------------------
  3830                              <1> 	;
  3831 00001448 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3832 00001449 F605[E5690000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3833 00001450 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3834                              <1> 	;
  3835 00001452 800D[E5690000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3836 00001459 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  3837 0000145B E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  3838 0000145D EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  3839                              <1> SND_LED1:
  3840 0000145F FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3841 00001460 F605[E5690000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  3842 00001467 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  3843                              <1> 	;
  3844 00001469 800D[E5690000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  3845                              <1> SL0:
  3846 00001470 B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  3847 00001472 E888FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3848 00001477 FA                  <1> 	cli
  3849 00001478 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  3850 0000147D 8025[E5690000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  3851 00001484 0805[E5690000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  3852 0000148A F605[E5690000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3853 00001491 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  3854                              <1> 	;
  3855 00001493 E867FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3856 00001498 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3857 00001499 F605[E5690000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  3858 000014A0 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  3859                              <1> SL2:
  3860 000014A2 B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  3861 000014A4 E856FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  3862 000014A9 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  3863                              <1> SL3:
  3864 000014AA 8025[E5690000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  3865                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  3866 000014B1 FB                  <1> 	sti				; ENABLE INTERRUPTS
  3867 000014B2 C3                  <1> 	retn				; RETURN TO CALLER
  3868                              <1> 
  3869                              <1> MAKE_LED:
  3870                              <1> 	;---------------------------------------------------------------------------------
  3871                              <1> 	; MAKE_LED
  3872                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  3873                              <1> 	;	THE MODE INDICATORS.
  3874                              <1> 	;---------------------------------------------------------------------------------
  3875                              <1> 	;
  3876                              <1> 	;push 	cx			; SAVE CX
  3877 000014B3 A0[E3690000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  3878 000014B8 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  3879                              <1> 	;mov	cl, 4			; SHIFT COUNT
  3880                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  3881 000014BA C0C004              <1> 	rol	al, 4 ; 20/02/2015
  3882 000014BD 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  3883                              <1> 	;pop	cx
  3884 000014BF C3                  <1> 	retn				; RETURN TO CALLER
  3885                              <1> 
  3886                              <1> ; % include 'kybdata.inc'   ; KEYBOARD DATA ; 11/03/2015
  3887                              <1> 
  3888                              <1> 
  3889                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  3890                                  
  3891                                  %include 'video.s' ; 07/03/2015
  3892                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  3893                              <1> ; (re-write kernel for test by using previous version without a major defect)
  3894                              <1> ; ****************************************************************************
  3895                              <1> ; Retro UNIX 386 v1 Kernel - VIDEO.INC
  3896                              <1> ; Last Modification: 05/12/2021
  3897                              <1> ;		  (Video Data is in 'VIDATA.INC')
  3898                              <1> ;
  3899                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
  3900                              <1> 
  3901                              <1> ; 05/12/2021
  3902                              <1> ; 30/06/2015
  3903                              <1> ; 27/06/2015
  3904                              <1> ; 11/03/2015
  3905                              <1> ; 02/09/2014
  3906                              <1> ; 30/08/2014
  3907                              <1> ; VIDEO FUNCTIONS
  3908                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  3909                              <1> 
  3910                              <1> write_tty:
  3911                              <1> 	; 13/08/2015
  3912                              <1> 	; 02/09/2014
  3913                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  3914                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  3915                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  3916                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  3917                              <1> 	;
  3918                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  3919                              <1> 	;	   AL = Character to be written
  3920                              <1> 	;	   EBX = Video Page (0 to 7)
  3921                              <1> 	;	   (BH = 0 --> Video Mode 3)
  3922                              <1> 
  3923                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  3924                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  3925                              <1> 
  3926                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  3927                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  3928                              <1> ;
  3929                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  3930                              <1> ;
  3931                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  3932                              <1> ;										:
  3933                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  3934                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  3935                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  3936                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  3937                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  3938                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  3939                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  3940                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  3941                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  3942                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  3943                              <1> ;   THE 0 COLOR IS USED.							:
  3944                              <1> ;   ENTRY --									:
  3945                              <1> ;     (AH) = CURRENT CRT MODE							:
  3946                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  3947                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  3948                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  3949                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  3950                              <1> ;   EXIT -- 									:
  3951                              <1> ;     ALL REGISTERS SAVED							:
  3952                              <1> ;--------------------------------------------------------------------------------
  3953                              <1> 
  3954 000014C0 FA                  <1> 	cli
  3955                              <1> 	;
  3956                              <1> 	; READ CURSOR (04/12/2013)
  3957                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  3958 000014C1 08FF                <1> 	or	bh, bh
  3959 000014C3 0F85AB000000        <1> 	jnz	beeper
  3960                              <1> 	; 01/09/2014
  3961 000014C9 803D[E0690000]03    <1> 	cmp	byte [CRT_MODE], 3
  3962 000014D0 7405                <1> 	je	short m3
  3963                              <1> 	;
  3964 000014D2 E876020000          <1> 	call	set_mode
  3965                              <1> m3:
  3966 000014D7 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  3967 000014D9 66D1E6              <1> 	shl	si, 1
  3968 000014DC 81C6[D66F0000]      <1> 	add	esi, cursor_posn
  3969 000014E2 668B16              <1> 	mov	dx, [esi]
  3970                              <1> 	;
  3971                              <1> 	; dx now has the current cursor position
  3972                              <1> 	;
  3973 000014E5 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  3974 000014E7 764D                <1> 	jbe	short u8
  3975                              <1> 	;
  3976                              <1> 	; write the char to the screen
  3977                              <1> u0:	
  3978                              <1> 	; ah = attribute/color
  3979                              <1> 	; al = character
  3980                              <1> 	; bl = video page number (0 to 7)
  3981                              <1> 	; bh = 0
  3982                              <1> 	;
  3983 000014E9 E832020000          <1> 	call	write_c_current
  3984                              <1> 	;
  3985                              <1> 	; position the cursor for next char
  3986 000014EE FEC2                <1> 	inc	dl		; next column
  3987                              <1> 	;cmp	dl, [CRT_COLS]
  3988 000014F0 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  3989 000014F3 0F85E9000000        <1>         jne     set_cpos
  3990 000014F9 B200                <1> 	mov	dl, 0		; column = 0
  3991                              <1> u10:				; (line feed found)
  3992 000014FB 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  3993 000014FE 722F                <1> 	jb 	short u6
  3994                              <1> 	;
  3995                              <1> 	; scroll required
  3996                              <1> u1:	
  3997                              <1> 	; SET CURSOR POSITION (04/12/2013)
  3998 00001500 E8DD000000          <1> 	call	set_cpos
  3999                              <1> 	;
  4000                              <1> 	; determine value to fill with during scroll
  4001                              <1> u2:
  4002                              <1> 	; READ_AC_CURRENT		:
  4003                              <1> 	;   THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER
  4004                              <1> 	;    AT THE CURRENT CURSOR POSITION
  4005                              <1> 	;
  4006                              <1> 	; INPUT				
  4007                              <1> 	;	(AH) = CURRENT CRT MODE
  4008                              <1> 	;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )
  4009                              <1> 	;	(DS) = DATA SEGMENT
  4010                              <1> 	;	(ES) = REGEN SEGMENT
  4011                              <1> 	; OUTPUT			
  4012                              <1> 	;	(AL) = CHARACTER READ
  4013                              <1> 	;	(AH) = ATTRIBUTE READ
  4014                              <1> 	;
  4015                              <1> 	; mov	ah, [CRT_MODE] ; move current mode into ah
  4016                              <1> 	;
  4017                              <1> 	; bl = video page number
  4018                              <1> 	;
  4019 00001505 E834010000          <1> 	call	find_position	; get regen location and port address
  4020                              <1> 	; dx = status port
  4021                              <1> 	; esi = cursor location/address
  4022                              <1> p11:
  4023 0000150A FB                  <1> 	sti			; enable interrupts
  4024 0000150B 90                  <1> 	nop			; allow for small interupts window
  4025 0000150C FA                  <1> 	cli			; blocks interrupts for single loop
  4026 0000150D EC                  <1> 	in	al, dx		; get status from adapter
  4027 0000150E A801                <1> 	test	al, RHRZ	; is horizontal retrace low
  4028 00001510 75F8                <1> 	jnz	short p11	; wait until it is
  4029                              <1> p12:				; now wait for either retrace high
  4030 00001512 EC                  <1> 	in	al, dx		; get status
  4031 00001513 A809                <1> 	test	al, RVRT+RHRZ	; is horizontal or vertical retrace high
  4032 00001515 74FB                <1> 	jz	short p12	; wait until either is active	
  4033                              <1> p13:
  4034 00001517 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
  4035 0000151D 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
  4036                              <1> 	;
  4037                              <1> 	; al = character, ah = attribute
  4038                              <1> 	;
  4039 00001520 FB                  <1> 	sti
  4040                              <1> 	; bl = video page number 	
  4041                              <1> u3:
  4042                              <1> 	;;mov	ax, 0601h 	; scroll one line
  4043                              <1> 	;;sub	cx, cx		; upper left corner
  4044                              <1> 	;;mov	dh, 25-1 	; lower right row
  4045                              <1> 	;;;mov	dl, [CRT_COLS]
  4046                              <1> 	;mov	dl, 80		; lower right column	
  4047                              <1> 	;;dec	dl
  4048                              <1> 	;;mov	dl, 79
  4049                              <1> 
  4050                              <1> 	;;call	scroll_up	; 04/12/2013
  4051                              <1> 	;;; 11/03/2015
  4052                              <1> 	; 02/09/2014
  4053                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  4054                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  4055                              <1> 	; 11/03/2015
  4056 00001521 6629C9              <1> 	sub	cx, cx
  4057 00001524 66BA4F18            <1> 	mov	dx, 184Fh ; dl= 79 (column), dh = 24 (row)
  4058                              <1> 	;
  4059 00001528 B001                <1> 	mov	al, 1		; scroll 1 line up
  4060                              <1> 		; ah = attribute
  4061 0000152A E939010000          <1> 	jmp	scroll_up
  4062                              <1> ;u4:
  4063                              <1> 	;;int	10h		; video-call return
  4064                              <1> 				; scroll up the screen
  4065                              <1> 				; tty return
  4066                              <1> ;u5:
  4067                              <1> 	;retn			; return to the caller
  4068                              <1> 
  4069                              <1> u6:				; set-cursor-inc
  4070 0000152F FEC6                <1> 	inc	dh		; next row
  4071                              <1> 				; set cursor
  4072                              <1> ;u7:					
  4073                              <1> 	;;mov	ah, 02h
  4074                              <1> 	;;jmp	short u4 	; establish the new cursor
  4075                              <1> 	;call	set_cpos
  4076                              <1> 	;jmp 	short u5
  4077 00001531 E9AC000000          <1> 	jmp     set_cpos
  4078                              <1> 
  4079                              <1> 	; check for control characters
  4080                              <1> u8:
  4081 00001536 7438                <1> 	je	short u9
  4082 00001538 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  4083 0000153A 74BF                <1> 	je	short u10
  4084 0000153C 3C07                <1> 	cmp	al, 07h 	; is it a bell
  4085 0000153E 7434                <1> 	je	short u11
  4086 00001540 3C08                <1> 	cmp	al, 08h		; is it a backspace
  4087                              <1> 	;jne	short u0
  4088 00001542 7424                <1> 	je	short bs	; 12/12/2013
  4089                              <1> 	; 12/12/2013 (tab stop)
  4090 00001544 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  4091 00001546 75A1                <1> 	jne	short u0
  4092 00001548 88D0                <1> 	mov	al, dl
  4093 0000154A 6698                <1> 	cbw
  4094 0000154C B108                <1> 	mov	cl, 8
  4095 0000154E F6F1                <1> 	div	cl
  4096 00001550 28E1                <1> 	sub	cl, ah
  4097                              <1> ts:
  4098                              <1> 	; 02/09/2014
  4099                              <1> 	; 01/09/2014
  4100 00001552 B020                <1> 	mov	al, 20h
  4101                              <1> tsloop:
  4102 00001554 6651                <1> 	push	cx
  4103 00001556 6650                <1> 	push	ax
  4104 00001558 30FF                <1> 	xor 	bh, bh
  4105                              <1> 	;mov	bl, [active_page]
  4106 0000155A E878FFFFFF          <1> 	call	m3
  4107 0000155F 6658                <1> 	pop	ax  ; ah = attribute/color
  4108 00001561 6659                <1> 	pop	cx
  4109 00001563 FEC9                <1> 	dec	cl
  4110 00001565 75ED                <1> 	jnz	short tsloop
  4111 00001567 C3                  <1> 	retn
  4112                              <1> bs:	
  4113                              <1> 	; back space found
  4114                              <1> 
  4115 00001568 08D2                <1> 	or	dl, dl 		; is it already at start of line
  4116                              <1> 	;je	short u7 	; set_cursor
  4117 0000156A 7476                <1> 	jz	short set_cpos
  4118 0000156C 664A                <1> 	dec	dx     		; no -- just move it back
  4119                              <1> 	;jmp	short u7
  4120 0000156E EB72                <1> 	jmp	short set_cpos
  4121                              <1> 
  4122                              <1> 	; carriage return found
  4123                              <1> u9:
  4124 00001570 B200                <1> 	mov	dl, 0 		; move to first column
  4125                              <1> 	;jmp	short u7
  4126 00001572 EB6E                <1> 	jmp	short set_cpos
  4127                              <1> 
  4128                              <1> 	; line feed found
  4129                              <1> ;u10:
  4130                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  4131                              <1> ;	jne	short u6 	; no, just set the cursor
  4132                              <1> ;       jmp     u1              ; yes, scroll the screen
  4133                              <1> 
  4134                              <1> beeper: 
  4135                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4136                              <1> 	; 18/01/2014
  4137                              <1> 	; 03/12/2013
  4138                              <1> 	; bell found
  4139                              <1> u11:
  4140 00001574 FB                  <1> 	sti
  4141 00001575 3A1D[E66F0000]      <1> 	cmp	bl, [active_page]
  4142 0000157B 7551                <1> 	jne	short u12	; Do not sound the beep 
  4143                              <1> 				; if it is not written on the active page
  4144 0000157D 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  4145 00001581 B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  4146                              <1> 	;call	beep		; sound the pod bell
  4147                              <1> 	;jmp	short u5 	; tty_return
  4148                              <1> 	;retn
  4149                              <1> 	
  4150                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  4151                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  4152                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  4153                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  4154                              <1> 
  4155                              <1> beep:
  4156                              <1> 	; 07/02/2015
  4157                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4158                              <1> 	; 18/01/2014
  4159                              <1> 	; 03/12/2013
  4160                              <1> 	;
  4161                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  4162                              <1> 	;
  4163                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  4164                              <1> 	;
  4165                              <1> 	; ENTRY:
  4166                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  4167                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  4168                              <1> 	; EXIT:				:
  4169                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  4170                              <1> 
  4171 00001583 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  4172 00001584 FA                  <1> 	cli			; block interrupts during update
  4173 00001585 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  4174 00001587 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  4175 00001589 EB00                <1> 	jmp	$+2		; I/O delay
  4176 0000158B 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  4177 0000158D E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  4178 0000158F EB00                <1> 	jmp	$+2		; I/O delay
  4179 00001591 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  4180 00001593 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  4181 00001595 E461                <1> 	in	al, PORT_B	; get current setting of port
  4182 00001597 88C4                <1> 	mov	ah, al		; save that setting
  4183 00001599 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  4184 0000159B E661                <1> 	out	PORT_B, al	; and restore interrupt status
  4185                              <1> 	;popf	; 18/01/2014
  4186 0000159D FB                  <1> 	sti
  4187                              <1> g7:				; 1/64 second per count (bl)
  4188 0000159E B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  4189 000015A3 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  4190 000015A8 FECB                <1> 	dec	bl		; (bl) length count expired?
  4191 000015AA 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  4192                              <1> 	;
  4193                              <1> 	;pushf			; save interrupt status
  4194 000015AC FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  4195 000015AD E461                <1> 	in	al, PORT_B	; get current port value
  4196                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  4197 000015AF 0CFC                <1>         or      al, ~(GATE2+SPK2)
  4198 000015B1 20C4                <1>         and	ah, al		; someone turned them off during beep
  4199 000015B3 88E0                <1> 	mov	al, ah		; recover value of port
  4200                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  4201 000015B5 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  4202 000015B7 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  4203                              <1> 	;popf			; restore interrupt flag state
  4204 000015B9 FB                  <1> 	sti
  4205 000015BA B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  4206 000015BF E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  4207                              <1> 	;pushf			; save interrupt status
  4208 000015C4 FA                  <1> 	cli			; block interrupts during update
  4209 000015C5 E461                <1> 	in	al, PORT_B	; get current port value in case	
  4210 000015C7 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  4211 000015C9 08E0                <1> 	or	al, ah		; recover value of port_b
  4212 000015CB E661                <1> 	out	PORT_B, al	; restore speaker status
  4213 000015CD 9D                  <1> 	popf			; restore interrupt flag state
  4214                              <1> u12:	
  4215 000015CE C3                  <1> 	retn
  4216                              <1> 
  4217                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  4218                              <1> 
  4219                              <1> WAITF:
  4220                              <1> waitf:
  4221                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4222                              <1> 	; 03/12/2013
  4223                              <1> 	;
  4224                              <1> ;	push ax			; save work register (ah)	
  4225                              <1> ;waitf1:
  4226                              <1> 				; use timer 1 output bits
  4227                              <1> ;	in	al, PORT_B	; read current counter output status
  4228                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  4229                              <1> ;	cmp	al, ah		; did it just change
  4230                              <1> ;	je	short waitf1	; wait for a change in output line
  4231                              <1> ;	;
  4232                              <1> ;	mov	ah, al		; save new lflag state
  4233                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  4234                              <1> ;	;
  4235                              <1> ;	pop	ax		; restore (ah)
  4236                              <1> ;	retn			; return (cx)=0
  4237                              <1> 
  4238                              <1> ; 05/12/2021 (Retro UNIX 386 v1.2)
  4239                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  4240                              <1> ; 17/12/2014 (dsectrm2.s)
  4241                              <1> ; WAITF
  4242                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  4243                              <1> ;
  4244                              <1> ;---WAITF-----------------------------------------------------------------------
  4245                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  4246                              <1> ; ENTRY:
  4247                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  4248                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  4249                              <1> ; EXIT:
  4250                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  4251                              <1> ;	(CX) = 0	
  4252                              <1> ;-------------------------------------------------------------------------------
  4253                              <1> 
  4254                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  4255                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  4256                              <1> 
  4257                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  4258                              <1> 	;PUSH	AX			; SAVE WORK REGISTER (AH)
  4259                              <1> 	; 05/12/2021
  4260 000015CF 50                  <1> 	push	eax
  4261                              <1> 	; 16/12/2014
  4262                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  4263 000015D0 D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  4264                              <1> ;17/12/2014	
  4265                              <1> ;WAITF1:
  4266                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  4267                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  4268                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  4269                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  4270                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  4271                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  4272                              <1> 	;
  4273                              <1> 	; 17/12/2014
  4274                              <1> 	;
  4275                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  4276                              <1> 	;
  4277                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  4278                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  4279                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  4280                              <1> WR_STATE_0:
  4281 000015D2 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4282 000015D4 A810                <1> 	TEST	AL,010H
  4283 000015D6 74FA                <1> 	JZ	SHORT WR_STATE_0
  4284                              <1> WR_STATE_1:
  4285 000015D8 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  4286 000015DA A810                <1> 	TEST	AL,010H
  4287 000015DC 75FA                <1> 	JNZ	SHORT WR_STATE_1
  4288 000015DE E2F2                <1>         LOOP    WR_STATE_0
  4289                              <1> 	;
  4290                              <1> 	;POP	AX			; RESTORE (AH)
  4291                              <1> 	; 05/12/2021
  4292 000015E0 58                  <1> 	pop	eax
  4293 000015E1 C3                  <1> 	RETn				; (CX) = 0
  4294                              <1> 
  4295                              <1> set_cpos:
  4296                              <1> 	; 27/06/2015
  4297                              <1> 	; 01/09/2014
  4298                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  4299                              <1> 	;
  4300                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  4301                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  4302                              <1> 	;
  4303                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4304                              <1> 	;
  4305                              <1> 	; SET_CPOS
  4306                              <1> 	;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  4307                              <1> 	;	NEW X-Y VALUES PASSED
  4308                              <1> 	; INPUT
  4309                              <1> 	;	DX - ROW,COLUMN OF NEW CURSOR
  4310                              <1> 	;	BH - DISPLAY PAGE OF CURSOR
  4311                              <1> 	; OUTPUT
  4312                              <1> 	;	CURSOR IS SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  4313                              <1> 	;
  4314 000015E2 0FB6C3              <1>         movzx   eax, bl  ; BL = video page number ; 27/06/2015 (movzx)
  4315 000015E5 D0E0                <1>         shl     al, 1   ; word offset
  4316 000015E7 BE[D66F0000]        <1> 	mov	esi, cursor_posn
  4317 000015EC 01C6                <1>         add     esi, eax
  4318 000015EE 668916              <1> 	mov	[esi], dx ; save the pointer
  4319 000015F1 381D[E66F0000]      <1> 	cmp	[active_page], bl
  4320 000015F7 7532                <1> 	jne	short m17
  4321                              <1> 	;call	m18	; CURSOR SET
  4322                              <1> ;m17:			; SET_CPOS_RETURN
  4323                              <1> 	; 01/09/2014
  4324                              <1> ;	retn
  4325                              <1> 		; DX  = row/column
  4326                              <1> m18:
  4327 000015F9 E832000000          <1> 	call	position ; determine location in regen buffer	
  4328 000015FE 668B0D[D46F0000]    <1> 	mov	cx, [CRT_START]
  4329 00001605 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  4330                              <1> 			; to the start address (offset) for this page
  4331 00001608 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  4332 0000160B B40E                <1> 	mov	ah, 14	; register number for cursor
  4333                              <1> 	;call	m16	; output value to the 6845	
  4334                              <1> 	;retn
  4335                              <1> 
  4336                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  4337                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  4338                              <1> m16:
  4339 0000160D FA                  <1> 	cli
  4340                              <1> 	;mov	dx, [addr_6845] ; address register
  4341 0000160E 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  4342 00001612 88E0                <1> 	mov	al, ah	; get value
  4343 00001614 EE                  <1> 	out	dx, al	; register set
  4344 00001615 6642                <1> 	inc	dx	; data register
  4345 00001617 EB00                <1> 	jmp	$+2	; i/o delay
  4346 00001619 88E8                <1> 	mov	al, ch	; data
  4347 0000161B EE                  <1> 	out	dx, al	
  4348 0000161C 664A                <1> 	dec	dx	
  4349 0000161E 88E0                <1> 	mov	al, ah
  4350 00001620 FEC0                <1> 	inc	al	; point to other data register
  4351 00001622 EE                  <1> 	out	dx, al	; set for second register
  4352 00001623 6642                <1> 	inc	dx
  4353 00001625 EB00                <1> 	jmp	$+2	; i/o delay
  4354 00001627 88C8                <1> 	mov	al, cl	; second data value
  4355 00001629 EE                  <1> 	out	dx, al
  4356 0000162A FB                  <1> 	sti
  4357                              <1> m17:
  4358 0000162B C3                  <1> 	retn
  4359                              <1> 
  4360                              <1> set_ctype:
  4361                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4362                              <1> 	;
  4363                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4364                              <1> 
  4365                              <1> ;	CH) = BITS 4-0 = START LINE FOR CURSOR
  4366                              <1> ;       ** HARDWARE WILL ALWAYS CAUSE BLINK
  4367                              <1> ;       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  4368                              <1> ;          OR NO CURSOR AT ALL
  4369                              <1> ;	(CL) = BITS 4-0 = END LINE FOR CURSOR
  4370                              <1> 
  4371                              <1> ;------------------------------------------------
  4372                              <1> ; SET_CTYPE
  4373                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  4374                              <1> ; INPUT
  4375                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  4376                              <1> ; OUTPUT	
  4377                              <1> ;	NONE
  4378                              <1> ;------------------------------------------------
  4379                              <1> 
  4380 0000162C B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  4381                              <1> 	;mov	[CURSOR_MODE], cx ; save in data area
  4382                              <1> 	;call	m16	; output cx register
  4383                              <1> 	;retn
  4384 0000162E EBDD                <1> 	jmp	m16
  4385                              <1> 
  4386                              <1> 
  4387                              <1> position:
  4388                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  4389                              <1> 	; 27/06/2015
  4390                              <1> 	; 02/09/2014
  4391                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4392                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  4393                              <1> 	;
  4394                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4395                              <1> 	;
  4396                              <1> 	; POSITION
  4397                              <1> 	;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  4398                              <1> 	;	OF A CHARACTER IN THE ALPHA MODE
  4399                              <1> 	; INPUT
  4400                              <1> 	;	AX = ROW, COLUMN POSITION
  4401                              <1> 	; OUTPUT
  4402                              <1> 	;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  4403                              <1> 
  4404                              <1> 		; DX = ROW, COLUMN POSITION
  4405                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
  4406 00001630 31C0                <1> 	xor	eax, eax ; 02/09/2014
  4407 00001632 B050                <1> 	mov	al, 80   ; determine bytes to row	
  4408 00001634 F6E6                <1> 	mul	dh 	 ; row value
  4409 00001636 30F6                <1> 	xor	dh, dh   ; 0	
  4410 00001638 6601D0              <1> 	add	ax, dx	 ; add column value to the result
  4411                              <1> 	;shl	ax, 1	; * 2 for attribute bytes
  4412                              <1> 	; 05/12/2021
  4413 0000163B D1E0                <1> 	shl	eax, 1
  4414                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  4415 0000163D C3                  <1> 	retn
  4416                              <1> 
  4417                              <1> find_position:
  4418                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  4419                              <1> 	; 27/06/2015
  4420                              <1> 	; 07/09/2014
  4421                              <1> 	; 02/09/2014
  4422                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4423                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4424 0000163E 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
  4425 00001641 89CE                <1> 	mov	esi, ecx
  4426                              <1> 	;shl	si, 1
  4427 00001643 D1E6                <1> 	shl	esi, 1 ; 05/12/2021
  4428 00001645 668B96[D66F0000]    <1> 	mov	dx, [esi+cursor_posn]
  4429 0000164C 7409                <1> 	jz	short p21
  4430                              <1> 	;xor	si, si
  4431 0000164E 31F6                <1> 	xor	esi, esi ; 05/12/2021
  4432                              <1> p20:
  4433                              <1> 	;add	si, [CRT_LEN]
  4434 00001650 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
  4435 00001655 E2F9                <1> 	loop	p20
  4436                              <1> p21:
  4437 00001657 6621D2              <1> 	and	dx, dx
  4438 0000165A 7407                <1> 	jz	short p22
  4439 0000165C E8CFFFFFFF          <1> 	call 	position ; determine location in regen in page
  4440 00001661 01C6                <1> 	add	esi, eax ; add location to start of regen page
  4441                              <1> p22:	
  4442                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  4443                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  4444                              <1> 	;add	dx, 6	; point at status port
  4445 00001663 66BADA03            <1> 	mov	dx, 03DAh ; status port
  4446                              <1> 	; cx = 0
  4447 00001667 C3                  <1> 	retn
  4448                              <1> 
  4449                              <1> scroll_up:
  4450                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  4451                              <1> 	; 16/01/2016
  4452                              <1> 	; 07/09/2014
  4453                              <1> 	; 02/09/2014
  4454                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  4455                              <1> 	; 04/04/2014
  4456                              <1> 	; 04/12/2013
  4457                              <1> 	;
  4458                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4459                              <1> 	;
  4460                              <1> 	; SCROLL UP
  4461                              <1> 	;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  4462                              <1> 	;	ON THE SCREEN
  4463                              <1> 	; INPUT
  4464                              <1> 	;	(AH) = CURRENT CRT MODE
  4465                              <1> 	;	(AL) = NUMBER OF ROWS TO SCROLL
  4466                              <1> 	;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  4467                              <1> 	;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  4468                              <1> 	;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  4469                              <1> 	;	(DS) = DATA SEGMENT
  4470                              <1> 	;	(ES) = REGEN BUFFER SEGMENT
  4471                              <1> 	; OUTPUT
  4472                              <1> 	;	NONE -- THE REGEN BUFFER IS MODIFIED
  4473                              <1> 	;
  4474                              <1> 	;	bh = 0  (02/09/2014)
  4475                              <1> 	;
  4476                              <1> 	; ((ah = 3))
  4477                              <1> 	; cl = left upper column
  4478                              <1> 	; ch = left upper row
  4479                              <1> 	; dl = right lower column
  4480                              <1> 	; dh = right lower row
  4481                              <1> 	;
  4482                              <1> 	; al = line count 
  4483                              <1> 	; ah = attribute to be used on blanked line	
  4484                              <1> 	; bl = video page number (0 to 7)
  4485                              <1> 	; 
  4486                              <1> 
  4487                              <1> 	; Test	Line Count
  4488 00001668 08C0                <1> 	or	al, al
  4489 0000166A 740C                <1> 	jz	short al_set
  4490 0000166C 88F7                <1> 	mov	bh, dh	; subtract lower row from upper row
  4491 0000166E 28EF                <1> 	sub	bh, ch
  4492 00001670 FEC7                <1> 	inc	bh	; adjust difference by 1
  4493 00001672 38C7                <1> 	cmp	bh, al 	; line count = amount of rows in window?
  4494 00001674 7502                <1> 	jne	short al_set ; if not the we're all set
  4495 00001676 30C0                <1> 	xor	al, al	; otherwise set al to zero
  4496                              <1> al_set:
  4497 00001678 30FF                <1> 	xor	bh, bh	; 0
  4498                              <1> 	;push	ax
  4499 0000167A 50                  <1> 	push	eax ; 05/12/2021
  4500                              <1> 	;mov 	esi, [crt_base]
  4501 0000167B BE00800B00          <1>         mov     esi, 0B8000h  
  4502 00001680 3A1D[E66F0000]      <1>         cmp     bl, [active_page]
  4503 00001686 750B                <1> 	jne	short n0
  4504                              <1> 	;
  4505 00001688 66A1[D46F0000]      <1>         mov     ax, [CRT_START]
  4506 0000168E 6601C6              <1>         add     si, ax
  4507 00001691 EB0F                <1>         jmp     short n1
  4508                              <1> n0:
  4509 00001693 20DB                <1>         and     bl, bl
  4510 00001695 740B                <1> 	jz	short n1
  4511 00001697 88D8                <1> 	mov	al, bl
  4512                              <1> n0x:
  4513                              <1>         ;add    si, [CRT_LEN]
  4514                              <1>         ;add    esi, 80*25*2 
  4515 00001699 6681C6A00F          <1>         add     si, 80*25*2
  4516 0000169E FEC8                <1>         dec	al
  4517 000016A0 75F7                <1> 	jnz	short n0x
  4518                              <1> n1:	
  4519                              <1>         ;Scroll position
  4520                              <1> 	;push	dx
  4521                              <1> 	; 05/12/2021
  4522 000016A2 52                  <1> 	push	edx
  4523 000016A3 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
  4524 000016A6 E885FFFFFF          <1> 	call	position
  4525 000016AB 01C6                <1> 	add	esi, eax
  4526 000016AD 89F7                <1> 	mov	edi, esi
  4527                              <1> 	;pop	dx	; lower right position in DX
  4528 000016AF 5A                  <1> 	pop	edx ; 05/12/2021
  4529 000016B0 6629CA              <1> 	sub	dx, cx
  4530 000016B3 FEC6                <1> 	inc	dh	; dh = #rows 
  4531 000016B5 FEC2                <1> 	inc	dl	; dl = #cols in block
  4532                              <1> 	;pop	ax	; al = line count, ah = attribute
  4533                              <1> 	; 05/12/2021
  4534 000016B7 58                  <1> 	pop	eax	; al = line count, ah = attribute
  4535 000016B8 31C9                <1> 	xor	ecx, ecx
  4536 000016BA 6689C1              <1> 	mov	cx, ax
  4537                              <1> 	;mov	ah, [CRT_COLS]
  4538 000016BD B450                <1> 	mov	ah, 80
  4539 000016BF F6E4                <1> 	mul	ah	; determine offset to from address
  4540 000016C1 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
  4541                              <1> 	;
  4542                              <1> 	;push	ax	; offset 
  4543                              <1> 	;push	dx
  4544                              <1> 	; 05/12/2021
  4545 000016C4 50                  <1> 	push	eax
  4546 000016C5 52                  <1> 	push	edx
  4547                              <1> 	;
  4548                              <1> 	; 04/04/2014
  4549 000016C6 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
  4550                              <1> n8:                      ; wait_display_enable
  4551 000016CA EC                  <1>         in      al, dx   ; get port
  4552 000016CB A808                <1> 	test	al, RVRT ; wait for vertical retrace	
  4553 000016CD 74FB                <1> 	jz	short n8 ; wait_display_enable
  4554 000016CF B025                <1> 	mov	al, 25h
  4555 000016D1 B2D8                <1> 	mov	dl, 0D8h ; address control port
  4556 000016D3 EE                  <1> 	out	dx, al	; turn off video during vertical retrace
  4557                              <1> 	;pop	dx	; #rows, #cols
  4558                              <1>        	;pop	ax	; offset
  4559                              <1> 	; 05/12/2021
  4560 000016D4 5A                  <1> 	pop	edx
  4561 000016D5 58                  <1> 	pop	eax
  4562 000016D6 6691                <1> 	xchg	ax, cx	; 
  4563                              <1> 	; ecx = offset, al = line count, ah = attribute
  4564                              <1> ;n9:
  4565 000016D8 08C0                <1> 	or	al, al
  4566 000016DA 7420                <1>         jz      short n3 
  4567 000016DC 01CE                <1>         add     esi, ecx ; from address for scroll
  4568 000016DE 88F7                <1> 	mov	bh, dh  ; #rows in block
  4569 000016E0 28C7                <1> 	sub	bh, al	; #rows to be moved
  4570                              <1> n2:
  4571                              <1> 	; Move rows
  4572 000016E2 88D1                <1> 	mov	cl, dl	; get # of cols to move
  4573 000016E4 56                  <1> 	push	esi
  4574 000016E5 57                  <1> 	push	edi	; save start address
  4575                              <1> n10:
  4576 000016E6 66A5                <1> 	movsw		; move that line on screen
  4577 000016E8 FEC9                <1> 	dec	cl
  4578 000016EA 75FA                <1>         jnz     short n10
  4579 000016EC 5F                  <1> 	pop	edi
  4580 000016ED 5E                  <1> 	pop	esi	; recover addresses
  4581                              <1>         ;mov    cl, [CRT_COLS] 
  4582                              <1> 	;add	cl, cl
  4583                              <1>         ;mov    ecx, 80*2
  4584 000016EE 66B9A000            <1>         mov     cx, 80*2
  4585 000016F2 01CE                <1>         add     esi, ecx  ; next line
  4586 000016F4 01CF                <1>         add     edi, ecx
  4587 000016F6 FECF                <1> 	dec	bh	 ; count of lines to move
  4588 000016F8 75E8                <1> 	jnz	short n2 ; row loop
  4589                              <1> 	; bh = 0
  4590 000016FA 88C6                <1> 	mov	dh, al	 ; #rows	
  4591                              <1> n3:
  4592                              <1> 	; attribute in ah
  4593 000016FC B020                <1> 	mov	al, ' '	 ; fill with blanks
  4594                              <1> n3x:
  4595                              <1> 	; Clear rows
  4596                              <1>                 ; dh =  #rows
  4597 000016FE 88D1                <1>         mov	cl, dl	; get # of cols to clear
  4598 00001700 57                  <1>         push    edi     ; save address
  4599                              <1> n11:
  4600 00001701 66AB                <1>         stosw           ; store fill character
  4601 00001703 FEC9                <1> 	dec	cl
  4602 00001705 75FA                <1>         jnz     short n11
  4603 00001707 5F                  <1>         pop     edi     ; recover address
  4604                              <1> 	;mov	cl, [CRT_COLS]
  4605                              <1> 	;add	cl, cl
  4606                              <1>         ;mov    ecx, 80*2
  4607 00001708 B1A0                <1>         mov	cl, 80*2
  4608 0000170A 01CF                <1>         add     edi, ecx
  4609 0000170C FECE                <1> 	dec	dh
  4610 0000170E 75EE                <1> 	jnz	short n3x ; 16/01/2016
  4611                              <1> 	;
  4612 00001710 3A1D[E66F0000]      <1> 	cmp	bl, [active_page]
  4613 00001716 7507                <1> 	jne	short n6
  4614                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
  4615 00001718 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3
  4616 0000171A 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
  4617 0000171E EE                  <1> 	out	dx, al
  4618                              <1> n6:
  4619 0000171F C3                  <1> 	retn
  4620                              <1> 
  4621                              <1> 
  4622                              <1> write_c_current:
  4623                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  4624                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  4625                              <1> 	; 18/01/2014
  4626                              <1> 	; 04/12/2013
  4627                              <1> 	;
  4628                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4629                              <1> 	;
  4630                              <1> 	; WRITE_C_CURRENT
  4631                              <1> 	;	THIS ROUTINE WRITES THE CHARACTER AT
  4632                              <1> 	;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED
  4633                              <1> 	; INPUT	
  4634                              <1> 	;	(AH) = CURRENT CRT MODE
  4635                              <1> 	;	(BH) = DISPLAY PAGE
  4636                              <1> 	;	(CX) = COUNT OF CHARACTERS TO WRITE
  4637                              <1> 	;	(AL) = CHAR TO WRITE
  4638                              <1> 	;	(DS) = DATA SEGMENT
  4639                              <1> 	;	(ES) = REGEN SEGMENT
  4640                              <1> 	; OUTPUT
  4641                              <1> 	;	DISPLAY REGEN BUFFER UPDATED
  4642                              <1> 
  4643 00001720 FA                  <1> 	cli		
  4644                              <1> 	; bl = video page
  4645                              <1> 	; al = character
  4646                              <1> 	; ah = color/attribute
  4647                              <1> 	;push	dx
  4648                              <1> 	;push	ax	; save character & attribute/color
  4649                              <1> 	; 05/12/2021
  4650 00001721 52                  <1> 	push	edx
  4651 00001722 50                  <1> 	push	eax
  4652 00001723 E816FFFFFF          <1> 	call 	find_position  ; get regen location and port address
  4653                              <1> 	; esi = regen location
  4654                              <1> 	; dx = status port
  4655                              <1> 	;
  4656                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  4657                              <1> 	;
  4658                              <1> p41:			; wait for horizontal retrace is low or vertical
  4659 00001728 FB                  <1> 	sti		; enable interrupts first
  4660 00001729 3A1D[E66F0000]      <1>         cmp     bl, [active_page]
  4661 0000172F 7510                <1> 	jne	short p44 
  4662 00001731 FA                  <1> 	cli 		; block interrupts for single loop
  4663 00001732 EC                  <1> 	in	al, dx	; get status from the adapter
  4664 00001733 A808                <1> 	test	al, RVRT ; check for vertical retrace first
  4665 00001735 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  4666 00001737 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  4667 00001739 75ED                <1> 	jnz	short p41 ; wait until it is
  4668                              <1> p42:			;  wait for either retrace high
  4669 0000173B EC                  <1> 	in	al, dx ; get status again
  4670 0000173C A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  4671 0000173E 74FB                <1> 	jz	short p42 ; wait until either retrace active
  4672                              <1> p43:	
  4673 00001740 FB                  <1> 	sti
  4674                              <1> p44:
  4675                              <1> 	;pop	ax	; restore the character (al) & attribute (ah)
  4676                              <1> 	; 05/12/2021
  4677 00001741 58                  <1> 	pop	eax
  4678 00001742 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  4679                              <1> 				; Retro UNIX 386 v1 feature only!
  4680 00001748 668906              <1> 	mov	[esi], ax
  4681                              <1> 	;pop	dx
  4682                              <1> 	; 05/12/2021
  4683 0000174B 5A                  <1> 	pop	edx
  4684 0000174C C3                  <1> 	retn
  4685                              <1> 
  4686                              <1> set_mode:
  4687                              <1> 	; 16/01/2016
  4688                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  4689                              <1> 	;
  4690                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4691                              <1> 
  4692                              <1> ;------------------------------------------------------
  4693                              <1> ; SET MODE					      :
  4694                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  4695                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  4696                              <1> ; INPUT						      :
  4697                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  4698                              <1> ; OUTPUT					      :
  4699                              <1> ;	NONE					      :
  4700                              <1> ;------------------------------------------------------
  4701                              <1> 
  4702 0000174D 57                  <1> 	push	edi ; 16/01/2016
  4703 0000174E 53                  <1> 	push	ebx
  4704 0000174F 52                  <1> 	push	edx
  4705 00001750 51                  <1> 	push	ecx ; 16/01/2016
  4706 00001751 50                  <1>         push    eax
  4707                              <1> 
  4708                              <1> 	;mov	dx, 03D4h 	; address or color card
  4709 00001752 B003                <1> 	mov	al, 3
  4710                              <1> ;M8:
  4711 00001754 A2[E0690000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  4712 00001759 B029                <1> 	mov	al, 29h
  4713                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
  4714 0000175B 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
  4715                              <1> 	;push	dx  		; save port value
  4716                              <1> 	;add	dx, 4		; point to control register
  4717 0000175D 66BAD803            <1> 	mov	dx, 3D8h
  4718 00001761 EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
  4719                              <1> 	;pop	dx
  4720                              <1> ;M9:
  4721 00001762 BB[186A0000]        <1> 	mov	ebx, video_params ; initialization table
  4722                              <1> 	;mov	ax, [ebx+10]      ; get the cursor mode from the table	
  4723                              <1> 	;xchg 	ah, al
  4724                              <1> 	;mov	[CURSOR_MODE], ax ; save cursor mode
  4725 00001767 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
  4726                              <1> 	
  4727                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
  4728 00001769 B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
  4729                              <1> M10:			;  initialization loop
  4730 0000176E 88E0                <1> 	mov	al, ah 	; get 6845 register number
  4731 00001770 EE                  <1> 	out	dx, al
  4732 00001771 6642                <1> 	inc	dx      ; point to data port
  4733 00001773 FEC4                <1> 	inc	ah	; next register value
  4734 00001775 8A03                <1> 	mov	al, [ebx] ; get table value
  4735 00001777 EE                  <1> 	out	dx, al	; out to chip
  4736 00001778 43                  <1> 	inc	ebx	; next in table
  4737 00001779 664A                <1> 	dec	dx	; back to pointer register
  4738 0000177B E2F1                <1> 	loop	M10	; do the whole table
  4739                              <1> 	
  4740                              <1> ;-----	FILL REGEN AREA WITH BLANK
  4741                              <1> 	;xor	ax, ax  
  4742                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
  4743                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
  4744                              <1> 	;mov	ecx, 8192 ; number of words in color card
  4745                              <1> 	; black background, light gray characeter color, space character
  4746                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
  4747                              <1> ;M13:			  ; clear buffer
  4748                              <1> 	;add	edi, 0B8000h ; [crt_base]
  4749                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  4750                              <1> 
  4751                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
  4752                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
  4753                              <1> 			 ; prepare to output to video enable port
  4754                              <1> 	;add	dx,4	 ; point to the mode control gerister
  4755 0000177D 66BAD803            <1> 	mov	dx, 3D8h
  4756                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
  4757 00001781 B029                <1> 	mov	al, 29h
  4758 00001783 EE                  <1> 	out	dx, al	 ; set video enable port
  4759                              <1> 
  4760                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
  4761                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
  4762                              <1> 	;
  4763                              <1> 	;mov byte [CRT_COLS], 80h ; initialize number of columns count
  4764                              <1> 	;
  4765                              <1> ;-----	SET CURSOR POSITIONS
  4766                              <1> 	;push	edi
  4767                              <1> 	;mov	word [CRT_LEN], 80*25*2
  4768 00001784 BF[D66F0000]        <1> 	mov	edi, cursor_posn
  4769 00001789 B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
  4770 0000178E 31C0                <1> 	xor	eax, eax
  4771 00001790 F3AB                <1> 	rep 	stosd	; fill with zeroes
  4772                              <1> 	;pop	edi
  4773                              <1> 
  4774                              <1> ;-----	SET UP OVERSCAN REGISTER
  4775 00001792 6642                <1> 	inc	dx	; set overscan port to a default
  4776 00001794 B030                <1> 	mov	al, 30h	; 30H valuye for all modes except 640X200 bw
  4777                              <1> ;M14:
  4778 00001796 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
  4779                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
  4780                              <1> 
  4781                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  4782                              <1> 	;
  4783 00001797 58                  <1> 	pop	eax
  4784 00001798 59                  <1> 	pop	ecx ; 16/01/2016
  4785 00001799 5A                  <1> 	pop	edx
  4786 0000179A 5B                  <1> 	pop	ebx
  4787 0000179B 5F                  <1> 	pop	edi ; 16/01/2016
  4788 0000179C C3                  <1> 	retn
  4789                              <1> 	
  4790                              <1> tty_sw:
  4791                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
  4792                              <1> 	; 30/06/2015
  4793                              <1> 	; 27/06/2015 
  4794                              <1> 	; 07/09/2014
  4795                              <1> 	; 02/09/2014 (Retro UNIX 386 v1 - beginning)
  4796                              <1> 	;
  4797                              <1> 	; (Modified registers : EAX)
  4798                              <1> 	;
  4799                              <1>         ;mov     byte [u.quant], 0  ; 04/03/2014
  4800                              <1> 	;
  4801                              <1> ;act_disp_page:
  4802                              <1> 	; 30/06/2015
  4803                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  4804                              <1> 	; 10/12/2013
  4805                              <1> 	; 04/12/2013
  4806                              <1> 	;
  4807                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  4808                              <1> 	;
  4809                              <1> 	; ACT_DISP_PAGE
  4810                              <1> 	;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  4811                              <1> 	;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  4812                              <1> 	; INPUT
  4813                              <1> 	;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  4814                              <1> 	; OUTPUT
  4815                              <1> 	;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  4816                              <1> 
  4817                              <1> 	;cli
  4818                              <1> 
  4819 0000179D 53                  <1> 	push	ebx
  4820                              <1> 	;push	cx
  4821                              <1> 	;push	dx
  4822                              <1> 	; 05/12/2021
  4823 0000179E 51                  <1> 	push	ecx
  4824 0000179F 52                  <1> 	push	edx
  4825                              <1> 	;
  4826 000017A0 A2[E66F0000]        <1> 	mov	[active_page], al ; save active page value ; [ptty]
  4827                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
  4828 000017A5 66B9A00F            <1> 	mov	cx, 25*80*2
  4829                              <1> 	; 27/06/2015
  4830 000017A9 0FB6D8              <1> 	movzx	ebx, al
  4831                              <1> 	;
  4832 000017AC 6698                <1> 	cbw	; 07/09/2014 (ah=0)
  4833 000017AE 66F7E1              <1> 	mul 	cx	; display page times regen length
  4834                              <1> 	; 10/12/2013
  4835 000017B1 66A3[D46F0000]      <1> 	mov	[CRT_START], ax ; save start address for later
  4836 000017B7 6689C1              <1> 	mov	cx, ax ; start address to cx
  4837                              <1> 	;sar	cx, 1
  4838 000017BA 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
  4839 000017BD B40C                <1> 	mov	ah, 12	; 6845 register for start address
  4840 000017BF E849FEFFFF          <1> 	call	m16
  4841                              <1> 	;sal	bx, 1
  4842                              <1> 	; 01/09/2014
  4843 000017C4 D0E3                <1> 	shl	bl, 1	; *2 for word offset
  4844 000017C6 81C3[D66F0000]      <1> 	add	ebx, cursor_posn
  4845 000017CC 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  4846 000017CF E825FEFFFF          <1> 	call	m18
  4847                              <1> 	;
  4848                              <1> 	;pop	dx
  4849                              <1> 	;pop	cx
  4850                              <1> 	; 05/12/2021
  4851 000017D4 5A                  <1> 	pop	edx
  4852 000017D5 59                  <1> 	pop	ecx
  4853 000017D6 5B                  <1> 	pop	ebx
  4854                              <1> 	;
  4855                              <1> 	;sti
  4856                              <1> 	;
  4857 000017D7 C3                  <1> 	retn
  4858                              <1> 
  4859                              <1> ; % include 'vidata.inc' ; VIDEO DATA ; 11/03/2015
  4860                              <1> 
  4861                              <1> ; /// End Of VIDEO FUNCTIONS ///
  4862                                  
  4863                                  setup_rtc_int:
  4864                                  ; source: http://wiki.osdev.org/RTC
  4865 000017D8 FA                      	cli		; disable interrupts
  4866                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  4867                                  	; in order to change this ...
  4868                                  	; frequency = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  4869                                  	; (rate must be above 2 and not over 15)
  4870                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  4871 000017D9 B08A                    	mov	al, 8Ah 
  4872 000017DB E670                    	out	70h, al ; set index to register A, disable NMI
  4873 000017DD 90                      	nop
  4874 000017DE E471                    	in	al, 71h ; get initial value of register A
  4875 000017E0 88C4                    	mov 	ah, al
  4876 000017E2 80E4F0                  	and	ah, 0F0h
  4877 000017E5 B08A                    	mov	al, 8Ah 
  4878 000017E7 E670                    	out	70h, al ; reset index to register A
  4879 000017E9 88E0                    	mov	al, ah
  4880 000017EB 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  4881 000017ED E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  4882                                  	; enable RTC interrupt
  4883 000017EF B08B                    	mov	al, 8Bh ;
  4884 000017F1 E670                    	out	70h, al ; select register B and disable NMI
  4885 000017F3 90                      	nop
  4886 000017F4 E471                    	in	al, 71h ; read the current value of register B
  4887 000017F6 88C4                    	mov	ah, al  ;
  4888 000017F8 B08B                    	mov 	al, 8Bh ;
  4889 000017FA E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  4890 000017FC 88E0                    	mov	al, ah  ;
  4891 000017FE 0C40                    	or	al, 40h ;
  4892 00001800 E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  4893 00001802 FB                      	sti
  4894 00001803 C3                      	retn
  4895                                  
  4896                                  ; Write memory information
  4897                                  ; Temporary Code
  4898                                  ; 06/11/2014
  4899                                  ; 14/08/2015 
  4900                                  memory_info:	
  4901 00001804 A1[BC6F0000]            	mov	eax, [memory_size] ; in pages
  4902 00001809 50                      	push	eax
  4903 0000180A C1E00C                  	shl	eax, 12		   ; in bytes
  4904 0000180D BB0A000000              	mov	ebx, 10
  4905 00001812 89D9                    	mov	ecx, ebx	   ; 10
  4906 00001814 BE[216C0000]            	mov	esi, mem_total_b_str	
  4907 00001819 E8B2000000              	call	bintdstr
  4908 0000181E 58                      	pop	eax
  4909 0000181F B107                    	mov	cl, 7
  4910 00001821 BE[456C0000]            	mov	esi, mem_total_p_str
  4911 00001826 E8A5000000              	call	bintdstr	
  4912                                  	; 14/08/2015
  4913 0000182B E8BD000000              	call	calc_free_mem
  4914                                  	; edx = calculated free pages
  4915                                  	; ecx = 0
  4916 00001830 A1[C06F0000]            	mov 	eax, [free_pages]
  4917 00001835 39D0                    	cmp	eax, edx ; calculated free mem value 
  4918                                  		; and initial free mem value are same or not?
  4919 00001837 751D                    	jne 	short pmim ; print mem info with '?' if not
  4920 00001839 52                      	push 	edx ; free memory in pages	
  4921                                  	;mov 	eax, edx
  4922 0000183A C1E00C                  	shl	eax, 12 ; convert page count
  4923                                  			; to byte count
  4924 0000183D B10A                    	mov	cl, 10
  4925 0000183F BE[656C0000]            	mov	esi, free_mem_b_str
  4926 00001844 E887000000              	call	bintdstr
  4927 00001849 58                      	pop	eax
  4928 0000184A B107                    	mov	cl, 7
  4929 0000184C BE[896C0000]            	mov	esi, free_mem_p_str
  4930 00001851 E87A000000              	call	bintdstr
  4931                                  pmim:
  4932 00001856 BE[0F6C0000]            	mov	esi, msg_memory_info
  4933                                  pmim_nb:	
  4934 0000185B AC                      	lodsb
  4935 0000185C 08C0                    	or	al, al
  4936 0000185E 740D                    	jz	short pmim_ok
  4937 00001860 56                      	push	esi
  4938 00001861 31DB                    	xor	ebx, ebx ; 0
  4939                                  			; Video page 0 (bl=0)
  4940 00001863 B407                    	mov	ah, 07h ; Black background, 
  4941                                  			; light gray forecolor
  4942 00001865 E856FCFFFF              	call	write_tty
  4943 0000186A 5E                      	pop	esi
  4944 0000186B EBEE                    	jmp	short pmim_nb
  4945                                  pmim_ok:
  4946 0000186D C3                      	retn
  4947                                  
  4948                                  ; Convert binary number to hexadecimal string
  4949                                  ; 10/05/2015  
  4950                                  ; dsectpm.s (28/02/2015)
  4951                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  4952                                  ; 01/12/2014
  4953                                  ; 25/11/2014
  4954                                  ;
  4955                                  bytetohex:
  4956                                  	; INPUT ->
  4957                                  	; 	AL = byte (binary number)
  4958                                  	; OUTPUT ->
  4959                                  	;	AX = hexadecimal string
  4960                                  	;
  4961 0000186E 53                      	push	ebx
  4962 0000186F 31DB                    	xor	ebx, ebx
  4963 00001871 88C3                    	mov	bl, al
  4964 00001873 C0EB04                  	shr	bl, 4
  4965 00001876 8A9B[C0180000]          	mov	bl, [ebx+hexchrs] 	 	
  4966 0000187C 86D8                    	xchg	bl, al
  4967 0000187E 80E30F                  	and	bl, 0Fh
  4968 00001881 8AA3[C0180000]          	mov	ah, [ebx+hexchrs] 
  4969 00001887 5B                      	pop	ebx	
  4970 00001888 C3                      	retn
  4971                                  
  4972                                  wordtohex:
  4973                                  	; INPUT ->
  4974                                  	; 	AX = word (binary number)
  4975                                  	; OUTPUT ->
  4976                                  	;	EAX = hexadecimal string
  4977                                  	;
  4978 00001889 53                      	push	ebx
  4979 0000188A 31DB                    	xor	ebx, ebx
  4980 0000188C 86E0                    	xchg	ah, al
  4981 0000188E 6650                    	push	ax
  4982 00001890 88E3                    	mov	bl, ah
  4983 00001892 C0EB04                  	shr	bl, 4
  4984 00001895 8A83[C0180000]          	mov	al, [ebx+hexchrs] 	 	
  4985 0000189B 88E3                    	mov	bl, ah
  4986 0000189D 80E30F                  	and	bl, 0Fh
  4987 000018A0 8AA3[C0180000]          	mov	ah, [ebx+hexchrs]
  4988 000018A6 C1E010                  	shl	eax, 16
  4989 000018A9 6658                    	pop	ax
  4990 000018AB 5B                      	pop	ebx
  4991 000018AC EBC0                    	jmp	short bytetohex
  4992                                  	;mov	bl, al
  4993                                  	;shr	bl, 4
  4994                                  	;mov	bl, [ebx+hexchrs] 	 	
  4995                                  	;xchg	bl, al	 	
  4996                                  	;and	bl, 0Fh
  4997                                  	;mov	ah, [ebx+hexchrs] 
  4998                                  	;pop	ebx	
  4999                                  	;retn
  5000                                  
  5001                                  dwordtohex:
  5002                                  	; INPUT ->
  5003                                  	; 	EAX = dword (binary number)
  5004                                  	; OUTPUT ->
  5005                                  	;	EDX:EAX = hexadecimal string
  5006                                  	;
  5007 000018AE 50                      	push	eax
  5008 000018AF C1E810                  	shr	eax, 16
  5009 000018B2 E8D2FFFFFF              	call	wordtohex
  5010 000018B7 89C2                    	mov	edx, eax
  5011 000018B9 58                      	pop	eax
  5012 000018BA E8CAFFFFFF              	call	wordtohex
  5013 000018BF C3                      	retn
  5014                                  
  5015                                  ; 10/05/2015
  5016                                  hex_digits:
  5017                                  hexchrs:
  5018 000018C0 303132333435363738-     	db '0123456789ABCDEF'
  5019 000018C9 39414243444546     
  5020                                  
  5021                                  ; Convert binary number to decimal/numeric string
  5022                                  ; 06/11/2014
  5023                                  ; Temporary Code
  5024                                  ;
  5025                                  
  5026                                  bintdstr:
  5027                                  	; EAX = binary number
  5028                                  	; ESI = decimal/numeric string address
  5029                                  	; EBX = divisor (10)
  5030                                  	; ECX = string length (<=10)
  5031 000018D0 01CE                    	add	esi, ecx
  5032                                  btdstr0:
  5033 000018D2 4E                      	dec	esi
  5034 000018D3 31D2                    	xor	edx, edx
  5035 000018D5 F7F3                    	div	ebx
  5036 000018D7 80C230                  	add	dl, 30h
  5037 000018DA 8816                    	mov	[esi], dl
  5038 000018DC FEC9                    	dec	cl
  5039 000018DE 740C                    	jz	btdstr2
  5040 000018E0 09C0                    	or	eax, eax
  5041 000018E2 75EE                    	jnz	short btdstr0
  5042                                  btdstr1:
  5043 000018E4 4E                      	dec	esi
  5044 000018E5 C60620                          mov     byte [esi], 20h ; blank space
  5045 000018E8 FEC9                    	dec	cl
  5046 000018EA 75F8                    	jnz	short btdstr1
  5047                                  btdstr2:
  5048 000018EC C3                      	retn
  5049                                  
  5050                                  ; Calculate free memory pages on M.A.T.
  5051                                  ; 06/11/2014
  5052                                  ; Temporary Code
  5053                                  ;
  5054                                  
  5055                                  calc_free_mem:
  5056 000018ED 31D2                    	xor	edx, edx
  5057                                  	;xor	ecx, ecx
  5058 000018EF 668B0D[D06F0000]        	mov	cx, [mat_size] ; in pages
  5059 000018F6 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  5060 000018F9 BE00001000              	mov	esi, MEM_ALLOC_TBL
  5061                                  cfm0:
  5062 000018FE AD                      	lodsd
  5063 000018FF 51                      	push	ecx
  5064 00001900 B920000000              	mov	ecx, 32
  5065                                  cfm1:
  5066 00001905 D1E8                    	shr	eax, 1
  5067 00001907 7301                    	jnc	short cfm2
  5068 00001909 42                      	inc	edx
  5069                                  cfm2:
  5070 0000190A E2F9                    	loop	cfm1
  5071 0000190C 59                      	pop	ecx
  5072 0000190D E2EF                    	loop	cfm0
  5073 0000190F C3                      	retn
  5074                                  
  5075                                  %include 'diskio.s'  ; 07/03/2015
  5076                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
  5077                              <1> ; (re-write kernel for test by using previous version without a major defect)
  5078                              <1> ; ****************************************************************************
  5079                              <1> ; Retro UNIX 386 v1 Kernel - DISKIO.INC
  5080                              <1> ; Last Modification: 05/12/2021
  5081                              <1> ;
  5082                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
  5083                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
  5084                              <1> 
  5085                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
  5086                              <1> 
  5087                              <1> ; ///////// DISK I/O SYSTEM ///////////////
  5088                              <1> 
  5089                              <1> ; 06/02/2015
  5090                              <1> diskette_io:
  5091 00001910 9C                  <1> 	pushfd
  5092 00001911 0E                  <1> 	push 	cs
  5093 00001912 E809000000          <1> 	call 	DISKETTE_IO_1
  5094 00001917 C3                  <1> 	retn
  5095                              <1> 	
  5096                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
  5097                              <1> ;//////////////////////////////////////////////////////
  5098                              <1> 
  5099                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  5100                              <1> ; 20/02/2015
  5101                              <1> ; 06/02/2015 (unix386.s)
  5102                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
  5103                              <1> ;
  5104                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
  5105                              <1> ;
  5106                              <1> ; ADISK.EQU
  5107                              <1> 
  5108                              <1> ;----- Wait control constants 
  5109                              <1> 
  5110                              <1> ;amount of time to wait while RESET is active.
  5111                              <1> 
  5112                              <1> WAITCPU_RESET_ON   EQU	21		;Reset on must last at least 14us
  5113                              <1> 					;at 250 KBS xfer rate.
  5114                              <1> 					;see INTEL MCS, 1985, pg. 5-456
  5115                              <1> 
  5116                              <1> WAITCPU_FOR_STATUS EQU	100		;allow 30 microseconds for
  5117                              <1> 					;status register to become valid
  5118                              <1> 					;before re-reading.
  5119                              <1> 
  5120                              <1> ;After sending a byte to NEC, status register may remain
  5121                              <1> ;incorrectly set for 24 us.
  5122                              <1> 
  5123                              <1> WAITCPU_RQM_LOW	   EQU	24		;number of loops to check for
  5124                              <1> 					;RQM low.
  5125                              <1> 
  5126                              <1> ; COMMON.MAC
  5127                              <1> ;
  5128                              <1> ;	Timing macros
  5129                              <1> ;
  5130                              <1> 
  5131                              <1> %macro 		SIODELAY 0 		; SHORT IODELAY
  5132                              <1> 		jmp short $+2
  5133                              <1> %endmacro		
  5134                              <1> 
  5135                              <1> %macro		IODELAY  0		; NORMAL IODELAY
  5136                              <1> 		jmp short $+2
  5137                              <1> 		jmp short $+2
  5138                              <1> %endmacro
  5139                              <1> 
  5140                              <1> %macro		NEWIODELAY 0
  5141                              <1> 		out	0EBh,al
  5142                              <1> %endmacro 
  5143                              <1> 
  5144                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
  5145                              <1> ;;; WAIT_FOR_MEM
  5146                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
  5147                              <1> ;WAIT_FDU_INT_HI	equ	1
  5148                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
  5149                              <1> ;;; WAIT_FOR_PORT
  5150                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
  5151                              <1> ;WAIT_FDU_SEND_HI	equ	0
  5152                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
  5153                              <1> ;Time to wait while waiting for each byte of NEC results = .5
  5154                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  5155                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
  5156                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
  5157                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
  5158                              <1> ;;; WAIT_REFRESH
  5159                              <1> ;amount of time to wait for head settle, per unit in parameter
  5160                              <1> ;table = 1 ms.
  5161                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
  5162                              <1> 
  5163                              <1> 
  5164                              <1> ; //////////////// DISKETTE I/O ////////////////
  5165                              <1> 
  5166                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
  5167                              <1> 
  5168                              <1> ;----------------------------------------
  5169                              <1> ;	EQUATES USED BY POST AND BIOS	:
  5170                              <1> ;----------------------------------------
  5171                              <1> 
  5172                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
  5173                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
  5174                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  5175                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
  5176                              <1> 
  5177                              <1> ;----------------------------------------
  5178                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
  5179                              <1> ;-------------------------------------------------------------------------------
  5180                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
  5181                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
  5182                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
  5183                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
  5184                              <1> 
  5185                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
  5186                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
  5187                              <1> ;		EQU	011H		; - RESERVED			      ;C
  5188                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
  5189                              <1> ;		EQU	013H		; - RESERVED			      ;E
  5190                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
  5191                              <1> 
  5192                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
  5193                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
  5194                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
  5195                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
  5196                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
  5197                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
  5198                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
  5199                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
  5200                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
  5201                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
  5202                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
  5203                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
  5204                              <1> 
  5205                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
  5206                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
  5207                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
  5208                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
  5209                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
  5210                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
  5211                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
  5212                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
  5213                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
  5214                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
  5215                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
  5216                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
  5217                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
  5218                              <1> 
  5219                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
  5220                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
  5221                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
  5222                              <1> 
  5223                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
  5224                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
  5225                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
  5226                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
  5227                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
  5228                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
  5229                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
  5230                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
  5231                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
  5232                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
  5233                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
  5234                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
  5235                              <1> 
  5236                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
  5237                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
  5238                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
  5239                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
  5240                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
  5241                              <1> 
  5242                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
  5243                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
  5244                              <1> ;INTA00		EQU	020H		; 8259 PORT
  5245                              <1> INTA01		EQU	021H		; 8259 PORT
  5246                              <1> INTB00		EQU	0A0H		; 2ND 8259
  5247                              <1> INTB01		EQU	0A1H		;
  5248                              <1> 
  5249                              <1> ;-------------------------------------------------------------------------------
  5250                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
  5251                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
  5252                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
  5253                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
  5254                              <1> ;-------------------------------------------------------------------------------
  5255                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
  5256                              <1> 
  5257                              <1> ;-------------------------------------------------------------------------------
  5258                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
  5259                              <1> 
  5260                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
  5261                              <1> ; (unix386.s <-- dsectrm2.s)
  5262                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
  5263                              <1> 
  5264                              <1> ; 10/12/2014
  5265                              <1> ;
  5266                              <1> ;int40h:
  5267                              <1> ;	pushf
  5268                              <1> ;	push 	cs
  5269                              <1> ;	;cli
  5270                              <1> ;	call 	DISKETTE_IO_1
  5271                              <1> ;	retn
  5272                              <1> 
  5273                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
  5274                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  5275                              <1> ;
  5276                              <1> 
  5277                              <1> ;-- INT13H ---------------------------------------------------------------------
  5278                              <1> ; DISKETTE I/O
  5279                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
  5280                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
  5281                              <1> ; INPUT
  5282                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
  5283                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
  5284                              <1> ;		ON ALL DRIVES
  5285                              <1> ;------------------------------------------------------------------------------- 
  5286                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
  5287                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
  5288                              <1> ;-------------------------------------------------------------------------------
  5289                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
  5290                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5291                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
  5292                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
  5293                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
  5294                              <1> ;		320/360	320/360	    0-39
  5295                              <1> ;		320/360	1.2M	    0-39
  5296                              <1> ;		1.2M	1.2M	    0-79
  5297                              <1> ;		720K	720K	    0-79
  5298                              <1> ;		1.44M	1.44M	    0-79	
  5299                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
  5300                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
  5301                              <1> ;		320/360	320/360	     1-8/9
  5302                              <1> ;		320/360	1.2M	     1-8/9
  5303                              <1> ;		1.2M	1.2M	     1-15
  5304                              <1> ;		720K	720K	     1-9
  5305                              <1> ;		1.44M	1.44M	     1-18		
  5306                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
  5307                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
  5308                              <1> ;		320/360	320/360	        8/9
  5309                              <1> ;		320/360	1.2M	        8/9
  5310                              <1> ;		1.2M	1.2M		15
  5311                              <1> ;		720K	720K		9
  5312                              <1> ;		1.44M	1.44M		18
  5313                              <1> ;
  5314                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
  5315                              <1> ;
  5316                              <1> ;-------------------------------------------------------------------------------
  5317                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
  5318                              <1> ;-------------------------------------------------------------------------------
  5319                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
  5320                              <1> ;-------------------------------------------------------------------------------
  5321                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
  5322                              <1> ;-------------------------------------------------------------------------------
  5323                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
  5324                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
  5325                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
  5326                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
  5327                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
  5328                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
  5329                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
  5330                              <1> ;		READ/WRITE ACCESS.
  5331                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
  5332                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
  5333                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
  5334                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
  5335                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
  5336                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
  5337                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
  5338                              <1> ;
  5339                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
  5340                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
  5341                              <1> ;		---------------------------------------------
  5342                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
  5343                              <1> ;		---------------------------------------------
  5344                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
  5345                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
  5346                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
  5347                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
  5348                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
  5349                              <1> ;		---------------------------------------------
  5350                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
  5351                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
  5352                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
  5353                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
  5354                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
  5355                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
  5356                              <1> ;-------------------------------------------------------------------------------
  5357                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
  5358                              <1> ;	REGISTERS
  5359                              <1> ;	  INPUT
  5360                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5361                              <1> ;	  OUTPUT
  5362                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
  5363                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
  5364                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5365                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5366                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
  5367                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
  5368                              <1> ;	    (BH) - 0
  5369                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
  5370                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
  5371                              <1> ;	    (AX) - 0
  5372                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
  5373                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
  5374                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
  5375                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
  5376                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
  5377                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
  5378                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
  5379                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
  5380                              <1> ;-------------------------------------------------------------------------------
  5381                              <1> ;	(AH)= 15H  READ DASD TYPE
  5382                              <1> ;	OUTPUT REGISTERS
  5383                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
  5384                              <1> ;		00 - DRIVE NOT PRESENT	
  5385                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
  5386                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
  5387                              <1> ;		03 - RESERVED (FIXED DISK)
  5388                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5389                              <1> ;-------------------------------------------------------------------------------
  5390                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
  5391                              <1> ;	OUTPUT REGISTERS
  5392                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
  5393                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
  5394                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
  5395                              <1> ;-------------------------------------------------------------------------------
  5396                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
  5397                              <1> ;	INPUT REGISTERS
  5398                              <1> ;	(AL) -	00 - NOT USED	
  5399                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
  5400                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
  5401                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
  5402                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
  5403                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
  5404                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
  5405                              <1> ;-------------------------------------------------------------------------------
  5406                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
  5407                              <1> ;	INPUT REGISTERS
  5408                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
  5409                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
  5410                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
  5411                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
  5412                              <1> ;	OUTPUT REGISTERS:
  5413                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
  5414                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
  5415                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
  5416                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
  5417                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
  5418                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
  5419                              <1> ;-------------------------------------------------------------------------------
  5420                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
  5421                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
  5422                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
  5423                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
  5424                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
  5425                              <1> ;		CHANGE ERROR CODE
  5426                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
  5427                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
  5428                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
  5429                              <1> ;
  5430                              <1> ; DATA VARIABLE -- @DISK_POINTER
  5431                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
  5432                              <1> ;-------------------------------------------------------------------------------
  5433                              <1> ; OUTPUT FOR ALL FUNCTIONS
  5434                              <1> ;	AH = STATUS OF OPERATION
  5435                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
  5436                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
  5437                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
  5438                              <1> ;		TYPE AH=(15)).
  5439                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
  5440                              <1> ;	FOR READ/WRITE/VERIFY
  5441                              <1> ;		DS,BX,DX,CX PRESERVED
  5442                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
  5443                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
  5444                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
  5445                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
  5446                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
  5447                              <1> ;-------------------------------------------------------------------------------
  5448                              <1> ;
  5449                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
  5450                              <1> ;
  5451                              <1> ;   -----------------------------------------------------------------
  5452                              <1> ;   |       |       |       |       |       |       |       |       |
  5453                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
  5454                              <1> ;   |       |       |       |       |       |       |       |       |
  5455                              <1> ;   -----------------------------------------------------------------
  5456                              <1> ;	|	|	|	|	|	|	|	|
  5457                              <1> ;	|	|	|	|	|	-----------------
  5458                              <1> ;	|	|	|	|	|		|
  5459                              <1> ;	|	|	|	|    RESERVED		|
  5460                              <1> ;	|	|	|	|		  PRESENT STATE
  5461                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
  5462                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
  5463                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
  5464                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
  5465                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
  5466                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
  5467                              <1> ;	|	|	|	|	110: RESERVED
  5468                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
  5469                              <1> ;	|	|	|	|
  5470                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
  5471                              <1> ;	|	|	|
  5472                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
  5473                              <1> ;	|	|			DRIVE)
  5474                              <1> ;	|	|
  5475                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
  5476                              <1> ;
  5477                              <1> ;						00: 500 KBS
  5478                              <1> ;						01: 300 KBS
  5479                              <1> ;						10: 250 KBS
  5480                              <1> ;						11: RESERVED
  5481                              <1> ;
  5482                              <1> ;
  5483                              <1> ;-------------------------------------------------------------------------------
  5484                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
  5485                              <1> ;-------------------------------------------------------------------------------
  5486                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
  5487                              <1> ;-------------------------------------------------------------------------------
  5488                              <1> 
  5489                              <1> struc MD
  5490 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
  5491 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
  5492 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
  5493 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
  5494 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
  5495 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
  5496 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
  5497 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
  5498 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
  5499 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
  5500 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
  5501 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
  5502 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
  5503                              <1> endstruc
  5504                              <1> 
  5505                              <1> BIT7OFF	EQU	7FH
  5506                              <1> BIT7ON	EQU	80H
  5507                              <1> 
  5508                              <1> ;;int13h: ; 16/02/2015
  5509                              <1> ;; 16/02/2015 - 21/02/2015
  5510                              <1> int40h:
  5511 00001918 9C                  <1> 	pushfd
  5512 00001919 0E                  <1> 	push 	cs
  5513 0000191A E801000000          <1> 	call 	DISKETTE_IO_1
  5514 0000191F C3                  <1> 	retn	
  5515                              <1> 
  5516                              <1> DISKETTE_IO_1:
  5517                              <1> 
  5518 00001920 FB                  <1> 	STI				; INTERRUPTS BACK ON
  5519 00001921 55                  <1> 	PUSH	eBP			; USER REGISTER
  5520 00001922 57                  <1> 	PUSH	eDI			; USER REGISTER
  5521 00001923 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
  5522 00001924 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
  5523 00001925 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
  5524 00001926 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
  5525                              <1> 					; [BP]   = SECTOR #
  5526                              <1> 					; [BP+1] = TRACK #
  5527                              <1> 					; [BP+2] = BUFFER OFFSET
  5528                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
  5529                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
  5530                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
  5531                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
  5532                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
  5533                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
  5534                              <1> 					; BH/[BP+3] = 0
  5535                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
  5536                              <1> 					; DH/[BP+5] = MAX HEAD #
  5537                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
  5538 00001928 06                  <1> 	push	es ; 06/02/2015	
  5539 00001929 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
  5540 0000192A 56                  <1> 	PUSH	eSI			; USER REGISTERS
  5541                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
  5542                              <1> 	;mov	cx, cs
  5543                              <1> 	;mov	ds, cx
  5544 0000192B 66B91000            <1> 	mov	cx, KDATA
  5545 0000192F 8ED9                <1>         mov     ds, cx
  5546 00001931 8EC1                <1>         mov     es, cx
  5547                              <1> 
  5548                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
  5549 00001933 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4 ; 18/02/2015
  5550 00001936 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
  5551 00001938 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5552                              <1> OK_FUNC:
  5553 0000193A 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
  5554 0000193D 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
  5555 0000193F 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
  5556 00001942 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
  5557 00001944 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
  5558 00001947 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
  5559 00001949 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
  5560                              <1> OK_DRV:
  5561 0000194B 31C9                <1> 	xor	ecx, ecx
  5562                              <1> 	;mov	esi, ecx ; 08/02/2015
  5563                              <1> 	; 05/12/2021
  5564 0000194D 89CE                <1> 	mov	esi, ecx
  5565 0000194F 89CF                <1> 	mov	edi, ecx ; 08/02/2015
  5566 00001951 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
  5567                              <1> 	;XOR	CH,CH			; CX = FUNCTION
  5568                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
  5569 00001953 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
  5570 00001956 BB[8E190000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
  5571 0000195B 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
  5572 0000195D 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
  5573 0000195F 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
  5574 00001961 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
  5575 00001964 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
  5576                              <1> 	;
  5577                              <1> 	; 11/12/2014
  5578 00001967 8815[A16A0000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
  5579                              <1> 	;
  5580 0000196D 8A25[3C700000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
  5581 00001973 C605[3C700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
  5582                              <1> 
  5583                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
  5584                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
  5585                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
  5586                              <1> ;
  5587                              <1> ;		DI	: DRIVE #
  5588                              <1> ;		SI-HI	: HEAD #
  5589                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
  5590                              <1> ;		ES	: BUFFER SEGMENT
  5591                              <1> ;		[BP]	: SECTOR #
  5592                              <1> ;		[BP+1]	: TRACK #
  5593                              <1> ;		[BP+2]	: BUFFER OFFSET
  5594                              <1> ;
  5595                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
  5596                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
  5597                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
  5598                              <1> ;	SPECIFIC ERROR CODE.
  5599                              <1> ;
  5600                              <1> 					; (AH) = @DSKETTE_STATUS
  5601 0000197A FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
  5602 0000197C 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
  5603 0000197D 1F                  <1> 	POP	DS
  5604 0000197E 07                  <1> 	pop	es	; 06/02/2015
  5605 0000197F 59                  <1> 	POP	eCX
  5606 00001980 5B                  <1> 	POP	eBX
  5607 00001981 5A                  <1> 	POP	eDX
  5608 00001982 5F                  <1> 	POP	eDI
  5609 00001983 89E5                <1> 	MOV	eBP, eSP
  5610 00001985 50                  <1> 	PUSH	eAX
  5611 00001986 9C                  <1> 	PUSHFd
  5612 00001987 58                  <1> 	POP	eAX
  5613                              <1> 	;MOV	[BP+6], AX
  5614 00001988 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
  5615 0000198B 58                  <1> 	POP	eAX
  5616 0000198C 5D                  <1> 	POP	eBP
  5617 0000198D CF                  <1> 	IRETd
  5618                              <1> 
  5619                              <1> ;-------------------------------------------------------------------------------
  5620                              <1> ; DW --> dd (06/02/2015)
  5621 0000198E [F2190000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
  5622 00001992 [671A0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
  5623 00001996 [771A0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
  5624 0000199A [881A0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
  5625 0000199E [991A0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
  5626 000019A2 [AA1A0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
  5627 000019A6 [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
  5628 000019AA [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
  5629 000019AE [3A1B0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
  5630 000019B2 [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
  5631 000019B6 [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
  5632 000019BA [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
  5633 000019BE [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
  5634 000019C2 [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
  5635 000019C6 [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
  5636 000019CA [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
  5637 000019CE [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
  5638 000019D2 [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
  5639 000019D6 [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
  5640 000019DA [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
  5641 000019DE [2E1B0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
  5642 000019E2 [F91B0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
  5643 000019E6 [211C0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
  5644 000019EA [5A1C0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
  5645 000019EE [DB1C0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
  5646                              <1> FNC_TAE EQU     $                       ; END
  5647                              <1> 
  5648                              <1> ;-------------------------------------------------------------------------------
  5649                              <1> ; DISK_RESET	(AH = 00H)	
  5650                              <1> ;		RESET THE DISKETTE SYSTEM.
  5651                              <1> ;
  5652                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5653                              <1> ;-------------------------------------------------------------------------------
  5654                              <1> DSK_RESET:
  5655 000019F2 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
  5656 000019F6 FA                  <1> 	CLI				; NO INTERRUPTS
  5657 000019F7 A0[3A700000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  5658 000019FC 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
  5659 000019FE C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
  5660                              <1> 					; DRIVE SELECT TO LOW NIBBLE
  5661 00001A01 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
  5662 00001A03 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5663 00001A04 C605[39700000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  5664                              <1> 	;JMP	$+2			; WAIT FOR I/O
  5665                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
  5666                              <1> 					;      PULSE WIDTH)
  5667                              <1> 	; 19/12/2014
  5668                              <1> 	NEWIODELAY
  5669 00001A0B E6EB                <2>  out 0EBh,al
  5670                              <1> 
  5671                              <1> 	; 17/12/2014 
  5672                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
  5673 00001A0D B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
  5674                              <1> wdw1:
  5675                              <1> 	NEWIODELAY   ; 27/02/2015
  5676 00001A12 E6EB                <2>  out 0EBh,al
  5677 00001A14 E2FC                <1> 	loop	wdw1
  5678                              <1> 	;
  5679 00001A16 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
  5680 00001A18 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
  5681                              <1> 	; 16/12/2014
  5682                              <1> 	IODELAY
  5683 00001A19 EB00                <2>  jmp short $+2
  5684 00001A1B EB00                <2>  jmp short $+2
  5685                              <1> 	;
  5686                              <1> 	;STI				; ENABLE THE INTERRUPTS
  5687 00001A1D E8EC0B0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  5688 00001A22 723A                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
  5689 00001A24 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
  5690                              <1> NXT_DRV:
  5691                              <1> 	;PUSH	CX			; SAVE FOR CALL
  5692                              <1> 	; 05/12/2021
  5693 00001A28 51                  <1> 	push	ecx
  5694 00001A29 B8[5D1A0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
  5695 00001A2E 50                  <1> 	PUSH	eAX			; "
  5696 00001A2F B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  5697 00001A31 E8CE0A0000          <1> 	CALL	NEC_OUTPUT
  5698 00001A36 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  5699 00001A37 E8020C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  5700                              <1> 	;POP	CX			; RESTORE AFTER CALL
  5701                              <1> 	; 05/12/2021
  5702 00001A3C 59                  <1> 	pop	ecx
  5703 00001A3D 721F                <1> 	JC	short DR_ERR		; ERROR RETURN
  5704 00001A3F 3A0D[3D700000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
  5705 00001A45 7517                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
  5706 00001A47 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
  5707 00001A49 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
  5708 00001A4C 76DA                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
  5709                              <1> 	;
  5710 00001A4E E843030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5711                              <1> RESBAC:
  5712 00001A53 E8D8080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5713                              <1> 	;MOV	BX,SI			; GET SAVED AL TO BL
  5714                              <1> 	; 05/12/2021
  5715 00001A58 89F3                <1> 	mov	ebx, esi
  5716 00001A5A 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5717 00001A5C C3                  <1> 	RETn		
  5718                              <1> DR_POP_ERR:
  5719                              <1> 	;POP	CX			; CLEAR STACK
  5720                              <1> 	; 05/12/2021
  5721 00001A5D 59                  <1> 	pop	ecx
  5722                              <1> DR_ERR:
  5723 00001A5E 800D[3C700000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
  5724 00001A65 EBEC                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
  5725                              <1> 
  5726                              <1> ;-------------------------------------------------------------------------------
  5727                              <1> ; DISK_STATUS	(AH = 01H)
  5728                              <1> ;	DISKETTE STATUS.
  5729                              <1> ;
  5730                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
  5731                              <1> ;
  5732                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
  5733                              <1> ;-------------------------------------------------------------------------------
  5734                              <1> DSK_STATUS:
  5735 00001A67 8825[3C700000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
  5736 00001A6D E8BE080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5737                              <1> 	;MOV	BX,SI			; GET SAVED AL TO BL
  5738                              <1> 	; 05/12/2021
  5739 00001A72 89F3                <1> 	mov	ebx, esi
  5740 00001A74 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5741 00001A76 C3                  <1> 	RETn		
  5742                              <1> 
  5743                              <1> ;-------------------------------------------------------------------------------
  5744                              <1> ; DISK_READ	(AH = 02H)	
  5745                              <1> ;	DISKETTE READ.
  5746                              <1> ;
  5747                              <1> ; ON ENTRY:	DI	: DRIVE #
  5748                              <1> ;		SI-HI	: HEAD #
  5749                              <1> ;		SI-LOW	: # OF SECTORS
  5750                              <1> ;		ES	: BUFFER SEGMENT
  5751                              <1> ;		[BP]	: SECTOR #
  5752                              <1> ;		[BP+1]	: TRACK #
  5753                              <1> ;		[BP+2]	: BUFFER OFFSET
  5754                              <1> ;
  5755                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5756                              <1> ;-------------------------------------------------------------------------------
  5757                              <1> 
  5758                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5759                              <1> 
  5760                              <1> DSK_READ:
  5761 00001A77 8025[3A700000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5762 00001A7E 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
  5763 00001A82 E815040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5764 00001A87 C3                  <1> 	RETn
  5765                              <1> 
  5766                              <1> ;-------------------------------------------------------------------------------
  5767                              <1> ; DISK_WRITE	(AH = 03H)
  5768                              <1> ;	DISKETTE WRITE.
  5769                              <1> ;
  5770                              <1> ; ON ENTRY:	DI	: DRIVE #
  5771                              <1> ;		SI-HI	: HEAD #
  5772                              <1> ;		SI-LOW	: # OF SECTORS
  5773                              <1> ;		ES	: BUFFER SEGMENT
  5774                              <1> ;		[BP]	: SECTOR #
  5775                              <1> ;		[BP+1]	: TRACK #
  5776                              <1> ;		[BP+2]	: BUFFER OFFSET
  5777                              <1> ;
  5778                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5779                              <1> ;-------------------------------------------------------------------------------
  5780                              <1> 
  5781                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
  5782                              <1> 
  5783                              <1> DSK_WRITE:
  5784 00001A88 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
  5785 00001A8C 800D[3A700000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
  5786 00001A93 E804040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5787 00001A98 C3                  <1> 	RETn
  5788                              <1> 
  5789                              <1> ;-------------------------------------------------------------------------------
  5790                              <1> ; DISK_VERF	(AH = 04H)
  5791                              <1> ;	DISKETTE VERIFY.
  5792                              <1> ;
  5793                              <1> ; ON ENTRY:	DI	: DRIVE #
  5794                              <1> ;		SI-HI	: HEAD #
  5795                              <1> ;		SI-LOW	: # OF SECTORS
  5796                              <1> ;		ES	: BUFFER SEGMENT
  5797                              <1> ;		[BP]	: SECTOR #
  5798                              <1> ;		[BP+1]	: TRACK #
  5799                              <1> ;		[BP+2]	: BUFFER OFFSET
  5800                              <1> ;
  5801                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5802                              <1> ;-------------------------------------------------------------------------------
  5803                              <1> DSK_VERF:
  5804 00001A99 8025[3A700000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
  5805 00001AA0 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
  5806 00001AA4 E8F3030000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
  5807 00001AA9 C3                  <1> 	RETn
  5808                              <1> 
  5809                              <1> ;-------------------------------------------------------------------------------
  5810                              <1> ; DISK_FORMAT	(AH = 05H)
  5811                              <1> ;	DISKETTE FORMAT.
  5812                              <1> ;
  5813                              <1> ; ON ENTRY:	DI	: DRIVE #
  5814                              <1> ;		SI-HI	: HEAD #
  5815                              <1> ;		SI-LOW	: # OF SECTORS
  5816                              <1> ;		ES	: BUFFER SEGMENT
  5817                              <1> ;		[BP]	: SECTOR #
  5818                              <1> ;		[BP+1]	: TRACK #
  5819                              <1> ;		[BP+2]	: BUFFER OFFSET
  5820                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
  5821                              <1> ;
  5822                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5823                              <1> ;-------------------------------------------------------------------------------
  5824                              <1> DSK_FORMAT:
  5825 00001AAA E830030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  5826 00001AAF E81D050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
  5827 00001AB4 800D[3A700000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
  5828 00001ABB E865050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
  5829 00001AC0 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
  5830 00001AC2 E8CF020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
  5831 00001AC7 E8C9050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
  5832 00001ACC 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
  5833 00001ACE E8A2050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
  5834                              <1> FM_WR:
  5835 00001AD3 E84F060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
  5836 00001AD8 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
  5837 00001ADA B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
  5838 00001ADC E8A7060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
  5839 00001AE1 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
  5840 00001AE3 B8[1F1B0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
  5841 00001AE8 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  5842 00001AE9 B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
  5843 00001AEB E80E090000          <1> 	CALL	GET_PARM
  5844 00001AF0 E80F0A0000          <1> 	CALL	NEC_OUTPUT
  5845 00001AF5 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
  5846 00001AF7 E802090000          <1> 	CALL	GET_PARM
  5847 00001AFC E8030A0000          <1> 	CALL	NEC_OUTPUT
  5848 00001B01 B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
  5849 00001B03 E8F6080000          <1> 	CALL	GET_PARM
  5850 00001B08 E8F7090000          <1> 	CALL	NEC_OUTPUT
  5851 00001B0D B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
  5852 00001B0F E8EA080000          <1> 	CALL	GET_PARM
  5853 00001B14 E8EB090000          <1> 	CALL	NEC_OUTPUT
  5854 00001B19 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  5855 00001B1A E8E5060000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
  5856                              <1> FM_DON:
  5857 00001B1F E8EC020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5858 00001B24 E807080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  5859                              <1> 	;MOV	BX,SI			; GET SAVED AL TO BL
  5860 00001B29 89F3                <1> 	mov	ebx, esi ; 05/12/2021
  5861 00001B2B 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  5862 00001B2D C3                  <1> 	RETn
  5863                              <1> 
  5864                              <1> ;-------------------------------------------------------------------------------
  5865                              <1> ; FNC_ERR
  5866                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
  5867                              <1> ;	SET BAD COMMAND IN STATUS.
  5868                              <1> ;
  5869                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  5870                              <1> ;-------------------------------------------------------------------------------
  5871                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
  5872                              <1> 	;MOV	AX,SI			; RESTORE AL
  5873                              <1> 	; 05/12/2021
  5874 00001B2E 89F0                <1> 	mov	eax, esi
  5875 00001B30 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5876 00001B32 8825[3C700000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
  5877 00001B38 F9                  <1> 	STC				; SET CARRY INDICATING ERROR
  5878 00001B39 C3                  <1> 	RETn
  5879                              <1> 
  5880                              <1> ;-------------------------------------------------------------------------------
  5881                              <1> ; DISK_PARMS	(AH = 08H)	
  5882                              <1> ;	READ DRIVE PARAMETERS.
  5883                              <1> ;
  5884                              <1> ; ON ENTRY:	DI : DRIVE #
  5885                              <1> ;
  5886                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
  5887                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
  5888                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
  5889                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
  5890                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
  5891                              <1> ;		BH/[BP+3] = 0
  5892                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
  5893                              <1> ;		DH/[BP+5] = MAX HEAD #
  5894                              <1> ;		DI/[BP+6] = OFFSET TO DISK_BASE
  5895                              <1> ;		ES        = SEGMENT OF DISK_BASE
  5896                              <1> ;		AX        = 0
  5897                              <1> ;
  5898                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
  5899                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
  5900                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
  5901                              <1> ;		       CALLER.
  5902                              <1> ;-------------------------------------------------------------------------------
  5903                              <1> DSK_PARMS:
  5904 00001B3A E8A0020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  5905                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
  5906 00001B3F 29D2                <1> 	sub     edx, edx ; 20/02/2015
  5907 00001B41 895504              <1>         mov	[ebp+4], edx ; 20/02/2015
  5908                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
  5909                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
  5910                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
  5911                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
  5912                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
  5913                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
  5914                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
  5915                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
  5916                              <1> 	;sub	edx, edx
  5917 00001B44 66A1[AE6A0000]      <1> 	mov     ax, [fd0_type]
  5918 00001B4A 6621C0              <1> 	and     ax, ax
  5919 00001B4D 7473                <1> 	jz      short NON_DRV
  5920 00001B4F FEC2                <1> 	inc     dl
  5921 00001B51 20E4                <1> 	and     ah, ah
  5922 00001B53 7402                <1> 	jz      short STO_DL
  5923 00001B55 FEC2                <1> 	inc     dl
  5924                              <1> STO_DL:
  5925                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
  5926 00001B57 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
  5927 00001B5A 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
  5928 00001B5E 7765                <1> 	JA	short NON_DRV1		; DRIVE INVALID
  5929                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
  5930 00001B60 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
  5931 00001B64 E88C080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  5932                              <1> 	;;20/02/2015
  5933                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
  5934                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
  5935 00001B69 7412                <1> 	JZ	short CHK_EST		; JUMP IF SO
  5936 00001B6B E8FD010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5937 00001B70 720B                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
  5938                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
  5939 00001B72 884504              <1>         mov	[ebp+4], al ; 06/02/2015
  5940 00001B75 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
  5941 00001B78 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
  5942 00001B7B EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
  5943                              <1> CHK_EST:
  5944 00001B7D 8AA7[49700000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
  5945 00001B83 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
  5946 00001B86 743D                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
  5947                              <1> USE_EST:
  5948 00001B88 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
  5949 00001B8B 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  5950 00001B8E 7555                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
  5951                              <1> 
  5952                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
  5953                              <1> 
  5954 00001B90 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
  5955 00001B92 E8D6010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5956 00001B97 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5957 00001B9A 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5958 00001B9D F687[49700000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
  5959 00001BA4 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
  5960                              <1> 
  5961                              <1> ;-----	IT IS 1.44 MB DRIVE
  5962                              <1> 
  5963                              <1> PARM144:
  5964 00001BA6 B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
  5965 00001BA8 E8C0010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  5966 00001BAD 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  5967 00001BB0 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  5968                              <1> STO_CX:
  5969 00001BB3 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
  5970                              <1> ES_DI:
  5971                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
  5972 00001BB6 895D0C              <1> 	mov	[ebp+12], ebx ; 06/02/2015
  5973                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
  5974                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  5975                              <1> DP_OUT:
  5976 00001BB9 E852020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  5977                              <1> 	;XOR	AX,AX			; CLEAR
  5978                              <1> 	; 05/12/2021
  5979 00001BBE 31C0                <1> 	xor	eax, eax
  5980 00001BC0 F8                  <1> 	CLC
  5981 00001BC1 C3                  <1> 	RETn
  5982                              <1> 
  5983                              <1> ;-----	NO DRIYE PRESENT HANDLER
  5984                              <1> 
  5985                              <1> NON_DRV:
  5986                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
  5987 00001BC2 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
  5988                              <1> NON_DRV1:
  5989 00001BC5 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
  5990 00001BCA 720B                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
  5991                              <1> 
  5992                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
  5993                              <1> 	
  5994 00001BCC E83F020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
  5995                              <1> 	;MOV	AX,SI			; RESTORE AL
  5996 00001BD1 89F0                <1> 	mov	eax, esi ; 05/12/2021
  5997 00001BD3 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
  5998 00001BD5 F9                  <1> 	STC
  5999 00001BD6 C3                  <1> 	RETn
  6000                              <1> 
  6001                              <1> NON_DRV2:
  6002                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
  6003 00001BD7 31C0                <1> 	xor	eax, eax	
  6004 00001BD9 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
  6005                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
  6006 00001BDD 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
  6007                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
  6008 00001BE0 89450C              <1> 	mov	[ebp+12], eax
  6009                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
  6010 00001BE3 EBD4                <1> 	JMP	SHORT DP_OUT
  6011                              <1> 
  6012                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
  6013                              <1> 
  6014                              <1> USE_EST2:
  6015 00001BE5 B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
  6016 00001BE7 E881010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6017 00001BEC 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
  6018 00001BEF 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
  6019 00001BF2 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  6020 00001BF5 74BC                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
  6021 00001BF7 EBAD                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
  6022                              <1> 
  6023                              <1> ;-------------------------------------------------------------------------------
  6024                              <1> ; DISK_TYPE (AH = 15H)	
  6025                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
  6026                              <1> ;
  6027                              <1> ;  ON ENTRY:	DI = DRIVE #
  6028                              <1> ;
  6029                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
  6030                              <1> ;-------------------------------------------------------------------------------
  6031                              <1> DSK_TYPE:
  6032 00001BF9 E8E1010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6033 00001BFE 8A87[49700000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
  6034 00001C04 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
  6035 00001C06 7415                <1> 	JZ	short NO_DRV
  6036 00001C08 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
  6037 00001C0A A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
  6038 00001C0C 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
  6039 00001C0E B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
  6040                              <1> DT_BACK:
  6041                              <1> 	;PUSH	AX			; SAVE RETURN VALUE
  6042 00001C10 50                  <1> 	push	eax ; 05/12/2021
  6043 00001C11 E8FA010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6044                              <1> 	;POP	AX			; RESTORE RETURN VALUE
  6045 00001C16 58                  <1> 	pop	eax ; 05/12/2021
  6046 00001C17 F8                  <1> 	CLC				; NO ERROR
  6047                              <1> 	;MOV	BX,SI			; GET SAVED AL TO BL
  6048                              <1> 	; 05/12/2021
  6049 00001C18 89F3                <1> 	mov	ebx, esi
  6050 00001C1A 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  6051 00001C1C C3                  <1> 	RETn
  6052                              <1> NO_DRV:	
  6053 00001C1D 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
  6054 00001C1F EBEF                <1> 	JMP	SHORT DT_BACK
  6055                              <1> 
  6056                              <1> ;-------------------------------------------------------------------------------
  6057                              <1> ; DISK_CHANGE	(AH = 16H)
  6058                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
  6059                              <1> ;
  6060                              <1> ; ON ENTRY:	DI = DRIVE #
  6061                              <1> ;
  6062                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  6063                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  6064                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  6065                              <1> ;-------------------------------------------------------------------------------
  6066                              <1> DSK_CHANGE:
  6067 00001C21 E8B9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6068 00001C26 8A87[49700000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  6069 00001C2C 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  6070 00001C2E 7421                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  6071 00001C30 A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  6072 00001C32 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  6073                              <1> DC0:
  6074 00001C34 E8600A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  6075 00001C39 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  6076                              <1> 
  6077 00001C3B C605[3C700000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  6078                              <1> 
  6079 00001C42 E8C9010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6080 00001C47 E8E4060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6081                              <1> 	;MOV	BX,SI			; GET SAVED AL TO BL
  6082                              <1> 	; 05/12/2021
  6083 00001C4C 89F3                <1> 	mov	ebx, esi
  6084 00001C4E 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  6085 00001C50 C3                  <1> 	RETn
  6086                              <1> DC_NON:
  6087 00001C51 800D[3C700000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  6088 00001C58 EBE8                <1> 	JMP	SHORT FINIS
  6089                              <1> 
  6090                              <1> ;-------------------------------------------------------------------------------
  6091                              <1> ; FORMAT_SET	(AH = 17H)
  6092                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  6093                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  6094                              <1> ;
  6095                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  6096                              <1> ;		DI     = DRIVE #
  6097                              <1> ;
  6098                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  6099                              <1> ;		AH = @DSKETTE_STATUS
  6100                              <1> ;		CY = 1 IF ERROR
  6101                              <1> ;-------------------------------------------------------------------------------
  6102                              <1> FORMAT_SET:
  6103 00001C5A E880010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6104                              <1> 	;PUSH	SI			; SAVE DASD TYPE
  6105                              <1> 	; 05/12/2021
  6106 00001C5F 56                  <1> 	push	esi
  6107 00001C60 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  6108 00001C63 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  6109 00001C65 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  6110 00001C68 80A7[49700000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  6111 00001C6F 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  6112 00001C71 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  6113 00001C73 808F[49700000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  6114 00001C7A EB48                <1> 	JMP	SHORT S0
  6115                              <1> NOT_320:
  6116 00001C7C E8A4030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  6117 00001C81 803D[3C700000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  6118 00001C88 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  6119                              <1> S3:
  6120 00001C8A 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  6121 00001C8C 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  6122 00001C8E 808F[49700000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  6123 00001C95 EB2D                <1> 	JMP	SHORT S0
  6124                              <1> NOT_320_12:
  6125 00001C97 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  6126 00001C99 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  6127 00001C9B 808F[49700000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  6128 00001CA2 EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  6129                              <1> NOT_12:	
  6130 00001CA4 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  6131 00001CA6 752A                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  6132                              <1> 
  6133 00001CA8 F687[49700000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  6134 00001CAF 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  6135 00001CB1 B050                <1> 	MOV	AL,MED_DET+RATE_300
  6136 00001CB3 F687[49700000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  6137 00001CBA 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  6138                              <1> ASSUME:
  6139 00001CBC B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  6140                              <1> OR_IT_IN:
  6141 00001CBE 0887[49700000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  6142                              <1> S0:
  6143 00001CC4 E847010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6144 00001CC9 E862060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6145                              <1> 	;POP	BX			; GET SAVED AL TO BL
  6146                              <1> 	; 05/12/2021
  6147 00001CCE 5B                  <1> 	pop	ebx
  6148 00001CCF 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  6149 00001CD1 C3                  <1> 	RETn
  6150                              <1> FS_ERR:
  6151 00001CD2 C605[3C700000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  6152 00001CD9 EBE9                <1> 	JMP	SHORT S0
  6153                              <1> 
  6154                              <1> ;-------------------------------------------------------------------------------
  6155                              <1> ; SET_MEDIA	(AH = 18H)
  6156                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  6157                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  6158                              <1> ;
  6159                              <1> ; ON ENTRY:
  6160                              <1> ;	[BP]	= SECTOR PER TRACK
  6161                              <1> ;	[BP+1]	= TRACK #
  6162                              <1> ;	DI	= DRIVE #
  6163                              <1> ;
  6164                              <1> ; ON EXIT:
  6165                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  6166                              <1> ;	IF NO ERROR:
  6167                              <1> ;		AH = 0
  6168                              <1> ;		CY = 0
  6169                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  6170                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  6171                              <1> ;	IF ERROR:	
  6172                              <1> ;		AH = @DSKETTE_STATUS
  6173                              <1> ;		CY = 1
  6174                              <1> ;-------------------------------------------------------------------------------
  6175                              <1> SET_MEDIA:
  6176 00001CDB E8FF000000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6177 00001CE0 F687[49700000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  6178 00001CE7 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  6179 00001CE9 E837030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  6180 00001CEE 803D[3C700000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  6181 00001CF5 746B                <1> 	JE	short SM_RTN
  6182 00001CF7 C605[3C700000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  6183                              <1> SM_CMOS:
  6184 00001CFE E8F2060000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6185                              <1> 	;;20/02/2015
  6186                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  6187                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  6188 00001D03 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  6189 00001D05 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  6190 00001D0A 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  6191 00001D0C 57                  <1> 	PUSH	eDI			; SAVE REG.
  6192 00001D0D 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  6193 00001D0F B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6194                              <1> DR_SEARCH:
  6195 00001D14 8AA3[2C6A0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6196 00001D1A 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6197 00001D1D 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  6198 00001D1F 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  6199                              <1> DR_FND:
  6200 00001D21 8BBB[2D6A0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  6201                              <1> MD_SEARCH:
  6202 00001D27 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  6203 00001D2A 386500              <1> 	CMP	[eBP],AH		; MATCH?
  6204 00001D2D 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  6205 00001D2F 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  6206 00001D32 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  6207 00001D35 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  6208                              <1> NXT_MD:
  6209                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6210 00001D37 83C305              <1>         add	ebx, 5 ; 18/02/2015
  6211 00001D3A E2D8                <1> 	LOOP    DR_SEARCH
  6212 00001D3C 5F                  <1> 	POP	eDI			; RESTORE REG.
  6213                              <1> MD_NOT_FND:
  6214 00001D3D C605[3C700000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  6215 00001D44 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  6216                              <1> MD_FND:
  6217 00001D46 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  6218 00001D49 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  6219 00001D4B 7502                <1> 	JNE	short MD_SET
  6220 00001D4D 0C20                <1> 	OR	AL,DBL_STEP
  6221                              <1> MD_SET:
  6222                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  6223 00001D4F 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  6224 00001D52 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  6225 00001D54 5F                  <1> 	POP	eDI
  6226 00001D55 80A7[49700000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  6227 00001D5C 0887[49700000]      <1> 	OR	[DSK_STATE+eDI], AL
  6228                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  6229                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  6230                              <1> SM_RTN:
  6231 00001D62 E8A9000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6232 00001D67 E8C4050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6233 00001D6C C3                  <1> 	RETn
  6234                              <1> 
  6235                              <1> ;----------------------------------------------------------------
  6236                              <1> ; DR_TYPE_CHECK							:
  6237                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  6238                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  6239                              <1> ; ON ENTRY:							:
  6240                              <1> ;	AL = DRIVE TYPE						:
  6241                              <1> ; ON EXIT:							:
  6242                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  6243                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  6244                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  6245                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  6246                              <1> ; REGISTERS ALTERED: eBX						:
  6247                              <1> ;----------------------------------------------------------------		
  6248                              <1> DR_TYPE_CHECK:
  6249                              <1> 	;PUSH	AX			
  6250                              <1> 	; 05/12/2021
  6251 00001D6D 50                  <1> 	push	eax
  6252 00001D6E 51                  <1> 	PUSH	eCX
  6253 00001D6F 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6254 00001D71 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6255                              <1> TYPE_CHK:	
  6256 00001D76 8AA3[2C6A0000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  6257 00001D7C 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6258 00001D7E 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  6259                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6260 00001D80 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  6261 00001D83 E2F1                <1> 	LOOP    TYPE_CHK
  6262                              <1> 	;
  6263 00001D85 BB[8B6A0000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  6264                              <1> 					; Default for GET_PARM (11/12/2014)
  6265                              <1> 	;
  6266 00001D8A F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  6267 00001D8B EB06                <1> 	JMP	SHORT TYPE_RTN
  6268                              <1> DR_TYPE_VALID:
  6269 00001D8D 8B9B[2D6A0000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  6270                              <1> TYPE_RTN:
  6271 00001D93 59                  <1> 	POP	eCX
  6272                              <1> 	;POP	AX
  6273                              <1> 	; 05/12/2021
  6274 00001D94 58                  <1> 	pop	eax
  6275 00001D95 C3                  <1> 	RETn	
  6276                              <1> 		
  6277                              <1> ;----------------------------------------------------------------
  6278                              <1> ; SEND_SPEC							:
  6279                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6280                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  6281                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  6282                              <1> ; ON EXIT:	NONE						:	
  6283                              <1> ; REGISTERS ALTERED: CX, DX					:
  6284                              <1> ;----------------------------------------------------------------		
  6285                              <1> SEND_SPEC:
  6286 00001D96 50                  <1> 	PUSH	eAX			; SAVE AX
  6287 00001D97 B8[BD1D0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  6288 00001D9C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6289 00001D9D B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6290 00001D9F E860070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6291 00001DA4 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  6292 00001DA6 E853060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6293 00001DAB E854070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6294 00001DB0 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  6295 00001DB2 E847060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  6296 00001DB7 E848070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6297 00001DBC 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6298                              <1> SPECBAC:
  6299 00001DBD 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6300 00001DBE C3                  <1> 	RETn
  6301                              <1> 
  6302                              <1> ;----------------------------------------------------------------
  6303                              <1> ; SEND_SPEC_MD							:
  6304                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  6305                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  6306                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  6307                              <1> ; ON EXIT:	NONE						:	
  6308                              <1> ; REGISTERS ALTERED: AX						:
  6309                              <1> ;----------------------------------------------------------------		
  6310                              <1> SEND_SPEC_MD:
  6311 00001DBF 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  6312 00001DC0 B8[DD1D0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  6313 00001DC5 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  6314 00001DC6 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  6315 00001DC8 E837070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6316 00001DCD 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  6317 00001DCF E830070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6318 00001DD4 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  6319 00001DD7 E828070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  6320 00001DDC 58                  <1> 	POP	eAX			; POP ERROR RETURN
  6321                              <1> SPEC_ESBAC:
  6322 00001DDD 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  6323 00001DDE C3                  <1> 	RETn
  6324                              <1> 
  6325                              <1> ;-------------------------------------------------------------------------------
  6326                              <1> ; XLAT_NEW  
  6327                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  6328                              <1> ;	MODE TO NEW ARCHITECTURE.
  6329                              <1> ;
  6330                              <1> ; ON ENTRY:	DI = DRIVE #
  6331                              <1> ;-------------------------------------------------------------------------------
  6332                              <1> XLAT_NEW:
  6333 00001DDF 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  6334 00001DE2 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  6335 00001DE4 80BF[49700000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  6336 00001DEB 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  6337 00001DED 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  6338 00001DF0 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  6339 00001DF3 A0[48700000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  6340 00001DF8 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  6341 00001DFA 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  6342 00001DFC 80A7[49700000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  6343 00001E03 0887[49700000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  6344                              <1> XN_OUT:
  6345 00001E09 C3                  <1> 	RETn
  6346                              <1> DO_DET:
  6347 00001E0A E897080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  6348 00001E0F C3                  <1> 	RETn
  6349                              <1> 
  6350                              <1> ;-------------------------------------------------------------------------------
  6351                              <1> ; XLAT_OLD 
  6352                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  6353                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  6354                              <1> ;
  6355                              <1> ; ON ENTRY:	DI = DRIVE
  6356                              <1> ;-------------------------------------------------------------------------------
  6357                              <1> XLAT_OLD:
  6358 00001E10 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  6359                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  6360                              <1>         ;ja	XO_OUT
  6361                              <1>         ; 05/12/2021
  6362 00001E13 77F4                <1> 	ja	short XN_OUT
  6363 00001E15 80BF[49700000]00    <1> 	CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  6364 00001E1C 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  6365                              <1> 
  6366                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  6367                              <1> 
  6368 00001E1E 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  6369 00001E21 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  6370 00001E24 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  6371 00001E26 D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  6372 00001E28 8425[48700000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  6373 00001E2E 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  6374                              <1> 
  6375                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  6376                              <1> 
  6377 00001E30 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  6378 00001E32 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  6379 00001E34 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  6380 00001E36 2025[48700000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  6381                              <1> 
  6382                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  6383                              <1> 
  6384 00001E3C 8A87[49700000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; ACCESS STATE
  6385 00001E42 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  6386 00001E44 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  6387 00001E46 0805[48700000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  6388                              <1> 
  6389                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  6390                              <1> 
  6391                              <1> SAVE_SET:
  6392 00001E4C 8AA7[49700000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  6393 00001E52 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  6394 00001E54 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  6395 00001E57 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  6396 00001E5A 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  6397 00001E5C B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  6398 00001E5E 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  6399 00001E61 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  6400 00001E63 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  6401 00001E66 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  6402                              <1> UNKNO:
  6403 00001E68 B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  6404 00001E6A EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  6405                              <1> CHK_144:
  6406 00001E6C E884050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  6407                              <1> 	;;20/02/2015
  6408                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  6409 00001E71 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  6410 00001E73 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  6411 00001E75 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  6412 00001E77 B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  6413 00001E79 EB0C                <1> 	JMP	SHORT TST_DET
  6414                              <1> CHK_250:
  6415 00001E7B B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  6416 00001E7D 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  6417 00001E80 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  6418 00001E82 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  6419 00001E85 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  6420                              <1> TST_DET:
  6421 00001E87 F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  6422 00001E8A 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  6423 00001E8C 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  6424                              <1> AL_SET:
  6425 00001E8E 80A7[49700000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  6426 00001E95 0887[49700000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  6427                              <1> XO_OUT:
  6428 00001E9B C3                  <1> 	RETn
  6429                              <1> 
  6430                              <1> ;-------------------------------------------------------------------------------
  6431                              <1> ; RD_WR_VF
  6432                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  6433                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  6434                              <1> ;
  6435                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  6436                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  6437                              <1> ;
  6438                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6439                              <1> ;-------------------------------------------------------------------------------
  6440                              <1> RD_WR_VF:
  6441                              <1> 	;PUSH	AX			; SAVE DMA, NEC PARAMETERS
  6442 00001E9C 50                  <1> 	push	eax ; 05/12/2021
  6443 00001E9D E83DFFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  6444 00001EA2 E8E9000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  6445                              <1> 	;POP	AX			; RESTORE READ/WRITE/VERIFY
  6446 00001EA7 58                  <1> 	pop	eax ; 05/12/2021
  6447                              <1> DO_AGAIN:
  6448                              <1> 	;PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6449 00001EA8 50                  <1> 	push	eax ; 05/12/2021
  6450 00001EA9 E877010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  6451                              <1> 	;POP	AX			; RESTORE READ/WRITE/VERIFY
  6452 00001EAE 58                  <1> 	pop	eax ; 05/12/2021
  6453                              <1> 	;JC	RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  6454                              <1> 	; 05/12/2021
  6455 00001EAF 7305                <1> 	jnc	short RWV
  6456 00001EB1 E9C3000000          <1> 	jmp	RWV_END
  6457                              <1> RWV:
  6458                              <1> 	;PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  6459 00001EB6 50                  <1> 	push	eax ; 05/12/2021
  6460 00001EB7 8AB7[49700000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6461 00001EBD 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  6462 00001EC0 E830050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  6463                              <1> 	;;20/02/2015
  6464                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  6465 00001EC5 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  6466 00001EC7 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  6467 00001EC9 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  6468 00001ECB F687[49700000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  6469 00001ED2 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  6470 00001ED4 B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  6471 00001ED6 EB0F                <1> 	JMP	SHORT RWV_2
  6472                              <1> RWV_1:
  6473 00001ED8 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  6474 00001EDA F687[49700000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  6475 00001EE1 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  6476 00001EE3 B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  6477 00001EE5 EB04                <1> 	jmp	short rwv_3
  6478                              <1> RWV_2:
  6479 00001EE7 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  6480 00001EE9 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  6481                              <1> rwv_3:
  6482 00001EEB E87DFEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  6483 00001EF0 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  6484                              <1> 
  6485                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  6486                              <1> 
  6487 00001EF2 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  6488 00001EF3 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  6489 00001EF5 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  6490                              <1> RWV_DR_SEARCH:
  6491 00001EFA 8AA3[2C6A0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  6492 00001F00 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  6493 00001F03 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  6494 00001F05 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  6495                              <1> RWV_DR_FND:
  6496 00001F07 8BBB[2D6A0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  6497                              <1> RWV_MD_SEARH:
  6498 00001F0D 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  6499 00001F10 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  6500                              <1> RWV_NXT_MD:
  6501                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  6502 00001F12 83C305              <1> 	add	eBX, 5
  6503 00001F15 E2E3                <1> 	LOOP	RWV_DR_SEARCH
  6504 00001F17 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6505                              <1> 
  6506                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  6507                              <1> 
  6508                              <1> RWV_ASSUME:
  6509 00001F18 BB[4A6A0000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  6510 00001F1D F687[49700000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  6511 00001F24 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  6512 00001F26 BB[646A0000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  6513 00001F2B EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  6514                              <1> 
  6515                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  6516                              <1> 	 			
  6517                              <1> RWV_MD_FND:
  6518 00001F2D 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  6519 00001F2F 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  6520                              <1> 	
  6521                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  6522                              <1> 
  6523                              <1> RWV_MD_FND1:
  6524 00001F30 E88AFEFFFF          <1> 	CALL	SEND_SPEC_MD
  6525 00001F35 E85B010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  6526 00001F3A 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  6527 00001F3C E834010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  6528                              <1> RWV_DBL:
  6529 00001F41 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6530 00001F42 E809040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  6531 00001F47 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6532 00001F48 7222                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  6533                              <1> 	;POP	AX			; RESTORE NEC, DMA COMMAND
  6534 00001F4A 58                  <1> 	pop	eax ; 05/12/2021
  6535                              <1> 	;PUSH	AX			; SAVE NEC COMMAND
  6536 00001F4B 50                  <1> 	push	eax ; 05/12/2021
  6537 00001F4C 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6538 00001F4D E858010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  6539 00001F52 5B                  <1> 	POP	eBX 
  6540                              <1> 	;POP	AX			; RESTORE NEC COMMAND
  6541 00001F53 58                  <1> 	pop	eax ; 05/12/2021
  6542 00001F54 722D                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  6543                              <1> 	;PUSH	AX			; SAVE NEC COMMAND
  6544 00001F56 50                  <1> 	push	eax ; 05/12/2021
  6545 00001F57 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  6546 00001F58 E82B020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  6547 00001F5D 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  6548 00001F5E 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6549 00001F60 E853020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  6550 00001F65 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  6551 00001F67 E898020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  6552                              <1> CHK_RET:
  6553 00001F6C E837030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  6554                              <1> 	;POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  6555 00001F71 58                  <1> 	pop	eax ; 05/12/2021
  6556 00001F72 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  6557 00001F74 E92FFFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  6558                              <1> RWV_END:
  6559 00001F79 E8E2020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  6560 00001F7E E875030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  6561                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  6562                              <1> 	;PUSH	AX			; SAVE NUMBER TRANSFERRED
  6563 00001F83 50                  <1> 	push	eax ; 05/12/2021
  6564 00001F84 E887FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  6565                              <1> 	;POP	AX			; RESTORE NUMBER TRANSFERRED
  6566 00001F89 58                  <1> 	pop	eax ; 05/12/2021
  6567 00001F8A E8A1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  6568 00001F8F C3                  <1> 	RETn
  6569                              <1> 
  6570                              <1> ;-------------------------------------------------------------------------------
  6571                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  6572                              <1> ;-------------------------------------------------------------------------------
  6573                              <1> SETUP_STATE:
  6574 00001F90 F687[49700000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  6575 00001F97 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  6576 00001F99 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  6577 00001F9D F687[49700000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  6578 00001FA4 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  6579 00001FA6 F687[49700000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  6580 00001FAD 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  6581 00001FAF 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  6582                              <1> AX_SET:	
  6583 00001FB3 80A7[49700000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  6584 00001FBA 08A7[49700000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  6585 00001FC0 8025[44700000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  6586 00001FC7 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  6587 00001FCA 0805[44700000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  6588                              <1> J1C:	
  6589 00001FD0 C3                  <1> 	RETn
  6590                              <1> 
  6591                              <1> ;-------------------------------------------------------------------------------
  6592                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  6593                              <1> ;-------------------------------------------------------------------------------
  6594                              <1> FMT_INIT:
  6595 00001FD1 F687[49700000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  6596 00001FD8 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  6597 00001FDA E816040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  6598                              <1> 	;; 20/02/2015
  6599                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  6600 00001FDF 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  6601 00001FE1 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  6602                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  6603 00001FE3 8AA7[49700000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  6604 00001FE9 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  6605 00001FEC 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  6606 00001FEE 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  6607 00001FF0 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  6608 00001FF3 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6609                              <1> N_360:	
  6610 00001FF5 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  6611 00001FF7 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  6612                              <1> F1_RATE:
  6613 00001FF9 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  6614 00001FFC EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  6615                              <1> N_12:	
  6616 00001FFE FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  6617 00002000 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  6618 00002002 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  6619 00002005 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  6620 00002007 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  6621 0000200A 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  6622 0000200C 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  6623 0000200F EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  6624                              <1> N_720:
  6625 00002011 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  6626 00002013 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  6627 00002015 EBE2                <1> 	JMP	SHORT F1_RATE
  6628                              <1> ISNT_12: 
  6629 00002017 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  6630                              <1> 
  6631                              <1> SKP_STATE:
  6632 0000201A 88A7[49700000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  6633                              <1> F1_OUT:
  6634 00002020 C3                  <1> 	RETn
  6635                              <1> CL_DRV:	
  6636 00002021 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  6637 00002023 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  6638                              <1> 
  6639                              <1> ;-------------------------------------------------------------------------------
  6640                              <1> ; MED_CHANGE	
  6641                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  6642                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  6643                              <1> ;
  6644                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  6645                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  6646                              <1> ;-------------------------------------------------------------------------------
  6647                              <1> MED_CHANGE:
  6648 00002025 E86F060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  6649 0000202A 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  6650 0000202C 80A7[49700000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  6651                              <1> 
  6652                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  6653                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  6654                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  6655                              <1> 
  6656 00002033 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  6657 00002036 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  6658 00002038 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  6659 0000203A F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  6660 0000203C FA                  <1> 	CLI				; NO INTERRUPTS
  6661 0000203D 2005[3A700000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  6662 00002043 FB                  <1> 	STI				; INTERRUPTS ENABLED
  6663 00002044 E8FA030000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  6664                              <1> 
  6665                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  6666                              <1> 
  6667 00002049 E8A4F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  6668 0000204E B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  6669 00002050 E8E8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6670 00002055 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  6671 00002057 E8E1040000          <1> 	CALL	SEEK			; ISSUE SEEK
  6672 0000205C C605[3C700000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  6673                              <1> OK1:
  6674 00002063 E831060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  6675 00002068 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  6676                              <1> OK4:
  6677 0000206A C605[3C700000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  6678                              <1> OK2:		
  6679 00002071 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  6680 00002072 C3                  <1> 	RETn
  6681                              <1> MC_OUT:
  6682 00002073 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  6683 00002074 C3                  <1> 	RETn
  6684                              <1> 
  6685                              <1> ;-------------------------------------------------------------------------------
  6686                              <1> ; SEND_RATE
  6687                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  6688                              <1> ; ON ENTRY:	DI = DRIVE #
  6689                              <1> ; ON EXIT:	NONE
  6690                              <1> ; REGISTERS ALTERED: DX
  6691                              <1> ;-------------------------------------------------------------------------------
  6692                              <1> SEND_RATE:
  6693                              <1> 	;PUSH	AX			; SAVE REG.
  6694                              <1> 	; 05/12/2021
  6695 00002075 50                  <1> 	push	eax
  6696 00002076 8025[44700000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  6697 0000207D 8A87[49700000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6698 00002083 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  6699 00002085 0805[44700000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  6700 0000208B C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  6701 0000208E 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  6702 00002092 EE                  <1> 	OUT	DX,AL
  6703                              <1> 	;POP	AX			; RESTORE REG.
  6704                              <1> 	; 05/12/2021
  6705 00002093 58                  <1> 	pop	eax
  6706 00002094 C3                  <1> 	RETn
  6707                              <1> 
  6708                              <1> ;-------------------------------------------------------------------------------
  6709                              <1> ; CHK_LASTRATE
  6710                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  6711                              <1> ; ON ENTRY:
  6712                              <1> ;	DI = DRIVE #
  6713                              <1> ; ON EXIT:
  6714                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  6715                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  6716                              <1> ; REGISTERS ALTERED: DX
  6717                              <1> ;-------------------------------------------------------------------------------
  6718                              <1> CHK_LASTRATE:
  6719                              <1> 	;PUSH	AX			; SAVE REG.
  6720                              <1> 	; 05/12/2021
  6721 00002095 50                  <1> 	push	eax
  6722 00002096 2225[44700000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  6723 0000209C 8A87[49700000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  6724 000020A2 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  6725 000020A6 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  6726                              <1> 					; ZF = 1 RATE IS THE SAME
  6727                              <1> 	;POP	AX			; RESTORE REG.
  6728                              <1> 	; 05/12/2021
  6729 000020A8 58                  <1> 	pop	eax
  6730 000020A9 C3                  <1> 	RETn
  6731                              <1> 
  6732                              <1> ;-------------------------------------------------------------------------------
  6733                              <1> ; DMA_SETUP
  6734                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  6735                              <1> ;
  6736                              <1> ; ON ENTRY:	AL = DMA COMMAND
  6737                              <1> ;
  6738                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6739                              <1> ;-------------------------------------------------------------------------------
  6740                              <1> 
  6741                              <1> ; SI = Head #, # of Sectors or DASD Type
  6742                              <1> 
  6743                              <1> ; 22/08/2015
  6744                              <1> ; 08/02/2015 - Protected Mode Modification
  6745                              <1> ; 06/02/2015 - 07/02/2015
  6746                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  6747                              <1> ; (DMA Addres = Physical Address)
  6748                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  6749                              <1> ;
  6750                              <1> ; 04/02/2016 (clc)
  6751                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  6752                              <1> ; 16/12/2014 (IODELAY)
  6753                              <1> 
  6754                              <1> DMA_SETUP:
  6755                              <1> 
  6756                              <1> ;; 20/02/2015
  6757 000020AA 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6758 000020AD F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  6759 000020B3 7569                <1> 	jnz	short dma_bnd_err_stc
  6760                              <1> 	;
  6761                              <1> 	;push	ax			; DMA command
  6762                              <1> 	; 05/12/2021
  6763 000020B5 50                  <1> 	push	eax
  6764 000020B6 52                  <1> 	push	edx			; *
  6765 000020B7 B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  6766 000020B9 E840030000          <1> 	call	GET_PARM		; 
  6767 000020BE 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6768                              <1> 	;mov	ax, si			; Sector count
  6769                              <1> 	;mov	ah, al			; AH = # OF SECTORS
  6770                              <1> 	;sub	al, al			; AL = 0, AX = # SECTORS * 256
  6771                              <1> 	;shr	ax, 1			; AX = # SECTORS * 128
  6772                              <1> 	;shl	ax, cl			; SHIFT BY PARAMETER VALUE
  6773                              <1> 	; 05/12/2021
  6774 000020C0 89F2                <1> 	mov	edx, esi
  6775 000020C2 29C0                <1> 	sub	eax, eax
  6776 000020C4 88D4                <1> 	mov	ah, dl
  6777 000020C6 D1E8                <1> 	shr	eax, 1
  6778 000020C8 D3E0                <1> 	shl	eax, cl
  6779                              <1> 	;
  6780 000020CA 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  6781 000020CC 6689C1              <1> 	mov	cx, ax
  6782 000020CF 5A                  <1> 	pop	edx			; *
  6783                              <1> 	;pop	ax
  6784                              <1> 	; 05/12/2021
  6785 000020D0 58                  <1> 	pop	eax
  6786 000020D1 3C42                <1> 	cmp	al, 42h
  6787 000020D3 7507                <1>         jne     short NOT_VERF
  6788 000020D5 BA0000FF00          <1> 	mov	edx, 0FF0000h
  6789 000020DA EB08                <1> 	jmp	short J33
  6790                              <1> NOT_VERF:
  6791 000020DC 6601CA              <1> 	add	dx, cx			; check for overflow
  6792 000020DF 723E                <1> 	jc	short dma_bnd_err
  6793                              <1> 	;
  6794 000020E1 6629CA              <1> 	sub	dx, cx			; Restore start address
  6795                              <1> J33:
  6796 000020E4 FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6797 000020E5 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6798                              <1> 	IODELAY				; WAIT FOR I/O
  6799 000020E7 EB00                <2>  jmp short $+2
  6800 000020E9 EB00                <2>  jmp short $+2
  6801 000020EB E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6802 000020ED 89D0                <1> 	mov	eax,edx			; Buffer address
  6803 000020EF E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6804                              <1> 	IODELAY				; WAIT FOR I/O
  6805 000020F1 EB00                <2>  jmp short $+2
  6806 000020F3 EB00                <2>  jmp short $+2
  6807 000020F5 88E0                <1> 	MOV	AL,AH
  6808 000020F7 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6809 000020F9 C1E810              <1> 	shr	eax,16
  6810                              <1> 	IODELAY				; I/O WAIT STATE
  6811 000020FC EB00                <2>  jmp short $+2
  6812 000020FE EB00                <2>  jmp short $+2
  6813 00002100 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6814                              <1> 	IODELAY
  6815 00002102 EB00                <2>  jmp short $+2
  6816 00002104 EB00                <2>  jmp short $+2
  6817 00002106 6689C8              <1> 	mov	ax,cx			; Byte count - 1
  6818 00002109 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6819                              <1> 	IODELAY				; WAIT FOR I/O
  6820 0000210B EB00                <2>  jmp short $+2
  6821 0000210D EB00                <2>  jmp short $+2
  6822 0000210F 88E0                <1> 	MOV	AL,AH
  6823 00002111 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6824                              <1> 	IODELAY
  6825 00002113 EB00                <2>  jmp short $+2
  6826 00002115 EB00                <2>  jmp short $+2
  6827 00002117 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6828 00002118 B002                <1> 	MOV	AL,2			; MODE FOR 8237
  6829 0000211A E60A                <1> 	OUT	DMA+10,AL		; INITIALIZE THE DISKETTE CHANNEL
  6830                              <1> 
  6831 0000211C F8                  <1> 	clc	; 04/02/2016
  6832 0000211D C3                  <1> 	retn
  6833                              <1> 
  6834                              <1> dma_bnd_err_stc:
  6835 0000211E F9                  <1> 	stc
  6836                              <1> dma_bnd_err:
  6837 0000211F C605[3C700000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6838 00002126 C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  6839                              <1> 
  6840                              <1> ;; 16/12/2014
  6841                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6842                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6843                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6844                              <1> ;;	IODELAY
  6845                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6846                              <1> ;;	;SIODELAY
  6847                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  6848                              <1> ;;      ;JNE	short NOT_VERF		; NO
  6849                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  6850                              <1> ;;      ;JMP	SHORT J33
  6851                              <1> ;;;NOT_VERF:	
  6852                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6853                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6854                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  6855                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  6856                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  6857                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  6858                              <1> ;;	;JNC	short J33
  6859                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  6860                              <1> ;;;J33:
  6861                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  6862                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6863                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6864                              <1> ;;	IODELAY
  6865                              <1> ;;	MOV	AL,AH
  6866                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6867                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  6868                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  6869                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  6870                              <1> ;;	IODELAY
  6871                              <1> ;;	;AND	AL,00001111B
  6872                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  6873                              <1> ;;	;SIODELAY
  6874                              <1> ;;
  6875                              <1> ;;;----- DETERMINE COUNT
  6876                              <1> ;;	sub	eax, eax ; 08/02/2015
  6877                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  6878                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  6879                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  6880                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  6881                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  6882                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  6883                              <1> ;;	CALL	GET_PARM		; "
  6884                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  6885                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  6886                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  6887                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  6888                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  6889                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6890                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6891                              <1> ;;	IODELAY
  6892                              <1> ;;	MOV	AL, AH
  6893                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6894                              <1> ;;	;IODELAY
  6895                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  6896                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  6897                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  6898                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  6899                              <1> ;;	add	ecx, eax ; 08/02/2015
  6900                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  6901                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6902                              <1> ;;	SIODELAY
  6903                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  6904                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  6905                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  6906                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  6907                              <1> ;;	jz	short NO_BAD
  6908                              <1> ;;dma_bnd_err:
  6909                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  6910                              <1> ;;NO_BAD:
  6911                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  6912                              <1> 
  6913                              <1> ;-------------------------------------------------------------------------------
  6914                              <1> ; FMTDMA_SET
  6915                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  6916                              <1> ;
  6917                              <1> ; ON ENTRY:	NOTHING REQUIRED
  6918                              <1> ;
  6919                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  6920                              <1> ;-------------------------------------------------------------------------------
  6921                              <1> 
  6922                              <1> 	; 05/12/2021
  6923                              <1> FMTDMA_SET:
  6924                              <1> ;; 20/02/2015 modification	
  6925 00002127 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  6926 0000212A F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  6927 00002130 75EC                <1> 	jnz	short dma_bnd_err_stc
  6928                              <1> 	;
  6929                              <1> 	;push	dx			; *
  6930                              <1> 	; 05/12/2021
  6931 00002132 52                  <1> 	push	edx
  6932 00002133 B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  6933 00002135 E8C4020000          <1> 	call	GET_PARM		; "
  6934                              <1> 	;mov	al, ah			; AL = SECTORS/TRACK VALUE
  6935                              <1> 	;sub	ah, ah			; AX = SECTORS/TRACK VALUE
  6936                              <1> 	;shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  6937                              <1> 	;dec	ax			; -1 FOR DMA VALUE
  6938                              <1> 	;mov	cx, ax
  6939                              <1> 	; 05/12/2021
  6940 0000213A 29C9                <1> 	sub	ecx, ecx
  6941 0000213C 88E1                <1> 	mov	cl, ah			; SECTORS/TRACK VALUE
  6942 0000213E D1E1                <1> 	shl	ecx, 1
  6943 00002140 D1E1                <1> 	shl	ecx, 1			; cx = SEC/TRK * 4 (OFFSET C,H,R,N)
  6944 00002142 6649                <1> 	dec	cx
  6945                              <1> 	;pop	dx			; *
  6946                              <1> 	; 05/12/2021
  6947 00002144 5A                  <1> 	pop	edx
  6948 00002145 6601CA              <1> 	add	dx, cx			; check for overflow
  6949 00002148 72D5                <1> 	jc	short dma_bnd_err
  6950                              <1> 	;
  6951 0000214A 6629CA              <1> 	sub	dx, cx			; Restore start address
  6952                              <1> 	;
  6953 0000214D B04A                <1> 	MOV	AL,04AH			; WILL WRITE TO THE DISKETTE
  6954 0000214F FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6955 00002150 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6956                              <1> 	IODELAY				; WAIT FOR I/O
  6957 00002152 EB00                <2>  jmp short $+2
  6958 00002154 EB00                <2>  jmp short $+2
  6959 00002156 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6960 00002158 89D0                <1> 	mov	eax,edx			; Buffer address
  6961 0000215A E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  6962                              <1> 	IODELAY				; WAIT FOR I/O
  6963 0000215C EB00                <2>  jmp short $+2
  6964 0000215E EB00                <2>  jmp short $+2
  6965 00002160 88E0                <1> 	MOV	AL,AH
  6966 00002162 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  6967 00002164 C1E810              <1> 	shr	eax,16
  6968                              <1> 	IODELAY				; I/O WAIT STATE
  6969 00002167 EB00                <2>  jmp short $+2
  6970 00002169 EB00                <2>  jmp short $+2
  6971 0000216B E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  6972                              <1> 	IODELAY
  6973 0000216D EB00                <2>  jmp short $+2
  6974 0000216F EB00                <2>  jmp short $+2
  6975 00002171 6689C8              <1> 	mov	ax,cx			; Byte count - 1
  6976 00002174 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  6977                              <1> 	IODELAY				; WAIT FOR I/O
  6978 00002176 EB00                <2>  jmp short $+2
  6979 00002178 EB00                <2>  jmp short $+2
  6980 0000217A 88E0                <1> 	MOV	AL,AH
  6981 0000217C E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  6982                              <1> 	IODELAY
  6983 0000217E EB00                <2>  jmp short $+2
  6984 00002180 EB00                <2>  jmp short $+2
  6985 00002182 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  6986 00002183 B002                <1> 	MOV	AL,2			; MODE FOR 8237
  6987 00002185 E60A                <1> 	OUT	DMA+10,AL		; INITIALIZE THE DISKETTE CHANNEL
  6988 00002187 C3                  <1> 	retn
  6989                              <1> 
  6990                              <1> ;; 08/02/2015 - Protected Mode Modification
  6991                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  6992                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  6993                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  6994                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  6995                              <1> ;;	IODELAY
  6996                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  6997                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  6998                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  6999                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  7000                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  7001                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  7002                              <1> ;;	;JNC	short J33A
  7003                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  7004                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  7005                              <1> ;;;J33A:
  7006                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  7007                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  7008                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7009                              <1> ;;	IODELAY
  7010                              <1> ;;	MOV	AL,AH
  7011                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  7012                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  7013                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  7014                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  7015                              <1> ;;	IODELAY
  7016                              <1> ;;	;AND	AL,00001111B
  7017                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  7018                              <1> ;;
  7019                              <1> ;;;----- DETERMINE COUNT
  7020                              <1> ;;	sub	eax, eax ; 08/02/2015
  7021                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  7022                              <1> ;;	CALL	GET_PARM		; "
  7023                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  7024                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  7025                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  7026                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  7027                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  7028                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  7029                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7030                              <1> ;;	IODELAY
  7031                              <1> ;;	MOV	AL, AH
  7032                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  7033                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  7034                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  7035                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  7036                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  7037                              <1> ;;	add	ecx, eax ; 08/02/2015
  7038                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  7039                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  7040                              <1> ;;	SIODELAY
  7041                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  7042                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  7043                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  7044                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  7045                              <1> ;;	jz	short FMTDMA_OK
  7046                              <1> ;;	stc	; 20/02/2015
  7047                              <1> ;;fmtdma_bnd_err:
  7048                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  7049                              <1> ;;FMTDMA_OK:
  7050                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  7051                              <1> 
  7052                              <1> ;-------------------------------------------------------------------------------
  7053                              <1> ; NEC_INIT	
  7054                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  7055                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  7056                              <1> ;
  7057                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  7058                              <1> ;
  7059                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7060                              <1> ;-------------------------------------------------------------------------------
  7061                              <1> NEC_INIT:
  7062                              <1> 	;PUSH	AX			; SAVE NEC COMMAND
  7063                              <1> 	; 05/12/2021
  7064 00002188 50                  <1> 	push	eax
  7065 00002189 E8B5020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  7066                              <1> 
  7067                              <1> ;-----	DO THE SEEK OPERATION
  7068                              <1> 
  7069 0000218E 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  7070 00002191 E8A7030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  7071                              <1> 	;POP	AX			; RECOVER COMMAND
  7072                              <1> 	; 05/12/2021
  7073 00002196 58                  <1> 	pop	eax
  7074 00002197 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  7075 00002199 BB[B7210000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  7076 0000219E 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  7077                              <1> 
  7078                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  7079                              <1> 
  7080 0000219F E860030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  7081 000021A4 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  7082 000021A7 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  7083 000021A9 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  7084 000021AC 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  7085 000021AF 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  7086 000021B1 E84E030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  7087 000021B6 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  7088                              <1> ER_1:
  7089 000021B7 C3                  <1> 	RETn
  7090                              <1> 
  7091                              <1> ;-------------------------------------------------------------------------------
  7092                              <1> ; RWV_COM
  7093                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  7094                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  7095                              <1> ;
  7096                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  7097                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7098                              <1> ;-------------------------------------------------------------------------------
  7099                              <1> RWV_COM:
  7100 000021B8 B8[03220000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  7101 000021BD 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  7102 000021BE 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  7103 000021C1 E83E030000          <1> 	CALL	NEC_OUTPUT
  7104 000021C6 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  7105 000021C9 E836030000          <1> 	CALL	NEC_OUTPUT
  7106 000021CE 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  7107 000021D1 E82E030000          <1> 	CALL	NEC_OUTPUT
  7108 000021D6 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  7109 000021D8 E821020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  7110 000021DD E822030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  7111 000021E2 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  7112 000021E4 E815020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  7113 000021E9 E816030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  7114 000021EE 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  7115                              <1> _R15:
  7116 000021F1 E80E030000          <1> 	CALL	NEC_OUTPUT
  7117 000021F6 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  7118 000021F8 E801020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  7119 000021FD E802030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  7120 00002202 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  7121                              <1> ER_2:
  7122 00002203 C3                  <1> 	RETn
  7123                              <1> 
  7124                              <1> ;-------------------------------------------------------------------------------
  7125                              <1> ; NEC_TERM
  7126                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  7127                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  7128                              <1> ;
  7129                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7130                              <1> ;-------------------------------------------------------------------------------
  7131                              <1> NEC_TERM:
  7132                              <1> 
  7133                              <1> ;-----	LET THE OPERATION HAPPEN
  7134                              <1> 
  7135 00002204 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  7136 00002205 E804040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  7137 0000220A 9C                  <1> 	PUSHFd	; 05/12/2021
  7138 0000220B E82E040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  7139 00002210 724B                <1> 	JC	short SET_END_POP
  7140 00002212 9D                  <1> 	POPFd	; 05/12/2021
  7141 00002213 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  7142                              <1> 
  7143                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  7144                              <1> 
  7145 00002215 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  7146 00002216 BE[3D700000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  7147 0000221B AC                  <1> 	lodsb				; GET ST0
  7148 0000221C 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  7149 0000221E 7433                <1> 	JZ	short SET_END
  7150 00002220 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  7151 00002222 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  7152                              <1> 
  7153                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  7154                              <1> 
  7155 00002224 AC                  <1> 	lodsb				; GET ST1
  7156 00002225 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  7157 00002227 B404                <1> 	MOV	AH,RECORD_NOT_FND
  7158 00002229 7222                <1> 	JC	short J19
  7159 0000222B C0E002              <1> 	SAL	AL,2
  7160 0000222E B410                <1> 	MOV	AH,BAD_CRC
  7161 00002230 721B                <1> 	JC	short J19
  7162 00002232 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  7163 00002234 B408                <1> 	MOV	AH,BAD_DMA
  7164 00002236 7215                <1> 	JC	short J19
  7165 00002238 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  7166 0000223B B404                <1> 	MOV	AH,RECORD_NOT_FND
  7167 0000223D 720E                <1> 	JC	short J19
  7168 0000223F D0E0                <1> 	SAL	AL,1
  7169 00002241 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  7170 00002243 7208                <1> 	JC	short J19
  7171 00002245 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  7172 00002247 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  7173 00002249 7202                <1> 	JC	short J19
  7174                              <1> 
  7175                              <1> ;----- 	NEC MUST HAVE FAILED
  7176                              <1> J18:
  7177 0000224B B420                <1> 	MOV	AH,BAD_NEC
  7178                              <1> J19:
  7179 0000224D 0825[3C700000]      <1> 	OR	[DSKETTE_STATUS],AH
  7180                              <1> SET_END:
  7181 00002253 803D[3C700000]01    <1> 	CMP	byte [DSKETTE_STATUS],1 ; SET ERROR CONDITION
  7182 0000225A F5                  <1> 	CMC
  7183 0000225B 5E                  <1> 	POP	eSI
  7184 0000225C C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  7185                              <1> 
  7186                              <1> SET_END_POP:
  7187 0000225D 9D                  <1> 	POPFd	; 05/12/2021
  7188 0000225E EBF3                <1> 	JMP	SHORT SET_END
  7189                              <1> 
  7190                              <1> ;-------------------------------------------------------------------------------
  7191                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  7192                              <1> ;-------------------------------------------------------------------------------
  7193                              <1> DSTATE:
  7194 00002260 803D[3C700000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  7195 00002267 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  7196 00002269 808F[49700000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  7197 00002270 F687[49700000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  7198 00002277 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  7199 00002279 8A87[49700000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  7200 0000227F 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  7201 00002281 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  7202 00002283 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  7203                              <1> 
  7204                              <1> ;----- 	CHECK IF IT IS 1.44M
  7205                              <1> 
  7206 00002285 E86B010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  7207                              <1> 	;;20/02/2015
  7208                              <1> 	;;JC	short M_12		; CMOS BAD
  7209 0000228A 7414                <1> 	jz	short M_12 ;; 20/02/2015
  7210 0000228C 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  7211 0000228E 7410                <1> 	JE	short M_12		; YES
  7212                              <1> M_720:
  7213 00002290 80A7[49700000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  7214 00002297 808F[49700000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  7215 0000229E EB07                <1> 	JMP	SHORT SETBAC		; BACK
  7216                              <1> M_12:	
  7217 000022A0 808F[49700000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  7218                              <1> 					; TURN ON DETERMINED & FMT CAPA
  7219                              <1> SETBAC:
  7220 000022A7 C3                  <1> 	RETn
  7221                              <1> 
  7222                              <1> ;-------------------------------------------------------------------------------
  7223                              <1> ; RETRY	
  7224                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  7225                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  7226                              <1> ;
  7227                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  7228                              <1> ;-------------------------------------------------------------------------------
  7229                              <1> RETRY:
  7230 000022A8 803D[3C700000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  7231 000022AF 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  7232 000022B1 803D[3C700000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  7233 000022B8 743C                <1> 	JZ	short NO_RETRY
  7234 000022BA 8AA7[49700000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  7235 000022C0 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  7236 000022C3 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  7237 000022C5 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  7238 000022C8 8A2D[44700000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  7239 000022CE C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  7240 000022D1 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  7241 000022D4 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  7242 000022D6 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  7243                              <1> 
  7244                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  7245                              <1> ;	 00000000B (500) -> 10000000B	(250)
  7246                              <1> ;	 10000000B (250) -> 01000000B	(300)
  7247                              <1> ;	 01000000B (300) -> 00000000B	(500)
  7248                              <1> 
  7249 000022D8 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  7250 000022DB D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  7251 000022DD 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  7252 000022E0 80A7[49700000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  7253                              <1> 					; RATE, DBL STEP OFF
  7254 000022E7 08A7[49700000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  7255 000022ED C605[3C700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  7256 000022F4 F9                  <1> 	STC				; SET CARRY FOR RETRY
  7257 000022F5 C3                  <1> 	RETn				; RETRY RETURN
  7258                              <1> 
  7259                              <1> NO_RETRY:
  7260 000022F6 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  7261 000022F7 C3                  <1> 	RETn				; NO RETRY RETURN
  7262                              <1> 
  7263                              <1> ;-------------------------------------------------------------------------------
  7264                              <1> ; NUM_TRANS
  7265                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  7266                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  7267                              <1> ;
  7268                              <1> ; ON ENTRY:	[BP+1] = TRACK
  7269                              <1> ;		SI-HI  = HEAD
  7270                              <1> ;		[BP]   = START SECTOR
  7271                              <1> ;
  7272                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  7273                              <1> ;-------------------------------------------------------------------------------
  7274                              <1> NUM_TRANS:
  7275 000022F8 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  7276 000022FA 803D[3C700000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  7277                              <1> 	; 05/12/2021
  7278 00002301 752C                <1> 	JNZ	short NT_OUT		; IF ERROR 0 TRANSFERRED
  7279 00002303 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  7280 00002305 E8F4000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  7281 0000230A 8A1D[42700000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  7282 00002310 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  7283 00002313 3A2D[41700000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  7284 00002319 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  7285 0000231B 8A2D[40700000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  7286 00002321 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  7287 00002324 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  7288 00002326 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7289                              <1> DIF_HD:
  7290 00002328 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  7291                              <1> SAME_TRK:
  7292 0000232A 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  7293 0000232D 88D8                <1> 	MOV	AL,BL			; TO AL
  7294                              <1> NT_OUT:
  7295 0000232F C3                  <1> 	RETn
  7296                              <1> 
  7297                              <1> ;-------------------------------------------------------------------------------
  7298                              <1> ; SETUP_END
  7299                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  7300                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  7301                              <1> ;
  7302                              <1> ; ON EXIT:
  7303                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7304                              <1> ;-------------------------------------------------------------------------------
  7305                              <1> SETUP_END:
  7306 00002330 B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  7307                              <1> 	;PUSH	AX			; SAVE NUMBER TRANSFERRED
  7308 00002332 50                  <1> 	push	eax ; 05/12/2021
  7309 00002333 E8C6000000          <1> 	CALL	GET_PARM
  7310 00002338 8825[3B700000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  7311                              <1> 	;POP	AX			; RESTORE NUMBER TRANSFERRED
  7312 0000233E 58                  <1> 	pop	eax ; 05/12/2021
  7313 0000233F 8A25[3C700000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  7314 00002345 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  7315 00002347 7402                <1> 	JZ	short NUN_ERR			; NO ERROR
  7316 00002349 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  7317                              <1> NUN_ERR: 
  7318 0000234B 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  7319 0000234E F5                  <1> 	CMC				; SUCCESS OR FAILURE
  7320 0000234F C3                  <1> 	RETn
  7321                              <1> 
  7322                              <1> ;-------------------------------------------------------------------------------
  7323                              <1> ; SETUP_DBL
  7324                              <1> ;	CHECK DOUBLE STEP.
  7325                              <1> ;
  7326                              <1> ; ON ENTRY :	DI = DRIVE
  7327                              <1> ;
  7328                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  7329                              <1> ;-------------------------------------------------------------------------------
  7330                              <1> SETUP_DBL:
  7331 00002350 8AA7[49700000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  7332 00002356 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  7333 00002359 757A                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  7334                              <1> 
  7335                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  7336                              <1> 
  7337 0000235B C605[39700000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  7338 00002362 E8DC000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  7339 00002367 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  7340 00002369 E8CF010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  7341 0000236E E864000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  7342 00002373 7245                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  7343                              <1> 
  7344                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  7345                              <1> 
  7346 00002375 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  7347 00002379 F687[49700000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  7348 00002380 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  7349 00002382 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  7350                              <1> 
  7351                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  7352                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  7353                              <1> ;	THEN SET DOUBLE STEP ON.
  7354                              <1> 
  7355                              <1> CNT_OK:
  7356 00002384 C605[3B700000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  7357                              <1> 	;PUSH	CX			; SAVE TRACK, COUNT
  7358                              <1> 	; 05/12/2021
  7359 0000238B 51                  <1> 	push	ecx
  7360 0000238C C605[3C700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  7361 00002393 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  7362 00002396 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  7363 00002398 C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  7364                              <1> 	;PUSH	AX			; SAVE HEAD
  7365                              <1> 	; 05/12/2021
  7366 0000239B 50                  <1> 	push	eax
  7367 0000239C E89C010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  7368                              <1> 	;POP	AX			; RESTORE HEAD
  7369                              <1> 	; 05/12/2021
  7370 000023A1 58                  <1> 	pop	eax
  7371 000023A2 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  7372 000023A5 E82D000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  7373 000023AA 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  7374 000023AB 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  7375 000023B0 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  7376                              <1> 	;POP	CX			; RESTORE COUNT
  7377                              <1> 	; 05/12/2021
  7378 000023B1 59                  <1> 	pop	ecx
  7379 000023B2 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  7380 000023B4 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  7381 000023B6 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  7382 000023B8 75CA                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  7383                              <1> 
  7384                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  7385                              <1> 
  7386                              <1> SD_ERR:	
  7387 000023BA F9                  <1> 	STC				; SET CARRY FOR ERROR
  7388 000023BB C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  7389                              <1> 
  7390                              <1> DO_CHK:
  7391 000023BC 8A0D[40700000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  7392 000023C2 888F[4D700000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  7393 000023C8 D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  7394 000023CA 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  7395 000023CC 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  7396 000023CE 808F[49700000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  7397                              <1> NO_DBL:
  7398 000023D5 F8                  <1> 	CLC				; CLEAR ERROR FLAG
  7399 000023D6 C3                  <1> 	RETn
  7400                              <1> 
  7401                              <1> ;-------------------------------------------------------------------------------
  7402                              <1> ; READ_ID
  7403                              <1> ;	READ ID FUNCTION.
  7404                              <1> ;
  7405                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  7406                              <1> ;
  7407                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  7408                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  7409                              <1> ;-------------------------------------------------------------------------------
  7410                              <1> READ_ID:
  7411 000023D7 B8[F4230000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  7412 000023DC 50                  <1> 	PUSH	eAX
  7413 000023DD B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  7414 000023DF E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7415 000023E4 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  7416 000023E7 88C4                <1> 	MOV	AH,AL
  7417 000023E9 E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  7418 000023EE E811FEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  7419 000023F3 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  7420                              <1> ER_3:
  7421 000023F4 C3                  <1> 	RETn
  7422                              <1> 
  7423                              <1> ;-------------------------------------------------------------------------------
  7424                              <1> ; CMOS_TYPE
  7425                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  7426                              <1> ;
  7427                              <1> ; ON ENTRY:	DI = DRIVE #
  7428                              <1> ;
  7429                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  7430                              <1> ;-------------------------------------------------------------------------------
  7431                              <1> 
  7432                              <1> CMOS_TYPE: ; 11/12/2014
  7433 000023F5 8A87[AE6A0000]      <1> 	mov	al, [eDI+fd0_type]
  7434 000023FB 20C0                <1> 	and 	al, al ; 18/12/2014
  7435 000023FD C3                  <1> 	retn
  7436                              <1> 
  7437                              <1> ;CMOS_TYPE:
  7438                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  7439                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  7440                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  7441                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  7442                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  7443                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  7444                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  7445                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  7446                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  7447                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  7448                              <1> ;TB:
  7449                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  7450                              <1> ;BAD_CM:
  7451                              <1> ;	RETn				; CY, STATUS OF READ
  7452                              <1> 
  7453                              <1> ;-------------------------------------------------------------------------------
  7454                              <1> ; GET_PARM
  7455                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  7456                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  7457                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  7458                              <1> ;	THE PARAMETER IN DL.
  7459                              <1> ;
  7460                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  7461                              <1> ;
  7462                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  7463                              <1> ;		AL,DH DESTROYED
  7464                              <1> ;-------------------------------------------------------------------------------
  7465                              <1> GET_PARM:
  7466                              <1> 	;PUSH	DS
  7467 000023FE 56                  <1> 	PUSH	eSI
  7468                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  7469                              <1>     	;MOV	DS,AX
  7470                              <1> 	;;mov	ax, cs
  7471                              <1> 	;;mov	ds, ax
  7472                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  7473 000023FF 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  7474                              <1> 	;SUB	BH,BH			; BX = INDEX
  7475 00002401 81E3FF000000        <1> 	and	ebx, 0FFh
  7476                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  7477                              <1> 	;
  7478                              <1> 	; 17/12/2014
  7479 00002407 66A1[A16A0000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  7480 0000240D 38E0                <1> 	cmp	al, ah
  7481 0000240F 7425                <1> 	je	short gpndc
  7482 00002411 A2[A26A0000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  7483 00002416 53                  <1> 	push	ebx ; 08/02/2015
  7484 00002417 88C3                <1> 	mov	bl, al 
  7485                              <1> 	; 11/12/2014
  7486 00002419 8A83[AE6A0000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  7487                              <1> 	; 18/12/2014
  7488 0000241F 20C0                <1> 	and	al, al
  7489 00002421 7507                <1> 	jnz	short gpdtc
  7490 00002423 BB[8B6A0000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  7491 00002428 EB05                <1>         jmp     short gpdpu
  7492                              <1> gpdtc:	
  7493 0000242A E83EF9FFFF          <1> 	call	DR_TYPE_CHECK
  7494                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  7495                              <1> gpdpu:
  7496 0000242F 891D[286A0000]      <1> 	mov	[DISK_POINTER], ebx
  7497 00002435 5B                  <1> 	pop	ebx
  7498                              <1> gpndc:
  7499 00002436 8B35[286A0000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  7500 0000243C 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  7501 0000243F 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  7502 00002441 5E                  <1> 	POP	eSI
  7503                              <1> 	;POP	DS
  7504 00002442 C3                  <1> 	RETn
  7505                              <1> 
  7506                              <1> ;-------------------------------------------------------------------------------
  7507                              <1> ; MOTOR_ON
  7508                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  7509                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  7510                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  7511                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  7512                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  7513                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  7514                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  7515                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  7516                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  7517                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  7518                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  7519                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  7520                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  7521                              <1> ;
  7522                              <1> ; ON ENTRY:	DI = DRIVE #
  7523                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  7524                              <1> ;-------------------------------------------------------------------------------
  7525                              <1> MOTOR_ON:
  7526 00002443 53                  <1> 	PUSH	eBX			; SAVE REG.
  7527 00002444 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  7528 00002449 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  7529 0000244B E8C0F9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  7530 00002450 E88AF9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  7531                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  7532                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  7533                              <1> M_WAIT:
  7534 00002455 B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  7535 00002457 E8A2FFFFFF          <1> 	CALL	GET_PARM
  7536                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  7537                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  7538                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  7539 0000245C 80FC08              <1> 	cmp	ah, 8
  7540                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  7541 0000245F 7702                <1> 	ja	short J13
  7542                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  7543 00002461 B408                <1> 	mov	ah, 8
  7544                              <1> 
  7545                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  7546                              <1> GP2:	
  7547                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  7548                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  7549 00002463 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  7550 00002468 E862F1FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  7551                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  7552 0000246D FECC                <1> 	dec	ah
  7553 0000246F 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  7554                              <1> MOT_IS_ON:
  7555 00002471 5B                  <1> 	POP	eBX			; RESTORE REG.
  7556 00002472 C3                  <1> 	RETn
  7557                              <1> 
  7558                              <1> ;-------------------------------------------------------------------------------
  7559                              <1> ; TURN_ON
  7560                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  7561                              <1> ;
  7562                              <1> ; ON ENTRY:	DI = DRIVE #
  7563                              <1> ;
  7564                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  7565                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  7566                              <1> ;		AX,BX,CX,DX DESTROYED
  7567                              <1> ;-------------------------------------------------------------------------------
  7568                              <1> TURN_ON:
  7569 00002473 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7570 00002475 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  7571 00002477 C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  7572 0000247A FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  7573 0000247B C605[3B700000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  7574 00002482 A0[3A700000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7575 00002487 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  7576 00002489 B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  7577 0000248B D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  7578                              <1> 
  7579                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  7580                              <1> ;  BL = DRIVE SELECT DESIRED
  7581                              <1> ;  AH = MOTOR ON MASK DESIRED
  7582                              <1> 
  7583 0000248D 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  7584 0000248F 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  7585 00002491 8425[3A700000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  7586 00002497 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  7587                              <1> 
  7588                              <1> TURN_IT_ON:
  7589 00002499 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  7590 0000249B 8A3D[3A700000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  7591 000024A1 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  7592 000024A4 8025[3A700000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  7593 000024AB 0825[3A700000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  7594 000024B1 A0[3A700000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  7595 000024B6 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  7596 000024B8 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  7597 000024BB FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  7598 000024BC 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  7599 000024BE C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  7600 000024C1 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  7601 000024C3 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  7602 000024C7 EE                  <1> 	OUT	DX,AL
  7603 000024C8 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  7604                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  7605 000024CA 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  7606 000024CC F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  7607 000024CD C3                  <1> 	RETn
  7608                              <1> 
  7609                              <1> NO_MOT_WAIT:
  7610 000024CE FB                  <1> 	sti
  7611                              <1> no_mot_w1: ; 27/02/2015
  7612 000024CF F9                  <1> 	STC				; SET NO WAIT REQUIRED
  7613                              <1> 	;STI				; INTERRUPTS BACK ON
  7614 000024D0 C3                  <1> 	RETn
  7615                              <1> 
  7616                              <1> ;-------------------------------------------------------------------------------
  7617                              <1> ; HD_WAIT
  7618                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  7619                              <1> ;
  7620                              <1> ; ON ENTRY:	DI = DRIVE #
  7621                              <1> ;
  7622                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  7623                              <1> ;-------------------------------------------------------------------------------
  7624                              <1> HD_WAIT:
  7625 000024D1 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  7626 000024D3 E826FFFFFF          <1> 	CALL	GET_PARM
  7627 000024D8 08E4                <1> 	or	ah, ah	; 17/12/2014
  7628 000024DA 7519                <1> 	jnz	short DO_WAT
  7629 000024DC F605[3A700000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  7630                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  7631                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  7632                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  7633 000024E3 741E                <1> 	jz	short HW_DONE
  7634 000024E5 B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  7635 000024E7 8A87[49700000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  7636 000024ED 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  7637 000024EF 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  7638 000024F1 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  7639                              <1> ;GP3:
  7640 000024F3 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  7641                              <1> ;	JMP	SHORT DO_WAT
  7642                              <1> 
  7643                              <1> ;ISNT_WRITE:
  7644                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  7645                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  7646                              <1> 
  7647                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  7648                              <1> DO_WAT:
  7649                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  7650                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  7651                              <1> J29:					; 	1 MILLISECOND LOOP
  7652                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  7653 000024F5 B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  7654 000024FA E8D0F0FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  7655                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  7656 000024FF FECC                <1> 	dec	ah
  7657 00002501 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  7658                              <1> HW_DONE:
  7659 00002503 C3                  <1> 	RETn
  7660                              <1> 
  7661                              <1> ;-------------------------------------------------------------------------------
  7662                              <1> ; NEC_OUTPUT
  7663                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  7664                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  7665                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  7666                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  7667                              <1> ; 
  7668                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  7669                              <1> ;
  7670                              <1> ; ON EXIT:	CY = 0  SUCCESS
  7671                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  7672                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  7673                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  7674                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  7675                              <1> ;		AX,CX,DX DESTROYED
  7676                              <1> ;-------------------------------------------------------------------------------
  7677                              <1> 
  7678                              <1> ; 09/12/2014 [Erdogan Tan] 
  7679                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  7680                              <1> ; Diskette Drive Controller Status Register (3F4h)
  7681                              <1> ;	This read only register facilitates the transfer of data between
  7682                              <1> ;	the system microprocessor and the controller.
  7683                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  7684                              <1> ;	  with the system micrprocessor.
  7685                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  7686                              <1> ;	  the transfer is to the controller.
  7687                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  7688                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  7689                              <1> ; Bit 3 - Reserved.
  7690                              <1> ; Bit 2 - Reserved.
  7691                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7692                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  7693                              <1> 
  7694                              <1> ; Data Register (3F5h)
  7695                              <1> ; This read/write register passes data, commands and parameters, and provides
  7696                              <1> ; diskette status information.
  7697                              <1>   		
  7698                              <1> NEC_OUTPUT:
  7699                              <1> 	;PUSH	BX			; SAVE REG.
  7700 00002504 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  7701                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  7702                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  7703                              <1> 	; 16/12/2014
  7704                              <1> 	; waiting for (max.) 0.5 seconds
  7705                              <1>         ;;mov	byte [wait_count], 0 ;; 27/02/2015
  7706                              <1> 	;
  7707                              <1> 	; 17/12/2014
  7708                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  7709                              <1> 	;
  7710                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  7711                              <1> 	;		go on.
  7712                              <1> 	;INPUT:
  7713                              <1> 	;	AH=Mask for isolation bits.
  7714                              <1> 	;	AL=pattern to look for.
  7715                              <1> 	;	DX=Port to test for
  7716                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7717                              <1> 	;	     (normally 30 microseconds per period.)
  7718                              <1> 	;
  7719                              <1> 	;WFP_SHORT:  
  7720                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  7721                              <1> 	;
  7722                              <1> 
  7723                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  7724                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  7725 00002508 B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  7726                              <1> ;
  7727                              <1> ;WFPS_OUTER_LP:
  7728                              <1> ;	;
  7729                              <1> ;WFPS_CHECK_PORT:
  7730                              <1> J23:
  7731 0000250D EC                  <1> 	IN	AL,DX			; GET STATUS
  7732 0000250E 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7733 00002510 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7734 00002512 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  7735                              <1> WFPS_HI:
  7736 00002514 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  7737 00002516 A810                <1> 	TEST	AL,010H			; transition on memory
  7738 00002518 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  7739                              <1> WFPS_LO:
  7740 0000251A E461                <1> 	IN	AL, PORT_B		; SYS1
  7741 0000251C A810                <1> 	TEST	AL,010H
  7742 0000251E 74FA                <1> 	JZ	SHORT WFPS_LO
  7743                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  7744 00002520 E2EB                <1> 	loop	J23	; 27/02/2015
  7745                              <1> ;	;
  7746                              <1> ;	dec	bl
  7747                              <1> ;	jnz	short WFPS_OUTER_LP
  7748                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  7749                              <1> ;J23:
  7750                              <1> ;	IN	AL,DX			; GET STATUS
  7751                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  7752                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  7753                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  7754                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  7755                              <1> 	;DEC	BL			; DECREMENT COUNTER
  7756                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  7757                              <1>    
  7758                              <1> 	;;27/02/2015
  7759                              <1> 	;16/12/2014
  7760                              <1>         ;;cmp	byte [wait_count], 10   ; (10/18.2 seconds)
  7761                              <1> 	;;jb	short J23
  7762                              <1> 
  7763                              <1> ;WFPS_TIMEOUT:
  7764                              <1> 
  7765                              <1> ;-----	FALL THRU TO ERROR RETURN
  7766                              <1> 
  7767 00002522 800D[3C700000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  7768                              <1> 	;POP	BX			; RESTORE REG.
  7769 00002529 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  7770 0000252A F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  7771 0000252B C3                  <1> 	RETn
  7772                              <1> 
  7773                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  7774                              <1> 
  7775                              <1> J27:	
  7776 0000252C 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  7777 0000252E 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  7778 00002530 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  7779                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  7780                              <1> 	; 27/02/2015
  7781 00002531 9C                  <1> 	PUSHFd	; 05/12/2021		; SAVE FLAGS
  7782                              <1> 	;MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  7783 00002532 29C9                <1> 	sub	ecx, ecx
  7784 00002534 B103                <1> 	mov	cl, 3 ; 05/12/2021
  7785 00002536 E894F0FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  7786 0000253B 9D                  <1> 	POPFd	; 05/12/2021			; RESTORE FLAGS FOR EXIT
  7787                              <1> 	;POP	BX			; RESTORE REG
  7788 0000253C C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  7789                              <1> 
  7790                              <1> ;-------------------------------------------------------------------------------
  7791                              <1> ; SEEK
  7792                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  7793                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  7794                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  7795                              <1> ;
  7796                              <1> ; ON ENTRY:	DI = DRIVE #
  7797                              <1> ;		CH = TRACK #
  7798                              <1> ;
  7799                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7800                              <1> ;		AX,BX,CX DX DESTROYED
  7801                              <1> ;-------------------------------------------------------------------------------
  7802                              <1> SEEK:
  7803 0000253D 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7804 0000253F B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  7805 00002541 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  7806 00002543 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  7807 00002545 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  7808 00002547 8405[39700000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  7809 0000254D 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  7810                              <1> 
  7811 0000254F 0805[39700000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  7812 00002555 E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7813 0000255A 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  7814                              <1> 
  7815                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  7816                              <1> 
  7817 0000255C C605[3C700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  7818 00002563 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  7819 00002568 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  7820                              <1> 
  7821                              <1> AFT_RECAL:
  7822 0000256A C687[4D700000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  7823 00002571 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  7824 00002573 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  7825                              <1> 
  7826                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  7827                              <1> 
  7828 00002575 F687[49700000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  7829 0000257C 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  7830 0000257E D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  7831                              <1> 
  7832 00002580 3AAF[4D700000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  7833 00002586 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  7834                              <1> 
  7835 00002588 BA[BB250000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  7836 0000258D 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  7837 0000258E 88AF[4D700000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  7838 00002594 B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  7839 00002596 E869FFFFFF          <1> 	CALL	NEC_OUTPUT
  7840 0000259B 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7841 0000259D 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  7842 0000259F E860FFFFFF          <1> 	CALL	NEC_OUTPUT
  7843 000025A4 8AA7[4D700000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  7844 000025AA E855FFFFFF          <1> 	CALL	NEC_OUTPUT
  7845 000025AF E827000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  7846                              <1> 
  7847                              <1> ;-----	WAIT FOR HEAD SETTLE
  7848                              <1> 
  7849                              <1> DO_WAIT:
  7850 000025B4 9C                  <1> 	PUSHFd	; 05/12/2021		; SAVE STATUS
  7851 000025B5 E817FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  7852 000025BA 9D                  <1> 	POPFd	; 05/12/2021		; RESTORE STATUS
  7853                              <1> RB:
  7854                              <1> NEC_ERR:
  7855                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  7856                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  7857 000025BB C3                  <1> 	RETn				; RETURN TO CALLER
  7858                              <1> 
  7859                              <1> ;-------------------------------------------------------------------------------
  7860                              <1> ; RECAL
  7861                              <1> ;	RECALIBRATE DRIVE
  7862                              <1> ;
  7863                              <1> ; ON ENTRY:	DI = DRIVE #
  7864                              <1> ;
  7865                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  7866                              <1> ;-------------------------------------------------------------------------------
  7867                              <1> RECAL:
  7868                              <1> 	;PUSH	CX
  7869                              <1> 	; 05/12/2021
  7870 000025BC 51                  <1> 	push	ecx
  7871 000025BD B8[D9250000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  7872 000025C2 50                  <1> 	PUSH	eAX
  7873 000025C3 B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  7874 000025C5 E83AFFFFFF          <1> 	CALL	NEC_OUTPUT
  7875 000025CA 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  7876 000025CC 88DC                <1> 	MOV	AH,BL
  7877 000025CE E831FFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  7878 000025D3 E803000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  7879 000025D8 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  7880                              <1> RC_BACK:
  7881                              <1> 	;POP	CX
  7882                              <1> 	; 05/12/2021
  7883 000025D9 59                  <1> 	pop	ecx
  7884 000025DA C3                  <1> 	RETn
  7885                              <1> 
  7886                              <1> ;-------------------------------------------------------------------------------
  7887                              <1> ; CHK_STAT_2
  7888                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  7889                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  7890                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  7891                              <1> ;
  7892                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7893                              <1> ;-------------------------------------------------------------------------------
  7894                              <1> CHK_STAT_2:
  7895 000025DB B8[03260000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  7896 000025E0 50                  <1> 	PUSH	eAX
  7897 000025E1 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  7898 000025E6 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  7899 000025E8 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  7900 000025EA E815FFFFFF          <1> 	CALL	NEC_OUTPUT
  7901 000025EF E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  7902 000025F4 720C                <1> 	JC	short J34
  7903 000025F6 A0[3D700000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  7904 000025FB 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  7905 000025FD 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  7906 000025FF 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  7907 00002601 F8                  <1> 	CLC				; GOOD RETURN
  7908                              <1> J34:
  7909 00002602 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  7910                              <1> CS_BACK:
  7911 00002603 C3                  <1> 	RETn
  7912                              <1> J35:
  7913 00002604 800D[3C700000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  7914 0000260B F9                  <1> 	STC				; ERROR RETURN CODE
  7915 0000260C EBF4                <1> 	JMP	SHORT J34
  7916                              <1> 
  7917                              <1> ;-------------------------------------------------------------------------------
  7918                              <1> ; WAIT_INT
  7919                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  7920                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  7921                              <1> ;	IF THE DRIVE IS NOT READY.
  7922                              <1> ;
  7923                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  7924                              <1> ;-------------------------------------------------------------------------------
  7925                              <1> 
  7926                              <1> ; 17/12/2014
  7927                              <1> ; 2.5 seconds waiting !
  7928                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  7929                              <1> ; amount of time to wait for completion interrupt from NEC.
  7930                              <1> 
  7931                              <1> 
  7932                              <1> WAIT_INT:
  7933 0000260E FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  7934 0000260F F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  7935                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  7936                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  7937                              <1> 
  7938                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  7939                              <1> 	;
  7940                              <1> 	;WAIT_FOR_MEM:	
  7941                              <1> 	;	Waits for a bit at a specified memory location pointed
  7942                              <1> 	;	to by ES:[DI] to become set.
  7943                              <1> 	;INPUT:
  7944                              <1> 	;	AH=Mask to test with.
  7945                              <1> 	;	ES:[DI] = memory location to watch.
  7946                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  7947                              <1> 	;	     (normally 30 microseconds per period.)
  7948                              <1> 
  7949                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  7950                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  7951                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  7952                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  7953                              <1> 	; 27/02/2015
  7954 00002610 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  7955                              <1> WFMS_CHECK_MEM:
  7956 00002615 F605[39700000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7957 0000261C 7516                <1>         jnz     short J37
  7958                              <1> WFMS_HI:
  7959 0000261E E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  7960 00002620 A810                <1> 	TEST	AL,010H			; transition on memory
  7961 00002622 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  7962                              <1> WFMS_LO:
  7963 00002624 E461                <1> 	IN	AL,PORT_B		;SYS1
  7964 00002626 A810                <1> 	TEST	AL,010H
  7965 00002628 74FA                <1> 	JZ	SHORT WFMS_LO
  7966 0000262A E2E9                <1>         LOOP    WFMS_CHECK_MEM
  7967                              <1> ;WFMS_OUTER_LP:
  7968                              <1> ;;	or	bl, bl			; check outer counter
  7969                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  7970                              <1> ;	dec	bl
  7971                              <1> ;	jz	short J36A	
  7972                              <1> ;	jmp	short WFMS_CHECK_MEM
  7973                              <1> 
  7974                              <1> 	;17/12/2014
  7975                              <1> 	;16/12/2014
  7976                              <1> ;	mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  7977                              <1> ;J36:
  7978                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  7979                              <1> ;	JNZ	short J37
  7980                              <1> 	;16/12/2014
  7981                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  7982                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  7983                              <1> 	;JNZ	short J36
  7984                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  7985                              <1> ;	jb	short J36
  7986                              <1> 
  7987                              <1> ;WFMS_TIMEOUT:
  7988                              <1> ;J36A:
  7989 0000262C 800D[3C700000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  7990 00002633 F9                  <1> 	STC				; ERROR RETURN
  7991                              <1> J37:
  7992 00002634 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  7993 00002635 8025[39700000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  7994 0000263C 9D                  <1> 	POPF				; RECOVER CARRY
  7995 0000263D C3                  <1> 	RETn				; GOOD RETURN CODE
  7996                              <1> 
  7997                              <1> ;-------------------------------------------------------------------------------
  7998                              <1> ; RESULTS
  7999                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  8000                              <1> ;	FOLLOWING AN INTERRUPT.
  8001                              <1> ;
  8002                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  8003                              <1> ;		AX,BX,CX,DX DESTROYED
  8004                              <1> ;-------------------------------------------------------------------------------
  8005                              <1> RESULTS:
  8006 0000263E 57                  <1> 	PUSH	eDI
  8007 0000263F BF[3D700000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  8008 00002644 B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  8009 00002646 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  8010                              <1> 
  8011                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  8012                              <1> 
  8013                              <1> _R10: 
  8014                              <1> 	; 16/12/2014
  8015                              <1> 	; wait for (max) 0.5 seconds
  8016                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  8017                              <1> 	;XOR	CX,CX			; COUNTER
  8018                              <1> 
  8019                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  8020                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  8021                              <1> 	; 27/02/2015
  8022 0000264A B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  8023                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  8024                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  8025                              <1> 
  8026                              <1> WFPSR_OUTER_LP:
  8027                              <1> 	;
  8028                              <1> WFPSR_CHECK_PORT:
  8029                              <1> J39:					; WAIT FOR MASTER
  8030 0000264F EC                  <1> 	IN	AL,DX			; GET STATUS
  8031 00002650 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  8032 00002652 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  8033 00002654 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  8034                              <1> WFPSR_HI:
  8035 00002656 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  8036 00002658 A810                <1> 	TEST	AL,010H			; transition on memory
  8037 0000265A 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  8038                              <1> WFPSR_LO:
  8039 0000265C E461                <1> 	IN	AL, PORT_B		; SYS1
  8040 0000265E A810                <1> 	TEST	AL,010H
  8041 00002660 74FA                <1> 	JZ	SHORT WFPSR_LO
  8042 00002662 E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  8043                              <1> 	;; 27/02/2015
  8044                              <1> 	;;dec	bh
  8045                              <1> 	;;jnz	short WFPSR_OUTER_LP
  8046                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  8047                              <1> 
  8048                              <1> 	;;mov	byte [wait_count], 0
  8049                              <1> ;J39:					; WAIT FOR MASTER
  8050                              <1> ;	IN	AL,DX			; GET STATUS
  8051                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  8052                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  8053                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  8054                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  8055                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  8056                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  8057                              <1> 	;
  8058                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  8059                              <1> 	;;jb	short J39	
  8060                              <1> 
  8061                              <1> ;WFPSR_TIMEOUT:
  8062 00002664 800D[3C700000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  8063 0000266B F9                  <1> 	STC				; SET ERROR RETURN
  8064 0000266C EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  8065                              <1> 
  8066                              <1> ;-----	READ IN THE STATUS
  8067                              <1> 
  8068                              <1> J42:
  8069 0000266E EB00                <1> 	JMP	$+2			; I/O DELAY
  8070 00002670 6642                <1> 	INC	DX			; POINT AT DATA PORT
  8071 00002672 EC                  <1> 	IN	AL,DX			; GET THE DATA
  8072                              <1> 	; 16/12/2014
  8073                              <1> 	NEWIODELAY
  8074 00002673 E6EB                <2>  out 0EBh,al
  8075 00002675 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  8076 00002677 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  8077                              <1> 	; 16/12/2014
  8078                              <1> ;	push	cx
  8079                              <1> ;	mov	cx, 30
  8080                              <1> ;wdw2:
  8081                              <1> ;	NEWIODELAY
  8082                              <1> ;	loop	wdw2
  8083                              <1> ;	pop	cx
  8084                              <1> 
  8085 00002678 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  8086 0000267D E84DEFFFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  8087 00002682 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  8088 00002684 EC                  <1> 	IN	AL,DX			; GET STATUS
  8089                              <1> 	; 16/12/2014
  8090                              <1> 	NEWIODELAY
  8091 00002685 E6EB                <2>  out 0EBh,al
  8092                              <1> 	;
  8093 00002687 A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  8094 00002689 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  8095                              <1> 
  8096 0000268B FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  8097 0000268D 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  8098 0000268F 800D[3C700000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  8099 00002696 F9                  <1> 	STC				; SET ERROR FLAG
  8100                              <1> 
  8101                              <1> ;-----	RESULT OPERATION IS DONE
  8102                              <1> POPRES:
  8103 00002697 5F                  <1> 	POP	eDI
  8104 00002698 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  8105                              <1> 
  8106                              <1> ;-------------------------------------------------------------------------------
  8107                              <1> ; READ_DSKCHNG
  8108                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  8109                              <1> ;
  8110                              <1> ; ON ENTRY:	DI = DRIVE #
  8111                              <1> ;
  8112                              <1> ; ON EXIT:	DI = DRIVE #
  8113                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  8114                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  8115                              <1> ;		AX,CX,DX DESTROYED
  8116                              <1> ;-------------------------------------------------------------------------------
  8117                              <1> READ_DSKCHNG:
  8118 00002699 E8A5FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  8119 0000269E 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  8120 000026A2 EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  8121 000026A3 A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  8122 000026A5 C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  8123                              <1> 
  8124                              <1> ;-------------------------------------------------------------------------------
  8125                              <1> ; DRIVE_DET
  8126                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  8127                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  8128                              <1> ; ON ENTRY:	DI = DRIVE #
  8129                              <1> ;-------------------------------------------------------------------------------
  8130                              <1> DRIVE_DET:
  8131 000026A6 E898FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  8132 000026AB E80CFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  8133 000026B0 724F                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  8134 000026B2 B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  8135 000026B4 E884FEFFFF          <1> 	CALL	SEEK
  8136 000026B9 7246                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  8137 000026BB B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  8138                              <1> SK_GIN:
  8139 000026BD FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  8140                              <1> 	;PUSH	CX			; SAVE TRACK
  8141                              <1> 	; 05/12/2021
  8142 000026BF 51                  <1> 	push	ecx
  8143 000026C0 E878FEFFFF          <1> 	CALL	SEEK
  8144 000026C5 723B                <1> 	JC	short POP_BAC		; POP AND RETURN
  8145 000026C7 B8[02270000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  8146 000026CC 50                  <1> 	PUSH	eAX
  8147 000026CD B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  8148 000026CF E830FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  8149 000026D4 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  8150 000026D7 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  8151 000026D9 E826FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  8152 000026DE E85BFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  8153 000026E3 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  8154                              <1> 	;POP	CX			; RESTORE TRACK
  8155                              <1> 	; 05/12/2021
  8156 000026E4 59                  <1> 	pop	ecx
  8157 000026E5 F605[3D700000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  8158 000026EC 74CF                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  8159 000026EE 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  8160 000026F0 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  8161                              <1> 
  8162                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  8163                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  8164                              <1> 
  8165 000026F2 808F[49700000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  8166 000026F9 C3                  <1> 	RETn				; ALL INFORMATION SET
  8167                              <1> IS_80:
  8168 000026FA 808F[49700000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  8169                              <1> DD_BAC:
  8170 00002701 C3                  <1> 	RETn
  8171                              <1> POP_BAC:
  8172                              <1> 	;POP	CX			; THROW AWAY
  8173                              <1> 	; 05/12/2021
  8174 00002702 59                  <1> 	pop	ecx
  8175 00002703 C3                  <1> 	RETn
  8176                              <1> 
  8177                              <1> fdc_int:  
  8178                              <1> 	  ; 30/07/2015	
  8179                              <1> 	  ; 16/02/2015
  8180                              <1> ;int_0Eh: ; 11/12/2014
  8181                              <1> 
  8182                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  8183                              <1> ; DISK_INT
  8184                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  8185                              <1> ;
  8186                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  8187                              <1> ;-------------------------------------------------------------------------------
  8188                              <1> DISK_INT_1:
  8189                              <1> 
  8190                              <1> 	;PUSH	AX			; SAVE WORK REGISTER
  8191                              <1> 	; 05/12/2021
  8192 00002704 50                  <1> 	push	eax
  8193 00002705 1E                  <1> 	push	ds
  8194 00002706 66B81000            <1> 	mov	ax, KDATA
  8195 0000270A 8ED8                <1> 	mov 	ds, ax
  8196 0000270C 800D[39700000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  8197 00002713 B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  8198 00002715 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  8199 00002717 1F                  <1> 	pop	ds
  8200                              <1> 	;POP	AX			; RECOVER REGISTER
  8201                              <1> 	; 05/12/2021
  8202 00002718 58                  <1> 	pop	eax
  8203 00002719 CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  8204                              <1> 
  8205                              <1> ;-------------------------------------------------------------------------------
  8206                              <1> ; DSKETTE_SETUP
  8207                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  8208                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  8209                              <1> ;-------------------------------------------------------------------------------
  8210                              <1> DSKETTE_SETUP:
  8211                              <1> 	;PUSH	AX			; SAVE REGISTERS
  8212                              <1> 	;PUSH	BX
  8213                              <1> 	;PUSH	CX
  8214 0000271A 52                  <1> 	PUSH	eDX
  8215                              <1> 	;PUSH	DI
  8216                              <1> 	;;PUSH	DS
  8217                              <1> 	; 14/12/2014
  8218                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  8219                              <1> 	;mov	[DISK_POINTER+2], cs
  8220                              <1> 	;
  8221                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  8222 0000271B 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  8223 0000271D 66C705[49700000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  8224 00002725 00                  <1>
  8225 00002726 8025[44700000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  8226 0000272D 800D[44700000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  8227 00002734 C605[39700000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  8228 0000273B C605[3B700000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  8229 00002742 C605[3A700000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  8230 00002749 C605[3C700000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  8231                              <1> 	;
  8232                              <1> 	; 28/02/2015
  8233                              <1> 	;mov	word [cfd], 100h 
  8234 00002750 E89DF2FFFF          <1> 	call	DSK_RESET
  8235 00002755 5A                  <1> 	pop	edx
  8236 00002756 C3                  <1> 	retn
  8237                              <1> 
  8238                              <1> ;SUP0:
  8239                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  8240                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  8241                              <1> ;	; 02/01/2015
  8242                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  8243                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  8244                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  8245                              <1> ;       cmp     byte [fd1_type], 0	
  8246                              <1> ;	jna	short sup1
  8247                              <1> ;	or	di, di
  8248                              <1> ;	jnz	short sup1
  8249                              <1> ;	inc	di
  8250                              <1> ;       jmp     short SUP0
  8251                              <1> ;sup1:
  8252                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  8253                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  8254                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  8255                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  8256                              <1> ;	;POP	DI
  8257                              <1> ;	POP	eDX
  8258                              <1> ;	;POP	CX
  8259                              <1> ;	;POP	BX
  8260                              <1> ;	;POP	AX
  8261                              <1> ;	RETn
  8262                              <1> 
  8263                              <1> ;//////////////////////////////////////////////////////
  8264                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8265                              <1> ;
  8266                              <1> 
  8267                              <1> int13h: ; 21/02/2015
  8268 00002757 9C                  <1> 	pushfd
  8269 00002758 0E                  <1> 	push 	cs
  8270 00002759 E859000000          <1> 	call 	DISK_IO
  8271 0000275E C3                  <1> 	retn
  8272                              <1> 
  8273                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  8274                              <1> ;/////////////////////////////////////////////////////////////////////
  8275                              <1> 
  8276                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  8277                              <1> ; 23/02/2015
  8278                              <1> ; 21/02/2015 (unix386.s)
  8279                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  8280                              <1> ;
  8281                              <1> ; Original Source Code:
  8282                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  8283                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  8284                              <1> ;
  8285                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  8286                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  8287                              <1> ;
  8288                              <1> 
  8289                              <1> ;The wait for controller to be not busy is 10 seconds.
  8290                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  8291                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  8292                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  8293                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  8294                              <1> 
  8295                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  8296                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  8297                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  8298                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  8299                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  8300                              <1> 
  8301                              <1> ;The wait for Data request on read and write longs is
  8302                              <1> ;2000 us. (?)
  8303                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  8304                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  8305                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  8306                              <1> 
  8307                              <1> ; Port 61h (PORT_B)
  8308                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  8309                              <1> 
  8310                              <1> ; 23/12/2014
  8311                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  8312                              <1> 
  8313                              <1> ;--- INT 13H -------------------------------------------------------------------
  8314                              <1> ;									       :
  8315                              <1> ; FIXED DISK I/O INTERFACE						       :
  8316                              <1> ;									       :
  8317                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  8318                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  8319                              <1> ;									       :
  8320                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  8321                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  8322                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  8323                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  8324                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  8325                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  8326                              <1> ;									       :
  8327                              <1> ;------------------------------------------------------------------------------:
  8328                              <1> ;									       :
  8329                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  8330                              <1> ;									       :
  8331                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  8332                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  8333                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  8334                              <1> ;			  DL > 80H - DISK				       :
  8335                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  8336                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  8337                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  8338                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  8339                              <1> ;	(AH)= 06H  UNUSED						       :
  8340                              <1> ;	(AH)= 07H  UNUSED						       :
  8341                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  8342                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  8343                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  8344                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  8345                              <1> ;	(AH)= 0AH  READ LONG						       :
  8346                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  8347                              <1> ;	(AH)= 0CH  SEEK 						       :
  8348                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  8349                              <1> ;	(AH)= 0EH  UNUSED						       :
  8350                              <1> ;	(AH)= 0FH  UNUSED						       :
  8351                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  8352                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  8353                              <1> ;	(AH)= 12H  UNUSED						       :
  8354                              <1> ;	(AH)= 13H  UNUSED						       :
  8355                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  8356                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  8357                              <1> ;									       :
  8358                              <1> ;-------------------------------------------------------------------------------
  8359                              <1> ;									       :
  8360                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  8361                              <1> ;									       :
  8362                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  8363                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  8364                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  8365                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  8366                              <1> ;									       :
  8367                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  8368                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  8369                              <1> ;				 (10 BITS TOTAL)			       :
  8370                              <1> ;									       :
  8371                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  8372                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  8373                              <1> ;									       :
  8374                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  8375                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  8376                              <1> ;									       :
  8377                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  8378                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  8379                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  8380                              <1> ;			       80H FOR A BAD SECTOR			       :
  8381                              <1> ;			   N = SECTOR NUMBER				       :
  8382                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  8383                              <1> ;			   THE TABLE SHOULD BE: 			       :
  8384                              <1> ;									       :
  8385                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  8386                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  8387                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  8388                              <1> ;									       :
  8389                              <1> ;-------------------------------------------------------------------------------
  8390                              <1> 
  8391                              <1> ;-------------------------------------------------------------------------------
  8392                              <1> ; OUTPUT								       :
  8393                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  8394                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  8395                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  8396                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  8397                              <1> ;									       :
  8398                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  8399                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  8400                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  8401                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  8402                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  8403                              <1> ;		REWRITTEN.						       :
  8404                              <1> ;									       :
  8405                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  8406                              <1> ;	   INPUT:							       :
  8407                              <1> ;	     (DL) = DRIVE NUMBER					       :
  8408                              <1> ;	   OUTPUT:							       :
  8409                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  8410                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  8411                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  8412                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  8413                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  8414                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  8415                              <1> ;									       :
  8416                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  8417                              <1> ;									       :
  8418                              <1> ;	AH = 0 - NOT PRESENT						       :
  8419                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  8420                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  8421                              <1> ;	     3 - FIXED DISK						       :
  8422                              <1> ;									       :
  8423                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  8424                              <1> ;									       :
  8425                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  8426                              <1> ;	INFORMATION.							       :
  8427                              <1> ;									       :
  8428                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  8429                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  8430                              <1> ;									       :
  8431                              <1> ;-------------------------------------------------------------------------------
  8432                              <1> 
  8433                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  8434                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  8435                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  8436                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  8437                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  8438                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  8439                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  8440                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  8441                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  8442                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  8443                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  8444                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  8445                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  8446                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  8447                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  8448                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  8449                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  8450                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  8451                              <1> 
  8452                              <1> ;--------------------------------------------------------
  8453                              <1> ;							:
  8454                              <1> ; FIXED DISK PARAMETER TABLE				:
  8455                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  8456                              <1> ;							:
  8457                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  8458                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  8459                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  8460                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  8461                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  8462                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  8463                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  8464                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  8465                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  8466                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  8467                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  8468                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  8469                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  8470                              <1> ;							:
  8471                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  8472                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  8473                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  8474                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  8475                              <1> ;							:
  8476                              <1> ;--------------------------------------------------------
  8477                              <1> 
  8478                              <1> ;--------------------------------------------------------
  8479                              <1> ;							:
  8480                              <1> ; HARDWARE SPECIFIC VALUES				:
  8481                              <1> ;							:
  8482                              <1> ;  -  CONTROLLER I/O PORT				:
  8483                              <1> ;							:
  8484                              <1> ;     > WHEN READ FROM: 				:
  8485                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  8486                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  8487                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  8488                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  8489                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  8490                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  8491                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  8492                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  8493                              <1> ;							:
  8494                              <1> ;     > WHEN WRITTEN TO:				:
  8495                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  8496                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  8497                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  8498                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  8499                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  8500                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  8501                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  8502                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  8503                              <1> ;							:
  8504                              <1> ;--------------------------------------------------------
  8505                              <1> 
  8506                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  8507                              <1> ;HF1_PORT	equ	0170h	
  8508                              <1> ;HF_REG_PORT	EQU	03F6H
  8509                              <1> ;HF1_REG_PORT	equ	0376h
  8510                              <1> 
  8511                              <1> HDC1_BASEPORT	equ	1F0h
  8512                              <1> HDC2_BASEPORT	equ	170h		
  8513                              <1> 
  8514 0000275F 90                  <1> align 2
  8515                              <1> 
  8516                              <1> ;-----		STATUS REGISTER
  8517                              <1> 
  8518                              <1> ST_ERROR	EQU	00000001B	;
  8519                              <1> ST_INDEX	EQU	00000010B	;
  8520                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  8521                              <1> ST_DRQ		EQU	00001000B	;
  8522                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  8523                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  8524                              <1> ST_READY	EQU	01000000B	;
  8525                              <1> ST_BUSY 	EQU	10000000B	;
  8526                              <1> 
  8527                              <1> ;-----		ERROR REGISTER
  8528                              <1> 
  8529                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  8530                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  8531                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  8532                              <1> ;		EQU	00001000B	; NOT USED
  8533                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  8534                              <1> ;		EQU	00100000B	; NOT USED
  8535                              <1> ERR_DATA_ECC	EQU	01000000B
  8536                              <1> ERR_BAD_BLOCK	EQU	10000000B
  8537                              <1> 
  8538                              <1> 
  8539                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  8540                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  8541                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  8542                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  8543                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  8544                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  8545                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  8546                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  8547                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  8548                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  8549                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  8550                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  8551                              <1> 
  8552                              <1> ;MAX_FILE	EQU	2
  8553                              <1> ;S_MAX_FILE	EQU	2
  8554                              <1> MAX_FILE	equ	4		; 22/12/2014
  8555                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  8556                              <1> 
  8557                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  8558                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  8559                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  8560                              <1> 
  8561                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  8562                              <1> 
  8563                              <1> ;-----		COMMAND BLOCK REFERENCE
  8564                              <1> 
  8565                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  8566                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  8567                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  8568                              <1> ; 19/12/2014
  8569                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  8570                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  8571                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8572                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  8573                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  8574                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  8575                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  8576                              <1> 
  8577                              <1> align 2
  8578                              <1> 
  8579                              <1> ;----------------------------------------------------------------
  8580                              <1> ; FIXED DISK I/O SETUP						:
  8581                              <1> ;								:
  8582                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  8583                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  8584                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  8585                              <1> ;								:
  8586                              <1> ;----------------------------------------------------------------
  8587                              <1> 
  8588                              <1> DISK_SETUP:
  8589                              <1> 	;CLI
  8590                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  8591                              <1> 	;xor	ax,ax
  8592                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  8593                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  8594                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  8595                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  8596                              <1> 	;MOV	[DISK_VECTOR+2],AX
  8597                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  8598                              <1> 	;MOV	[ORG_VECTOR+2],CS
  8599                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  8600                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  8601                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  8602                              <1> 	;;MOV	[HDISK_INT+2],CS
  8603                              <1> 	;mov	[HDISK_INT1+2],CS
  8604                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  8605                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  8606                              <1> 	;mov	[HDISK_INT2+2],CS
  8607                              <1> 	;
  8608                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  8609                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  8610                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  8611                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  8612                              <1> 	;push	cs
  8613                              <1> 	;pop	ds
  8614                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  8615                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  8616 00002760 C705[54700000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  8617 00002768 0900                <1>
  8618                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  8619                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  8620 0000276A C705[58700000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  8621 00002772 0900                <1>
  8622                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  8623                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  8624 00002774 C705[5C700000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  8625 0000277C 0900                <1>
  8626                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  8627                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  8628 0000277E C705[60700000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  8629 00002786 0900                <1>
  8630                              <1> 	;
  8631                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  8632                              <1> 	;;;AND	AL,0BFH
  8633                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  8634                              <1> 	;;;JMP	$+2
  8635                              <1> 	;;IODELAY
  8636                              <1> 	;;OUT	INTB01,AL
  8637                              <1> 	;;IODELAY
  8638                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  8639                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  8640                              <1> 	;;;JMP	$+2
  8641                              <1> 	;;IODELAY
  8642                              <1> 	;;OUT	INTA01,AL
  8643                              <1> 	;
  8644                              <1> 	;STI
  8645                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  8646                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  8647                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  8648                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8649                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  8650                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  8651                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  8652                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  8653                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  8654                              <1> 	;mov	si, hd0_type
  8655 00002788 BE[B06A0000]        <1> 	mov	esi, hd0_type
  8656                              <1> 	;mov	cx, 4
  8657 0000278D B904000000          <1> 	mov	ecx, 4
  8658                              <1> hde_l:
  8659 00002792 AC                  <1> 	lodsb
  8660 00002793 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  8661 00002795 7206                <1> 	jb	short _L4
  8662 00002797 FE05[50700000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  8663                              <1> _L4: ; 26/02/2015
  8664 0000279D E2F3                <1> 	loop	hde_l	
  8665                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  8666                              <1> ;L4:
  8667                              <1> 	; 
  8668                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  8669                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  8670                              <1> 	;;mov 	cl, 3
  8671                              <1> 	;;
  8672                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  8673                              <1> ;;hdc_dl:
  8674                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  8675                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  8676                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  8677                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  8678                              <1> 	;;jnc	short hdc_reset0
  8679                              <1> 	;;loop	hdc_dl
  8680                              <1> 	;;; 27/12/2014
  8681                              <1> 	;;stc
  8682                              <1> 	;;retn
  8683                              <1> 	;
  8684                              <1> ;;hdc_reset0:
  8685                              <1> 	; 18/01/2015
  8686 0000279F 8A0D[50700000]      <1> 	mov	cl, [HF_NUM]
  8687 000027A5 20C9                <1> 	and	cl, cl
  8688 000027A7 740D                <1> 	jz	short POD_DONE
  8689                              <1> 	;
  8690 000027A9 B27F                <1> 	mov	dl, 7Fh
  8691                              <1> hdc_reset1:
  8692 000027AB FEC2                <1> 	inc	dl
  8693                              <1> 	;; 31/12/2015
  8694                              <1> 	;;push	dx
  8695                              <1> 	;;push	cx
  8696                              <1> 	;;push	ds
  8697                              <1> 	;;sub	ax, ax
  8698                              <1> 	;;mov	ds, ax
  8699                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  8700                              <1> 	;;pop	ds
  8701                              <1> 	;;MOV	BX,AX
  8702                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  8703                              <1> 	;;MOV	CX,AX
  8704                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  8705                              <1> 	;;
  8706                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  8707                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  8708                              <1> 	;;pop	cx
  8709                              <1> 	;;pop	dx
  8710                              <1> 	;;
  8711                              <1> 	; 18/01/2015
  8712 000027AD B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  8713                              <1> 	;int	13h
  8714 000027AF E8A3FFFFFF          <1> 	call	int13h
  8715 000027B4 E2F5                <1> 	loop	hdc_reset1
  8716                              <1> POD_DONE:
  8717 000027B6 C3                  <1> 	RETn
  8718                              <1> 
  8719                              <1> ;;-----	POD_ERROR
  8720                              <1> 
  8721                              <1> ;;CTL_ERRX:
  8722                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  8723                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  8724                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8725                              <1> ;	;JMP	short POD_DONE
  8726                              <1> 
  8727                              <1> ;;HD_RESET_1:
  8728                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  8729                              <1> ;;	;PUSH	CX
  8730                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  8731                              <1> ;;	INT	13H
  8732                              <1> ;;	JC	short RES_2
  8733                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  8734                              <1> ;;	INT	13H
  8735                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  8736                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  8737                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8738                              <1> ;;					; (30 seconds)		
  8739                              <1> ;;	;cmc
  8740                              <1> ;;	;JNC	short RES_1
  8741                              <1> ;;	jb	short RES_1
  8742                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  8743                              <1> ;;	;TEST	DL,1
  8744                              <1> ;;	;JNZ	RES_E1
  8745                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  8746                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  8747                              <1> ;;	;JMP	SHORT RES_E1
  8748                              <1> ;;RES_ER: ; 22/12/2014
  8749                              <1> ;;RES_OK:
  8750                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8751                              <1> ;;	;POP	BX
  8752                              <1> ;;	RETn
  8753                              <1> ;;
  8754                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  8755                              <1> ;;	INT	13H
  8756                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  8757                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  8758                              <1> ;;	INT	13H
  8759                              <1> ;;	JC	short RES_ER
  8760                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  8761                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  8762                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  8763                              <1> ;;	INT	13H
  8764                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  8765                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  8766                              <1> ;;	JE	short RES_OK
  8767                              <1> ;;	CMP	AH,DATA_CORRECTED
  8768                              <1> ;;	JE	short RES_OK
  8769                              <1> ;;	CMP	AH,BAD_ECC
  8770                              <1> ;;	JE	short RES_OK
  8771                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  8772                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  8773                              <1> ;;					; (60 seconds)		
  8774                              <1> ;;	cmc
  8775                              <1> ;;	JC	short RES_ER		; FAILED
  8776                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  8777                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  8778                              <1> ;;	AND	AL,3FH
  8779                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  8780                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  8781                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  8782                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  8783                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  8784                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  8785                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  8786                              <1> ;;	;TEST	DL,1
  8787                              <1> ;;	;JNZ	short RES_E1
  8788                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  8789                              <1> ;;;RES_E1:
  8790                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  8791                              <1> ;;;RES_OK:
  8792                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  8793                              <1> ;;	;POP	BX
  8794                              <1> ;;	;RETn
  8795                              <1> ;
  8796                              <1> ;;SET_FAIL:
  8797                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  8798                              <1> ;	;CALL	CMOS_READ
  8799                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  8800                              <1> ;	;XCHG	AH,AL			; SAVE IT
  8801                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  8802                              <1> ;	;RETn
  8803                              <1> ;
  8804                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  8805                              <1> ;	;POP	AX			; SAVE RETURN
  8806                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  8807                              <1> ;	;POP	BX
  8808                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  8809                              <1> ;	;PUSH	CX
  8810                              <1> ;	;PUSH	AX
  8811                              <1> ;	;push	ds
  8812                              <1> ;	;xor	ax, ax
  8813                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  8814                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  8815                              <1> ;	;				; BX = START TIME
  8816                              <1> ;	;				; CX = END TIME
  8817                              <1> ;	;pop	ds
  8818                              <1> ;	;CMP	BX,CX
  8819                              <1> ;	;JB	short TCHK1		; START < END
  8820                              <1> ;	;CMP	BX,AX
  8821                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  8822                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  8823                              <1> ;;TCHK1: CMP	AX,BX
  8824                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  8825                              <1> ;;TCHK2: CMP	AX,CX
  8826                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  8827                              <1> ;;					; OR CURRENT < END < START
  8828                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  8829                              <1> ;;	RETn
  8830                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  8831                              <1> ;;	RETn
  8832                              <1> ;;
  8833                              <1> ;;int_13h:
  8834                              <1> 
  8835                              <1> ;----------------------------------------
  8836                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  8837                              <1> ;----------------------------------------
  8838                              <1> 
  8839                              <1> DISK_IO:
  8840 000027B7 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  8841                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  8842                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  8843                              <1> 	;;call	int40h
  8844                              <1> 	;jb	DISKETTE_IO_1
  8845                              <1> 	; 05/12/2021
  8846 000027BA 7305                <1> 	jnb	short A1
  8847 000027BC E95FF1FFFF          <1> 	jmp	DISKETTE_IO_1
  8848                              <1> ;RET_2:
  8849                              <1> 	;RETf	2			; BACK TO CALLER
  8850                              <1> ;	retf	4
  8851                              <1> A1:
  8852 000027C1 FB                  <1> 	STI				; ENABLE INTERRUPTS
  8853                              <1> 	;; 04/01/2015
  8854                              <1> 	;;OR	AH,AH
  8855                              <1> 	;;JNZ	short A2
  8856                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  8857                              <1> 	;;SUB	AH,AH
  8858 000027C2 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  8859 000027C5 772E                <1> 	JA	short RET_2
  8860                              <1> 	; 18/01/2015
  8861 000027C7 08E4                <1> 	or	ah,ah
  8862 000027C9 742D                <1> 	jz	short A4
  8863 000027CB 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  8864 000027CE 7504                <1> 	jne	short A2
  8865 000027D0 28E4                <1> 	sub	ah,ah	; Reset
  8866 000027D2 EB24                <1> 	jmp	short A4
  8867                              <1> A2:
  8868 000027D4 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  8869                              <1> 	;JNZ	short A3
  8870                              <1>         ;JMP    GET_PARM_N
  8871                              <1> 	;je	GET_PARM_N
  8872                              <1> 	; 05/12/2021
  8873 000027D7 7505                <1> 	jne	short A3
  8874 000027D9 E90D030000          <1> 	jmp	GET_PARM_N
  8875                              <1> A3:	
  8876 000027DE 80FC15              <1> 	CMP	AH,15H			; READ DASD TYPE IS ALSO
  8877                              <1> 	;JNZ	short A4
  8878                              <1>         ;JMP    READ_DASD_TYPE
  8879                              <1> 	;je	READ_DASD_TYPE
  8880                              <1> 	; 05/12/2021
  8881 000027E1 7505                <1> 	jne	short A3_A4
  8882 000027E3 E9BA020000          <1> 	jmp	READ_DASD_TYPE
  8883                              <1> A3_A4:
  8884                              <1> 	; 02/02/2015
  8885 000027E8 80FC1D              <1> 	cmp	ah, 1Dh			; (Temporary for Retro UNIX 386 v1)
  8886                              <1> 	; 12/01/2015
  8887 000027EB F5                  <1> 	cmc
  8888 000027EC 730A                <1> 	jnc	short A4
  8889                              <1> 	; 30/01/2015
  8890                              <1> 	;mov	byte [CS:DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  8891 000027EE C605[4F700000]01    <1>         mov     byte [DISK_STATUS1], BAD_CMD
  8892                              <1> 	;jmp	short RET_2
  8893                              <1> RET_2:
  8894 000027F5 CA0400              <1> 	retf	4
  8895                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  8896 000027F8 C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  8897 000027FC 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  8898 000027FD 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  8899 000027FE 52                  <1> 	PUSH	eDX
  8900 000027FF 1E                  <1> 	PUSH	DS
  8901 00002800 06                  <1> 	PUSH	ES
  8902 00002801 56                  <1> 	PUSH	eSI
  8903 00002802 57                  <1> 	PUSH	eDI
  8904                              <1> 	;;04/01/2015
  8905                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  8906                              <1> 	;;JNZ	short A5
  8907                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  8908                              <1> ;;A5:	
  8909                              <1> 	;push	cs
  8910                              <1> 	;pop	ds
  8911                              <1> 	; 21/02/2015
  8912                              <1> 	;push	ax
  8913                              <1> 	; 05/12/2021
  8914 00002803 50                  <1> 	push	eax
  8915 00002804 66B81000            <1> 	mov	ax, KDATA
  8916 00002808 8ED8                <1> 	mov	ds, ax
  8917 0000280A 8EC0                <1> 	mov	es, ax	
  8918                              <1> 	;pop	ax
  8919                              <1> 	; 05/12/2021
  8920 0000280C 58                  <1> 	pop	eax
  8921 0000280D E889000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  8922                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8923 00002812 8A25[4F700000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  8924 00002818 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  8925 0000281B F5                  <1> 	CMC				; SUCCESS OR FAILURE
  8926 0000281C 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  8927 0000281D 5E                  <1> 	POP	eSI
  8928 0000281E 07                  <1>         POP     ES
  8929 0000281F 1F                  <1>         POP     DS
  8930 00002820 5A                  <1> 	POP	eDX
  8931 00002821 59                  <1> 	POP	eCX
  8932 00002822 5B                  <1> 	POP	eBX
  8933 00002823 C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  8934                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  8935 00002824 CA0400              <1> 	retf	4
  8936                              <1> ; 21/02/2015
  8937                              <1> ;       dw --> dd
  8938                              <1> M1:					; FUNCTION TRANSFER TABLE
  8939 00002827 [E0290000]          <1> 	dd	DISK_RESET		; 000H
  8940 0000282B [552A0000]          <1> 	dd	RETURN_STATUS		; 001H
  8941 0000282F [622A0000]          <1> 	dd	DISK_READ		; 002H
  8942 00002833 [6B2A0000]          <1> 	dd	DISK_WRITE		; 003H
  8943 00002837 [742A0000]          <1> 	dd	DISK_VERF		; 004H
  8944 0000283B [8C2A0000]          <1> 	dd	FMT_TRK 		; 005H
  8945 0000283F [D6290000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  8946 00002843 [D6290000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  8947 00002847 [D6290000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  8948 0000284B [4D2B0000]          <1> 	dd	INIT_DRV		; 009H
  8949 0000284F [AC2B0000]          <1> 	dd	RD_LONG 		; 00AH
  8950 00002853 [B52B0000]          <1> 	dd	WR_LONG 		; 00BH
  8951 00002857 [BE2B0000]          <1> 	dd	DISK_SEEK		; 00CH
  8952 0000285B [E0290000]          <1> 	dd	DISK_RESET		; 00DH
  8953 0000285F [D6290000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  8954 00002863 [D6290000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  8955 00002867 [E62B0000]          <1> 	dd	TST_RDY 		; 010H
  8956 0000286B [0A2C0000]          <1> 	dd	HDISK_RECAL		; 011H
  8957 0000286F [D6290000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  8958 00002873 [D6290000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  8959 00002877 [402C0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  8960                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  8961 0000287B [D6290000]          <1> 	dd	BAD_COMMAND		; 015h
  8962 0000287F [D6290000]          <1> 	dd	BAD_COMMAND		; 016h
  8963 00002883 [D6290000]          <1> 	dd	BAD_COMMAND		; 017h
  8964 00002887 [D6290000]          <1> 	dd	BAD_COMMAND		; 018h
  8965 0000288B [D6290000]          <1> 	dd	BAD_COMMAND		; 019h
  8966 0000288F [D6290000]          <1> 	dd	BAD_COMMAND		; 01Ah
  8967 00002893 [622A0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  8968 00002897 [6B2A0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  8969                              <1> M1L     EQU    $-M1
  8970                              <1> 
  8971                              <1> DISK_IO_CONT:
  8972                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  8973 0000289B 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  8974                              <1> 	;;JNZ	short SU0
  8975                              <1>         ;;JMP	RETURN_STATUS
  8976                              <1> 	;je	RETURN_STATUS
  8977                              <1> 	; 05/12/2021
  8978 0000289E 7505                <1> 	jne	short SU0
  8979 000028A0 E9B0010000          <1> 	jmp	RETURN_STATUS
  8980                              <1> SU0:
  8981 000028A5 C605[4F700000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  8982                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  8983                              <1> 	;mov	si, bx ;; 14/02/2015
  8984 000028AC 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  8985 000028AE 8A1D[50700000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  8986                              <1> 	;; 04/01/2015
  8987                              <1> 	;;PUSH	AX
  8988 000028B4 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  8989                              <1> 					; (get drive number as 0 to 3)
  8990 000028B7 38D3                <1> 	CMP	BL,DL
  8991                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  8992                              <1>         ;jbe    BAD_COMMAND ;; 14/02/2015
  8993                              <1> 	; 05/12/2021
  8994 000028B9 7705                <1> 	ja	short su0_su1
  8995 000028BB E916010000          <1> 	jmp	BAD_COMMAND
  8996                              <1> su0_su1:
  8997                              <1>         ;;03/01/2015
  8998 000028C0 29DB                <1> 	sub	ebx, ebx
  8999 000028C2 88D3                <1> 	mov	bl, dl
  9000                              <1> 	;sub	bh, bh
  9001 000028C4 883D[64700000]      <1> 	mov	[LBAMode], bh 	; 0
  9002                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  9003                              <1> 	;test	byte [ebx+hd0_type], 1
  9004                              <1> 	;jz	short su1		; no
  9005                              <1> 	;inc	byte [LBAMode]
  9006                              <1> ;su1:
  9007                              <1> 	; 21/02/2015 (32 bit modification)
  9008                              <1> 	; 04/01/2015
  9009                              <1> 	;push	ax ; ***
  9010                              <1> 	; 05/12/2021
  9011 000028CA 50                  <1> 	push	eax ; ***
  9012                              <1> 	;PUSH	ES ; **
  9013                              <1> 	;PUSH	DX ; *
  9014                              <1> 	; 05/12/2021
  9015 000028CB 52                  <1> 	push	edx ; *
  9016                              <1> 	;push	ax
  9017 000028CC 50                  <1> 	push	eax
  9018 000028CD E849060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  9019                              <1> 	; 02/02/2015
  9020                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  9021 000028D2 668B4310            <1> 	mov	ax, [ebx+16]
  9022 000028D6 66A3[A46A0000]      <1> 	mov	[HF_PORT], ax
  9023                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  9024 000028DC 668B5312            <1> 	mov	dx, [ebx+18]
  9025 000028E0 668915[A66A0000]    <1> 	mov	[HF_REG_PORT], dx
  9026                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  9027 000028E7 8A4314              <1> 	mov	al, [ebx+20]
  9028                              <1> 	; 23/02/2015
  9029 000028EA A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  9030 000028EC 7406                <1> 	jz 	short su1
  9031 000028EE FE05[64700000]      <1> 	inc	byte [LBAMode] ; 1 
  9032                              <1> su1: 	 
  9033 000028F4 C0E804              <1> 	shr 	al, 4
  9034 000028F7 2401                <1> 	and	al, 1			
  9035 000028F9 A2[A86A0000]        <1> 	mov	[hf_m_s], al 
  9036                              <1> 	;
  9037                              <1> 	; 03/01/2015
  9038                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  9039 000028FE 8A4308              <1> 	mov	al, [ebx+8]
  9040                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  9041 00002901 EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  9042                              <1> 					; Control Byte:  (= 08h, here)
  9043                              <1> 					; bit 0 - 0
  9044                              <1> 					; bit 1 - nIEN (1 = disable irq)
  9045                              <1> 					; bit 2 - SRST (software RESET)
  9046                              <1> 					; bit 3 - use extra heads (8 to 15)
  9047                              <1> 					;         -always set to 1-	
  9048                              <1> 					; (bits 3 to 7 are reserved
  9049                              <1> 					;          for ATA devices)
  9050 00002902 8A25[51700000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  9051 00002908 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  9052 0000290B 08C4                <1> 	OR	AH,AL
  9053 0000290D 8825[51700000]      <1> 	MOV	[CONTROL_BYTE],AH	
  9054                              <1> 	; 04/01/2015
  9055                              <1> 	;pop	ax
  9056                              <1> 	; 05/12/2021
  9057 00002913 58                  <1> 	pop	eax
  9058                              <1> 	;pop	dx ; * ;; 14/02/2015
  9059                              <1> 	; 05/12/2021
  9060 00002914 5A                  <1> 	pop	edx ; *
  9061 00002915 20E4                <1> 	and	ah, ah	; Reset function ?
  9062 00002917 7506                <1> 	jnz	short su2
  9063                              <1> 	;;pop	dx ; * ;; 14/02/2015
  9064                              <1> 	;pop	es ; **
  9065                              <1> 	;pop	ax ; ***
  9066                              <1> 	; 05/12/2021
  9067 00002919 58                  <1> 	pop	eax ; ***	
  9068                              <1> 	;;pop	bx
  9069 0000291A E9C1000000          <1>         jmp     DISK_RESET
  9070                              <1> su2:
  9071 0000291F 803D[64700000]00    <1> 	cmp	byte [LBAMode], 0
  9072 00002926 765E                <1> 	jna	short su3
  9073                              <1> 	;
  9074                              <1> 	; 02/02/2015 (LBA read/write function calls)
  9075 00002928 80FC1B              <1> 	cmp	ah, 1Bh
  9076 0000292B 720B                <1> 	jb	short lbarw1
  9077 0000292D 80FC1C              <1> 	cmp	ah, 1Ch
  9078 00002930 7759                <1> 	ja 	short invldfnc
  9079                              <1> 	;;pop	dx ; * ; 14/02/2015
  9080                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  9081 00002932 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  9082                              <1> 	;; 14/02/2015
  9083 00002934 88D1                <1> 	mov	cl, dl ; 14/02/2015
  9084                              <1> 	;;mov	dx, bx
  9085                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  9086                              <1> 	;;mov	bx, di
  9087                              <1> 	;mov	si, di ; Buffer offset
  9088 00002936 EB2E                <1> 	jmp	short lbarw2
  9089                              <1> lbarw1:
  9090                              <1> 	; convert CHS to LBA
  9091                              <1> 	;
  9092                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  9093                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  9094                              <1> 	;	+ Sector - 1
  9095                              <1> 	;push	dx ; * ;; 14/02/2015
  9096                              <1> 	; 05/12/2021
  9097 00002938 52                  <1> 	push	edx ; *
  9098                              <1> 	;xor	dh, dh
  9099 00002939 31D2                <1> 	xor	edx, edx
  9100                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  9101 0000293B 8A530E              <1> 	mov	dl, [ebx+14]
  9102                              <1> 	;xor	ah, ah
  9103 0000293E 31C0                <1> 	xor	eax, eax
  9104                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  9105 00002940 8A4302              <1> 	mov	al, [ebx+2]
  9106 00002943 FEC8                <1> 	dec	al
  9107                              <1> 	;inc	ax		; 0 =  256
  9108 00002945 40                  <1> 	inc	eax ; 05/12/2021
  9109 00002946 66F7E2              <1> 	mul 	dx
  9110                              <1> 		; AX = # of Heads" * Sectors/Track
  9111 00002949 6689CA              <1> 	mov	dx, cx
  9112                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  9113 0000294C 83E13F              <1> 	and	ecx, 3fh
  9114 0000294F 86D6                <1> 	xchg	dl, dh
  9115 00002951 C0EE06              <1> 	shr	dh, 6
  9116                              <1> 		; DX = cylinder (0 to 1023)
  9117                              <1> 	;mul 	dx
  9118                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  9119 00002954 F7E2                <1> 	mul	edx
  9120 00002956 FEC9                <1> 	dec	cl  ; sector - 1
  9121                              <1> 	;add	ax, cx
  9122                              <1> 	;adc	dx, 0
  9123                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  9124 00002958 01C8                <1> 	add	eax, ecx
  9125                              <1> 	;pop	cx ; * ; ch = head, cl = drive number (zero based)
  9126                              <1> 	; 05/12/2021
  9127 0000295A 59                  <1> 	pop	ecx ; * ; ch = head, cl = drive number (zero based)
  9128                              <1> 	;push	dx
  9129                              <1> 	;push	ax
  9130 0000295B 50                  <1> 	push	eax
  9131                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  9132 0000295C 8A430E              <1> 	mov	al, [ebx+14]
  9133 0000295F F6E5                <1> 	mul	ch
  9134                              <1> 		; AX = Head * Sectors/Track
  9135 00002961 6699                <1>         cwd
  9136                              <1> 	;pop	dx
  9137 00002963 5A                  <1> 	pop	edx
  9138                              <1> 	;add	ax, dx
  9139                              <1> 	;pop	dx
  9140                              <1> 	;adc	dx, 0 ; add carry bit
  9141 00002964 01D0                <1> 	add	eax, edx
  9142                              <1> lbarw2:
  9143 00002966 29D2                <1> 	sub	edx, edx ; 21/02/2015
  9144 00002968 88CA                <1> 	mov	dl, cl ; 21/02/2015
  9145 0000296A C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  9146                              <1> 				; NOTE: Features register (1F1h, 171h)
  9147                              <1> 				; is not used for ATA device R/W functions. 
  9148                              <1> 				; It is old/obsolete 'write precompensation'
  9149                              <1> 				; register and error register
  9150                              <1> 				; for old ATA/IDE devices.
  9151                              <1> 	; 18/01/2014
  9152                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  9153 0000296E 8A0D[A86A0000]      <1> 	mov	cl, [hf_m_s]
  9154                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  9155                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  9156                              <1> 				; bit 6 = 1 = LBA mode
  9157                              <1> 				; bit 7 = 1
  9158 00002974 80C90E              <1> 	or	cl, 0Eh ; 1110b
  9159                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  9160 00002977 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  9161 0000297C C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  9162                              <1> 	;or	dh, ch
  9163 0000297F 09C8                <1> 	or	eax, ecx	
  9164                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  9165                              <1> 				  ; (Sector Number Register)
  9166                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  9167                              <1> 				  ; (Cylinder Low Register)
  9168                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  9169                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  9170                              <1> 				  ; (Cylinder High Register)
  9171                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  9172                              <1> 				  ; (Drive/Head Register)
  9173                              <1> 	
  9174                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  9175 00002981 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  9176                              <1> 	;14/02/2015
  9177                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  9178 00002984 EB37                <1> 	jmp	short su4
  9179                              <1> su3:
  9180                              <1> 	; 02/02/2015 
  9181                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  9182 00002986 80FC14              <1> 	cmp 	ah, 14h
  9183 00002989 7603                <1> 	jna 	short chsfnc
  9184                              <1> invldfnc:
  9185                              <1>         ; 14/02/2015  
  9186                              <1> 	;pop	es ; **
  9187                              <1>         ;pop	ax ; ***
  9188                              <1>         ; 05/12/2021
  9189 0000298B 58                  <1> 	pop	eax ; ***
  9190                              <1> 	;jmp	short BAD_COMMAND_POP
  9191 0000298C EB48                <1>         jmp     short BAD_COMMAND
  9192                              <1> chsfnc:	
  9193                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  9194 0000298E 668B4305            <1> 	mov	ax, [ebx+5]
  9195 00002992 66C1E802            <1> 	SHR	AX,2
  9196 00002996 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  9197                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  9198                              <1> 	;;PUSH	DX
  9199                              <1> 	;;MOV	DX,[HF_REG_PORT]
  9200                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  9201                              <1> 	;;POP	DX ; * 
  9202                              <1> 	;;POP	ES ; **
  9203                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  9204                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  9205                              <1> 	;;OR	AH,AL
  9206                              <1> 	;;MOV	[CONTROL_BYTE],AH
  9207                              <1> 	;
  9208 00002999 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  9209 0000299B 243F                <1> 	AND	AL,3FH
  9210 0000299D 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  9211 000029A0 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  9212 000029A3 88C8                <1> 	MOV	AL,CL
  9213 000029A5 C0E806              <1> 	SHR	AL,6
  9214 000029A8 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  9215                              <1> 	;;05/01/2015
  9216                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  9217 000029AB A0[A86A0000]        <1> 	mov	al, [hf_m_s]
  9218 000029B0 C0E004              <1> 	SHL	AL,4
  9219 000029B3 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  9220 000029B6 08F0                <1> 	OR	AL,DH
  9221                              <1> 	;OR	AL,80H or 20H
  9222 000029B8 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  9223 000029BA 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  9224                              <1> su4:
  9225                              <1> 	;POP	ES ; **
  9226                              <1>         ;; 14/02/2015
  9227                              <1>         ;;POP   AX
  9228                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  9229                              <1>         ;;PUSH  AX
  9230                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  9231                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  9232                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  9233                              <1> 	;pop     ax ; ***
  9234                              <1> 	; 05/12/2021
  9235 000029BD 58                  <1> 	pop	eax ; ***
  9236 000029BE 8845F9              <1> 	mov     [CMD_BLOCK+1], al
  9237 000029C1 29DB                <1>         sub	ebx, ebx
  9238 000029C3 88E3                <1> 	mov     bl, ah
  9239                              <1>         ;xor	bh, bh
  9240                              <1>         ;sal	bx, 1
  9241 000029C5 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  9242                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  9243                              <1>         ;;CMP   AX,M1L                  ; TEST WITHIN RANGE
  9244                              <1>         ;;JNB   short BAD_COMMAND_POP
  9245                              <1>         ;cmp	bx, M1L
  9246 000029C9 83FB74              <1> 	cmp	ebx, M1L
  9247 000029CC 7308                <1> 	jnb	short BAD_COMMAND
  9248                              <1>         ;xchg	bx, si
  9249 000029CE 87DE                <1>         xchg	ebx, esi
  9250                              <1> 	;;;POP	AX			; RESTORE AX
  9251                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  9252                              <1> 	
  9253                              <1> 	;;PUSH	CX
  9254                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  9255                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  9256                              <1> 	;SHR	CX,4
  9257                              <1> 	;MOV	AX,ES
  9258                              <1> 	;ADD	AX,CX
  9259                              <1> 	;MOV	ES,AX
  9260                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  9261                              <1> 	;;POP	AX
  9262                              <1> 	;;POP	CX
  9263                              <1> 	;;JMP	word [CS:SI+M1]
  9264                              <1> 	;jmp	word [SI+M1]
  9265 000029D0 FFA6[27280000]      <1> 	jmp	dword [esi+M1]
  9266                              <1> ;;BAD_COMMAND_POP:
  9267                              <1> ;;	POP	AX
  9268                              <1> ;;	POP	BX
  9269                              <1> BAD_COMMAND:
  9270 000029D6 C605[4F700000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  9271 000029DD B000                <1> 	MOV	AL,0
  9272 000029DF C3                  <1> 	RETn
  9273                              <1> 
  9274                              <1> ;----------------------------------------
  9275                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  9276                              <1> ;----------------------------------------
  9277                              <1> 
  9278                              <1> ; 18-1-2015 : one controller reset (not other one)
  9279                              <1> 
  9280                              <1> DISK_RESET:
  9281 000029E0 FA                  <1> 	CLI
  9282 000029E1 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  9283                              <1> 	;JMP	$+2
  9284                              <1> 	IODELAY
  9285 000029E3 EB00                <2>  jmp short $+2
  9286 000029E5 EB00                <2>  jmp short $+2
  9287                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  9288 000029E7 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  9289 000029E9 E6A1                <1> 	OUT	INTB01,AL
  9290 000029EB FB                  <1> 	STI				; START INTERRUPTS
  9291                              <1> 	; 14/02/2015
  9292                              <1> 	;mov	di, dx
  9293                              <1> 	; 05/12/2021
  9294 000029EC 89D7                <1> 	mov	edi, edx	
  9295                              <1> 	; 04/01/2015
  9296                              <1> 	;xor	di,di
  9297                              <1> drst0:
  9298 000029EE B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  9299                              <1> 	;MOV	DX,HF_REG_PORT
  9300 000029F0 668B15[A66A0000]    <1> 	MOV	DX,[HF_REG_PORT]
  9301 000029F7 EE                  <1> 	OUT	DX,AL			; RESET
  9302                              <1> ;	MOV	CX,10			; DELAY COUNT
  9303                              <1> ;DRD:	DEC	CX
  9304                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  9305                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  9306 000029F8 B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  9307 000029FD E8CDEBFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  9308                              <1>                                         ; 40 micro seconds)
  9309 00002A02 A0[51700000]        <1> 	mov	al,[CONTROL_BYTE]
  9310 00002A07 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  9311 00002A09 EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  9312 00002A0A E807040000          <1> 	CALL	NOT_BUSY
  9313 00002A0F 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  9314 00002A11 668B15[A46A0000]    <1> 	MOV	DX,[HF_PORT]
  9315 00002A18 FEC2                <1> 	inc	dl  ; HF_PORT+1
  9316                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  9317                              <1>         ;mov	cl, 10
  9318 00002A1A B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  9319                              <1> drst1:
  9320 00002A1F EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  9321 00002A20 3C01                <1> 	CMP	AL,1
  9322                              <1> 	; 04/01/2015
  9323 00002A22 740A                <1> 	jz	short drst2
  9324                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  9325                              <1>         	; Drive/Head Register - bit 4
  9326 00002A24 E2F9                <1> 	loop	drst1
  9327                              <1> DRERR:	
  9328 00002A26 C605[4F700000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  9329 00002A2D C3                  <1> 	RETn
  9330                              <1> drst2:
  9331                              <1> 	; 14/02/2015
  9332                              <1> 	;mov	dx, di
  9333                              <1> 	; 05/12/2021
  9334 00002A2E 89FA                <1> 	mov	edx, edi
  9335                              <1> ;drst3:
  9336                              <1> ;	; 05/01/2015
  9337                              <1> ;	shl 	di,1
  9338                              <1> ;	; 04/01/2015
  9339                              <1> ;	mov	ax,[di+hd_cports]
  9340                              <1> ;	cmp	ax,[HF_REG_PORT]
  9341                              <1> ;	je	short drst4
  9342                              <1> ;	mov	[HF_REG_PORT], ax
  9343                              <1> ;	; 03/01/2015
  9344                              <1> ;	mov	ax,[di+hd_ports]
  9345                              <1> ;       mov     [HF_PORT], ax
  9346                              <1> ;	; 05/01/2014
  9347                              <1> ;	shr	di,1
  9348                              <1> ;	; 04/01/2015
  9349                              <1> ;	jmp	short drst0	; reset other controller
  9350                              <1> ;drst4:
  9351                              <1> ;	; 05/01/2015
  9352                              <1> ;	shr	di,1
  9353                              <1> ;	mov	al,[di+hd_dregs]
  9354                              <1> ;	and	al,10h ; bit 4 only
  9355                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  9356                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  9357                              <1> 	;
  9358 00002A30 A0[A86A0000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  9359 00002A35 A801                <1> 	test	al,1
  9360                              <1> ;	jnz	short drst6
  9361 00002A37 7516                <1>         jnz     short drst4
  9362 00002A39 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  9363                              <1> ;drst5:
  9364                              <1> drst3:
  9365 00002A3D E80B010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  9366                              <1> 	;mov	dx,di
  9367 00002A42 E8C3010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  9368                              <1> 	; 04/01/2014
  9369                              <1> ;	inc	di
  9370                              <1> ;	mov	dx,di
  9371                              <1> ;	cmp	dl,[HF_NUM]
  9372                              <1> ;	jb	short drst3
  9373                              <1> ;DRE:
  9374 00002A47 C605[4F700000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  9375 00002A4E C3                  <1> 	RETn
  9376                              <1> ;drst6:
  9377                              <1> drst4:		; Drive/Head Register - bit 4
  9378 00002A4F 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  9379                              <1>         ;jmp    short drst5
  9380 00002A53 EBE8                <1>         jmp     short drst3
  9381                              <1> 
  9382                              <1> ;----------------------------------------
  9383                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  9384                              <1> ;----------------------------------------
  9385                              <1> 
  9386                              <1> RETURN_STATUS:
  9387 00002A55 A0[4F700000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  9388 00002A5A C605[4F700000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  9389 00002A61 C3                  <1> 	RETn
  9390                              <1> 
  9391                              <1> ;----------------------------------------
  9392                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  9393                              <1> ;----------------------------------------
  9394                              <1> 
  9395                              <1> DISK_READ:
  9396 00002A62 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  9397 00002A66 E92A020000          <1>         JMP     COMMANDI
  9398                              <1> 
  9399                              <1> ;----------------------------------------
  9400                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  9401                              <1> ;----------------------------------------
  9402                              <1> 
  9403                              <1> DISK_WRITE:
  9404 00002A6B C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  9405 00002A6F E976020000          <1>         JMP     COMMANDO
  9406                              <1> 
  9407                              <1> ;----------------------------------------
  9408                              <1> ;	DISK VERIFY	     (AH = 04H) :
  9409                              <1> ;----------------------------------------
  9410                              <1> 
  9411                              <1> DISK_VERF:
  9412 00002A74 C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  9413 00002A78 E8E4020000          <1> 	CALL	COMMAND
  9414 00002A7D 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  9415 00002A7F E856030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  9416 00002A84 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  9417 00002A86 E8E3030000          <1> 	CALL	CHECK_STATUS
  9418                              <1> VERF_EXIT:
  9419 00002A8B C3                  <1> 	RETn
  9420                              <1> 
  9421                              <1> ;----------------------------------------
  9422                              <1> ;	FORMATTING	     (AH = 05H) :
  9423                              <1> ;----------------------------------------
  9424                              <1> 
  9425                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  9426 00002A8C C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  9427                              <1> 	;PUSH	ES
  9428                              <1> 	;PUSH	BX
  9429 00002A90 53                  <1> 	push	ebx
  9430 00002A91 E885040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  9431                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  9432 00002A96 8A430E              <1> 	mov	al, [ebx+14]
  9433 00002A99 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  9434 00002A9C 5B                  <1> 	pop	ebx
  9435                              <1> 	;POP	BX
  9436                              <1> 	;POP	ES
  9437 00002A9D E94F020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  9438                              <1> 
  9439                              <1> ;----------------------------------------
  9440                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  9441                              <1> ;----------------------------------------
  9442                              <1> 
  9443                              <1> READ_DASD_TYPE:
  9444                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  9445 00002AA2 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9446                              <1> 	;PUSH	ES
  9447 00002AA3 53                  <1> 	PUSH	eBX
  9448                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  9449                              <1> 	;push	cs
  9450                              <1> 	;pop	ds
  9451 00002AA4 66BB1000            <1>         mov	bx, KDATA
  9452 00002AA8 8EDB                <1> 	mov	ds, bx
  9453                              <1> 	;mov	es, bx
  9454 00002AAA C605[4F700000]00    <1> 	MOV     byte [DISK_STATUS1],0
  9455 00002AB1 8A1D[50700000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  9456 00002AB7 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  9457 00002ABA 38D3                <1> 	CMP	BL,DL
  9458 00002ABC 7625                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  9459 00002ABE E858040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  9460                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  9461 00002AC3 8A4302              <1> 	mov	al, [ebx+2]
  9462                              <1> 	;MOV	CL,[ES:BX+14]
  9463 00002AC6 8A4B0E              <1> 	mov	cl, [ebx+14]
  9464 00002AC9 F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  9465                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  9466 00002ACB 668B0B              <1> 	mov	cx, [ebx]
  9467                              <1> 	;
  9468                              <1> 	; 02/01/2015 
  9469                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  9470                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  9471 00002ACE 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  9472                              <1> 	;
  9473 00002AD0 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  9474 00002AD3 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  9475 00002AD6 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  9476                              <1> 	;SUB	AX,AX
  9477 00002AD9 28C0                <1> 	sub	al, al
  9478 00002ADB B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  9479 00002ADD 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  9480                              <1> 	;POP	ES
  9481 00002ADE 1F                  <1> 	POP	DS
  9482 00002ADF F8                  <1> 	CLC				; CLEAR CARRY
  9483                              <1> 	;RETf	2
  9484 00002AE0 CA0400              <1> 	retf	4
  9485                              <1> RDT_NOT_PRESENT:
  9486                              <1> 	;SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  9487                              <1> 	; 05/12/2021
  9488 00002AE3 29C0                <1> 	sub	eax, eax
  9489                              <1> 	;MOV	CX,AX			; ZERO BLOCK COUNT
  9490                              <1> 	;MOV	DX,AX
  9491 00002AE5 89C1                <1> 	mov	ecx, eax
  9492 00002AE7 89C2                <1> 	mov	edx, eax
  9493 00002AE9 EBF2                <1> 	JMP	short RDT2
  9494                              <1> 
  9495                              <1> ;----------------------------------------
  9496                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  9497                              <1> ;----------------------------------------
  9498                              <1> 
  9499                              <1> GET_PARM_N:
  9500                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  9501 00002AEB 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  9502                              <1> 	;PUSH	ES
  9503 00002AEC 53                  <1> 	PUSH	eBX
  9504                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  9505                              <1> 	;MOV	DS,AX
  9506                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  9507                              <1> 	;JZ	short G0
  9508                              <1> 	;LES	BX,@HF1_TBL_VEC
  9509                              <1> 	;JMP	SHORT G1
  9510                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  9511                              <1> ;G1:
  9512                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  9513                              <1> 	; 22/12/2014
  9514                              <1> 	;push	cs
  9515                              <1> 	;pop	ds
  9516 00002AED 66BB1000            <1> 	mov	bx, KDATA
  9517 00002AF1 8EDB                <1> 	mov	ds, bx
  9518                              <1> 	;mov	es, bx
  9519                              <1> 	;
  9520 00002AF3 80EA80              <1> 	SUB	DL,80H
  9521 00002AF6 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  9522 00002AF9 7340                <1> 	JAE	short G4
  9523                              <1> 	;
  9524 00002AFB 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  9525                              <1> 	; 22/12/2014
  9526 00002AFD 88D3                <1> 	mov	bl, dl
  9527                              <1> 	;xor	bh, bh  
  9528 00002AFF C0E302              <1> 	shl	bl, 2			; convert index to offset
  9529                              <1> 	;add	bx, HF_TBL_VEC
  9530 00002B02 81C3[54700000]      <1> 	add	ebx, HF_TBL_VEC
  9531                              <1> 	;mov	ax, [bx+2]
  9532                              <1> 	;mov	es, ax			; dpt segment
  9533                              <1> 	;mov	bx, [bx]		; dpt offset
  9534 00002B08 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  9535                              <1> 
  9536 00002B0A C605[4F700000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9537                              <1>         ;MOV     AX,[ES:BX]              ; MAX NUMBER OF CYLINDERS
  9538 00002B11 668B03              <1> 	mov	ax, [ebx]
  9539                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  9540 00002B14 6648                <1> 	dec	ax			; max. cylinder number
  9541 00002B16 88C5                <1> 	MOV	CH,AL
  9542 00002B18 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  9543 00002B1C 66D1E8              <1> 	SHR	AX,1
  9544 00002B1F 66D1E8              <1> 	SHR	AX,1
  9545                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  9546 00002B22 0A430E              <1> 	or	al, [ebx+14]
  9547 00002B25 88C1                <1> 	MOV	CL,AL
  9548                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  9549 00002B27 8A7302              <1> 	mov	dh, [ebx+2]
  9550 00002B2A FECE                <1> 	DEC	DH			; 0-N RANGE
  9551 00002B2C 8A15[50700000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  9552                              <1> 	;SUB	AX,AX
  9553                              <1> 	; 05/12/2021
  9554 00002B32 29C0                <1> 	sub	eax, eax
  9555                              <1> 	; 27/12/2014 
  9556                              <1> 	; ES:DI = Address of disk parameter table from BIOS
  9557                              <1> 	; (Programmer's Guide to the AMIBIOS - 1993)
  9558                              <1> 	;mov	di, bx			; HDPT offset
  9559 00002B34 89DF                <1> 	mov	edi, ebx
  9560                              <1> G5:
  9561 00002B36 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  9562                              <1> 	;POP	ES
  9563 00002B37 1F                  <1> 	POP	DS
  9564                              <1> 	;RETf	2
  9565 00002B38 CA0400              <1> 	retf	4
  9566                              <1> G4:
  9567 00002B3B C605[4F700000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  9568                              <1> 	; 05/12/2021
  9569 00002B42 29C0                <1> 	sub	eax, eax
  9570 00002B44 B407                <1> 	MOV	AH,INIT_FAIL
  9571                              <1> 	;SUB	AL,AL
  9572                              <1> 	;SUB	DX,DX
  9573 00002B46 29D2                <1> 	sub	edx, edx
  9574                              <1> 	;SUB	CX,CX
  9575 00002B48 29C9                <1> 	sub	ecx, ecx
  9576 00002B4A F9                  <1> 	STC				; SET ERROR FLAG
  9577 00002B4B EBE9                <1> 	JMP	short G5
  9578                              <1> 
  9579                              <1> ;----------------------------------------
  9580                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  9581                              <1> ;----------------------------------------
  9582                              <1> 	; 03/01/2015
  9583                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  9584                              <1> 	; logical sector per logical track
  9585                              <1> 	; and logical heads - 1 would be set but
  9586                              <1> 	; it is seen as it will be good
  9587                              <1> 	; if physical parameters will be set here
  9588                              <1> 	; because, number of heads <= 16.
  9589                              <1> 	; (logical heads usually more than 16)
  9590                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  9591                              <1> 	;	== INT 13h physical parameters
  9592                              <1> 
  9593                              <1> ;INIT_DRV:
  9594                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  9595                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  9596                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  9597                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  9598                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  9599                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  9600                              <1> ;	OR	AH,AL			; TO MAX HEAD
  9601                              <1> ;	MOV	[CMD_BLOCK+5],AH
  9602                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  9603                              <1> ;	MOV	[CMD_BLOCK+1],AL
  9604                              <1> ;	SUB	AX,AX
  9605                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  9606                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  9607                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  9608                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  9609                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  9610                              <1> ;	CALL	CHECK_STATUS
  9611                              <1> ;INIT_EXIT:
  9612                              <1> ;	RETn
  9613                              <1> 
  9614                              <1> ; 04/01/2015
  9615                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  9616                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  9617                              <1> INIT_DRV:
  9618                              <1> 	;xor	ah,ah
  9619 00002B4D 31C0                <1> 	xor	eax,eax ; 21/02/2015
  9620 00002B4F B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  9621 00002B51 3825[64700000]      <1>         cmp     [LBAMode], ah   ; 0
  9622 00002B57 7702                <1> 	ja	short idrv0
  9623 00002B59 B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  9624                              <1> idrv0:
  9625                              <1> 	; DL = drive number (0 based)
  9626 00002B5B E8BB030000          <1> 	call	GET_VEC
  9627                              <1> 	;push	bx
  9628 00002B60 53                  <1> 	push	ebx ; 21/02/2015
  9629                              <1> 	;add	bx,ax
  9630 00002B61 01C3                <1> 	add	ebx,eax
  9631                              <1> 	;; 05/01/2015
  9632 00002B63 8A25[A86A0000]      <1> 	mov	ah,[hf_m_s] ; drive number (0= master, 1= slave)
  9633                              <1> 	;;and 	ah,1 
  9634 00002B69 C0E404              <1> 	shl	ah,4
  9635 00002B6C 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  9636                              <1> 	;mov	al,[es:bx]
  9637 00002B6F 8A03                <1> 	mov	al,[ebx] ; 21/02/2015
  9638 00002B71 FEC8                <1> 	dec	al	 ; last head number 
  9639                              <1> 	;and	al,0Fh
  9640 00002B73 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  9641                              <1> 	;
  9642 00002B75 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  9643 00002B79 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  9644                              <1> 	;pop	bx
  9645 00002B7C 5B                  <1> 	pop	ebx
  9646 00002B7D 29C0                <1> 	sub	eax,eax ; 21/02/2015
  9647 00002B7F B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  9648 00002B81 803D[64700000]00    <1> 	cmp	byte [LBAMode],0
  9649 00002B88 7702                <1> 	ja	short idrv1
  9650 00002B8A B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  9651                              <1> idrv1:
  9652                              <1> 	;xor	ah,ah
  9653                              <1> 	;add	bx,ax
  9654 00002B8C 01C3                <1> 	add	ebx,eax ; 21/02/2015
  9655                              <1> 	;mov	al,[es:bx]
  9656                              <1> 			; sector number
  9657 00002B8E 8A03                <1> 	mov	al,[ebx]
  9658 00002B90 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  9659 00002B93 28C0                <1> 	sub	al,al
  9660 00002B95 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  9661 00002B98 E8C4010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  9662 00002B9D 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  9663 00002B9F E872020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  9664 00002BA4 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  9665 00002BA6 E8C3020000          <1> 	call	CHECK_STATUS
  9666                              <1> INIT_EXIT:
  9667 00002BAB C3                  <1> 	RETn
  9668                              <1> 
  9669                              <1> ;----------------------------------------
  9670                              <1> ;	READ LONG	     (AH = 0AH) :
  9671                              <1> ;----------------------------------------
  9672                              <1> 
  9673                              <1> RD_LONG:
  9674                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  9675 00002BAC C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  9676 00002BB0 E9E0000000          <1>         JMP     COMMANDI
  9677                              <1> 
  9678                              <1> ;----------------------------------------
  9679                              <1> ;	WRITE LONG	     (AH = 0BH) :
  9680                              <1> ;----------------------------------------
  9681                              <1> 
  9682                              <1> WR_LONG:
  9683                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  9684 00002BB5 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  9685 00002BB9 E92C010000          <1>         JMP     COMMANDO
  9686                              <1> 
  9687                              <1> ;----------------------------------------
  9688                              <1> ;	SEEK		     (AH = 0CH) :
  9689                              <1> ;----------------------------------------
  9690                              <1> 
  9691                              <1> DISK_SEEK:
  9692 00002BBE C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  9693 00002BC2 E89A010000          <1> 	CALL	COMMAND
  9694 00002BC7 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  9695 00002BC9 E80C020000          <1> 	CALL	_WAIT
  9696 00002BCE 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  9697 00002BD0 E899020000          <1> 	CALL	CHECK_STATUS
  9698 00002BD5 803D[4F700000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  9699 00002BDC 7507                <1> 	JNE	short DS_EXIT
  9700 00002BDE C605[4F700000]00    <1>         MOV     byte [DISK_STATUS1],0
  9701                              <1> DS_EXIT:
  9702 00002BE5 C3                  <1> 	RETn
  9703                              <1> 
  9704                              <1> ;----------------------------------------
  9705                              <1> ;	TEST DISK READY      (AH = 10H) :
  9706                              <1> ;----------------------------------------
  9707                              <1> 
  9708                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  9709 00002BE6 E82B020000          <1> 	CALL	NOT_BUSY
  9710 00002BEB 751C                <1> 	JNZ	short TR_EX
  9711 00002BED 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  9712 00002BF0 668B15[A46A0000]    <1> 	MOV	DX,[HF_PORT]
  9713 00002BF7 80C206              <1> 	add	dl,6
  9714 00002BFA EE                  <1> 	OUT	DX,AL
  9715 00002BFB E886020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  9716 00002C00 7507                <1> 	JNZ	short TR_EX
  9717 00002C02 C605[4F700000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  9718                              <1> TR_EX:	
  9719 00002C09 C3                  <1> 	RETn
  9720                              <1> 
  9721                              <1> ;----------------------------------------
  9722                              <1> ;	RECALIBRATE	     (AH = 11H) :
  9723                              <1> ;----------------------------------------
  9724                              <1> 
  9725                              <1> HDISK_RECAL:
  9726 00002C0A C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  9727 00002C0E E84E010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  9728 00002C13 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  9729 00002C15 E8C0010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  9730 00002C1A 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  9731 00002C1C E8B9010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  9732 00002C21 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  9733                              <1> RECAL_X:
  9734 00002C23 E846020000          <1> 	CALL	CHECK_STATUS
  9735 00002C28 803D[4F700000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  9736 00002C2F 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  9737 00002C31 C605[4F700000]00    <1> 	MOV	byte [DISK_STATUS1],0
  9738                              <1> RECAL_EXIT:
  9739 00002C38 803D[4F700000]00    <1>         CMP     byte [DISK_STATUS1],0
  9740 00002C3F C3                  <1> 	RETn
  9741                              <1> 
  9742                              <1> ;----------------------------------------
  9743                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  9744                              <1> ;----------------------------------------
  9745                              <1> 
  9746                              <1> CTLR_DIAGNOSTIC:
  9747 00002C40 FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  9748 00002C41 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9749                              <1> 	;AND	AL,0BFH
  9750 00002C43 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  9751                              <1> 	;JMP	$+2
  9752                              <1> 	IODELAY
  9753 00002C45 EB00                <2>  jmp short $+2
  9754 00002C47 EB00                <2>  jmp short $+2
  9755 00002C49 E6A1                <1> 	OUT	INTB01,AL
  9756                              <1> 	IODELAY
  9757 00002C4B EB00                <2>  jmp short $+2
  9758 00002C4D EB00                <2>  jmp short $+2
  9759 00002C4F E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9760 00002C51 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9761                              <1> 	;JMP	$+2
  9762                              <1> 	IODELAY
  9763 00002C53 EB00                <2>  jmp short $+2
  9764 00002C55 EB00                <2>  jmp short $+2
  9765 00002C57 E621                <1> 	OUT	INTA01,AL
  9766 00002C59 FB                  <1> 	STI
  9767 00002C5A E8B7010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  9768 00002C5F 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  9769                              <1> 	;MOV	DX, HF_PORT+7
  9770 00002C61 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
  9771 00002C68 80C207              <1> 	add	dl, 7
  9772 00002C6B B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  9773 00002C6D EE                  <1> 	OUT	DX,AL
  9774 00002C6E E8A3010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  9775 00002C73 B480                <1> 	MOV	AH,TIME_OUT
  9776 00002C75 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  9777                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  9778 00002C77 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
  9779 00002C7E FEC2                <1> 	inc	dl
  9780 00002C80 EC                  <1> 	IN	AL,DX
  9781 00002C81 A2[46700000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  9782 00002C86 B400                <1> 	MOV	AH,0
  9783 00002C88 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  9784 00002C8A 7402                <1> 	JE	SHORT CD_EXIT
  9785 00002C8C B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  9786                              <1> CD_EXIT:
  9787 00002C8E 8825[4F700000]      <1> 	MOV	[DISK_STATUS1],AH
  9788 00002C94 C3                  <1> 	RETn
  9789                              <1> 
  9790                              <1> ;----------------------------------------
  9791                              <1> ; COMMANDI				:
  9792                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  9793                              <1> ;	NSECTOR RETURNS ZERO		:
  9794                              <1> ;----------------------------------------
  9795                              <1> COMMANDI:
  9796 00002C95 E85A020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9797 00002C9A 724D                <1> 	JC	short CMD_ABORT
  9798                              <1> 	;MOV	DI,BX
  9799 00002C9C 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  9800 00002C9E E8BE000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9801 00002CA3 7544                <1> 	JNZ	short CMD_ABORT
  9802                              <1> CMD_I1:
  9803 00002CA5 E830010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  9804 00002CAA 753D                <1> 	JNZ	short TM_OUT		; TIME OUT
  9805                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  9806 00002CAC B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  9807                              <1> 	;MOV	DX,HF_PORT
  9808 00002CB1 668B15[A46A0000]    <1> 	mov	dx,[HF_PORT]
  9809 00002CB8 FA                  <1> 	CLI
  9810 00002CB9 FC                  <1> 	CLD
  9811 00002CBA F3666D              <1> 	REP	INSW			; GET THE SECTOR
  9812 00002CBD FB                  <1> 	STI
  9813 00002CBE F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  9814 00002CC2 7419                <1> 	JZ	CMD_I3
  9815 00002CC4 E87A010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9816 00002CC9 721E                <1> 	JC	short TM_OUT
  9817                              <1> 	;MOV	DX,HF_PORT
  9818 00002CCB 668B15[A46A0000]    <1> 	mov	dx,[HF_PORT]
  9819                              <1> 	;MOV	CX,4			; GET ECC BYTES
  9820 00002CD2 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  9821 00002CD7 EC                  <1> CMD_I2: IN	AL,DX
  9822                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  9823 00002CD8 8807                <1> 	mov 	[edi], al ; 21/02/2015
  9824 00002CDA 47                  <1> 	INC	eDI
  9825 00002CDB E2FA                <1> 	LOOP	CMD_I2
  9826 00002CDD E88C010000          <1> CMD_I3: CALL	CHECK_STATUS
  9827 00002CE2 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  9828 00002CE4 FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  9829 00002CE7 75BC                <1> 	JNZ	SHORT CMD_I1
  9830                              <1> CMD_ABORT:
  9831 00002CE9 C3                  <1> TM_OUT: RETn
  9832                              <1> 
  9833                              <1> ;----------------------------------------
  9834                              <1> ; COMMANDO				:
  9835                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  9836                              <1> ;	NSECTOR RETURNS ZERO		:
  9837                              <1> ;----------------------------------------
  9838                              <1> COMMANDO:
  9839 00002CEA E805020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  9840 00002CEF 72F8                <1> 	JC	short CMD_ABORT
  9841 00002CF1 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  9842 00002CF3 E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  9843 00002CF8 75EF                <1> 	JNZ	short CMD_ABORT
  9844 00002CFA E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9845 00002CFF 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  9846                              <1> CMD_O1: ;PUSH	DS
  9847                              <1> 	;PUSH	ES			; MOVE ES TO DS
  9848                              <1> 	;POP	DS
  9849                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  9850                              <1> 	;MOV	DX,HF_PORT
  9851                              <1> 	; 01/02/2015
  9852 00002D01 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
  9853                              <1> 	;push	es
  9854                              <1> 	;pop	ds
  9855                              <1> 	;mov	cx, 256
  9856 00002D08 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  9857 00002D0D FA                  <1> 	CLI
  9858 00002D0E FC                  <1> 	CLD
  9859 00002D0F F3666F              <1> 	REP	OUTSW
  9860 00002D12 FB                  <1> 	STI
  9861                              <1> 	;POP	DS			; RESTORE DS
  9862 00002D13 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  9863 00002D17 7419                <1> 	JZ	short CMD_O3
  9864 00002D19 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  9865 00002D1E 72C9                <1> 	JC	short TM_OUT
  9866                              <1> 	;MOV	DX,HF_PORT
  9867 00002D20 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
  9868                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  9869 00002D27 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  9870                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  9871 00002D2C 8A06                <1> 	mov	al, [esi]
  9872 00002D2E EE                  <1> 	OUT	DX,AL
  9873 00002D2F 46                  <1> 	INC	eSI
  9874 00002D30 E2FA                <1> 	LOOP	CMD_O2
  9875                              <1> CMD_O3:
  9876 00002D32 E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  9877 00002D37 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  9878 00002D39 E830010000          <1> 	CALL	CHECK_STATUS
  9879 00002D3E 75A9                <1> 	JNZ	short CMD_ABORT
  9880 00002D40 F605[45700000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  9881 00002D47 75B8                <1> 	JNZ	SHORT CMD_O1
  9882                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  9883 00002D49 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
  9884                              <1> 	;add	dl, 2
  9885 00002D50 FEC2                <1> 	inc	dl
  9886 00002D52 FEC2                <1> 	inc	dl
  9887 00002D54 EC                  <1> 	IN	AL,DX			;
  9888 00002D55 A8FF                <1> 	TEST	AL,0FFH 		;
  9889 00002D57 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  9890 00002D59 C605[4F700000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  9891                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  9892                              <1> CMD_O4:
  9893 00002D60 C3                  <1> 	RETn
  9894                              <1> 
  9895                              <1> ;--------------------------------------------------------
  9896                              <1> ; COMMAND						:
  9897                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  9898                              <1> ; OUTPUT						:
  9899                              <1> ;	BL = STATUS					:
  9900                              <1> ;	BH = ERROR REGISTER				:
  9901                              <1> ;--------------------------------------------------------
  9902                              <1> 
  9903                              <1> COMMAND:
  9904 00002D61 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  9905                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  9906                              <1> COMMAND1:
  9907                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  9908 00002D62 E87FFEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  9909                              <1> 	;;POP	CX
  9910 00002D67 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  9911 00002D69 803D[4F700000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  9912                              <1> 	;JZ	short CMD_TIMEOUT
  9913                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  9914                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  9915 00002D70 7507                <1> 	jne	short COMMAND4
  9916                              <1> CMD_TIMEOUT:
  9917 00002D72 C605[4F700000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9918                              <1> COMMAND4:
  9919 00002D79 5B                  <1> 	POP	eBX
  9920 00002D7A 803D[4F700000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  9921 00002D81 C3                  <1> 	RETn
  9922                              <1> COMMAND2:
  9923 00002D82 5B                  <1> 	POP	eBX
  9924 00002D83 57                  <1> 	PUSH	eDI
  9925 00002D84 C605[47700000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  9926 00002D8B FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  9927 00002D8C E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  9928                              <1> 	;AND	AL,0BFH
  9929 00002D8E 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  9930                              <1> 	;JMP	$+2
  9931                              <1> 	IODELAY
  9932 00002D90 EB00                <2>  jmp short $+2
  9933 00002D92 EB00                <2>  jmp short $+2
  9934 00002D94 E6A1                <1> 	OUT	INTB01,AL
  9935 00002D96 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  9936 00002D98 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  9937                              <1> 	;JMP	$+2
  9938                              <1> 	IODELAY
  9939 00002D9A EB00                <2>  jmp short $+2
  9940 00002D9C EB00                <2>  jmp short $+2
  9941 00002D9E E621                <1> 	OUT	INTA01,AL
  9942 00002DA0 FB                  <1> 	STI
  9943 00002DA1 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  9944                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  9945 00002DA3 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
  9946 00002DAA FEC2                <1> 	inc	dl
  9947 00002DAC F605[51700000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  9948 00002DB3 7411                <1> 	JZ	short COMMAND3
  9949 00002DB5 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  9950 00002DB8 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  9951 00002DBA 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  9952 00002DBC 7208                <1> 	JB	short COMMAND3
  9953 00002DBE 3C40                <1> 	CMP	AL,40H
  9954 00002DC0 7704                <1> 	JA	short COMMAND3
  9955 00002DC2 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  9956                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  9957                              <1> COMMAND3:
  9958 00002DC6 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  9959 00002DCA EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  9960                              <1> 	IODELAY
  9961 00002DCB EB00                <2>  jmp short $+2
  9962 00002DCD EB00                <2>  jmp short $+2
  9963 00002DCF 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  9964 00002DD0 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  9965 00002DD2 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  9966 00002DD6 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  9967 00002DD8 5F                  <1> 	POP	eDI
  9968 00002DD9 C3                  <1> 	RETn				; ZERO FLAG IS SET
  9969                              <1> 
  9970                              <1> ;CMD_TIMEOUT:
  9971                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  9972                              <1> ;COMMAND4:
  9973                              <1> ;	POP	BX
  9974                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  9975                              <1> ;	RETn
  9976                              <1> 
  9977                              <1> ;----------------------------------------
  9978                              <1> ;	WAIT FOR INTERRUPT		:
  9979                              <1> ;----------------------------------------
  9980                              <1> ;WAIT:
  9981                              <1> _WAIT:
  9982 00002DDA FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  9983                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  9984                              <1> 	;CLC
  9985                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  9986                              <1> 	;INT	15H
  9987                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  9988                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  9989                              <1> 
  9990                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  9991                              <1> 	;; 21/02/2015
  9992                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  9993                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  9994 00002DDB B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  9995                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  9996                              <1> ;-----	WAIT LOOP
  9997                              <1> 
  9998                              <1> WT1:	
  9999                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
 10000 00002DE0 F605[47700000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
 10001                              <1> 	;LOOPZ	WT1
 10002 00002DE7 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
 10003                              <1> 	;DEC	BL
 10004                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
 10005                              <1> 
 10006                              <1> WT1_hi:
 10007 00002DE9 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
 10008 00002DEB A810                <1> 	test	al, 10h			; transition on memory
 10009 00002DED 75FA                <1> 	jnz	short WT1_hi		; refresh.
 10010                              <1> WT1_lo:
 10011 00002DEF E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
 10012 00002DF1 A810                <1> 	test	al, 10h			
 10013 00002DF3 74FA                <1> 	jz	short WT1_lo
 10014 00002DF5 E2E9                <1> 	loop	WT1
 10015                              <1> 	;;or	bl, bl
 10016                              <1> 	;;jz	short WT2	
 10017                              <1> 	;;dec	bl
 10018                              <1> 	;;jmp	short WT1
 10019                              <1> 	;dec	bl
 10020                              <1> 	;jnz	short WT1	
 10021                              <1> 
 10022 00002DF7 C605[4F700000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
 10023 00002DFE EB0E                <1> 	JMP	SHORT WT4
 10024 00002E00 C605[4F700000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
 10025 00002E07 C605[47700000]00    <1> 	MOV	byte [HF_INT_FLAG],0
 10026 00002E0E 803D[4F700000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
 10027 00002E15 C3                  <1> 	RETn
 10028                              <1> 
 10029                              <1> ;----------------------------------------
 10030                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
 10031                              <1> ;----------------------------------------
 10032                              <1> NOT_BUSY:
 10033 00002E16 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
 10034                              <1> 	;PUSH	eBX
 10035                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
 10036 00002E17 668B15[A46A0000]    <1> 	mov	DX, [HF_PORT]
 10037 00002E1E 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
 10038                              <1> 	;MOV	BL,DELAY_1
 10039                              <1> 					; wait for 10 seconds
 10040                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
 10041                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
 10042                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
 10043 00002E21 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
 10044                              <1> 	;
 10045                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
 10046                              <1> NB1:	
 10047 00002E26 EC                  <1> 	IN	AL,DX			; CHECK STATUS
 10048                              <1> 	;TEST	AL,ST_BUSY
 10049 00002E27 2480                <1> 	and	al, ST_BUSY
 10050                              <1> 	;LOOPNZ	NB1
 10051 00002E29 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
 10052                              <1> 	;DEC	BL			
 10053                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
 10054                              <1> 
 10055 00002E2B E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
 10056 00002E2D A810                <1> 	TEST	AL,010H			; transition on memory
 10057 00002E2F 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
 10058 00002E31 E461                <1> NB1_lo: IN	AL,SYS1
 10059 00002E33 A810                <1> 	TEST	AL,010H
 10060 00002E35 74FA                <1> 	JZ	short NB1_lo
 10061 00002E37 E2ED                <1> 	LOOP	NB1
 10062                              <1> 	;dec	bl
 10063                              <1> 	;jnz	short NB1
 10064                              <1> 	;
 10065                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
 10066                              <1> ;;	jb	short NB1
 10067                              <1> 	;
 10068                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
 10069                              <1> 	;JMP	SHORT NB3
 10070 00002E39 B080                <1> 	mov	al, TIME_OUT
 10071                              <1> NB2:	
 10072                              <1> 	;MOV	byte [DISK_STATUS1],0
 10073                              <1> ;NB3:	
 10074                              <1> 	;POP	eBX
 10075 00002E3B A2[4F700000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
 10076                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
 10077 00002E40 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
 10078 00002E42 C3                  <1> 	RETn
 10079                              <1> 
 10080                              <1> ;----------------------------------------
 10081                              <1> ;	WAIT FOR DATA REQUEST		:
 10082                              <1> ;----------------------------------------
 10083                              <1> WAIT_DRQ:
 10084                              <1> 	;MOV	CX,DELAY_3
 10085                              <1> 	;MOV	DX,HF_PORT+7
 10086 00002E43 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
 10087 00002E4A 80C207              <1> 	add	dl, 7
 10088                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
 10089                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
 10090                              <1> 					; (but it is written as 2000
 10091                              <1> 					; micro seconds in ATORGS.ASM file
 10092                              <1> 					; of Award Bios - 1999, D1A0622)
 10093 00002E4D B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
 10094 00002E52 EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
 10095 00002E53 A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
 10096 00002E55 7516                <1> 	JNZ	short WQ_OK
 10097                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
 10098                              <1> WQ_hi:	
 10099 00002E57 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
 10100 00002E59 A810                <1> 	TEST	AL,010H			; transition on memory
 10101 00002E5B 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
 10102 00002E5D E461                <1> WQ_lo:  IN      AL,SYS1
 10103 00002E5F A810                <1> 	TEST	AL,010H
 10104 00002E61 74FA                <1> 	JZ	SHORT WQ_lo
 10105 00002E63 E2ED                <1> 	LOOP	WQ_1
 10106                              <1> 
 10107 00002E65 C605[4F700000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
 10108 00002E6C F9                  <1> 	STC
 10109                              <1> WQ_OK:
 10110 00002E6D C3                  <1> 	RETn
 10111                              <1> ;WQ_OK:	;CLC
 10112                              <1> ;	RETn
 10113                              <1> 
 10114                              <1> ;----------------------------------------
 10115                              <1> ;	CHECK FIXED DISK STATUS 	:
 10116                              <1> ;----------------------------------------
 10117                              <1> CHECK_STATUS:
 10118 00002E6E E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
 10119 00002E73 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
 10120 00002E75 A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
 10121 00002E77 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
 10122 00002E79 E847000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
 10123                              <1> CHECK_S1:
 10124 00002E7E 803D[4F700000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
 10125 00002E85 C3                  <1> 	RETn
 10126                              <1> 
 10127                              <1> ;----------------------------------------
 10128                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
 10129                              <1> ;----------------------------------------
 10130                              <1> CHECK_ST:
 10131                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
 10132 00002E86 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]
 10133 00002E8D 80C207              <1> 	add	dl, 7
 10134 00002E90 EC                  <1> 	IN	AL,DX
 10135 00002E91 A2[45700000]        <1> 	MOV	[HF_STATUS],AL
 10136 00002E96 B400                <1> 	MOV	AH,0
 10137 00002E98 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
 10138 00002E9A 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
 10139 00002E9C B4CC                <1> 	MOV	AH,WRITE_FAULT
 10140 00002E9E A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
 10141 00002EA0 7514                <1> 	JNZ	short CKST_EXIT
 10142 00002EA2 B4AA                <1> 	MOV	AH,NOT_RDY
 10143 00002EA4 A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
 10144 00002EA6 740E                <1> 	JZ	short CKST_EXIT
 10145 00002EA8 B440                <1> 	MOV	AH,BAD_SEEK
 10146 00002EAA A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
 10147 00002EAC 7408                <1> 	JZ	short CKST_EXIT
 10148 00002EAE B411                <1> 	MOV	AH,DATA_CORRECTED
 10149 00002EB0 A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
 10150 00002EB2 7502                <1> 	JNZ	short CKST_EXIT
 10151 00002EB4 B400                <1> 	MOV	AH,0
 10152                              <1> CKST_EXIT:
 10153 00002EB6 8825[4F700000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
 10154 00002EBC 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
 10155 00002EBF 7403                <1> 	JZ	short CKST_EX1
 10156 00002EC1 80FC00              <1> 	CMP	AH,0
 10157                              <1> CKST_EX1:
 10158 00002EC4 C3                  <1> 	RETn
 10159                              <1> 
 10160                              <1> ;----------------------------------------
 10161                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
 10162                              <1> ;----------------------------------------
 10163                              <1> CHECK_ER:
 10164                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
 10165 00002EC5 668B15[A46A0000]    <1> 	mov	dx, [HF_PORT]		;
 10166 00002ECC FEC2                <1> 	inc	dl
 10167 00002ECE EC                  <1> 	IN	AL,DX
 10168 00002ECF A2[46700000]        <1> 	MOV	[HF_ERROR],AL
 10169 00002ED4 53                  <1> 	PUSH	eBX ; 21/02/2015
 10170 00002ED5 B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
 10171 00002EDA D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
 10172 00002EDC 7202                <1> 	JC	short CK2		; FOUND THE ERROR
 10173 00002EDE E2FA                <1> 	LOOP	CK1			; KEEP TRYING
 10174 00002EE0 BB[986A0000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
 10175 00002EE5 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
 10176                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
 10177                              <1> 	;mov	ah, [bx]
 10178 00002EE7 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
 10179 00002EE9 8825[4F700000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
 10180 00002EEF 5B                  <1> 	POP	eBX
 10181 00002EF0 80FC00              <1> 	CMP	AH,0
 10182 00002EF3 C3                  <1> 	RETn
 10183                              <1> 
 10184                              <1> ;--------------------------------------------------------
 10185                              <1> ; CHECK_DMA						:
 10186                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
 10187                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
 10188                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
 10189                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
 10190                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
 10191                              <1> ;  -ERROR OTHERWISE					:
 10192                              <1> ;--------------------------------------------------------
 10193                              <1> CHECK_DMA:
 10194                              <1> 	;PUSH	AX			; SAVE REGISTERS
 10195                              <1> 	; 05/12/2021
 10196 00002EF4 50                  <1> 	push	eax
 10197 00002EF5 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
 10198 00002EF9 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
 10199 00002EFD 7404                <1> 	JZ	short CKD1
 10200 00002EFF 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
 10201 00002F03 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
 10202 00002F06 7706                <1> 	JA	short CKDOK		; IT WILL FIT
 10203 00002F08 7207                <1> 	JB	short CKDERR		; TOO MANY
 10204 00002F0A 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
 10205 00002F0C 7203                <1> 	JB	short CKDERR		; ERROR
 10206 00002F0E F8                  <1> CKDOK:	CLC				; CLEAR CARRY
 10207                              <1> 	;POP	AX
 10208                              <1> 	; 05/12/2021
 10209 00002F0F 58                  <1> 	pop	eax
 10210 00002F10 C3                  <1> 	RETn				; NORMAL RETURN
 10211 00002F11 F9                  <1> CKDERR: STC				; INDICATE ERROR
 10212 00002F12 C605[4F700000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
 10213                              <1> 	;POP	AX
 10214                              <1> 	; 05/12/2021
 10215 00002F19 58                  <1> 	pop	eax	
 10216 00002F1A C3                  <1> 	RETn
 10217                              <1> 
 10218                              <1> ;----------------------------------------
 10219                              <1> ;	SET UP ES:BX-> DISK PARMS	:
 10220                              <1> ;----------------------------------------
 10221                              <1> 					
 10222                              <1> ; INPUT -> DL = 0 based drive number
 10223                              <1> ; OUTPUT -> ES:BX = disk parameter table address
 10224                              <1> 
 10225                              <1> GET_VEC:
 10226                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
 10227                              <1> 	;MOV	ES,AX
 10228                              <1> 	;TEST	DL,1
 10229                              <1> 	;JZ	short GV_0
 10230                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
 10231                              <1> ;	JMP	SHORT GV_EXIT
 10232                              <1> ;GV_0:
 10233                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
 10234                              <1> ;
 10235                              <1> 	;xor	bh, bh
 10236 00002F1B 31DB                <1> 	xor	ebx, ebx
 10237 00002F1D 88D3                <1> 	mov	bl, dl
 10238                              <1> 	;;02/01/2015
 10239                              <1> 	;;shl	bl, 1			; port address offset
 10240                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
 10241                              <1> 	;;shl	bl, 1			; dpt pointer offset
 10242 00002F1F C0E302              <1> 	shl	bl, 2	;;
 10243                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
 10244 00002F22 81C3[54700000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
 10245                              <1> 	;push	word [bx+2]		; dpt segment
 10246                              <1> 	;pop	es
 10247                              <1> 	;mov	bx, [bx]		; dpt offset
 10248 00002F28 8B1B                <1> 	mov	ebx, [ebx]		
 10249                              <1> ;GV_EXIT:
 10250 00002F2A C3                  <1> 	RETn
 10251                              <1> 
 10252                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 10253                              <1> hdc1_int: ; 21/02/2015
 10254                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
 10255                              <1> ;								:
 10256                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
 10257                              <1> ;								:
 10258                              <1> ;----------------------------------------------------------------
 10259                              <1> 
 10260                              <1> ; 22/12/2014
 10261                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
 10262                              <1> ;	 '11/15/85'
 10263                              <1> ; AWARD BIOS 1999 (D1A0622) 
 10264                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
 10265                              <1> 
 10266                              <1> ;int_76h:
 10267                              <1> HD_INT:
 10268                              <1> 	;push	ax
 10269                              <1> 	; 05/12/2021
 10270 00002F2B 50                  <1> 	push	eax
 10271 00002F2C 1E                  <1> 	push	ds
 10272                              <1> 	;CALL	DDS
 10273                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
 10274 00002F2D 66B81000            <1> 	mov	ax, KDATA
 10275 00002F31 8ED8                <1> 	mov 	ds, ax
 10276                              <1> 	;
 10277                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
 10278                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
 10279 00002F33 C605[47700000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
 10280                              <1> 	;
 10281                              <1> 	;push	dx
 10282                              <1> 	; 05/12/2021
 10283 00002F3A 52                  <1> 	push	edx
 10284 00002F3B 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
 10285                              <1> 					; Clear Controller
 10286                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
 10287 00002F3F EC                  <1> 	in	al, dx			;
 10288                              <1> 	;pop	dx
 10289                              <1> 	; 05/12/2021
 10290 00002F40 5A                  <1> 	pop	edx
 10291                              <1> 	NEWIODELAY
 10292 00002F41 E6EB                <2>  out 0EBh,al
 10293                              <1> 	;
 10294 00002F43 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
 10295 00002F45 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
 10296                              <1> 	;JMP	$+2			; WAIT
 10297                              <1> 	NEWIODELAY
 10298 00002F47 E6EB                <2>  out 0EBh,al
 10299 00002F49 E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
 10300 00002F4B 1F                  <1> 	pop	ds
 10301                              <1> 	;STI				; RE-ENABLE INTERRUPTS
 10302                              <1> 	;MOV	AX,9100H		; DEVICE POST
 10303                              <1> 	;INT	15H			;  INTERRUPT
 10304                              <1> irq15_iret: ; 25/02/2015
 10305                              <1> 	;pop	ax
 10306                              <1> 	; 05/12/2021
 10307 00002F4C 58                  <1> 	pop	eax
 10308 00002F4D CF                  <1> 	iretd			; RETURN FROM INTERRUPT
 10309                              <1> 
 10310                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 10311                              <1> hdc2_int: ; 21/02/2015
 10312                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
 10313                              <1> ;								:
 10314                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
 10315                              <1> ;								:
 10316                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 10317                              <1> 
 10318                              <1> ;int_77h:
 10319                              <1> HD1_INT:
 10320                              <1> 	;push	ax
 10321                              <1> 	; 05/12/2021
 10322 00002F4E 50                  <1> 	push	eax
 10323                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
 10324                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 10325 00002F4F B00B                <1> 	mov	al, 0Bh  ; In-Service Register
 10326 00002F51 E6A0                <1> 	out	0A0h, al
 10327 00002F53 EB00                <1>         jmp short $+2
 10328 00002F55 EB00                <1> 	jmp short $+2
 10329 00002F57 E4A0                <1> 	in	al, 0A0h
 10330 00002F59 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
 10331 00002F5B 74EF                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
 10332                              <1> 	;
 10333 00002F5D 1E                  <1> 	push	ds
 10334                              <1> 	;CALL	DDS
 10335                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
 10336 00002F5E 66B81000            <1> 	mov	ax, KDATA
 10337 00002F62 8ED8                <1> 	mov 	ds, ax
 10338                              <1> 	;
 10339                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
 10340                              <1>         ;or	byte [CS:HF_INT_FLAG],0C0h 
 10341 00002F64 800D[47700000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
 10342                              <1> 	;
 10343                              <1> 	;push	dx
 10344                              <1> 	; 05/12/2021
 10345 00002F6B 52                  <1> 	push	edx
 10346 00002F6C 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
 10347                              <1> 					; Clear Controller (Award BIOS 1999)
 10348 00002F70 EBCD                <1> 	jmp	short Clear_IRQ1415
 10349                              <1> 
 10350                              <1> ;%include 'diskdata.inc' ; 11/03/2015
 10351                              <1> ;%include 'diskbss.inc' ; 11/03/2015
 10352                              <1> 
 10353                              <1> ;////////////////////////////////////////////////////////////////////
 10354                              <1> ;; END OF DISK I/O SYTEM ///
 10355                                  %include 'memory.s'  ; 09/03/2015
 10356                              <1> ; Retro UNIX 386 v2 - memory.s - 26/01/2020
 10357                              <1> ; Last Modification: 04/12/2021 (Retro UNIX 386 v1.2)
 10358                              <1> ; ----------------------------------------------------------------------------
 10359                              <1> ;
 10360                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
 10361                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
 10362                              <1> ; 18/10/2015 (!not completed!)
 10363                              <1> ;
 10364                              <1> ; Source code for NASM - Netwide Assembler (2.11)
 10365                              <1> 
 10366                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
 10367                              <1> 
 10368                              <1> ;;04/11/2014 (unix386.s)	
 10369                              <1> ;PDE_A_PRESENT	equ 1		; Present flag for PDE
 10370                              <1> ;PDE_A_WRITE	equ 2		; Writable (write permission) flag
 10371                              <1> ;PDE_A_USER	equ 4		; User (non-system/kernel) page flag
 10372                              <1> ;;
 10373                              <1> ;PTE_A_PRESENT	equ 1		; Present flag for PTE (bit 0)
 10374                              <1> ;PTE_A_WRITE	equ 2		; Writable (write permission) flag (bit 1)
 10375                              <1> ;PTE_A_USER	equ 4		; User (non-system/kernel) page flag (bit 2)
 10376                              <1> ;PTE_A_ACCESS   equ 32		; Accessed flag (bit 5) ; 09/03/2015
 10377                              <1> 
 10378                              <1> ; 27/04/2015
 10379                              <1> ; 09/03/2015
 10380                              <1> PAGE_SIZE 	equ 4096	; page size in bytes
 10381                              <1> PAGE_SHIFT 	equ 12		; page table shift count
 10382                              <1> PAGE_D_SHIFT 	equ 22 ; 12+10	; page directory shift count
 10383                              <1> PAGE_OFF	equ 0FFFh	; 12 bit byte offset in page frame
 10384                              <1> PTE_MASK 	equ 03FFh	; page table entry mask
 10385                              <1> PTE_DUPLICATED  equ 200h	; duplicated page sign (AVL bit 0)
 10386                              <1> PDE_A_CLEAR	equ 0F000h	; to clear PDE attribute bits
 10387                              <1> PTE_A_CLEAR	equ 0F000h	; to clear PTE attribute bits
 10388                              <1> LOGIC_SECT_SIZE equ 512		; logical sector size
 10389                              <1> ERR_MAJOR_PF	equ 0E0h	; major error: page fault
 10390                              <1> ; 15/10/2016 (TRDOS 386 v2)
 10391                              <1> ERR_MINOR_IM	equ 4 ;15/10/2016 (1->4); insufficient (out of) memory
 10392                              <1> ERR_MINOR_PV	equ 6 ;15/10/2016 (3->6); protection violation
 10393                              <1> SWP_DISK_READ_ERR 	   equ 40
 10394                              <1> SWP_DISK_NOT_PRESENT_ERR   equ 41
 10395                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 42
 10396                              <1> SWP_NO_FREE_SPACE_ERR      equ 43
 10397                              <1> SWP_DISK_WRITE_ERR         equ 44
 10398                              <1> SWP_NO_PAGE_TO_SWAP_ERR    equ 45
 10399                              <1> PTE_A_ACCESS_BIT equ 5	; Bit 5 (accessed flag)        
 10400                              <1> SECTOR_SHIFT     equ 3	; sector shift (to convert page block number)
 10401                              <1> ; 10/06/2021 (Retro UNIX 386 v2)
 10402                              <1> ; 12/07/2016 (TRDOS 386 v2) 
 10403                              <1> PTE_SHARED	 equ 400h		; AVL bit 1, direct memory access bit	
 10404                              <1> 					; (Indicates that the page is not allocated
 10405                              <1> 					; for the process, it is a shared or system
 10406                              <1>                                         ; page, it must not be deallocated!)
 10407                              <1> ; 14/12/2020
 10408                              <1> ; (Linear Frame Buffer - video memory mark : AVL bit 1, outside M.A.T.)
 10409                              <1> PDE_EXTERNAL	equ 400h	; Page directory entry for external memory blocks
 10410                              <1> PTE_EXTERNAL	equ 400h	; Allocated kernel pages for Linear Frame Buffer
 10411                              <1> 				; (Out of memory allocation table)	
 10412                              <1> ;
 10413                              <1> ;; Retro Unix 386 v1 - paging method/principles
 10414                              <1> ;;
 10415                              <1> ;; 10/10/2014
 10416                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
 10417                              <1> ;;
 10418                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
 10419                              <1> ;;	(virtual address = physical address)
 10420                              <1> ;; KERNEL PAGE TABLES:
 10421                              <1> ;;	Kernel page directory and all page tables are
 10422                              <1> ;;	on memory as initialized, as equal to physical memory
 10423                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
 10424                              <1> ;;
 10425                              <1> ;;	what for: User pages may be swapped out, when accessing
 10426                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
 10427                              <1> ;;	kernel would have to swap it in! But it is also may be
 10428                              <1> ;;	in use by a user process. (In system/kernel mode
 10429                              <1> ;;	kernel can access all memory pages even if they are
 10430                              <1> ;;	reserved/allocated for user processes. Swap out/in would
 10431                              <1> ;;	cause conflicts.) 
 10432                              <1> ;;	
 10433                              <1> ;;	As result of these conditions,
 10434                              <1> ;;	all kernel pages must be initialized as equal to 
 10435                              <1> ;;	physical layout for preventing page faults. 
 10436                              <1> ;;	Also, calling "allocate page" procedure after
 10437                              <1> ;;	a page fault can cause another page fault (double fault)
 10438                              <1> ;;	if all kernel page tables would not be initialized.
 10439                              <1> ;;
 10440                              <1> ;;	[first_page] = Beginning of users space, as offset to 
 10441                              <1> ;;	memory allocation table. (double word aligned)
 10442                              <1> ;;
 10443                              <1> ;;	[next_page] = first/next free space to be searched
 10444                              <1> ;;	as offset to memory allocation table. (dw aligned)
 10445                              <1> ;;
 10446                              <1> ;;	[last_page] = End of memory (users space), as offset
 10447                              <1> ;;	to memory allocation table. (double word aligned)
 10448                              <1> ;;
 10449                              <1> ;; USER PAGE TABLES:
 10450                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
 10451                              <1> ;;		'ready only' marked copies of the 
 10452                              <1> ;;		parent process's page table entries (for
 10453                              <1> ;;		same physical memory).
 10454                              <1> ;;		(A page will be copied to a new page after
 10455                              <1> ;;		 if it causes R/W page fault.)
 10456                              <1> ;;
 10457                              <1> ;;	Every user process has own (different)
 10458                              <1> ;;	page directory and page tables.	
 10459                              <1> ;;
 10460                              <1> ;;	Code starts at virtual address 0, always.
 10461                              <1> ;;	(Initial value of EIP is 0 in user mode.)
 10462                              <1> ;;	(Programs can be written/developed as simple
 10463                              <1> ;;	 flat memory programs.)
 10464                              <1> ;;
 10465                              <1> ;; MEMORY ALLOCATION STRATEGY:
 10466                              <1> ;;	Memory page will be allocated by kernel only 
 10467                              <1> ;;		(in kernel/system mode only).
 10468                              <1> ;;	* After a
 10469                              <1> ;;	  - 'not present' page fault
 10470                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
 10471                              <1> ;;	* For loading (opening, reading) a file or disk/drive
 10472                              <1> ;;	* As responce to 'allocate additional memory blocks' 
 10473                              <1> ;;	  request by running process.
 10474                              <1> ;;	* While creating a process, allocating a new buffer,
 10475                              <1> ;;	  new page tables etc.
 10476                              <1> ;;
 10477                              <1> ;;	At first,
 10478                              <1> ;;	- 'allocate page' procedure will be called;
 10479                              <1> ;,	   if it will return with a valid (>0) physical address
 10480                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
 10481                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
 10482                              <1> ;;	- 'allocate page' will be called for allocating page
 10483                              <1> ;;	   directory, page table and running space (data/code).
 10484                              <1> ;;	- every successful 'allocate page' call will decrease
 10485                              <1> ;;	  'free_pages' count (pointer).
 10486                              <1> ;;	- 'out of (insufficient) memory error' will be returned
 10487                              <1> ;;	  if 'free_pages' points to a ZERO.
 10488                              <1> ;;	- swapping out and swapping in (if it is not a new page)
 10489                              <1> ;;	  procedures will be called as responce to 'out of memory'
 10490                              <1> ;;	  error except errors caused by attribute conflicts.
 10491                              <1> ;;	 (swapper functions)	 
 10492                              <1> ;;					
 10493                              <1> ;;	At second,
 10494                              <1> ;;	- page directory entry will be updated then page table
 10495                              <1> ;;	  entry will be updated.		
 10496                              <1> ;;
 10497                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
 10498                              <1> ;;	- M.A.T. has a size according to available memory as
 10499                              <1> ;;	  follows:
 10500                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
 10501                              <1> ;;		  - a bit with value of 0 means allocated page
 10502                              <1> ;;		  - a bit with value of 1 means a free page
 10503                              <1> ;,	- 'free_pages' pointer holds count of free pages
 10504                              <1> ;;	  depending on M.A.T.
 10505                              <1> ;;		(NOTE: Free page count will not be checked
 10506                              <1> ;;		again -on M.A.T.- after initialization. 
 10507                              <1> ;;		Kernel will trust on initial count.)
 10508                              <1> ;,	- 'free_pages' count will be decreased by allocation
 10509                              <1> ;;	  and it will be increased by deallocation procedures.
 10510                              <1> ;;	
 10511                              <1> ;;	- Available memory will be calculated during
 10512                              <1> ;;	  the kernel's initialization stage (in real mode).
 10513                              <1> ;;	  Memory allocation table and kernel page tables 
 10514                              <1> ;;	  will be formatted/sized as result of available
 10515                              <1> ;;	  memory calculation before paging is enabled.
 10516                              <1> ;;
 10517                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
 10518                              <1> ;;	- Memory Allocation Table size will be 128 KB.
 10519                              <1> ;;	- Memory allocation for kernel page directory size 
 10520                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10521                              <1> ;;	  for page tables)
 10522                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
 10523                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
 10524                              <1> ;;	- User (available) space will be started 
 10525                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
 10526                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10527                              <1> ;;	  memory allocation table and kernel's page directory
 10528                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10529                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10530                              <1> ;; 	  for buffers.
 10531                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10532                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10533                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
 10534                              <1> ;;
 10535                              <1> ;; For 1GB Available Memory:
 10536                              <1> ;;	- Memory Allocation Table size will be 32 KB.
 10537                              <1> ;;	- Memory allocation for kernel page directory size 
 10538                              <1> ;;	  is always 4 KB. (in addition to total allocation size
 10539                              <1> ;;	  for page tables)
 10540                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
 10541                              <1> ;;	  is 1 MB (256*4*1024 bytes).
 10542                              <1> ;;	- User (available) space will be started 
 10543                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
 10544                              <1> ;;	- The first 640 KB is for kernel's itself plus
 10545                              <1> ;;	  memory allocation table and kernel's page directory
 10546                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
 10547                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
 10548                              <1> ;; 	  for buffers.
 10549                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
 10550                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
 10551                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
 10552                              <1> ;;
 10553                              <1> ;;
 10554                              <1> 
 10555                              <1> ;;************************************************************************************
 10556                              <1> ;; 
 10557                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
 10558                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
 10559                              <1> 
 10560                              <1> ;; Main factor: "sys fork" system call 
 10561                              <1> ;;	
 10562                              <1> ;; 		FORK
 10563                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
 10564                              <1> ;;  writable pages ---->|
 10565                              <1> ;;                      |----> child - duplicated PTEs, read only pages
 10566                              <1> ;; 
 10567                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
 10568                              <1> ;; 
 10569                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
 10570                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
 10571                              <1> ;;       -while R/W bit is 0-. 
 10572                              <1> ;; 
 10573                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
 10574                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
 10575                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
 10576                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
 10577                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
 10578                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
 10579                              <1> ;; 
 10580                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
 10581                              <1> ;; # Parent's read only pages are copied to new child pages. 
 10582                              <1> ;;   Parent's PTE attributes are not changed.
 10583                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
 10584                              <1> ;;    destroy/mix previous fork result).
 10585                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
 10586                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
 10587                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
 10588                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
 10589                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
 10590                              <1> ;;   as Child's Page Table Entries without copying actual page.
 10591                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
 10592                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
 10593                              <1> ;; 
 10594                              <1> ;; !? WHAT FOR (duplication after duplication):
 10595                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
 10596                              <1> ;; program/executable code continues from specified location as child process, 
 10597                              <1> ;; returns back previous code location as parent process, every child after 
 10598                              <1> ;; every sys fork uses last image of code and data just prior the fork.
 10599                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
 10600                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
 10601                              <1> ;; was copied to child's process segment (all of code and data) according to
 10602                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
 10603                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
 10604                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
 10605                              <1> ;; (complete running image of parent process) to the child process; 
 10606                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
 10607                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
 10608                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
 10609                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
 10610                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
 10611                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
 10612                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
 10613                              <1> ;; new/fresh pages will be used to load and run new executable/program.
 10614                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
 10615                              <1> ;; for sharing same read only pages between parent and child processes.
 10616                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
 10617                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
 10618                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
 10619                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
 10620                              <1> ;; -deallocation problem-.
 10621                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
 10622                              <1> ;; 
 10623                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10624                              <1> ;; # Page fault handler will do those:
 10625                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10626                              <1> ;;   - If it is reset/clear, there is a child uses same page.
 10627                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
 10628                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
 10629                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
 10630                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
 10631                              <1> ;;     read only page will be converted to writable and unique page which belongs
 10632                              <1> ;;     to child process.)	
 10633                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
 10634                              <1> ;; # Page fault handler will do those:
 10635                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
 10636                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
 10637                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
 10638                              <1> ;;     address or not. 
 10639                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
 10640                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
 10641                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
 10642                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
 10643                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
 10644                              <1> ;; 
 10645                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
 10646                              <1> ;;       will be set as writable (and unique) in case of child process was using 
 10647                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
 10648                              <1> ;;       duplication method details, it is not possible multiple child processes
 10649                              <1> ;;       were using same page with duplicated PTEs.
 10650                              <1> ;; 
 10651                              <1> ;;************************************************************************************   
 10652                              <1> 
 10653                              <1> ;; 08/10/2014
 10654                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
 10655                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
 10656                              <1> 
 10657                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
 10658                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
 10659                              <1> ;; (25/08/2014, Revision: 5057) file 
 10660                              <1> ;; by KolibriOS Team (2004-2012)
 10661                              <1> 
 10662                              <1> allocate_page:
 10663                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 10664                              <1> 	;	 (temporary modifications)
 10665                              <1> 	; 01/07/2015
 10666                              <1> 	; 05/05/2015
 10667                              <1> 	; 30/04/2015
 10668                              <1> 	; 16/10/2014
 10669                              <1> 	; 08/10/2014
 10670                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
 10671                              <1> 	;
 10672                              <1> 	; INPUT -> none
 10673                              <1> 	;
 10674                              <1> 	; OUTPUT ->
 10675                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 10676                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
 10677                              <1> 	;
 10678                              <1> 	;	CF = 1 and EAX = 0 
 10679                              <1> 	; 		   if there is not a free page to be allocated	
 10680                              <1> 	;
 10681                              <1> 	; Modified Registers -> none (except EAX)
 10682                              <1> 	;
 10683 00002F72 A1[C06F0000]        <1> 	mov	eax, [free_pages]
 10684 00002F77 21C0                <1> 	and	eax, eax
 10685 00002F79 7438                <1> 	jz	short out_of_memory
 10686                              <1> 	;
 10687 00002F7B 53                  <1> 	push	ebx
 10688 00002F7C 51                  <1> 	push	ecx
 10689                              <1> 	;
 10690 00002F7D BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
 10691 00002F82 89D9                <1> 	mov	ecx, ebx
 10692                              <1>  				     ; NOTE: 32 (first_page) is initial
 10693                              <1> 				     ; value of [next_page].
 10694                              <1> 				     ; It points to the first available
 10695                              <1> 				     ; page block for users (ring 3) ...	
 10696                              <1> 				     ; (MAT offset 32 = 1024/32)	
 10697                              <1> 				     ; (at the of the first 4 MB)		
 10698 00002F84 031D[C46F0000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
 10699                              <1> 				 ; next_free_page >> 5
 10700 00002F8A 030D[C86F0000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
 10701                              <1> 				 ; (total_pages - 1) >> 5
 10702                              <1> al_p_scan:
 10703 00002F90 39CB                <1> 	cmp	ebx, ecx
 10704 00002F92 770A                <1> 	ja	short al_p_notfound
 10705                              <1> 	;
 10706                              <1> 	; 01/07/2015
 10707                              <1> 	; AMD64 Architecture Programmers Manual
 10708                              <1> 	; Volume 3:
 10709                              <1> 	; General-Purpose and System Instructions
 10710                              <1> 	;
 10711                              <1> 	; BSF - Bit Scan Forward
 10712                              <1> 	;
 10713                              <1> 	;   Searches the value in a register or a memory location
 10714                              <1> 	;   (second operand) for the least-significant set bit. 
 10715                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
 10716                              <1> 	;   and stores the index of the least-significant set bit in a destination
 10717                              <1> 	;   register (first operand). If the second operand contains 0, 
 10718                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
 10719                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
 10720                              <1> 	;   of the searched value
 10721                              <1> 	;
 10722 00002F94 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 10723                              <1> 			   ; Clear ZF if a bit is found set (1) and 
 10724                              <1> 			   ; loads the destination with an index to
 10725                              <1> 			   ; first set bit. (0 -> 31) 
 10726                              <1> 			   ; Sets ZF to 1 if no bits are found set.
 10727 00002F97 751C                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
 10728                              <1> 			 ;
 10729                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
 10730                              <1> 			 ;	  with value of 1 means 
 10731                              <1> 			 ;	  the corresponding page is free 
 10732                              <1> 			 ;	  (Retro UNIX 386 v1 feature only!)
 10733 00002F99 83C304              <1> 	add	ebx, 4
 10734                              <1> 			 ; We return back for searching next page block
 10735                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
 10736                              <1> 			 ;	 we always will find at least 1 free page here.
 10737 00002F9C EBF2                <1>         jmp     short al_p_scan
 10738                              <1> 	;
 10739                              <1> al_p_notfound:
 10740 00002F9E 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10741 00002FA4 890D[C46F0000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
 10742                              <1> 				 ; (deallocate_page procedure will change it)
 10743 00002FAA 31C0                <1> 	xor	eax, eax
 10744 00002FAC A3[C06F0000]        <1> 	mov	[free_pages], eax ; 0
 10745 00002FB1 59                  <1> 	pop	ecx
 10746 00002FB2 5B                  <1> 	pop	ebx
 10747                              <1> 	;
 10748                              <1> ; 17/04/2021
 10749                              <1> ; ('swap_out' procedure call is disabled as temporary)
 10750                              <1> 
 10751                              <1> out_of_memory:
 10752                              <1> ;	call	swap_out
 10753                              <1> ;	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
 10754                              <1> ;	;
 10755                              <1> ;	sub 	eax, eax ; 0
 10756 00002FB3 F9                  <1> 	stc
 10757 00002FB4 C3                  <1> 	retn
 10758                              <1> 
 10759                              <1> al_p_found:
 10760 00002FB5 89D9                <1> 	mov	ecx, ebx
 10761 00002FB7 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
 10762 00002FBD 890D[C46F0000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
 10763                              <1> 				 ; address/offset (to the next)
 10764 00002FC3 FF0D[C06F0000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
 10765                              <1> 	;
 10766 00002FC9 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
 10767                              <1> 				 ; is copied into the Carry Flag and then cleared
 10768                              <1> 				 ; in the destination.
 10769                              <1> 				 ;
 10770                              <1> 				 ; Reset the bit which is corresponding to the 
 10771                              <1> 				 ; (just) allocated page.
 10772                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
 10773 00002FCC C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
 10774 00002FCF 01C8                <1> 	add	eax, ecx	 ; = page number
 10775 00002FD1 C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
 10776                              <1> 	; EAX = physical address of memory page
 10777                              <1> 	;
 10778                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
 10779                              <1> 	;       according to this EAX value...
 10780 00002FD4 59                  <1> 	pop	ecx
 10781 00002FD5 5B                  <1> 	pop	ebx
 10782                              <1> al_p_ok:
 10783 00002FD6 C3                  <1> 	retn
 10784                              <1> 
 10785                              <1> make_page_dir:
 10786                              <1> 	; 18/04/2015
 10787                              <1> 	; 12/04/2015
 10788                              <1> 	; 23/10/2014
 10789                              <1> 	; 16/10/2014
 10790                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10791                              <1> 	;
 10792                              <1> 	; INPUT ->
 10793                              <1> 	;	none
 10794                              <1> 	; OUTPUT ->
 10795                              <1> 	;	(EAX = 0)
 10796                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10797                              <1> 	;	cf = 0 ->
 10798                              <1> 	;	u.pgdir = page directory (physical) address of the current
 10799                              <1> 	;		  process/user.
 10800                              <1> 	;
 10801                              <1> 	; Modified Registers -> EAX
 10802                              <1> 	;
 10803 00002FD7 E896FFFFFF          <1> 	call	allocate_page
 10804 00002FDC 7216                <1> 	jc	short mkpd_error
 10805                              <1> 	;
 10806 00002FDE A3[18710000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
 10807                              <1> 				  ; (Physical address)
 10808                              <1> clear_page:
 10809                              <1> 	; 18/04/2015
 10810                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10811                              <1> 	;
 10812                              <1> 	; INPUT ->
 10813                              <1> 	;	EAX = physical address of the page
 10814                              <1> 	; OUTPUT ->
 10815                              <1> 	;	all bytes of the page will be cleared
 10816                              <1> 	;
 10817                              <1> 	; Modified Registers -> none
 10818                              <1> 	;
 10819 00002FE3 57                  <1> 	push	edi
 10820 00002FE4 51                  <1> 	push	ecx
 10821 00002FE5 50                  <1> 	push	eax
 10822 00002FE6 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 10823 00002FEB 89C7                <1> 	mov	edi, eax
 10824 00002FED 31C0                <1> 	xor	eax, eax
 10825 00002FEF F3AB                <1> 	rep	stosd
 10826 00002FF1 58                  <1> 	pop	eax
 10827 00002FF2 59                  <1> 	pop	ecx
 10828 00002FF3 5F                  <1> 	pop	edi
 10829                              <1> mkpd_error:
 10830                              <1> mkpt_error:
 10831 00002FF4 C3                  <1> 	retn
 10832                              <1> 
 10833                              <1> make_page_table:
 10834                              <1> 	; 23/06/2015
 10835                              <1> 	; 18/04/2015
 10836                              <1> 	; 12/04/2015
 10837                              <1> 	; 16/10/2014
 10838                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10839                              <1> 	;
 10840                              <1> 	; INPUT ->
 10841                              <1> 	;	EBX = virtual (linear) address
 10842                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10843                              <1> 	;	      (higher 20 bits must be ZERO)
 10844                              <1> 	;	      (bit 0 must be 1)	 
 10845                              <1> 	;	u.pgdir = page directory (physical) address
 10846                              <1> 	; OUTPUT ->
 10847                              <1> 	;	EDX = Page directory entry address
 10848                              <1> 	;	EAX = Page table address
 10849                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10850                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
 10851                              <1> 	;
 10852                              <1> 	; Modified Registers -> EAX, EDX
 10853                              <1> 	;
 10854 00002FF5 E878FFFFFF          <1> 	call	allocate_page
 10855 00002FFA 72F8                <1> 	jc	short mkpt_error
 10856 00002FFC E811000000          <1> 	call	set_pde	
 10857 00003001 EBE0                <1> 	jmp	short clear_page
 10858                              <1> 
 10859                              <1> make_page:
 10860                              <1> 	; 24/07/2015
 10861                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
 10862                              <1> 	;
 10863                              <1> 	; INPUT ->
 10864                              <1> 	;	EBX = virtual (linear) address
 10865                              <1> 	;	ECX = page attributes (lower 12 bits)
 10866                              <1> 	;	      (higher 20 bits must be ZERO)
 10867                              <1> 	;	      (bit 0 must be 1)	 
 10868                              <1> 	;	u.pgdir = page directory (physical) address
 10869                              <1> 	; OUTPUT ->
 10870                              <1> 	;	EBX = Virtual address
 10871                              <1> 	;	(EDX = PTE value)
 10872                              <1> 	;	EAX = Physical address
 10873                              <1> 	;	cf = 1 -> insufficient (out of) memory error
 10874                              <1> 	;
 10875                              <1> 	; Modified Registers -> EAX, EDX
 10876                              <1> 	;
 10877 00003003 E86AFFFFFF          <1> 	call	allocate_page
 10878 00003008 7207                <1> 	jc	short mkp_err
 10879 0000300A E821000000          <1> 	call	set_pte	
 10880 0000300F 73D2                <1> 	jnc	short clear_page ; 18/04/2015
 10881                              <1> mkp_err:
 10882 00003011 C3                  <1> 	retn
 10883                              <1> 
 10884                              <1> set_pde:	; Set page directory entry (PDE)
 10885                              <1> 	; 20/07/2015
 10886                              <1> 	; 18/04/2015
 10887                              <1> 	; 12/04/2015
 10888                              <1> 	; 23/10/2014
 10889                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10890                              <1> 	;
 10891                              <1> 	; INPUT ->
 10892                              <1> 	;	EAX = physical address
 10893                              <1> 	;	      (use present value if EAX = 0)
 10894                              <1> 	;	EBX = virtual (linear) address
 10895                              <1> 	;	ECX = page table attributes (lower 12 bits)
 10896                              <1> 	;	      (higher 20 bits must be ZERO)
 10897                              <1> 	;	      (bit 0 must be 1)	 
 10898                              <1> 	;	u.pgdir = page directory (physical) address
 10899                              <1> 	; OUTPUT ->
 10900                              <1> 	;	EDX = PDE address
 10901                              <1> 	;	EAX = page table address (physical)
 10902                              <1> 	;	;(CF=1 -> Invalid page address)
 10903                              <1> 	;
 10904                              <1> 	; Modified Registers -> EDX
 10905                              <1> 	;
 10906 00003012 89DA                <1> 	mov	edx, ebx
 10907 00003014 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
 10908 00003017 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
 10909 0000301A 0315[18710000]      <1> 	add	edx, [u.pgdir]
 10910                              <1> 	;
 10911 00003020 21C0                <1> 	and	eax, eax
 10912 00003022 7506                <1> 	jnz	short spde_1
 10913                              <1> 	;
 10914 00003024 8B02                <1> 	mov	eax, [edx]  ; old PDE value
 10915                              <1> 	;test	al, 1
 10916                              <1> 	;jz	short spde_2
 10917 00003026 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
 10918                              <1> spde_1:
 10919                              <1> 	;and	cx, 0FFFh
 10920 0000302A 8902                <1> 	mov	[edx], eax
 10921 0000302C 66090A              <1> 	or	[edx], cx
 10922 0000302F C3                  <1> 	retn
 10923                              <1> ;spde_2: ; error
 10924                              <1> ;	stc
 10925                              <1> ;	retn
 10926                              <1> 
 10927                              <1> set_pte:	; Set page table entry (PTE)
 10928                              <1> 	; 24/07/2015
 10929                              <1> 	; 20/07/2015
 10930                              <1> 	; 23/06/2015
 10931                              <1> 	; 18/04/2015
 10932                              <1> 	; 12/04/2015
 10933                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 10934                              <1> 	;
 10935                              <1> 	; INPUT ->
 10936                              <1> 	;	EAX = physical page address
 10937                              <1> 	;	      (use present value if EAX = 0)
 10938                              <1> 	;	EBX = virtual (linear) address
 10939                              <1> 	;	ECX = page attributes (lower 12 bits)
 10940                              <1> 	;	      (higher 20 bits must be ZERO)
 10941                              <1> 	;	      (bit 0 must be 1)	 
 10942                              <1> 	;	u.pgdir = page directory (physical) address
 10943                              <1> 	; OUTPUT ->
 10944                              <1> 	;	EAX = physical page address
 10945                              <1> 	;	(EDX = PTE value)
 10946                              <1> 	;	EBX = virtual address
 10947                              <1> 	;
 10948                              <1> 	;	CF = 1 -> error
 10949                              <1> 	;
 10950                              <1> 	; Modified Registers -> EAX, EDX
 10951                              <1> 	;
 10952 00003030 50                  <1> 	push	eax
 10953 00003031 A1[18710000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
 10954 00003036 E837000000          <1> 	call 	get_pde
 10955                              <1> 		; EDX = PDE address
 10956                              <1> 		; EAX = PDE value
 10957 0000303B 5A                  <1> 	pop	edx ; physical page address
 10958 0000303C 722A                <1> 	jc	short spte_err ; PDE not present
 10959                              <1> 	;
 10960 0000303E 53                  <1> 	push	ebx ; 24/07/2015
 10961 0000303F 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10962                              <1> 			    ; EDX = PT address (physical)	
 10963 00003043 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
 10964 00003046 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
 10965                              <1> 			 ; clear higher 10 bits (PD bits)
 10966 0000304C C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
 10967 0000304F 01C3                <1> 	add	ebx, eax
 10968                              <1> 	;
 10969 00003051 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
 10970 00003053 A801                <1> 	test	al, 1
 10971 00003055 740C                <1> 	jz	short spte_0
 10972 00003057 09D2                <1> 	or	edx, edx
 10973 00003059 750F                <1> 	jnz	short spte_1
 10974 0000305B 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
 10975 0000305F 89C2                <1> 	mov	edx, eax
 10976 00003061 EB09                <1> 	jmp	short spte_2	
 10977                              <1> spte_0:
 10978                              <1> 	; If this PTE contains a swap (disk) address,
 10979                              <1> 	; it can be updated by using 'swap_in' procedure
 10980                              <1> 	; only!
 10981 00003063 21C0                <1> 	and	eax, eax
 10982 00003065 7403                <1> 	jz	short spte_1
 10983                              <1> 	; 24/07/2015
 10984                              <1> 	; swapped page ! (on disk)
 10985 00003067 5B                  <1> 	pop	ebx
 10986                              <1> spte_err:
 10987 00003068 F9                  <1> 	stc
 10988 00003069 C3                  <1> 	retn
 10989                              <1> spte_1: 
 10990 0000306A 89D0                <1> 	mov	eax, edx
 10991                              <1> spte_2:
 10992 0000306C 09CA                <1> 	or	edx, ecx
 10993                              <1> 	; 23/06/2015
 10994 0000306E 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
 10995                              <1> 	; 24/07/2015
 10996 00003070 5B                  <1> 	pop	ebx
 10997 00003071 C3                  <1> 	retn
 10998                              <1> 
 10999                              <1> get_pde:	; Get present value of the relevant PDE
 11000                              <1> 	; 20/07/2015
 11001                              <1> 	; 18/04/2015
 11002                              <1> 	; 12/04/2015
 11003                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 11004                              <1> 	;
 11005                              <1> 	; INPUT ->
 11006                              <1> 	;	EBX = virtual (linear) address
 11007                              <1> 	;	EAX = page directory (physical) address
 11008                              <1> 	; OUTPUT ->
 11009                              <1> 	;	EDX = Page directory entry address
 11010                              <1> 	;	EAX = Page directory entry value
 11011                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 11012                              <1> 	; Modified Registers -> EDX, EAX
 11013                              <1> 	;
 11014 00003072 89DA                <1> 	mov	edx, ebx
 11015 00003074 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
 11016 00003077 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
 11017 0000307A 01C2                <1> 	add	edx, eax ; page directory address (physical)
 11018 0000307C 8B02                <1> 	mov	eax, [edx]
 11019 0000307E A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
 11020 00003080 751F                <1> 	jnz	short gpte_retn
 11021 00003082 F9                  <1> 	stc
 11022                              <1> gpde_retn:	
 11023 00003083 C3                  <1> 	retn
 11024                              <1> 
 11025                              <1> get_pte:
 11026                              <1> 		; Get present value of the relevant PTE
 11027                              <1> 	; 29/07/2015
 11028                              <1> 	; 20/07/2015
 11029                              <1> 	; 18/04/2015
 11030                              <1> 	; 12/04/2015
 11031                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
 11032                              <1> 	;
 11033                              <1> 	; INPUT ->
 11034                              <1> 	;	EBX = virtual (linear) address
 11035                              <1> 	;	EAX = page directory (physical) address
 11036                              <1> 	; OUTPUT ->
 11037                              <1> 	;	EDX = Page table entry address (if CF=0)
 11038                              <1> 	;	      Page directory entry address (if CF=1)
 11039                              <1> 	;            (Bit 0 value is 0 if PT is not present)
 11040                              <1> 	;	EAX = Page table entry value (page address)
 11041                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
 11042                              <1> 	; Modified Registers -> EAX, EDX
 11043                              <1> 	;
 11044 00003084 E8E9FFFFFF          <1> 	call 	get_pde
 11045 00003089 72F8                <1> 	jc	short gpde_retn	; page table is not present
 11046                              <1> 	;jnc	short gpte_1
 11047                              <1> 	;retn
 11048                              <1> ;gpte_1:
 11049 0000308B 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
 11050 0000308F 89DA                <1> 	mov	edx, ebx
 11051 00003091 C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
 11052 00003094 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
 11053                              <1> 			 ; clear higher 10 bits (PD bits)
 11054 0000309A C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
 11055 0000309D 01C2                <1> 	add	edx, eax
 11056 0000309F 8B02                <1> 	mov	eax, [edx]
 11057                              <1> gpte_retn:
 11058 000030A1 C3                  <1> 	retn
 11059                              <1> 
 11060                              <1> deallocate_page_dir:
 11061                              <1> 	; 15/09/2015
 11062                              <1> 	; 05/08/2015
 11063                              <1> 	; 30/04/2015
 11064                              <1> 	; 28/04/2015
 11065                              <1> 	; 17/10/2014
 11066                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 11067                              <1> 	;
 11068                              <1> 	; INPUT ->
 11069                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
 11070                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 11071                              <1> 	; OUTPUT ->
 11072                              <1> 	;	All of page tables in the page directory
 11073                              <1> 	;	and page dir's itself will be deallocated
 11074                              <1> 	;	except 'read only' duplicated pages (will be converted
 11075                              <1> 	;	to writable pages).
 11076                              <1> 	;
 11077                              <1> 	; Modified Registers -> EAX
 11078                              <1> 	;
 11079                              <1> 	;
 11080 000030A2 56                  <1> 	push	esi
 11081 000030A3 51                  <1> 	push	ecx
 11082 000030A4 50                  <1> 	push	eax
 11083 000030A5 89C6                <1> 	mov	esi, eax 
 11084 000030A7 31C9                <1> 	xor	ecx, ecx
 11085                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
 11086                              <1> 	; it must not be deallocated
 11087 000030A9 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
 11088                              <1> dapd_0:
 11089 000030AB AD                  <1> 	lodsd
 11090 000030AC A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
 11091 000030AE 7409                <1> 	jz	short dapd_1	
 11092 000030B0 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 11093 000030B4 E812000000          <1> 	call	deallocate_page_table			
 11094                              <1> dapd_1:
 11095 000030B9 41                  <1> 	inc	ecx ; page directory entry index
 11096 000030BA 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
 11097 000030C0 72E9                <1> 	jb	short dapd_0
 11098                              <1> dapd_2:
 11099 000030C2 58                  <1> 	pop	eax
 11100 000030C3 E872000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
 11101 000030C8 59                  <1> 	pop	ecx
 11102 000030C9 5E                  <1> 	pop	esi
 11103 000030CA C3                  <1> 	retn
 11104                              <1> 
 11105                              <1> deallocate_page_table:
 11106                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 11107                              <1> 	;	 (temporary modifications)
 11108                              <1> 	; 12/07/2016 (TRDOS 386 v2)
 11109                              <1> 	; 19/09/2015
 11110                              <1> 	; 15/09/2015
 11111                              <1> 	; 05/08/2015
 11112                              <1> 	; 30/04/2015
 11113                              <1> 	; 28/04/2015
 11114                              <1> 	; 24/10/2014
 11115                              <1> 	; 23/10/2014
 11116                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 11117                              <1> 	;
 11118                              <1> 	; INPUT ->
 11119                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
 11120                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
 11121                              <1> 	;	(ECX = page directory entry index)
 11122                              <1> 	; OUTPUT ->
 11123                              <1> 	;	All of pages in the page table and page table's itself
 11124                              <1> 	;	will be deallocated except 'read only' duplicated pages
 11125                              <1> 	;	(will be converted to writable pages).
 11126                              <1> 	;
 11127                              <1> 	; Modified Registers -> EAX
 11128                              <1> 	;
 11129 000030CB 56                  <1> 	push	esi
 11130 000030CC 57                  <1> 	push	edi
 11131 000030CD 52                  <1> 	push	edx
 11132 000030CE 50                  <1> 	push	eax ; *
 11133 000030CF 89C6                <1> 	mov	esi, eax 
 11134 000030D1 31FF                <1> 	xor	edi, edi ; 0
 11135                              <1> dapt_0:
 11136 000030D3 AD                  <1> 	lodsd
 11137 000030D4 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
 11138 000030D6 7455                <1> 	jz	short dapt_1
 11139                              <1> 	;
 11140 000030D8 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
 11141                              <1> 				  ; (must be 1)
 11142 000030DA 753F                <1> 	jnz	short dapt_3
 11143                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
 11144 000030DC 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
 11145                              <1> 				   ; as child's page ?
 11146 000030E0 7444                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
 11147                              <1> 	; check the parent's PTE value is read only & same page or not.. 
 11148                              <1> 	; ECX = page directory entry index (0-1023)
 11149 000030E2 53                  <1> 	push	ebx
 11150 000030E3 51                  <1> 	push	ecx
 11151 000030E4 66C1E102            <1> 	shl	cx, 2 ; *4 
 11152 000030E8 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
 11153 000030EA 8B0B                <1> 	mov	ecx, [ebx]
 11154 000030EC F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
 11155 000030EF 7428                <1> 	jz	short dapt_2	; parent process does not use this page
 11156 000030F1 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11157                              <1> 	; EDI = page table entry index (0-1023)
 11158 000030F6 89FA                <1> 	mov	edx, edi 
 11159 000030F8 66C1E202            <1> 	shl	dx, 2 ; *4 
 11160 000030FC 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
 11161 000030FE 8B1A                <1> 	mov	ebx, [edx]
 11162 00003100 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
 11163 00003103 7414                <1> 	jz	short dapt_2	; parent process does not use this page
 11164 00003105 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
 11165 00003109 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
 11166 0000310E 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
 11167 00003110 7507                <1> 	jne	short dapt_2	; not same page
 11168                              <1> 				; deallocate the child's page
 11169 00003112 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
 11170 00003115 59                  <1> 	pop	ecx
 11171 00003116 5B                  <1> 	pop	ebx
 11172 00003117 EB0D                <1> 	jmp	short dapt_4
 11173                              <1> 
 11174                              <1> ; 17/04/2021
 11175                              <1> ; ('dapt_1' is disabled as temporary)
 11176                              <1> ;
 11177                              <1> ;dapt_1:
 11178                              <1> ;	or	eax, eax	; swapped page ?
 11179                              <1> ;	jz	short dapt_5	; no
 11180                              <1> ;				; yes
 11181                              <1> ;	shr	eax, 1
 11182                              <1> ;	call	unlink_swap_block ; Deallocate swapped page block
 11183                              <1> ;				  ; on the swap disk (or in file)
 11184                              <1> ;	jmp	short dapt_5
 11185                              <1> dapt_2:
 11186 00003119 59                  <1> 	pop	ecx
 11187 0000311A 5B                  <1> 	pop	ebx
 11188                              <1> dapt_3:	
 11189                              <1> 	; 12/07/2016
 11190 0000311B 66A90004            <1> 	test	ax, PTE_SHARED ; shared or direct memory access indicator
 11191 0000311F 7505                <1> 	jnz	short dapt_4   ; AVL bit 1 = 1, do not deallocate this page!
 11192                              <1> 	;
 11193                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
 11194 00003121 E814000000          <1> 	call	deallocate_page ; set the mem allocation bit of this page
 11195                              <1> dapt_4:
 11196 00003126 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
 11197                              <1> dapt_1:	; 17/04/2021 (temporary)
 11198                              <1> dapt_5:
 11199 0000312D 47                  <1> 	inc	edi ; page table entry index
 11200 0000312E 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
 11201 00003134 729D                <1> 	jb	short dapt_0
 11202                              <1> 	;
 11203 00003136 58                  <1> 	pop	eax ; *
 11204 00003137 5A                  <1> 	pop	edx
 11205 00003138 5F                  <1> 	pop	edi	
 11206 00003139 5E                  <1> 	pop	esi
 11207                              <1> 	;
 11208                              <1> 	;call	deallocate_page	; deallocate the page table's itself
 11209                              <1> 	;retn
 11210                              <1> 
 11211                              <1> deallocate_page:
 11212                              <1> 	; 15/09/2015
 11213                              <1> 	; 28/04/2015
 11214                              <1> 	; 10/03/2015
 11215                              <1> 	; 17/10/2014
 11216                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
 11217                              <1> 	;
 11218                              <1> 	; INPUT -> 
 11219                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11220                              <1> 	; OUTPUT ->
 11221                              <1> 	;	[free_pages] is increased
 11222                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
 11223                              <1> 	;	CF = 1 if the page is already deallocated
 11224                              <1> 	; 	       (or not allocated) before.  
 11225                              <1> 	;
 11226                              <1> 	; Modified Registers -> EAX
 11227                              <1> 	;
 11228 0000313A 53                  <1> 	push	ebx
 11229 0000313B 52                  <1> 	push	edx
 11230                              <1> 	;
 11231 0000313C C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
 11232                              <1> 				     ; 12 bits right
 11233                              <1> 				     ; to get page number
 11234 0000313F 89C2                <1> 	mov	edx, eax
 11235                              <1> 	; 15/09/2015
 11236 00003141 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
 11237                              <1> 				     ; (1 allocation bit = 1 page)
 11238                              <1> 				     ; (1 allocation bytes = 8 pages)
 11239 00003144 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
 11240                              <1> 				     ; (to get 32 bit position)			
 11241                              <1> 	;
 11242 00003147 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
 11243 0000314C 01D3                <1> 	add	ebx, edx
 11244 0000314E 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
 11245                              <1> 				     ; (allocation bit position)	 
 11246 00003151 3B15[C46F0000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
 11247                              <1> 				     ; than the address in 'next_page' ?
 11248                              <1> 				     ; (next/first free page value)		
 11249 00003157 7306                <1> 	jnb	short dap_1	     ; no	
 11250 00003159 8915[C46F0000]      <1> 	mov	[next_page], edx     ; yes
 11251                              <1> dap_1:
 11252 0000315F 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
 11253                              <1> 				     ; set relevant bit to 1.
 11254                              <1> 				     ; set CF to the previous bit value	
 11255                              <1> 	;cmc			     ; complement carry flag	
 11256                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
 11257                              <1> 				     ; if the page is already deallocated
 11258                              <1> 				     ; before.	
 11259 00003162 FF05[C06F0000]      <1>         inc     dword [free_pages]
 11260                              <1> dap_2:
 11261 00003168 5A                  <1> 	pop	edx
 11262 00003169 5B                  <1> 	pop	ebx
 11263 0000316A C3                  <1> 	retn
 11264                              <1> 
 11265                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 11266                              <1> ;;                                                              ;;
 11267                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
 11268                              <1> ;; Distributed under terms of the GNU General Public License    ;;
 11269                              <1> ;;                                                              ;;
 11270                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 11271                              <1> 
 11272                              <1> ;;$Revision: 5057 $
 11273                              <1> 
 11274                              <1> 
 11275                              <1> ;;align 4
 11276                              <1> ;;proc alloc_page
 11277                              <1> 
 11278                              <1> ;;        pushfd
 11279                              <1> ;;        cli
 11280                              <1> ;;        push    ebx
 11281                              <1> ;;;//-
 11282                              <1> ;;        cmp     [pg_data.pages_free], 1
 11283                              <1> ;;        jle     .out_of_memory
 11284                              <1> ;;;//-
 11285                              <1> ;;
 11286                              <1> ;;        mov     ebx, [page_start]
 11287                              <1> ;;        mov     ecx, [page_end]
 11288                              <1> ;;.l1:
 11289                              <1> ;;        bsf     eax, [ebx];
 11290                              <1> ;;        jnz     .found
 11291                              <1> ;;        add     ebx, 4
 11292                              <1> ;;        cmp     ebx, ecx
 11293                              <1> ;;        jb      .l1
 11294                              <1> ;;        pop     ebx
 11295                              <1> ;;        popfd
 11296                              <1> ;;        xor     eax, eax
 11297                              <1> ;;        ret
 11298                              <1> ;;.found:
 11299                              <1> ;;;//-
 11300                              <1> ;;        dec     [pg_data.pages_free]
 11301                              <1> ;;        jz      .out_of_memory
 11302                              <1> ;;;//-
 11303                              <1> ;;        btr     [ebx], eax
 11304                              <1> ;;        mov     [page_start], ebx
 11305                              <1> ;;        sub     ebx, sys_pgmap
 11306                              <1> ;;        lea     eax, [eax+ebx*8]
 11307                              <1> ;;        shl     eax, 12
 11308                              <1> ;;;//-       dec [pg_data.pages_free]
 11309                              <1> ;;        pop     ebx
 11310                              <1> ;;        popfd
 11311                              <1> ;;        ret
 11312                              <1> ;;;//-
 11313                              <1> ;;.out_of_memory:
 11314                              <1> ;;        mov     [pg_data.pages_free], 1
 11315                              <1> ;;        xor     eax, eax
 11316                              <1> ;;        pop     ebx
 11317                              <1> ;;        popfd
 11318                              <1> ;;        ret
 11319                              <1> ;;;//-
 11320                              <1> ;;endp
 11321                              <1> 
 11322                              <1> duplicate_page_dir:
 11323                              <1> 	; 21/09/2015
 11324                              <1> 	; 31/08/2015
 11325                              <1> 	; 20/07/2015
 11326                              <1> 	; 28/04/2015
 11327                              <1> 	; 27/04/2015
 11328                              <1> 	; 18/04/2015
 11329                              <1> 	; 12/04/2015
 11330                              <1> 	; 18/10/2014
 11331                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 11332                              <1> 	;
 11333                              <1> 	; INPUT -> 
 11334                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 11335                              <1> 	;		    page directory.
 11336                              <1> 	; OUTPUT ->
 11337                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 11338                              <1> 	;	       page directory.
 11339                              <1> 	;	(New page directory with new page table entries.)
 11340                              <1> 	;	(New page tables with read only copies of the parent's
 11341                              <1> 	;	pages.)
 11342                              <1> 	;	EAX = 0 -> Error (CF = 1)
 11343                              <1> 	;
 11344                              <1> 	; Modified Registers -> none (except EAX)
 11345                              <1> 	;
 11346 0000316B E802FEFFFF          <1> 	call	allocate_page
 11347 00003170 723E                <1> 	jc	short dpd_err
 11348                              <1> 	;
 11349 00003172 55                  <1> 	push	ebp ; 20/07/2015
 11350 00003173 56                  <1> 	push	esi
 11351 00003174 57                  <1> 	push	edi
 11352 00003175 53                  <1> 	push	ebx
 11353 00003176 51                  <1> 	push	ecx
 11354 00003177 8B35[18710000]      <1> 	mov	esi, [u.pgdir]
 11355 0000317D 89C7                <1> 	mov	edi, eax
 11356 0000317F 50                  <1> 	push	eax ; save child's page directory address
 11357                              <1> 	; 31/08/2015
 11358                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 11359                              <1> 	; (use same system space for all user page tables) 
 11360 00003180 A5                  <1> 	movsd
 11361 00003181 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 11362 00003186 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 11363                              <1> dpd_0:	
 11364 0000318B AD                  <1> 	lodsd
 11365                              <1> 	;or	eax, eax
 11366                              <1>         ;jnz     short dpd_1
 11367 0000318C A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 11368 0000318E 7508                <1> 	jnz	short dpd_1
 11369                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
 11370 00003190 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 11371 00003196 EB0F                <1> 	jmp	short dpd_2
 11372                              <1> dpd_1:	
 11373 00003198 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 11374 0000319C 89C3                <1> 	mov	ebx, eax
 11375                              <1> 	; EBX = Parent's page table address
 11376 0000319E E81F000000          <1> 	call	duplicate_page_table
 11377 000031A3 720C                <1> 	jc	short dpd_p_err
 11378                              <1> 	; EAX = Child's page table address
 11379 000031A5 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 11380                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 11381                              <1> 			 ; (present, writable, user)
 11382                              <1> dpd_2:
 11383 000031A7 AB                  <1> 	stosd
 11384 000031A8 E2E1                <1> 	loop	dpd_0
 11385                              <1> 	;
 11386 000031AA 58                  <1> 	pop	eax  ; restore child's page directory address
 11387                              <1> dpd_3:
 11388 000031AB 59                  <1> 	pop	ecx
 11389 000031AC 5B                  <1> 	pop	ebx
 11390 000031AD 5F                  <1> 	pop	edi
 11391 000031AE 5E                  <1> 	pop	esi
 11392 000031AF 5D                  <1> 	pop	ebp ; 20/07/2015
 11393                              <1> dpd_err:
 11394 000031B0 C3                  <1> 	retn
 11395                              <1> dpd_p_err:
 11396                              <1> 	; release the allocated pages missing (recover free space)
 11397 000031B1 58                  <1> 	pop	eax  ; the new page directory address (physical)
 11398 000031B2 8B1D[18710000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 11399 000031B8 E8E5FEFFFF          <1> 	call 	deallocate_page_dir
 11400 000031BD 29C0                <1> 	sub	eax, eax ; 0
 11401 000031BF F9                  <1> 	stc
 11402 000031C0 EBE9                <1> 	jmp	short dpd_3	
 11403                              <1> 
 11404                              <1> duplicate_page_table:
 11405                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 11406                              <1> 	;	 (temporary modifications)
 11407                              <1> 	; 16/04/2021 (Retro UNIX 386 v2)
 11408                              <1> 	; 20/02/2017 (TRDOS 386 v2)
 11409                              <1> 	; 21/09/2015
 11410                              <1> 	; 20/07/2015
 11411                              <1> 	; 05/05/2015
 11412                              <1> 	; 28/04/2015
 11413                              <1> 	; 27/04/2015
 11414                              <1> 	; 18/04/2015
 11415                              <1> 	; 18/10/2014
 11416                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
 11417                              <1> 	;
 11418                              <1> 	; INPUT -> 
 11419                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 11420                              <1> 	;       20/02/2017		 
 11421                              <1> 	;	EBP = Linear address of the page (from 'duplicate_page_dir')
 11422                              <1> 	;	      (Linear address = CORE + user's virtual address) 	
 11423                              <1> 	; OUTPUT ->
 11424                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 11425                              <1> 	;	      (with 'read only' attribute of page table entries)
 11426                              <1> 	;	20/02/2017
 11427                              <1> 	;	EBP = Next linear page address (for 'duplicate_page_dir')
 11428                              <1> 	;	
 11429                              <1> 	;	CF = 1 -> error 
 11430                              <1> 	;
 11431                              <1> 	; Modified Registers -> EBP (except EAX)
 11432                              <1> 	;
 11433 000031C2 E8ABFDFFFF          <1> 	call	allocate_page
 11434 000031C7 7258                <1> 	jc	short dpt_err
 11435                              <1> 	;
 11436 000031C9 50                  <1> 	push	eax ; *
 11437 000031CA 56                  <1> 	push	esi
 11438 000031CB 57                  <1> 	push	edi
 11439 000031CC 52                  <1> 	push	edx
 11440 000031CD 51                  <1> 	push	ecx
 11441                              <1> 	;
 11442 000031CE 89DE                <1> 	mov	esi, ebx
 11443 000031D0 89C7                <1> 	mov	edi, eax
 11444 000031D2 89C2                <1> 	mov	edx, eax
 11445 000031D4 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 11446                              <1> dpt_0:
 11447 000031DA AD                  <1> 	lodsd
 11448 000031DB 21C0                <1> 	and	eax, eax
 11449 000031DD 7432                <1> 	jz	short dpt_3
 11450 000031DF A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
 11451                              <1> 	; 17/04/2021 (temporary)
 11452                              <1> 	;jnz	short dpt_1
 11453 000031E1 7439                <1> 	jz	short dpt_p_err
 11454                              <1> 
 11455                              <1> ; 17/04/2021
 11456                              <1> ; ('reload_page' procedure call is disabled as temporary)
 11457                              <1> ;
 11458                              <1> ;	; 20/07/2015
 11459                              <1> ;	; ebp = virtual (linear) address of the memory page
 11460                              <1> ;	call	reload_page ; 28/04/2015
 11461                              <1> ;	jc	short dpt_p_err
 11462                              <1> dpt_1:
 11463                              <1> 	; 21/09/2015
 11464 000031E3 89C1                <1> 	mov	ecx, eax
 11465 000031E5 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11466 000031E9 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
 11467 000031EC 751A                <1> 	jnz	short dpt_2
 11468                              <1> 	; Read only (parent) page
 11469                              <1> 	; 	- there is a third process which uses this page -
 11470                              <1> 	; Allocate a new page for the child process
 11471 000031EE E87FFDFFFF          <1> 	call	allocate_page
 11472 000031F3 7227                <1> 	jc	short dpt_p_err
 11473 000031F5 57                  <1> 	push	edi
 11474 000031F6 56                  <1> 	push	esi
 11475 000031F7 89CE                <1> 	mov	esi, ecx
 11476 000031F9 89C7                <1> 	mov	edi, eax
 11477 000031FB B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 11478 00003200 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 11479 00003202 5E                  <1> 	pop	esi
 11480 00003203 5F                  <1> 	pop	edi
 11481                              <1> 	;
 11482                              <1> 
 11483                              <1> ; 17/04/2021
 11484                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
 11485                              <1> ; 
 11486                              <1> ;	push	ebx
 11487                              <1> ;	push	eax
 11488                              <1> ;	; 20/07/2015
 11489                              <1> ;	mov	ebx, ebp
 11490                              <1> ;	; ebx = virtual (linear) address of the memory page
 11491                              <1> ;	call	add_to_swap_queue
 11492                              <1> ;	pop	eax
 11493                              <1> ;	pop	ebx
 11494                              <1> 
 11495                              <1> 	; 21/09/2015
 11496 00003204 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 11497                              <1> 		; user + writable + present page
 11498 00003206 EB09                <1> 	jmp	short dpt_3
 11499                              <1> dpt_2:
 11500                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 11501 00003208 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
 11502                              <1> 		    ; (read only page!)
 11503 0000320A 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
 11504 0000320D 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
 11505                              <1> dpt_3:
 11506 00003211 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 11507                              <1> 	;
 11508 00003212 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 11509                              <1> 	;
 11510 00003218 39D7                <1> 	cmp	edi, edx
 11511 0000321A 72BE                <1> 	jb	short dpt_0
 11512                              <1> dpt_p_err:
 11513 0000321C 59                  <1> 	pop	ecx
 11514 0000321D 5A                  <1> 	pop	edx
 11515 0000321E 5F                  <1> 	pop	edi
 11516 0000321F 5E                  <1> 	pop	esi
 11517 00003220 58                  <1> 	pop	eax ; *
 11518                              <1> dpt_err:
 11519 00003221 C3                  <1> 	retn
 11520                              <1> 
 11521                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
 11522                              <1> 	; 17/04/2021 - Retro UNIX 386 v2
 11523                              <1> 	;	 (temporary modifications)
 11524                              <1> 	; 21/09/2015
 11525                              <1> 	; 19/09/2015
 11526                              <1> 	; 17/09/2015
 11527                              <1> 	; 28/08/2015
 11528                              <1> 	; 20/07/2015
 11529                              <1> 	; 28/06/2015
 11530                              <1> 	; 03/05/2015
 11531                              <1> 	; 30/04/2015
 11532                              <1> 	; 18/04/2015
 11533                              <1> 	; 12/04/2015
 11534                              <1> 	; 30/10/2014
 11535                              <1> 	; 11/09/2014
 11536                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
 11537                              <1> 	;
 11538                              <1> 	; Note: This is not an interrupt/exception handler.
 11539                              <1> 	;	This is a 'page fault remedy' subroutine 
 11540                              <1> 	;	which will be called by standard/uniform
 11541                              <1> 	;	exception handler.
 11542                              <1> 	;
 11543                              <1> 	; INPUT -> 
 11544                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
 11545                              <1> 	;
 11546                              <1> 	;	cr2 = the virtual (linear) address 
 11547                              <1> 	;	      which has caused to page fault (19/09/2015)
 11548                              <1> 	;
 11549                              <1> 	; OUTPUT ->
 11550                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11551                              <1> 	;	EAX = 0 -> no error
 11552                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
 11553                              <1> 	;
 11554                              <1> 	; Modified Registers -> none (except EAX)
 11555                              <1> 	;	
 11556                              <1>         ;
 11557                              <1>         ; ERROR CODE:
 11558                              <1> 	;	 31  .....	4   3	2   1	0
 11559                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11560                              <1> 	;	|   Reserved  | I | R | U | W | P |
 11561                              <1> 	;	+---+-- --+---+---+---+---+---+---+
 11562                              <1> 	;
 11563                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
 11564                              <1>     	;		a page-protection violation. When not set,
 11565                              <1> 	;		it was caused by a non-present page.
 11566                              <1> 	; W : WRITE   -	When set, the page fault was caused by
 11567                              <1> 	;		a page write. When not set, it was caused
 11568                              <1> 	;		by a page read.
 11569                              <1> 	; U : USER    -	When set, the page fault was caused 
 11570                              <1> 	;		while CPL = 3. 
 11571                              <1> 	;		This does not necessarily mean that
 11572                              <1> 	;		the page fault was a privilege violation.
 11573                              <1> 	; R : RESERVD -	When set, the page fault was caused by
 11574                              <1> 	;     WRITE	reading a 1 in a reserved field.
 11575                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
 11576                              <1> 	;     FETCH	an instruction fetch
 11577                              <1> 	;
 11578                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
 11579                              <1> 	;  31               22                  12 11                    0
 11580                              <1> 	; +-------------------+-------------------+-----------------------+
 11581                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
 11582                              <1>        	; +-------------------+-------------------+-----------------------+
 11583                              <1> 	;
 11584                              <1> 
 11585                              <1> 	;; CR3 REGISTER (Control Register 3)
 11586                              <1> 	;  31                                   12             5 4 3 2   0
 11587                              <1> 	; +---------------------------------------+-------------+---+-----+
 11588                              <1>       	; |                                       |  		|P|P|     |
 11589                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
 11590                              <1>       	; |                                       | 		|D|T|     |
 11591                              <1>    	; +---------------------------------------+-------------+---+-----+
 11592                              <1> 	;
 11593                              <1> 	;	PWT    - WRITE THROUGH
 11594                              <1> 	;	PCD    - CACHE DISABLE		
 11595                              <1> 	;
 11596                              <1> 	;
 11597                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
 11598                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11599                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11600                              <1>       	; |                                       |     | | | | |P|P|U|R| |
 11601                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
 11602                              <1>       	; |                                       |     | | | | |D|T|S|W| |
 11603                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11604                              <1> 	;
 11605                              <1>         ;       P      - PRESENT
 11606                              <1>         ;       R/W    - READ/WRITE
 11607                              <1>         ;       U/S    - USER/SUPERVISOR
 11608                              <1> 	;	PWT    - WRITE THROUGH
 11609                              <1> 	;	PCD    - CACHE DISABLE	
 11610                              <1> 	;	A      - ACCESSED	
 11611                              <1>         ;       D      - DIRTY (IGNORED)
 11612                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11613                              <1> 	;	G      - GLOBAL	(IGNORED) 
 11614                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11615                              <1> 	;
 11616                              <1> 	;
 11617                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
 11618                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11619                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11620                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
 11621                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
 11622                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
 11623                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
 11624                              <1> 	;
 11625                              <1>         ;       P      - PRESENT
 11626                              <1>         ;       R/W    - READ/WRITE
 11627                              <1>         ;       U/S    - USER/SUPERVISOR
 11628                              <1> 	;	PWT    - WRITE THROUGH
 11629                              <1> 	;	PCD    - CACHE DISABLE	
 11630                              <1> 	;	A      - ACCESSED	
 11631                              <1>         ;       D      - DIRTY
 11632                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
 11633                              <1> 	;	G      - GLOBAL	 
 11634                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11635                              <1> 	;
 11636                              <1> 	;
 11637                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
 11638                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 11639                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11640                              <1>       	; |                                       |     | | | | | | |U|R| |
 11641                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
 11642                              <1>       	; |                                       |     | | | | | | |S|W| |
 11643                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
 11644                              <1> 	;
 11645                              <1>         ;       P      - PRESENT
 11646                              <1>         ;       R/W    - READ/WRITE
 11647                              <1>         ;       U/S    - USER/SUPERVISOR
 11648                              <1>         ;       D      - DIRTY
 11649                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
 11650                              <1> 	;
 11651                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
 11652                              <1> 	;
 11653                              <1> 	;
 11654                              <1> 	;; Invalid Page Table Entry
 11655                              <1> 	; 31                                                           1 0
 11656                              <1>       	; +-------------------------------------------------------------+-+
 11657                              <1>       	; |                                                             | |
 11658                              <1>       	; |                          AVAILABLE                          |0|
 11659                              <1>       	; |                                                             | |
 11660                              <1>       	; +-------------------------------------------------------------+-+
 11661                              <1> 	;
 11662                              <1> 
 11663 00003222 53                  <1> 	push	ebx
 11664 00003223 52                  <1> 	push	edx
 11665 00003224 51                  <1> 	push	ecx
 11666                              <1> 	;
 11667                              <1> 	; 21/09/2015 (debugging)
 11668 00003225 FF05[30710000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
 11669 0000322B FF05[50820000]      <1> 	inc	dword [PF_Count]  ; total page fault count	
 11670                              <1> 	; 28/06/2015
 11671                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
 11672 00003231 8A15[48820000]      <1> 	mov	dl, [error_code]
 11673                              <1> 	;
 11674 00003237 F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
 11675                              <1> 			; sign
 11676 0000323A 741A                <1> 	jz	short pfh_alloc_np
 11677                              <1> 	; 
 11678                              <1> 	; If it is not a 'write on read only page' type page fault
 11679                              <1> 	; major page fault error with minor reason must be returned without 
 11680                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
 11681                              <1> 	; after return here!
 11682                              <1> 	; Page fault will be remedied, by copying page contents
 11683                              <1> 	; to newly allocated page with write permission;
 11684                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
 11685                              <1> 	; used for working with minimum possible memory usage. 
 11686                              <1> 	; sys_fork will duplicate page directory and tables of parent  
 11687                              <1> 	; process with 'read only' flag. If the child process attempts to
 11688                              <1> 	; write on these read only pages, page fault will be directed here
 11689                              <1> 	; for allocating a new page with same data/content. 
 11690                              <1> 	;
 11691                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
 11692                              <1> 	; will not force to separate CODE and DATA space 
 11693                              <1> 	; in a process/program... 
 11694                              <1> 	; CODE segment/section may contain DATA!
 11695                              <1> 	; It is flat, smoth and simplest programming method already as in 
 11696                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
 11697                              <1> 	;	
 11698 0000323C F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
 11699                              <1> 			; sign
 11700 0000323F 0F8481000000        <1>         jz      pfh_p_err
 11701                              <1> 	; 31/08/2015
 11702 00003245 F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
 11703                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
 11704 00003248 747C                <1>         jz	pfh_pv_err
 11705                              <1> 	;
 11706                              <1> 	; make a new page and copy the parent's page content
 11707                              <1> 	; as the child's new page content
 11708                              <1> 	;
 11709 0000324A 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
 11710                              <1> 			 ; which has caused to page fault
 11711 0000324D E87C000000          <1> 	call 	copy_page
 11712 00003252 726B                <1>         jc      pfh_im_err ; insufficient memory
 11713                              <1> 	;
 11714 00003254 EB63                <1>         jmp     pfh_cpp_ok
 11715                              <1> 	;
 11716                              <1> pfh_alloc_np:
 11717 00003256 E817FDFFFF          <1> 	call	allocate_page	; (allocate a new page)
 11718 0000325B 7262                <1>         jc      pfh_im_err	; 'insufficient memory' error
 11719                              <1> pfh_chk_cpl:
 11720                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11721                              <1> 		; (Lower 12 bits are ZERO, because 
 11722                              <1> 		;	the address is on a page boundary)
 11723 0000325D 80E204              <1> 	and	dl, 4	; CPL = 3 ?
 11724 00003260 7505                <1> 	jnz	short pfh_um
 11725                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
 11726 00003262 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
 11727                              <1> 			 ; of the current/active page directory
 11728                              <1> 			 ; (Always kernel/system mode page directory, here!)
 11729                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
 11730 00003265 EB06                <1> 	jmp	short pfh_get_pde
 11731                              <1> 	;
 11732                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
 11733 00003267 8B1D[18710000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
 11734                              <1> 			; Physical address of the USER's page directory
 11735                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
 11736                              <1> pfh_get_pde:
 11737 0000326D 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
 11738 00003270 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
 11739                              <1> 			 ; which has been caused to page fault
 11740                              <1> 			 ;
 11741 00003273 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
 11742 00003276 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
 11743                              <1> 	;
 11744 00003279 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
 11745 0000327B 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
 11746 0000327D F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
 11747 00003280 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
 11748                              <1> 			  	  ; set/validate page directory entry
 11749 00003282 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
 11750 00003287 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
 11751 00003289 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
 11752 0000328B EB16                <1> 	jmp	short pfh_get_pte
 11753                              <1> pfh_set_pde:
 11754                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
 11755                              <1> 	;;	 (So, we know this PDE is empty or invalid)
 11756                              <1> 	;
 11757 0000328D 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
 11758 0000328F 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
 11759 00003291 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
 11760 00003293 89C3                <1> 	mov	ebx, eax
 11761 00003295 E8D8FCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
 11762 0000329A 7223                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
 11763                              <1> pfh_spde_1:
 11764                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 11765 0000329C 89C1                <1> 	mov	ecx, eax
 11766 0000329E E840FDFFFF          <1> 	call	clear_page ; Clear page content
 11767                              <1> pfh_get_pte:
 11768 000032A3 0F20D0              <1> 	mov	eax, cr2 ; virtual address
 11769                              <1> 			 ; which has been caused to page fault
 11770 000032A6 89C7                <1> 	mov	edi, eax ; 20/07/2015
 11771 000032A8 C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
 11772                              <1> 			 ; higher 20 bits of the page fault address 
 11773 000032AB 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
 11774 000032B0 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
 11775 000032B3 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
 11776                              <1> ; 17/04/2021 temporary
 11777                              <1> ;	mov	eax, [ebx] ; get previous value of pte
 11778                              <1> ;		; bit 0 of EAX is always 0 (otherwise we would not be here)
 11779                              <1> ; 17/04/2021
 11780                              <1> ; ('swap_in' procedure call has been disabled as temporary)
 11781                              <1> ;
 11782                              <1> ;	and	eax, eax
 11783                              <1> ;	jz	short pfh_gpte_1
 11784                              <1> ;	; 20/07/2015
 11785                              <1> ;	xchg	ebx, ecx ; new page address (physical)
 11786                              <1> ;	push	ebp ; 20/07/2015
 11787                              <1> ;	mov	ebp, cr2
 11788                              <1> ;		; ECX = physical address of the page table entry
 11789                              <1> ;		; EBX = Memory page address (physical!)
 11790                              <1> ;		; EAX = Swap disk (offset) address
 11791                              <1> ;		; EBP = virtual address (page fault address)
 11792                              <1> ;	call	swap_in
 11793                              <1> ;	pop	ebp
 11794                              <1> ;	jc      short pfh_err_retn
 11795                              <1> ;	xchg	ecx, ebx
 11796                              <1> ;		; EBX = physical address of the page table entry
 11797                              <1> ;		; ECX = new page
 11798                              <1> pfh_gpte_1:
 11799 000032B5 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
 11800 000032B7 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
 11801                              <1> pfh_cpp_ok:
 11802                              <1> ; 17/04/2021
 11803                              <1> ; ('add_to_swap_queue' procedure call has been disabled as temporary)
 11804                              <1> ;
 11805                              <1> ;	; 20/07/2015
 11806                              <1> ;	mov	ebx, cr2
 11807                              <1> ;	call 	add_to_swap_queue
 11808                              <1> 	;
 11809                              <1> 	; The new PTE (which contains the new page) will be added to 
 11810                              <1> 	; the swap queue, here. 
 11811                              <1> 	; (Later, if memory will become insufficient, 
 11812                              <1> 	; one page will be swapped out which is at the head of 
 11813                              <1> 	; the swap queue by using FIFO and access check methods.)
 11814                              <1> 	;
 11815 000032B9 31C0                <1> 	xor	eax, eax  ; 0
 11816                              <1> 	;
 11817                              <1> pfh_err_retn:
 11818 000032BB 59                  <1> 	pop	ecx
 11819 000032BC 5A                  <1> 	pop	edx
 11820 000032BD 5B                  <1> 	pop	ebx
 11821 000032BE C3                  <1> 	retn 
 11822                              <1> 	
 11823                              <1> pfh_im_err:
 11824 000032BF B8E4000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
 11825                              <1> 			; Major (Primary) Error: Page Fault
 11826                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
 11827 000032C4 EBF5                <1> 	jmp	short pfh_err_retn
 11828                              <1> 
 11829                              <1> pfh_p_err: ; 09/03/2015
 11830                              <1> pfh_pv_err:
 11831                              <1> 	; Page fault was caused by a protection-violation
 11832 000032C6 B8E6000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
 11833                              <1> 			; Major (Primary) Error: Page Fault
 11834                              <1> 			; Minor (Secondary) Error: Protection violation !
 11835 000032CB F9                  <1> 	stc
 11836 000032CC EBED                <1> 	jmp	short pfh_err_retn
 11837                              <1> 
 11838                              <1> copy_page:
 11839                              <1> 	; 16/04/2021
 11840                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11841                              <1> 	; 22/09/2015
 11842                              <1> 	; 21/09/2015
 11843                              <1> 	; 19/09/2015
 11844                              <1> 	; 07/09/2015
 11845                              <1> 	; 31/08/2015
 11846                              <1> 	; 20/07/2015
 11847                              <1> 	; 05/05/2015
 11848                              <1> 	; 03/05/2015
 11849                              <1> 	; 18/04/2015
 11850                              <1> 	; 12/04/2015
 11851                              <1> 	; 30/10/2014
 11852                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
 11853                              <1> 	;
 11854                              <1> 	; INPUT -> 
 11855                              <1> 	;	EBX = Virtual (linear) address of source page
 11856                              <1> 	;	     (Page fault address)
 11857                              <1> 	; OUTPUT ->
 11858                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11859                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11860                              <1> 	;	EAX = 0 (CF = 1) 
 11861                              <1> 	;		if there is not a free page to be allocated
 11862                              <1> 	;	(page content of the source page will be copied
 11863                              <1> 	;	onto the target/new page) 	
 11864                              <1> 	;
 11865                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
 11866                              <1> 	;
 11867                              <1> 
 11868                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11869                              <1> 	; INPUT: 
 11870                              <1> 	;	EBX = Virtual (linear) address of source page
 11871                              <1> 	;	     (Page fault address)
 11872                              <1> 	; OUTPUT:
 11873                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
 11874                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
 11875                              <1> 	;	EAX = 0 (CF = 1) 
 11876                              <1> 	;		if there is not a free page to be allocated
 11877                              <1> 	;	(page content of the source page will be copied
 11878                              <1> 	;	onto the target/new page) 	
 11879                              <1> 	;
 11880                              <1> 	; Modified Registers -> ecx, ebx (except EAX) ; 16/04/2021
 11881                              <1> 	
 11882 000032CE 56                  <1> 	push	esi ; *
 11883 000032CF 57                  <1> 	push	edi ; **
 11884                              <1> 	; 16/04/2021
 11885                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11886                              <1> 	;push	ebx ; ***
 11887                              <1> 	;push	ecx ; ****
 11888 000032D0 31F6                <1> 	xor 	esi, esi
 11889 000032D2 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
 11890 000032D5 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
 11891 000032D7 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
 11892 000032DA 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
 11893 000032DD 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
 11894 000032DF 031D[18710000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
 11895 000032E5 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
 11896 000032E7 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
 11897 000032EB 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
 11898 000032ED 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11899 000032F3 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
 11900 000032F7 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
 11901                              <1> 	; 07/09/2015
 11902 000032F9 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
 11903                              <1> 				     ; read only page as a child process?)	
 11904 000032FE 7509                <1> 	jnz	short cpp_0 ; yes
 11905 00003300 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
 11906 00003302 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
 11907 00003307 EB32                <1> 	jmp	short cpp_1
 11908                              <1> cpp_0:
 11909 00003309 89FE                <1> 	mov	esi, edi
 11910 0000330B 0335[1C710000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
 11911 00003311 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
 11912 00003313 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 11913 00003317 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
 11914 00003319 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
 11915 0000331F 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
 11916 00003323 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
 11917 00003325 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
 11918                              <1> 	; 21/09/2015
 11919 00003327 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
 11920 00003329 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
 11921                              <1> 	;
 11922 0000332D F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
 11923 00003330 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
 11924                              <1> 	;
 11925 00003332 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
 11926 00003337 39C8                <1> 	cmp	eax, ecx   ; Same page?	
 11927 00003339 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
 11928                              <1> 			    ; Convert child's page to writable page
 11929                              <1> cpp_1:
 11930 0000333B E832FCFFFF          <1> 	call	allocate_page
 11931 00003340 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
 11932 00003342 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
 11933 00003344 7405                <1> 	jz	short cpp_2
 11934                              <1> 		; Convert read only page to writable page 
 11935                              <1> 		;(for the parent of the current process)
 11936                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
 11937                              <1> 	; 22/09/2015
 11938 00003346 890E                <1> 	mov	[esi], ecx
 11939 00003348 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
 11940                              <1> 				 ; 1+2+4 = 7
 11941                              <1> cpp_2:
 11942 0000334B 89C7                <1> 	mov	edi, eax ; new page address of the child process
 11943                              <1> 	; 07/09/2015
 11944 0000334D 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
 11945 0000334F B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
 11946 00003354 F3A5                <1> 	rep	movsd ; 31/08/2015
 11947                              <1> cpp_3:		
 11948 00003356 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
 11949 00003358 8903                <1> 	mov	[ebx], eax ; Update PTE
 11950 0000335A 28C0                <1> 	sub	al, al ; clear attributes
 11951                              <1> cpp_4:
 11952                              <1> 	; 16/04/2021
 11953                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 11954                              <1> 	;pop	ecx ; ****
 11955                              <1> 	;pop	ebx ; ***
 11956 0000335C 5F                  <1> 	pop	edi ; **
 11957 0000335D 5E                  <1> 	pop	esi ; *
 11958 0000335E C3                  <1> 	retn
 11959                              <1> 
 11960                              <1> ;; 28/04/2015
 11961                              <1> ;; 24/10/2014
 11962                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
 11963                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
 11964                              <1> ;;
 11965                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
 11966                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
 11967                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
 11968                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
 11969                              <1> ;;
 11970                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
 11971                              <1> ;;
 11972                              <1> ;; Method:
 11973                              <1> ;;	Swap page queue is a list of allocated pages with physical
 11974                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
 11975                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
 11976                              <1> ;;	When a new page is being allocated, swap queue is updated
 11977                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
 11978                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
 11979                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
 11980                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
 11981                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
 11982                              <1> ;;	offset value becomes it's previous offset value - 4.
 11983                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
 11984                              <1> ;;	the queue/list is not shifted.
 11985                              <1> ;;	After the queue/list shift, newly allocated page is added
 11986                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
 11987                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
 11988                              <1> ;;	will not be added to the tail of swap page queue.  		 
 11989                              <1> ;;	
 11990                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
 11991                              <1> ;;	the first non-accessed, writable page in the list, 
 11992                              <1> ;;	from the head to the tail. The list is shifted to left 
 11993                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
 11994                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
 11995                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
 11996                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
 11997                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
 11998                              <1> ;;	procedure will be failed)...
 11999                              <1> ;;
 12000                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
 12001                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
 12002                              <1> ;;	(PTE) will be added to the tail of the queue after
 12003                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
 12004                              <1> ;;	the queue will be rotated and the PTE in the head will be
 12005                              <1> ;;	added to the tail after resetting 'accessed' bit. 
 12006                              <1> ;;
 12007                              <1> ;;
 12008                              <1> ;;	
 12009                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
 12010                              <1> ;;
 12011                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
 12012                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
 12013                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
 12014                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
 12015                              <1> ;;
 12016                              <1> ;; [swpd_next] = the first free block address in swapped page records
 12017                              <1> ;;    		 for next free block search by 'swap_out' procedure.
 12018                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
 12019                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
 12020                              <1> ;; 		 (entire swap space must be accessed by using
 12021                              <1> ;;		 31 bit offset address) 
 12022                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
 12023                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
 12024                              <1> ;;		  0 for file, or beginning sector of the swap partition
 12025                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
 12026                              <1> ;;
 12027                              <1> ;; 					
 12028                              <1> ;; Method:
 12029                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
 12030                              <1> ;;	procedure swaps out a page from memory to the swap disk 
 12031                              <1> ;;	(partition) or swap file to get a new free page at the memory.
 12032                              <1> ;;	Swapping out is performed by using swap page queue.
 12033                              <1> ;;
 12034                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
 12035                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
 12036                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
 12037                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
 12038                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
 12039                              <1> ;;	Absolute physical (logical) address of the swapped page is 
 12040                              <1> ;;	calculated by adding offset value to the swap partition's 
 12041                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
 12042                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
 12043                              <1> ;;	and offset value is equal to absolute (physical or logical)
 12044                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
 12045                              <1> ;;	is in a partitioned virtual hard disk.) 
 12046                              <1> ;;
 12047                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
 12048                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
 12049                              <1> ;;
 12050                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
 12051                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
 12052                              <1> ;;
 12053                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
 12054                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
 12055                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
 12056                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
 12057                              <1> ;;	it means relevant (respective) block is in use, and, 
 12058                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
 12059                              <1> ;;      swap disk/file block is free.
 12060                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
 12061                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
 12062                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
 12063                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
 12064                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
 12065                              <1> ;;	------------------------------------------------------------
 12066                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
 12067                              <1> ;;	------------------------------------------------------------
 12068                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
 12069                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
 12070                              <1> ;;
 12071                              <1> ;;	..............................................................
 12072                              <1> ;;
 12073                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
 12074                              <1> ;;	then it searches Swap Allocation Table if free count is not
 12075                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
 12076                              <1> ;;	position with value of 1 on the table is converted to swap
 12077                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
 12078                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
 12079                              <1> ;;	number of physical swap disk or virtual swap disk)
 12080                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
 12081                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
 12082                              <1> ;;	(memory page). That will be a direct disk write procedure.
 12083                              <1> ;;	(for preventing late memory allocation, significant waiting). 
 12084                              <1> ;;	If disk write procedure returns with error or free count of 
 12085                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
 12086                              <1> ;;	'insufficient memory error' (cf=1). 
 12087                              <1> ;;
 12088                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
 12089                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
 12090                              <1> ;;	in other words, 'swap_out' will not check the table for other
 12091                              <1> ;;	free blocks after a disk write error. It will return to 
 12092                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
 12093                              <1> ;;
 12094                              <1> ;;	After writing the page on to swap disk/file address/sector,
 12095                              <1> ;;	'swap_out' procedure returns with that swap (offset) sector
 12096                              <1> ;;	address (cf=0). 
 12097                              <1> ;;
 12098                              <1> ;;	..............................................................
 12099                              <1> ;;
 12100                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
 12101                              <1> ;;	file sectors at specified memory page. Then page allocation
 12102                              <1> ;;	procedure updates relevant page table entry with 'present' 
 12103                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
 12104                              <1> ;;	to do, except to terminate the process which is the owner of
 12105                              <1> ;;	the swapped page.
 12106                              <1> ;;
 12107                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
 12108                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
 12109                              <1> ;;	updates [swpd_first] pointer if it is required.
 12110                              <1> ;;
 12111                              <1> ;;	..............................................................	 
 12112                              <1> ;;
 12113                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
 12114                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
 12115                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
 12116                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
 12117                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
 12118                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
 12119                              <1> ;;
 12120                              <1> 
 12121                              <1> ; 17/04/2021
 12122                              <1> ; ('swap_in' procedure call is disabled as temporary)
 12123                              <1> 
 12124                              <1> ; 30/11/2021 - temporary !
 12125                              <1> ;swap_in:
 12126                              <1> 	; 31/08/2015
 12127                              <1> 	; 20/07/2015
 12128                              <1> 	; 28/04/2015
 12129                              <1> 	; 18/04/2015
 12130                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12131                              <1> 	;
 12132                              <1> 	; INPUT -> 
 12133                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
 12134                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
 12135                              <1> 	;	EAX = Offset Address for the swapped page on the
 12136                              <1> 	;	      swap disk or in the swap file.
 12137                              <1> 	;
 12138                              <1> 	; OUTPUT ->
 12139                              <1> 	;	EAX = 0 if loading at memory has been successful
 12140                              <1> 	;
 12141                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
 12142                              <1> 	;		  or sector not present or drive not ready
 12143                              <1> 	;	     EAX = Error code
 12144                              <1> 	;	     [u.error] = EAX 
 12145                              <1> 	;		       = The last error code for the process
 12146                              <1> 	;		         (will be reset after returning to user)	  
 12147                              <1> 	;
 12148                              <1> 	; Modified Registers -> EAX
 12149                              <1> 	;
 12150                              <1> 
 12151                              <1> ;       cmp     dword [swp_drv], 0
 12152                              <1> ;	jna	short swpin_dnp_err
 12153                              <1> ;
 12154                              <1> ;	cmp	eax, [swpd_size]
 12155                              <1> ;	jnb	short swpin_snp_err
 12156                              <1> ;
 12157                              <1> ;	push	esi
 12158                              <1> ;	push	ebx
 12159                              <1> ;	push	ecx
 12160                              <1> ;	mov	esi, [swp_drv]	
 12161                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 12162                              <1> ;		; Note: Even if corresponding physical disk's sector 
 12163                              <1> ;		; size different than 512 bytes, logical disk sector
 12164                              <1> ;		; size is 512 bytes and disk reading procedure
 12165                              <1> ;		; will be performed for reading 4096 bytes
 12166                              <1> ;		; (2*2048, 8*512). 
 12167                              <1> ;	; ESI = Logical disk description table address
 12168                              <1> ;	; EBX = Memory page (buffer) address (physical!)
 12169                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
 12170                              <1> ;	; ECX = Sector count ; 8 sectors
 12171                              <1> ;	push	eax
 12172                              <1> ;	call	logical_disk_read
 12173                              <1> ;	pop	eax
 12174                              <1> ;	jnc	short swpin_read_ok
 12175                              <1> ;	;
 12176                              <1> ;	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
 12177                              <1> ;	mov	[u.error], eax
 12178                              <1> ;	jmp	short swpin_retn
 12179                              <1> ;	;
 12180                              <1> ;swpin_read_ok:
 12181                              <1> ;	; EAX = Offset address (logical sector number)
 12182                              <1> ;	call	unlink_swap_block  ; Deallocate swap block	
 12183                              <1> ;	;
 12184                              <1> ;	; EBX = Memory page (buffer) address (physical!)
 12185                              <1> ;	; 20/07/2015
 12186                              <1> ;	mov	ebx, ebp ; virtual address (page fault address)
 12187                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12188                              <1> ;	mov	bl, [u.uno] ; current process number
 12189                              <1> ;	; EBX = Virtual (Linear) address & process number combination
 12190                              <1> ;	call	swap_queue_shift
 12191                              <1> ;	; eax = 0 ; 10/06/2016 (if ebx input > 0, eax output = 0)
 12192                              <1> ;	;sub	eax, eax  ; 0 ; Error Code = 0  (no error)
 12193                              <1> ;	; zf = 1
 12194                              <1> ;swpin_retn:
 12195                              <1> ;	pop	ecx
 12196                              <1> ;	pop	ebx
 12197                              <1> ;	pop	esi
 12198                              <1> ;	retn
 12199                              <1> ;
 12200                              <1> ;swpin_dnp_err:
 12201                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR
 12202                              <1> ;swpin_err_retn:
 12203                              <1> ;	mov	[u.error], eax
 12204                              <1> ;	stc
 12205                              <1> ;	retn
 12206                              <1> ;
 12207                              <1> ;swpin_snp_err:
 12208                              <1> ;	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
 12209                              <1> ;	jmp	short swpin_err_retn
 12210                              <1> 
 12211                              <1> ; 17/04/2021
 12212                              <1> ; ('swap_out' procedure call is disabled as temporary)
 12213                              <1> 
 12214                              <1> ; 30/11/2021 - temporary !
 12215                              <1> ;swap_out:
 12216                              <1> 	; 10/06/2016
 12217                              <1> 	; 07/06/2016
 12218                              <1>         ; 23/05/2016
 12219                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
 12220                              <1> 	; 24/10/2014 - 31/08/2015 (Retro UNIX 386 v1)
 12221                              <1> 	;
 12222                              <1> 	; INPUT -> 
 12223                              <1> 	;	none
 12224                              <1> 	;
 12225                              <1> 	; OUTPUT ->
 12226                              <1> 	;	EAX = Physical page address (which is swapped out
 12227                              <1> 	;	      for allocating a new page)
 12228                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
 12229                              <1> 	;		  or sector not present or drive not ready
 12230                              <1> 	;	     EAX = Error code
 12231                              <1> 	;	     [u.error] = EAX 
 12232                              <1> 	;		       = The last error code for the process
 12233                              <1> 	;		         (will be reset after returning to user)	  
 12234                              <1> 	;
 12235                              <1> 	; Modified Registers -> none (except EAX)
 12236                              <1> 	;
 12237                              <1> 
 12238                              <1> ;	cmp 	word [swpq_count], 1
 12239                              <1> ;       jc      swpout_im_err ; 'insufficient memory'
 12240                              <1> ;
 12241                              <1> ;       ;cmp    dword [swp_drv], 1
 12242                              <1> ;	;jc	short swpout_dnp_err ; 'swap disk/file not present'
 12243                              <1> ;
 12244                              <1> ;       cmp     dword [swpd_free], 1
 12245                              <1> ;       jc      swpout_nfspc_err ; 'no free space on swap disk'
 12246                              <1> ;
 12247                              <1> ;	push	ebx ; *
 12248                              <1> ;swpout_1:
 12249                              <1> ;	; 10/06/2016
 12250                              <1> ;	xor	ebx, ebx ; shift the queue and return a PTE value
 12251                              <1> ;	call	swap_queue_shift
 12252                              <1> ;	and	eax, eax	; 0 = empty queue (improper entries)
 12253                              <1> ;       jz      swpout_npts_err        ; There is not any proper PTE
 12254                              <1> ;				       ; pointer in the swap queue
 12255                              <1> ;	; EAX = PTE value of the page
 12256                              <1> ;	; EBX = PTE address of the page
 12257                              <1> ;	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 12258                              <1> ;	;
 12259                              <1> ;	; 07/06/2016
 12260                              <1> ;	; 19/05/2016
 12261                              <1> ;	; check this page is in timer events or not
 12262                              <1> ;	
 12263                              <1> ;swpout_timer_page_0:
 12264                              <1> ;	push	edx ; **
 12265                              <1> ;
 12266                              <1> ;	; 07/06/2016
 12267                              <1> ;	cmp	byte [timer_events], 0 
 12268                              <1> ;	jna	short swpout_2
 12269                              <1> ;	;
 12270                              <1> ;	mov	dl, [timer_events]
 12271                              <1> ;
 12272                              <1> ;	push	ecx ; ***
 12273                              <1> ;	push	ebx ; ****
 12274                              <1> ;	mov	ebx, timer_set ; beginning address of timer event
 12275                              <1> ;			       ; structures 
 12276                              <1> ;swpout_timer_page_1:
 12277                              <1> ;	mov	cl, [ebx]
 12278                              <1> ;	or	cl, cl ; 0 = free, >0 = process number
 12279                              <1> ;	jz	short swpout_timer_page_3
 12280                              <1> ;	mov	ecx, [ebx+12] ; response (signal return) address
 12281                              <1> ;	and	cx, PTE_A_CLEAR ; clear offset part (right 12 bits)
 12282                              <1> ;				; of the response byte address, to
 12283                              <1> ;				; get beginning of the page address)
 12284                              <1> ;	cmp	eax, ecx
 12285                              <1> ;	jne	short swpout_timer_page_2 ; not same page
 12286                              <1> ;	
 12287                              <1> ;	; !same page!
 12288                              <1> ;	;
 12289                              <1> ;	; NOTE: // 19/05/2016 // - TRDOS 386 feature only ! -
 12290                              <1> ;	; This page will be used by the kernel to put timer event
 12291                              <1> ;	; response (signal return) byte at the requested address;
 12292                              <1> ;	; in order to prevent a possible wrong write (while
 12293                              <1> ;	; this page is swapped out) on physical memory,
 12294                              <1> ;	; we must protect this page against to be swapped out!
 12295                              <1> ;	;
 12296                              <1> ;	pop	ebx ; ****
 12297                              <1> ;	pop	ecx ; ***
 12298                              <1> ;	pop	edx ; **
 12299                              <1> ;	jmp	short swpout_1	; do not swap out this page !
 12300                              <1> ; 
 12301                              <1> ;swpout_timer_page_2:
 12302                              <1> ;	; 07/06/2016
 12303                              <1> ;	dec	dl
 12304                              <1> ;	jz	short swpout_timer_page_4
 12305                              <1> ;swpout_timer_page_3:
 12306                              <1> ;	;cmp	ebx, timer_set + 240 ; last timer event (15*16) 
 12307                              <1> ;	;jnb	short swpout_timer_page_4
 12308                              <1> ;	add	ebx, 16
 12309                              <1> ;	jmp	short swpout_timer_page_1	
 12310                              <1> ;
 12311                              <1> ;swpout_timer_page_4:
 12312                              <1> ;	pop	ebx ; ****
 12313                              <1> ;	pop	ecx ; ***
 12314                              <1> ;swpout_2:
 12315                              <1> ;	mov	edx, ebx	       ; Page table entry address	
 12316                              <1> ;	mov	ebx, eax	       ; Buffer (Page) Address				
 12317                              <1> ;	;
 12318                              <1> ;	call	link_swap_block
 12319                              <1> ;	jnc	short swpout_3	       ; It may not be needed here	
 12320                              <1> ;				       ; because [swpd_free] value
 12321                              <1> ;				       ; was checked at the beginging. 	
 12322                              <1> ;	pop	edx ; **
 12323                              <1> ;	pop	ebx ; *
 12324                              <1> ;	jmp	short swpout_nfspc_err 
 12325                              <1> ;swpout_3:
 12326                              <1> ;	test	eax, 80000000h ; test bit 31 (this may not be needed!)
 12327                              <1> ;	jnz	short swpout_nfspc_err  ; 10/06/2016 (bit 31 = 1 !)
 12328                              <1> ;	;	
 12329                              <1> ;	push	esi ; **
 12330                              <1> ;	push	ecx ; ***
 12331                              <1> ;	push	eax ; sector address ; (31 bit !, bit 31 = 0)
 12332                              <1> ;	mov	esi, [swp_drv]	
 12333                              <1> ;	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
 12334                              <1> ;		; Note: Even if corresponding physical disk's sector 
 12335                              <1> ;		; size different than 512 bytes, logical disk sector
 12336                              <1> ;		; size is 512 bytes and disk writing procedure
 12337                              <1> ;		; will be performed for writing 4096 bytes
 12338                              <1> ;		; (2*2048, 8*512). 
 12339                              <1> ;	; ESI = Logical disk description table address
 12340                              <1> ;	; EBX = Buffer (Page) address
 12341                              <1> ;	; EAX = Sector adress (offset address, logical sector number)
 12342                              <1> ;	; ECX = Sector count ; 8 sectors
 12343                              <1> ;	; edx = PTE address
 12344                              <1> ;	call	logical_disk_write
 12345                              <1> ;	; edx = PTE address
 12346                              <1> ;	pop	ecx ; sector address	
 12347                              <1> ;	jnc	short swpout_write_ok
 12348                              <1> ;	;
 12349                              <1> ;	;; call	unlink_swap_block ; this block must be left as 'in use'
 12350                              <1> ;swpout_dw_err:
 12351                              <1> ;	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
 12352                              <1> ;	mov	[u.error], eax
 12353                              <1> ;	jmp	short swpout_retn
 12354                              <1> ;	;
 12355                              <1> ;swpout_write_ok:
 12356                              <1> ;	; EBX = Buffer (page) address
 12357                              <1> ;	; EDX = Page Table Entry address
 12358                              <1> ;	; ECX = Swap disk sector (file block) address (31 bit)
 12359                              <1> ;	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
 12360                              <1> ;	mov 	[edx], ecx 
 12361                              <1> ;		; bit 0 = 0 (swapped page)
 12362                              <1> ;	mov	eax, ebx
 12363                              <1> ;swpout_retn:
 12364                              <1> ;	pop	ecx ; ***
 12365                              <1> ;	pop	esi ; **
 12366                              <1> ;	pop	ebx ; *
 12367                              <1> ;	retn
 12368                              <1> ;
 12369                              <1> ;;swpout_dnp_err:
 12370                              <1> ;;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
 12371                              <1> ;;	jmp	short swpout_err_retn
 12372                              <1> ;swpout_nfspc_err:
 12373                              <1> ;	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
 12374                              <1> ;swpout_err_retn:
 12375                              <1> ;	mov	[u.error], eax
 12376                              <1> ;	;stc
 12377                              <1> ;	retn
 12378                              <1> ;swpout_npts_err:
 12379                              <1> ;	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
 12380                              <1> ;	pop	ebx
 12381                              <1> ;	jmp	short swpout_err_retn
 12382                              <1> ;swpout_im_err:
 12383                              <1> ;	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
 12384                              <1> ;	jmp	short swpout_err_retn
 12385                              <1> 
 12386                              <1> ; 17/04/2021
 12387                              <1> ; ('swap_queue_shift' procedure call is disabled as temporary)
 12388                              <1> 
 12389                              <1> ; 30/11/2021 - temporary !
 12390                              <1> ;swap_queue_shift:
 12391                              <1> 	; 26/03/2017
 12392                              <1> 	; 10/06/2016
 12393                              <1> 	; 09/06/2016 - TRDOS 386 (TRDOS v2.0)
 12394                              <1> 	; 23/10/2014 - 20/07/2015 (Retro UNIX 386 v1)
 12395                              <1> 	;
 12396                              <1> 	; INPUT ->
 12397                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
 12398                              <1> 	;	      and process number combination (bit 0 to 11)
 12399                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
 12400                              <1> 	;	
 12401                              <1> 	; OUTPUT ->
 12402                              <1> 	;	If EBX input > 0 
 12403                              <1> 	;	   the queue will be shifted 4 bytes (dword),
 12404                              <1> 	; 	   from the tail to the head, up to entry offset
 12405                              <1> 	; 	   which points to EBX input value or nothing
 12406                              <1> 	;	   to do if EBX value is not found on the queue.
 12407                              <1> 	;	   (The entry -with EBX value- will be removed
 12408                              <1> 	;	   from the queue if it is found.)
 12409                              <1> 	;
 12410                              <1> 	;	   EAX = 0		
 12411                              <1> 	;
 12412                              <1> 	;	If EBX input = 0
 12413                              <1> 	;	   the queue will be shifted 4 bytes (dword),
 12414                              <1> 	; 	   from the tail to the head, if the PTE address
 12415                              <1> 	;	   which is pointed in head of the queue is marked
 12416                              <1> 	;	   as "accessed" or it is marked as "non present".
 12417                              <1> 	;	   (If "accessed" flag of the PTE -which is pointed
 12418                              <1> 	;	   in the head- is set -to 1-, it will be reset
 12419                              <1> 	;	   -to 0- and then, the queue will be rotated 
 12420                              <1> 	;	   -without dropping pointer of the PTE from 
 12421                              <1> 	;	   the queue- for 4 bytes on head to tail direction.
 12422                              <1> 	;	   Pointer in the head will be moved into the tail,
 12423                              <1> 	;	   other PTEs will be shifted on head direction.)
 12424                              <1> 	;
 12425                              <1> 	;	   Swap queue will be shifted up to the first
 12426                              <1> 	;	   'present' or 'non accessed' page will be found
 12427                              <1> 	;	   (as pointed) on the queue head (then it will be
 12428                              <1>         ;          removed/dropped from the queue).
 12429                              <1> 	;
 12430                              <1> 	;	   EAX (> 0) = PTE value of the page which is
 12431                              <1> 	;		 (it's pointer -virtual address-) dropped
 12432                              <1> 	;		 (removed) from swap queue.
 12433                              <1> 	;	   EBX = PTE address of the page (if EAX > 0)
 12434                              <1> 	;	         which is (it's pointer -virtual address-)
 12435                              <1> 	;		 dropped (removed) from swap queue.
 12436                              <1> 	;
 12437                              <1> 	;	   EAX = 0 -> empty swap queue ! 
 12438                              <1> 	;
 12439                              <1> 	; Modified Registers -> EAX, EBX
 12440                              <1> 	;
 12441                              <1> ;	movzx   eax, word [swpq_count]  ; Max. 1024
 12442                              <1> ;	and	ax, ax
 12443                              <1> ;	jz	short swpqs_retn
 12444                              <1> ;	push	edi
 12445                              <1> ;	push	esi
 12446                              <1> ;	push	ecx
 12447                              <1> ;	mov	esi, swap_queue
 12448                              <1> ;	mov	ecx, eax
 12449                              <1> ;	or	ebx, ebx
 12450                              <1> ;	jz	short swpqs_7
 12451                              <1> ;swpqs_1:
 12452                              <1> ;	lodsd
 12453                              <1> ;	cmp	eax, ebx
 12454                              <1> ;	je	short swpqs_2
 12455                              <1> ;	loop	swpqs_1
 12456                              <1> ;	; 10/06/2016
 12457                              <1> ;	sub	eax, eax 
 12458                              <1> ;	jmp	short swpqs_6
 12459                              <1> ;swpqs_2:
 12460                              <1> ;	mov	edi, esi
 12461                              <1> ;	sub 	edi, 4
 12462                              <1> ;swpqs_3:
 12463                              <1> ;	dec	word [swpq_count]
 12464                              <1> ;	jz	short swpqs_5
 12465                              <1> ;swpqs_4:
 12466                              <1> ;	dec 	ecx
 12467                              <1> ;	rep	movsd	; shift up (to the head)
 12468                              <1> ;swpqs_5:
 12469                              <1> ;	xor	eax, eax
 12470                              <1> ;	mov	[edi], eax
 12471                              <1> ;swpqs_6:
 12472                              <1> ;	pop	ecx
 12473                              <1> ;	pop	esi
 12474                              <1> ;	pop	edi
 12475                              <1> ;swpqs_retn:
 12476                              <1> ;	retn		
 12477                              <1> ;swpqs_7:
 12478                              <1> ;	mov	edi, esi ; head
 12479                              <1> ;	lodsd
 12480                              <1> ;	; 20/07/2015
 12481                              <1> ;	mov	ebx, eax
 12482                              <1> ;	and	ebx, ~PAGE_OFF ; ~0FFFh 
 12483                              <1> ;		      ; ebx = virtual address (at page boundary)	
 12484                              <1> ;	and	eax, PAGE_OFF ; 0FFFh
 12485                              <1> ;		      ; ax = process number (1 to 4095)
 12486                              <1> ;	cmp	al, [u.uno]
 12487                              <1> ;		; Max. 16 (nproc) processes for Retro UNIX 386 v1
 12488                              <1> ;	jne	short swpqs_8
 12489                              <1> ;	mov	eax, [u.pgdir]
 12490                              <1> ;	jmp	short swpqs_9
 12491                              <1> ;swpqs_8:
 12492                              <1> ;	; 09/06/2016
 12493                              <1> ;	cmp	byte [eax+p.stat-1], 0
 12494                              <1> ;	jna	short swpqs_3     ; free (or terminated) process
 12495                              <1> ;	cmp	byte [eax+p.stat-1], 2 ; waiting
 12496                              <1> ;	ja	short swpqs_3 	  ; zombie (3) or undefined ?	
 12497                              <1> ;
 12498                              <1> ;	;shl	ax, 2
 12499                              <1> ;	shl	al, 2
 12500                              <1> ;	mov 	eax, [eax+p.upage-4]
 12501                              <1> ;	or	eax, eax
 12502                              <1> ;	jz	short swpqs_3 ; invalid upage
 12503                              <1> ;	add	eax, u.pgdir - user
 12504                              <1> ;			 ; u.pgdir value for the process
 12505                              <1> ;			 ; is in [eax]
 12506                              <1> ;	mov	eax, [eax]
 12507                              <1> ;	and	eax, eax
 12508                              <1> ;	jz	short swpqs_3 ; invalid page directory
 12509                              <1> ;swpqs_9:
 12510                              <1> ;	push	edx
 12511                              <1> ;	; eax = page directory
 12512                              <1> ;	; ebx = virtual address
 12513                              <1> ;	call	get_pte
 12514                              <1> ;	mov	ebx, edx	; PTE address
 12515                              <1> ;	pop	edx
 12516                              <1> ;	; 10/06/2016
 12517                              <1> ;	jc	short swpqs_13 ; empty PDE
 12518                              <1> ;	; EAX = PTE value
 12519                              <1> ;	test	al, PTE_A_PRESENT ; bit 0 = 1
 12520                              <1> ;	jz	short swpqs_13  ; Drop non-present page
 12521                              <1> ;			        ; from the queue (head)
 12522                              <1> ;	test	al, PTE_A_WRITE	; bit 1 = 0 (read only)
 12523                              <1> ;	jz	short swpqs_13  ; Drop read only page
 12524                              <1> ;			        ; from the queue (head) 	
 12525                              <1> ;	;test	al, PTE_A_ACCESS ; bit 5 = 1 (Accessed)
 12526                              <1> ;	;jnz	short swpqs_11  ; present
 12527                              <1> ;			        ; accessed page
 12528                              <1> ;       btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
 12529                              <1> ;	jc	short swpqs_11  ; accessed page
 12530                              <1> ;
 12531                              <1> ;	dec	ecx
 12532                              <1> ;	mov	[swpq_count], cx
 12533                              <1> ;       jz      short swpqs_10
 12534                              <1> ;		; esi = head + 4
 12535                              <1> ;		; edi = head
 12536                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 12537                              <1> ;swpqs_10:
 12538                              <1> ;	mov	[edi], ecx ; 0
 12539                              <1> ;	jmp	short swpqs_6 ; 26/03/2017
 12540                              <1> ;
 12541                              <1> ;swpqs_11:
 12542                              <1> ;	mov	[ebx], eax     ; save changed attribute
 12543                              <1> ;	; Rotation (head -> tail)
 12544                              <1> ;	dec	ecx     ; entry count -> last entry number		
 12545                              <1> ;	jz	short swpqs_10
 12546                              <1> ;		; esi = head + 4
 12547                              <1> ;		; edi = head
 12548                              <1> ;	mov	eax, [edi] ; 20/07/2015
 12549                              <1> ;	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
 12550                              <1> ;	mov	[edi], eax ; head -> tail ; [k] = [1]
 12551                              <1> ;
 12552                              <1> ;	mov	cx, [swpq_count]
 12553                              <1> ;
 12554                              <1> ;swpqs_12:
 12555                              <1> ;	mov	esi, swap_queue ; head
 12556                              <1> ;       jmp     swpqs_7
 12557                              <1> ;
 12558                              <1> ;swpqs_13:
 12559                              <1> ;	dec	ecx
 12560                              <1> ;	mov	[swpq_count], cx
 12561                              <1> ;       jz      swpqs_5
 12562                              <1> ;	jmp	short swpqs_12
 12563                              <1> 
 12564                              <1> ; 17/04/2021
 12565                              <1> ; ('add_to_swp_queue' procedure call is disabled as temporary)
 12566                              <1> 
 12567                              <1> ; 30/11/2021 - temporary !
 12568                              <1> ;add_to_swap_queue:
 12569                              <1> 	; 20/02/2017
 12570                              <1> 	; 20/07/2015
 12571                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12572                              <1> 	;
 12573                              <1> 	; Adds new page to swap queue
 12574                              <1> 	; (page directories and page tables must not be added
 12575                              <1> 	; to swap queue)	
 12576                              <1> 	;
 12577                              <1> 	; INPUT ->
 12578                              <1> 	;	EBX = Linear (Virtual) addr for current process
 12579                              <1> 	;	[u.uno]
 12580                              <1> 	;	20/02/2017
 12581                              <1> 	;	(Linear address = CORE + user's virtual address)
 12582                              <1> 	;
 12583                              <1> 	; OUTPUT ->
 12584                              <1> 	;	EAX = [swpq_count]
 12585                              <1> 	;	      (after the PTE has been added)
 12586                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
 12587                              <1> 	;	      the PTE could not be added.
 12588                              <1> 	;
 12589                              <1> 	; Modified Registers -> EAX
 12590                              <1> 	;
 12591                              <1> ;	push	ebx
 12592                              <1> ;       and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
 12593                              <1> ;	mov	bl, [u.uno] ; current process number
 12594                              <1> ;	call	swap_queue_shift ; drop from the queue if
 12595                              <1> ;				 ; it is already on the queue
 12596                              <1> ;		; then add it to the tail of the queue
 12597                              <1> ;	movzx	eax, word [swpq_count]
 12598                              <1> ;	cmp	ax, 1024
 12599                              <1> ;	jb	short atsq_1
 12600                              <1> ;	sub	ax, ax
 12601                              <1> ;	pop	ebx
 12602                              <1> ;	retn
 12603                              <1> ;atsq_1:
 12604                              <1> ;	push	esi
 12605                              <1> ;	mov	esi, swap_queue
 12606                              <1> ;	and	ax, ax
 12607                              <1> ;	jz	short atsq_2
 12608                              <1> ;	shl	ax, 2	; convert to offset
 12609                              <1> ;	add	esi, eax
 12610                              <1> ;	shr	ax, 2
 12611                              <1> ;atsq_2:
 12612                              <1> ;	inc	ax
 12613                              <1> ;	mov	[esi], ebx ; Virtual address + [u.uno] combination
 12614                              <1> ;	mov	[swpq_count], ax
 12615                              <1> ;	pop	esi
 12616                              <1> ;	pop	ebx
 12617                              <1> ;	retn
 12618                              <1> 
 12619                              <1> ; 17/04/2021
 12620                              <1> ; ('unlink_swap_block' procedure call is disabled as temporary)
 12621                              <1> 
 12622                              <1> ; 30/11/2021 - temporary !
 12623                              <1> ;unlink_swap_block:
 12624                              <1> 	; 15/09/2015
 12625                              <1> 	; 30/04/2015
 12626                              <1> 	; 18/04/2015
 12627                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12628                              <1> 	;
 12629                              <1> 	; INPUT -> 
 12630                              <1> 	;	EAX = swap disk/file offset address
 12631                              <1> 	;	      (bit 1 to bit 31)
 12632                              <1> 	; OUTPUT ->
 12633                              <1> 	;	[swpd_free] is increased
 12634                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
 12635                              <1> 	;
 12636                              <1> 	; Modified Registers -> EAX
 12637                              <1> 	;
 12638                              <1> ;	push	ebx
 12639                              <1> ;	push	edx
 12640                              <1> ;	;
 12641                              <1> ;	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
 12642                              <1> ;				     ; 3 bits right
 12643                              <1> ;				     ; to get swap block/page number
 12644                              <1> ;	mov	edx, eax
 12645                              <1> ;	; 15/09/2015
 12646                              <1> ;	shr	edx, 3		     ; to get offset to S.A.T.
 12647                              <1> ;				     ; (1 allocation bit = 1 page)
 12648                              <1> ;				     ; (1 allocation bytes = 8 pages)
 12649                              <1> ;	and	dl, 0FCh 	     ; clear lower 2 bits
 12650                              <1> ;				     ; (to get 32 bit position)			
 12651                              <1> ;	;
 12652                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table address
 12653                              <1> ;	add	ebx, edx
 12654                              <1> ;	and	eax, 1Fh	     ; lower 5 bits only
 12655                              <1> ;				     ; (allocation bit position)	 
 12656                              <1> ;	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
 12657                              <1> ;				     ; than the address in 'swpd_next' ?
 12658                              <1> ;				     ; (next/first free block value)		
 12659                              <1> ;	jnb	short uswpbl_1	     ; no	
 12660                              <1> ;	mov	[swpd_next], eax     ; yes	
 12661                              <1> ;uswpbl_1:
 12662                              <1> ;	bts	[ebx], eax	     ; unlink/release/deallocate block
 12663                              <1> ;				     ; set relevant bit to 1.
 12664                              <1> ;				     ; set CF to the previous bit value	
 12665                              <1> ;	cmc			     ; complement carry flag	
 12666                              <1> ;	jc	short uswpbl_2	     ; do not increase swfd_free count
 12667                              <1> ;				     ; if the block is already deallocated
 12668                              <1> ;				     ; before.	
 12669                              <1> ;       inc     dword [swpd_free]
 12670                              <1> ;uswpbl_2:
 12671                              <1> ;	pop	edx
 12672                              <1> ;	pop	ebx
 12673                              <1> ;	retn
 12674                              <1> 
 12675                              <1> ; 17/04/2021
 12676                              <1> ; ('link_swap_block' procedure call is disabled as temporary)
 12677                              <1> 
 12678                              <1> ; 30/11/2021 - temporary !
 12679                              <1> ;link_swap_block:
 12680                              <1> 	; 01/07/2015
 12681                              <1> 	; 18/04/2015
 12682                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
 12683                              <1> 	;
 12684                              <1> 	; INPUT -> none
 12685                              <1> 	;
 12686                              <1> 	; OUTPUT ->
 12687                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
 12688                              <1> 	;	      in sectors (corresponding 
 12689                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
 12690                              <1> 	;
 12691                              <1> 	;	CF = 1 and EAX = 0 
 12692                              <1> 	; 		   if there is not a free block to be allocated	
 12693                              <1> 	;
 12694                              <1> 	; Modified Registers -> none (except EAX)
 12695                              <1> 	;
 12696                              <1> 
 12697                              <1> ;	;mov	eax, [swpd_free]
 12698                              <1> ;	;and	eax, eax
 12699                              <1> ;	;jz	short out_of_swpspc
 12700                              <1> ;	;
 12701                              <1> ;	push	ebx
 12702                              <1> ;	push	ecx
 12703                              <1> ;	;
 12704                              <1> ;	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
 12705                              <1> ;	mov	ecx, ebx
 12706                              <1> ;	add	ebx, [swpd_next] ; Free block searching starts from here
 12707                              <1> ;				 ; next_free_swap_block >> 5
 12708                              <1> ;	add	ecx, [swpd_last] ; Free block searching ends here
 12709                              <1> ;				 ; (total_swap_blocks - 1) >> 5
 12710                              <1> ;lswbl_scan:
 12711                              <1> ;	cmp	ebx, ecx
 12712                              <1> ;	ja	short lswbl_notfound
 12713                              <1> ;	;
 12714                              <1> ;	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
 12715                              <1> ;			   ; Clears ZF if a bit is found set (1) and 
 12716                              <1> ;			   ; loads the destination with an index to
 12717                              <1> ;			   ; first set bit. (0 -> 31) 
 12718                              <1> ;			   ; Sets ZF to 1 if no bits are found set.
 12719                              <1> ;	; 01/07/2015
 12720                              <1> ;	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
 12721                              <1> ;			 ;
 12722                              <1> ;			 ; NOTE:  a Swap Disk Allocation Table bit 
 12723                              <1> ;			 ;	  with value of 1 means 
 12724                              <1> ;			 ;	  the corresponding page is free 
 12725                              <1> ;			 ;	  (Retro UNIX 386 v1 feaure only!)
 12726                              <1> ;	add	ebx, 4
 12727                              <1> ;			 ; We return back for searching next page block
 12728                              <1> ;			 ; NOTE: [swpd_free] is not ZERO; so, 
 12729                              <1> ;			 ;	 we always will find at least 1 free block here.
 12730                              <1> ;	jmp    	short lswbl_scan
 12731                              <1> ;	;
 12732                              <1> ;lswbl_notfound:	
 12733                              <1> ;	sub	ecx, swap_alloc_table
 12734                              <1> ;	mov	[swpd_next], ecx ; next/first free page = last page 
 12735                              <1> ;				 ; (unlink_swap_block procedure will change it)
 12736                              <1> ;	xor	eax, eax
 12737                              <1> ;	mov	[swpd_free], eax
 12738                              <1> ;	stc
 12739                              <1> ;lswbl_ok:
 12740                              <1> ;	pop	ecx
 12741                              <1> ;	pop	ebx
 12742                              <1> ;	retn
 12743                              <1> ;	;
 12744                              <1> ;;out_of_swpspc:
 12745                              <1> ;;	stc
 12746                              <1> ;;	retn
 12747                              <1> ;
 12748                              <1> ;lswbl_found:
 12749                              <1> ;	mov	ecx, ebx
 12750                              <1> ;	sub	ecx, swap_alloc_table
 12751                              <1> ;	mov	[swpd_next], ecx ; Set first free block searching start
 12752                              <1> ;				 ; address/offset (to the next)
 12753                              <1> ;       dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
 12754                              <1> ;	;
 12755                              <1> ;	btr	[ebx], eax	 ; The destination bit indexed by the source value
 12756                              <1> ;				 ; is copied into the Carry Flag and then cleared
 12757                              <1> ;				 ; in the destination.
 12758                              <1> ;				 ;
 12759                              <1> ;				 ; Reset the bit which is corresponding to the 
 12760                              <1> ;				 ; (just) allocated block.
 12761                              <1> ;	shl	ecx, 5		 ; (block offset * 32) + block index
 12762                              <1> ;	add	eax, ecx	 ; = block number
 12763                              <1> ;	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
 12764                              <1> ;				 ; 1 block =  8 sectors
 12765                              <1> ;	;
 12766                              <1> ;	; EAX = offset address of swap disk/file sector (beginning of the block)
 12767                              <1> ;	;
 12768                              <1> ;	; NOTE: The relevant page table entry will be updated
 12769                              <1> ;	;       according to this EAX value...
 12770                              <1> ;	;
 12771                              <1> ;	jmp	short lswbl_ok
 12772                              <1> 
 12773                              <1> ; 17/04/2021
 12774                              <1> ; ('logical_disk_read' procedure call is disabled as temporary)
 12775                              <1> 
 12776                              <1> ; 30/11/2021 - temporary !
 12777                              <1> ;logical_disk_read:
 12778                              <1> 	; 20/07/2015
 12779                              <1> 	; 09/03/2015 (temporary code here)
 12780                              <1> 	;
 12781                              <1> 	; INPUT ->
 12782                              <1> 	; 	ESI = Logical disk description table address
 12783                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12784                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12785                              <1> 	; 	ECX = Sector count
 12786                              <1> 	;
 12787                              <1> 	;
 12788                              <1> ;	retn
 12789                              <1> 
 12790                              <1> ; 17/04/2021
 12791                              <1> ; ('logical_disk_write' procedure call is disabled as temporary)
 12792                              <1> 
 12793                              <1> ; 30/11/2021 - temporary !
 12794                              <1> ;logical_disk_write:
 12795                              <1> 	; 20/07/2015
 12796                              <1> 	; 09/03/2015 (temporary code here)
 12797                              <1> 	;
 12798                              <1> 	; INPUT ->
 12799                              <1> 	; 	ESI = Logical disk description table address
 12800                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
 12801                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
 12802                              <1> 	; 	ECX = Sector count
 12803                              <1> 	;
 12804                              <1> ;	retn
 12805                              <1> 
 12806                              <1> get_physical_addr:
 12807                              <1> 	; 17/04/2021 - Rerto UNIX 386 v2
 12808                              <1> 	;	(temporary modifications)
 12809                              <1> 	; 19/04/2020 - Retro UNIX 386 v2
 12810                              <1> 	; 18/10/2015
 12811                              <1> 	; 29/07/2015
 12812                              <1> 	; 20/07/2015
 12813                              <1> 	; 04/06/2015
 12814                              <1> 	; 20/05/2015
 12815                              <1> 	; 28/04/2015
 12816                              <1> 	; 18/04/2015
 12817                              <1> 	; Get physical address
 12818                              <1> 	;     (allocates a new page for user if it is not present)
 12819                              <1> 	;	
 12820                              <1> 	; (This subroutine is needed for mapping user's virtual 
 12821                              <1> 	; (buffer) address to physical address (of the buffer).)
 12822                              <1> 	; ('sys write', 'sys read' system calls...)
 12823                              <1> 	;
 12824                              <1> 	; INPUT ->
 12825                              <1> 	;	EBX = virtual address
 12826                              <1> 	;	u.pgdir = page directory (physical) address
 12827                              <1> 	;
 12828                              <1> 	; OUTPUT ->
 12829                              <1> 	;	EAX = physical address 
 12830                              <1> 	;	EBX = linear address	
 12831                              <1> 	;	EDX = physical address of the page frame
 12832                              <1> 	;	      (with attribute bits)
 12833                              <1> 	;	ECX = byte count within the page frame
 12834                              <1> 	;
 12835                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
 12836                              <1> 	;
 12837                              <1> 
 12838                              <1> 	; 19/04/2020 - Retro UNIX386 v2
 12839 0000335F A1[18710000]        <1> 	mov	eax, [u.pgdir]
 12840                              <1> 
 12841                              <1> ifs_get_physical_addr: ; 19/04/2020 - Retro UNIX 386 v2
 12842                              <1> 	
 12843 00003364 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
 12844                              <1> 	;
 12845                              <1> 	;mov	eax, [u.pgdir]
 12846 0000336A E815FDFFFF          <1> 	call	get_pte
 12847                              <1> 		; EDX = Page table entry address (if CF=0)
 12848                              <1> 	        ;       Page directory entry address (if CF=1)
 12849                              <1> 		;       (Bit 0 value is 0 if PT is not present)
 12850                              <1> 		; EAX = Page table entry value (page address)
 12851                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
 12852 0000336F 731C                <1> 	jnc	short gpa_1
 12853                              <1> 	;
 12854 00003371 E8FCFBFFFF          <1> 	call	allocate_page
 12855 00003376 724B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
 12856                              <1> gpa_0:
 12857 00003378 E866FCFFFF          <1> 	call 	clear_page
 12858                              <1> 	; EAX = Physical (base) address of the allocated (new) page
 12859 0000337D 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
 12860                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
 12861                              <1> 			   ; (user, writable, present page)	
 12862 0000337F 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
 12863 00003381 A1[18710000]        <1> 	mov	eax, [u.pgdir]	
 12864 00003386 E8F9FCFFFF          <1> 	call	get_pte
 12865 0000338B 7236                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12866                              <1> gpa_1:
 12867                              <1> 	; EAX = PTE value, EDX = PTE address
 12868 0000338D A801                <1> 	test 	al, PTE_A_PRESENT
 12869 0000338F 750A                <1> 	jnz	short gpa_3
 12870 00003391 09C0                <1> 	or	eax, eax
 12871 00003393 7420                <1> 	jz	short gpa_4  ; Allocate a new page
 12872                              <1> 
 12873                              <1> ; 17/04/2021
 12874                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12875 00003395 EB2C                <1> 	jmp	short gpa_im_err  ; temporary !
 12876                              <1> 
 12877                              <1> 	; 20/07/2015
 12878                              <1> ;	push	ebp
 12879                              <1> ;	mov	ebp, ebx ; virtual (linear) address
 12880                              <1> ;	; reload swapped page
 12881                              <1> ;	call	reload_page ; 28/04/2015
 12882                              <1> ;	pop	ebp
 12883                              <1> ;	jc	short gpa_retn
 12884                              <1> gpa_2:
 12885                              <1> ; 17/04/2021
 12886                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)
 12887                              <1> 
 12888                              <1> 	; 20/07/2015
 12889                              <1> 	; 20/05/2015
 12890                              <1> 	; add this page to swap queue
 12891                              <1> ;	push	eax 
 12892                              <1> ;	; EBX = Linear (CORE+virtual) address ; 20/02/2017 
 12893                              <1> ;	call 	add_to_swap_queue
 12894                              <1> ;	pop	eax
 12895                              <1> 		; PTE address in EDX
 12896                              <1> 		; virtual address in EBX
 12897                              <1> 	; EAX = memory page address
 12898 00003397 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
 12899                              <1> 				  ; present flag, bit 0 = 1
 12900                              <1> 				  ; user flag, bit 2 = 1	
 12901                              <1> 				  ; writable flag, bit 1 = 1
 12902 00003399 8902                <1> 	mov	[edx], eax  ; Update PTE value
 12903                              <1> gpa_3:
 12904                              <1> 	; 18/10/2015
 12905 0000339B 89D9                <1> 	mov	ecx, ebx
 12906 0000339D 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
 12907 000033A3 89C2                <1> 	mov 	edx, eax
 12908 000033A5 662500F0            <1> 	and	ax, PTE_A_CLEAR
 12909 000033A9 01C8                <1> 	add	eax, ecx
 12910 000033AB F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
 12911 000033AD 81C100100000        <1> 	add	ecx, PAGE_SIZE
 12912 000033B3 F8                  <1> 	clc
 12913                              <1> gpa_retn:
 12914 000033B4 C3                  <1> 	retn	
 12915                              <1> gpa_4:	
 12916 000033B5 E8B8FBFFFF          <1> 	call	allocate_page
 12917 000033BA 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
 12918 000033BC E822FCFFFF          <1> 	call	clear_page
 12919 000033C1 EBD4                <1> 	jmp	short gpa_2
 12920                              <1> 
 12921                              <1> gpa_im_err:	
 12922 000033C3 B804000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12923                              <1> 				  ; Major error = 0 (No protection fault)	
 12924 000033C8 C3                  <1> 	retn
 12925                              <1> 
 12926                              <1> ; 17/04/2021
 12927                              <1> ; ('reload_page' procedure call is disabled as temporary)
 12928                              <1> 
 12929                              <1> ; 30/11/2021 - temporary !
 12930                              <1> ;reload_page:
 12931                              <1> 	; 20/07/2015
 12932                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
 12933                              <1> 	;
 12934                              <1> 	; Reload (Restore) swapped page at memory
 12935                              <1> 	;
 12936                              <1> 	; INPUT -> 
 12937                              <1> 	;	EBP = Virtual (linear) memory address
 12938                              <1> 	;	EAX = PTE value (swap disk sector address)
 12939                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
 12940                              <1> 	; OUTPUT ->
 12941                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
 12942                              <1> 	;
 12943                              <1> 	;	CF = 1 and EAX = error code
 12944                              <1> 	;
 12945                              <1> 	; Modified Registers -> none (except EAX)
 12946                              <1> 	;
 12947                              <1> ;	shr	eax, 1   ; Convert PTE value to swap disk address 
 12948                              <1> ;	push	ebx      ;
 12949                              <1> ;	mov	ebx, eax ; Swap disk (offset) address	
 12950                              <1> ;	call	allocate_page
 12951                              <1> ;	jc	short rlp_im_err
 12952                              <1> ;	xchg 	eax, ebx	
 12953                              <1> ;	; EBX = Physical memory (page) address
 12954                              <1> ;	; EAX = Swap disk (offset) address
 12955                              <1> ;	; EBP = Virtual (linear) memory address
 12956                              <1> ;	call	swap_in
 12957                              <1> ;	jc	short rlp_swp_err  ; (swap disk/file read error)
 12958                              <1> ;	mov	eax, ebx	
 12959                              <1> ;rlp_retn:
 12960                              <1> ;	pop	ebx
 12961                              <1> ;	retn
 12962                              <1> ;	
 12963                              <1> ;rlp_im_err:	
 12964                              <1> ;	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
 12965                              <1> ;				  ; Major error = 0 (No protection fault)	
 12966                              <1> ;	jmp	short rlp_retn
 12967                              <1> ;
 12968                              <1> ;rlp_swp_err:
 12969                              <1> ;	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
 12970                              <1> ;	jmp	short rlp_retn
 12971                              <1> 
 12972                              <1> copy_page_dir:
 12973                              <1> 	; 17/04/2021 (temporary modifications)
 12974                              <1> 	; 19/09/2015
 12975                              <1> 	; temporary - 07/09/2015
 12976                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 12977                              <1> 	;
 12978                              <1> 	; INPUT -> 
 12979                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
 12980                              <1> 	;		    page directory.
 12981                              <1> 	; OUTPUT ->
 12982                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
 12983                              <1> 	;	       page directory.
 12984                              <1> 	;	(New page directory with new page table entries.)
 12985                              <1> 	;	(New page tables with read only copies of the parent's
 12986                              <1> 	;	pages.)
 12987                              <1> 	;	EAX = 0 -> Error (CF = 1)
 12988                              <1> 	;
 12989                              <1> 	; Modified Registers -> none (except EAX)
 12990                              <1> 	;
 12991 000033C9 E8A4FBFFFF          <1> 	call	allocate_page
 12992 000033CE 723E                <1> 	jc	short cpd_err
 12993                              <1> 	;
 12994 000033D0 55                  <1> 	push	ebp ; 20/07/2015
 12995 000033D1 56                  <1> 	push	esi
 12996 000033D2 57                  <1> 	push	edi
 12997 000033D3 53                  <1> 	push	ebx
 12998 000033D4 51                  <1> 	push	ecx
 12999 000033D5 8B35[18710000]      <1> 	mov	esi, [u.pgdir]
 13000 000033DB 89C7                <1> 	mov	edi, eax
 13001 000033DD 50                  <1> 	push	eax ; save child's page directory address
 13002                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
 13003                              <1> 	; (use same system space for all user page tables) 
 13004 000033DE A5                  <1> 	movsd
 13005 000033DF BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
 13006 000033E4 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
 13007                              <1> cpd_0:	
 13008 000033E9 AD                  <1> 	lodsd
 13009                              <1> 	;or	eax, eax
 13010                              <1>         ;jnz	short cpd_1
 13011 000033EA A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
 13012 000033EC 7508                <1> 	jnz	short cpd_1
 13013                              <1>  	; (virtual address at the end of the page table)	
 13014 000033EE 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
 13015 000033F4 EB0F                <1> 	jmp	short cpd_2
 13016                              <1> cpd_1:	
 13017 000033F6 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
 13018 000033FA 89C3                <1> 	mov	ebx, eax
 13019                              <1> 	; EBX = Parent's page table address
 13020 000033FC E81F000000          <1> 	call	copy_page_table
 13021 00003401 720C                <1> 	jc	short cpd_p_err
 13022                              <1> 	; EAX = Child's page table address
 13023 00003403 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
 13024                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
 13025                              <1> 			 ; (present, writable, user)
 13026                              <1> cpd_2:
 13027 00003405 AB                  <1> 	stosd
 13028 00003406 E2E1                <1> 	loop	cpd_0
 13029                              <1> 	;
 13030 00003408 58                  <1> 	pop	eax  ; restore child's page directory address
 13031                              <1> cpd_3:
 13032 00003409 59                  <1> 	pop	ecx
 13033 0000340A 5B                  <1> 	pop	ebx
 13034 0000340B 5F                  <1> 	pop	edi
 13035 0000340C 5E                  <1> 	pop	esi
 13036 0000340D 5D                  <1> 	pop	ebp
 13037                              <1> cpd_err:
 13038 0000340E C3                  <1> 	retn
 13039                              <1> cpd_p_err:
 13040                              <1> 	; release the allocated pages missing (recover free space)
 13041 0000340F 58                  <1> 	pop	eax  ; the new page directory address (physical)
 13042 00003410 8B1D[18710000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
 13043 00003416 E887FCFFFF          <1> 	call 	deallocate_page_dir
 13044 0000341B 29C0                <1> 	sub	eax, eax ; 0
 13045 0000341D F9                  <1> 	stc
 13046 0000341E EBE9                <1> 	jmp	short cpd_3	
 13047                              <1> 
 13048                              <1> copy_page_table:
 13049                              <1> 	; 17/04/2021 (temporary modifications)
 13050                              <1> 	; 19/09/2015
 13051                              <1> 	; temporary - 07/09/2015
 13052                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
 13053                              <1> 	;
 13054                              <1> 	; INPUT -> 
 13055                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
 13056                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
 13057                              <1> 	; OUTPUT ->
 13058                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
 13059                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
 13060                              <1> 	;	CF = 1 -> error 
 13061                              <1> 	;
 13062                              <1> 	; Modified Registers -> EBP (except EAX)
 13063                              <1> 	;
 13064 00003420 E84DFBFFFF          <1> 	call	allocate_page
 13065 00003425 7244                <1> 	jc	short cpt_err
 13066                              <1> 	;
 13067 00003427 50                  <1> 	push	eax ; *
 13068                              <1> 	;push 	ebx
 13069 00003428 56                  <1> 	push	esi
 13070 00003429 57                  <1> 	push	edi
 13071 0000342A 52                  <1> 	push	edx
 13072 0000342B 51                  <1> 	push	ecx
 13073                              <1> 	;
 13074 0000342C 89DE                <1> 	mov	esi, ebx
 13075 0000342E 89C7                <1> 	mov	edi, eax
 13076 00003430 89C2                <1> 	mov	edx, eax
 13077 00003432 81C200100000        <1> 	add	edx, PAGE_SIZE 	
 13078                              <1> cpt_0:
 13079 00003438 AD                  <1> 	lodsd
 13080 00003439 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 = 1
 13081                              <1> 	;jnz	short cpt_1 (*)
 13082                              <1> 	; 17/04/2021 (temporary (*)
 13083                              <1> 	;and	eax, eax (*)
 13084 0000343B 741E                <1> 	jz	short cpt_2  ; 17/04/2021
 13085                              <1> 	
 13086                              <1> ; 17/04/2021
 13087                              <1> ; ('reload_page' procedure call is disabled as temporary)
 13088                              <1> ;
 13089                              <1> ;	; ebp = virtual (linear) address of the memory page
 13090                              <1> ;	call	reload_page ; 28/04/2015
 13091                              <1> ;	jc	short cpt_p_err
 13092                              <1> cpt_1:
 13093 0000343D 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
 13094 00003441 89C1                <1> 	mov	ecx, eax
 13095                              <1> 	; Allocate a new page for the child process
 13096 00003443 E82AFBFFFF          <1> 	call	allocate_page
 13097 00003448 721C                <1> 	jc	short cpt_p_err
 13098 0000344A 57                  <1> 	push	edi
 13099 0000344B 56                  <1> 	push	esi
 13100 0000344C 89CE                <1> 	mov	esi, ecx
 13101 0000344E 89C7                <1> 	mov	edi, eax
 13102 00003450 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
 13103 00003455 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
 13104 00003457 5E                  <1> 	pop	esi
 13105 00003458 5F                  <1> 	pop	edi
 13106                              <1> 	; 
 13107                              <1> 
 13108                              <1> ; 17/04/2021
 13109                              <1> ; ('add_to_swap_queue' procedure call is disabled as temporary)	
 13110                              <1> ;
 13111                              <1> ;	push	ebx
 13112                              <1> ;	push	eax
 13113                              <1> ;	mov	ebx, ebp
 13114                              <1> ;	; ebx = virtual address of the memory page
 13115                              <1> ;	call	add_to_swap_queue
 13116                              <1> ;	pop	eax
 13117                              <1> ;	pop	ebx
 13118                              <1> 	;
 13119                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
 13120 00003459 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
 13121                              <1> cpt_2:
 13122 0000345B AB                  <1> 	stosd  ; EDI points to child's PTE  	 
 13123                              <1> 	;
 13124 0000345C 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
 13125                              <1> 	;
 13126 00003462 39D7                <1> 	cmp	edi, edx
 13127 00003464 72D2                <1> 	jb	short cpt_0
 13128                              <1> cpt_p_err:
 13129 00003466 59                  <1> 	pop	ecx
 13130 00003467 5A                  <1> 	pop	edx
 13131 00003468 5F                  <1> 	pop	edi
 13132 00003469 5E                  <1> 	pop	esi
 13133                              <1> 	;pop	ebx
 13134 0000346A 58                  <1> 	pop	eax ; *
 13135                              <1> cpt_err:
 13136 0000346B C3                  <1> 	retn
 13137                              <1> 
 13138                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
 13139                              <1> 
 13140                              <1> ;; Data:
 13141                              <1> 
 13142                              <1> ; 09/03/2015
 13143                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
 13144                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
 13145                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
 13146                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 13147                              <1> ;swpd_next:  dd 0 ; next free page block
 13148                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
 13149                                  %include 'sysdefs.s' ; 09/03/2015
 13150                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 13151                              <1> ; (re-write kernel for test by using previous version without a major defect)
 13152                              <1> ; ****************************************************************************
 13153                              <1> ; Retro UNIX 386 v1 Kernel - SYSDEFS.INC
 13154                              <1> ; Last Modification: 11/12/2021
 13155                              <1> ;
 13156                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 13157                              <1> ; (Modified from 
 13158                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 13159                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 13160                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
 13161                              <1> ; ----------------------------------------------------------------------------
 13162                              <1> ;
 13163                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 13164                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 13165                              <1> ; <Bell Laboratories (17/3/1972)>
 13166                              <1> ; <Preliminary Release of UNIX Implementation Document>
 13167                              <1> ;
 13168                              <1> ; ****************************************************************************
 13169                              <1> 
 13170                              <1> nproc 	equ	16  ; number of processes
 13171                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
 13172                              <1> nbuf	equ	6   ; number of buffers (04/02/2016)
 13173                              <1> 
 13174                              <1> ; 22/11/2021
 13175                              <1> NFILES 	equ	50
 13176                              <1> OPENFILES equ	10  ; open files (for user) ; 28/03/2020
 13177                              <1> 
 13178                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
 13179                              <1> ;core	equ 	0  	    ; 19/04/2013	
 13180                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
 13181                              <1> 	; (if total size of argument list and arguments is 128 bytes)
 13182                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
 13183                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
 13184                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
 13185                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
 13186                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
 13187                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
 13188                              <1> 	; '/core' dump file size = 32768 bytes
 13189                              <1>  
 13190                              <1> ; 08/03/2014 
 13191                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)		 	 
 13192                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
 13193                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
 13194                              <1> 
 13195                              <1> ; 30/08/2013
 13196                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
 13197                              <1> 
 13198                              <1> ; 05/02/2014
 13199                              <1> ; process status
 13200                              <1> ;SFREE 	equ 0
 13201                              <1> ;SRUN	equ 1
 13202                              <1> ;SWAIT	equ 2
 13203                              <1> ;SZOMB	equ 3
 13204                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
 13205                              <1> 
 13206                              <1> ; 09/03/2015
 13207                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
 13208                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
 13209                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
 13210                              <1> 
 13211                              <1> ; 17/09/2015
 13212                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
 13213                              <1> 
 13214                              <1> ; 21/09/2015 (36) 
 13215                              <1> ; 01/07/2015 (35)
 13216                              <1> ; 14/07/2013 (0-34)
 13217                              <1> ; UNIX v1 system calls
 13218                              <1> _rele 	equ 0
 13219                              <1> _exit 	equ 1
 13220                              <1> _fork 	equ 2
 13221                              <1> _read 	equ 3
 13222                              <1> _write	equ 4
 13223                              <1> _open	equ 5
 13224                              <1> _close 	equ 6
 13225                              <1> _wait 	equ 7
 13226                              <1> _creat 	equ 8
 13227                              <1> _link 	equ 9
 13228                              <1> _unlink	equ 10
 13229                              <1> _exec	equ 11
 13230                              <1> _chdir	equ 12
 13231                              <1> _time 	equ 13
 13232                              <1> _mkdir 	equ 14
 13233                              <1> _chmod	equ 15
 13234                              <1> _chown	equ 16
 13235                              <1> _break	equ 17
 13236                              <1> _stat	equ 18
 13237                              <1> _seek	equ 19
 13238                              <1> _tell 	equ 20
 13239                              <1> _mount	equ 21
 13240                              <1> _umount	equ 22
 13241                              <1> _setuid	equ 23
 13242                              <1> _getuid	equ 24
 13243                              <1> _stime	equ 25
 13244                              <1> _quit	equ 26	
 13245                              <1> _intr	equ 27
 13246                              <1> _fstat	equ 28
 13247                              <1> _emt 	equ 29
 13248                              <1> _mdate 	equ 30
 13249                              <1> _stty 	equ 31
 13250                              <1> _gtty	equ 32
 13251                              <1> _ilgins	equ 33
 13252                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
 13253                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
 13254                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
 13255                              <1> 
 13256                              <1> %macro sys 1-4
 13257                              <1>     ; 13/04/2015
 13258                              <1>     ; Retro UNIX 386 v1 system call.		
 13259                              <1>     mov eax, %1
 13260                              <1>     %if %0 >= 2   
 13261                              <1>         mov ebx, %2
 13262                              <1>         %if %0 >= 3    
 13263                              <1>             mov ecx, %3
 13264                              <1>             %if %0 = 4
 13265                              <1>                mov edx, %4   
 13266                              <1>             %endif
 13267                              <1>         %endif
 13268                              <1>     %endif
 13269                              <1>     int 30h	   
 13270                              <1> %endmacro
 13271                              <1> 
 13272                              <1> ; 13/05/2015 - ERROR CODES
 13273                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
 13274                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
 13275                              <1> ; 14/05/2015
 13276                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
 13277                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
 13278                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
 13279                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
 13280                              <1> ; 16/05/2015		
 13281                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
 13282                              <1> ; 18/05/2015
 13283                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
 13284                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
 13285                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
 13286                              <1> ; 07/06/2015
 13287                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
 13288                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
 13289                              <1> ; 09/06/2015
 13290                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
 13291                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
 13292                              <1> ; 16/06/2015
 13293                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
 13294                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
 13295                              <1> ; 22/06/2015
 13296                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
 13297                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
 13298                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
 13299                              <1> ; 23/06/2015
 13300                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
 13301                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
 13302                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
 13303                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
 13304                              <1> ; 27/06/2015
 13305                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
 13306                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
 13307                              <1> ; 29/06/2015
 13308                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
 13309                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error	
 13310                              <1> 
 13311                              <1> ; 26/08/2015
 13312                              <1> ; 24/07/2015
 13313                              <1> ; 24/06/2015
 13314                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
 13315                              <1> ; 01/07/2015
 13316                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
 13317                              <1> ;
 13318                              <1> ; 22/11/2021
 13319                              <1> ERR_READ_ONLY_FS   equ 30  ; 'read only file system !' error
 13320                              <1> ; 28/11/2021
 13321                              <1> ERR_INV_FILE	   equ 255 ; 'invalid file (inode) !' error 	
 13322                              <1> 
 13323                              <1> ; 26/11/2021 ('no free blocks on disk !' error)
 13324                              <1> ERR_ALLOC	   equ 33  ; 'disk allocation error !'	
 13325                              <1> ; 04/12/2021
 13326                              <1> ERR_PERM_DENIED	   equ 11 ; 'permission denied !' error
 13327                              <1> ; 11/12/2021
 13328                              <1> ERR_INV_FUNC	   equ 1  ; 'invalid system call !' error	   					 		
 13329                                  %include 'u0.s'      ; 15/03/2015
 13330                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 13331                              <1> ; (re-write kernel for test by using previous version without a major defect)
 13332                              <1> ; ****************************************************************************
 13333                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
 13334                              <1> ; Last Modification: 05/12/2021
 13335                              <1> ; ----------------------------------------------------------------------------
 13336                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 13337                              <1> ; (v0.1 - Beginning: 11/07/2012)
 13338                              <1> ;
 13339                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 13340                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 13341                              <1> ; <Bell Laboratories (17/3/1972)>
 13342                              <1> ; <Preliminary Release of UNIX Implementation Document>
 13343                              <1> ;
 13344                              <1> ; Retro UNIX 8086 v1 - U0.ASM (28/07/2014) //// UNIX v1 -> u0.s
 13345                              <1> ;
 13346                              <1> ; ****************************************************************************
 13347                              <1> 
 13348                              <1> sys_init:
 13349                              <1> 	; 27/11/2021
 13350                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 (test) compatibility modification
 13351                              <1> 	; 18/10/2015
 13352                              <1> 	; 28/08/2015
 13353                              <1> 	; 24/08/2015
 13354                              <1> 	; 14/08/2015
 13355                              <1> 	; 24/07/2015 
 13356                              <1> 	; 02/07/2015
 13357                              <1> 	; 01/07/2015
 13358                              <1> 	; 23/06/2015
 13359                              <1> 	; 15/04/2015
 13360                              <1> 	; 13/04/2015
 13361                              <1> 	; 11/03/2015 (Retro UNIX 386 v1 - Beginning)
 13362                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13363                              <1> 	;
 13364                              <1> 	;call	ldrv_init ; Logical drive description tables initialization
 13365                              <1> 	;
 13366                              <1> 	;; 14/02/2014
 13367                              <1> 	;; 14/07/2013
 13368                              <1> 	;mov	ax, 41
 13369                              <1> 	;mov	[rootdir], ax
 13370                              <1> 	;mov	[u.cdir], ax
 13371                              <1> 	;and	al, 1 ; 15/04/2015
 13372                              <1> 	
 13373                              <1> 	; 27/11/2021
 13374                              <1> 	; 18/04/2021 - Retro UNIX 386 v2
 13375 0000346C 31C0                <1> 	xor	eax, eax
 13376                              <1> 	; 12/12/2021 - Temporary
 13377 0000346E A2[F06D0000]        <1> 	mov	[p.ttyc], al ; 0  ; test !!!
 13378 00003473 FEC0                <1> 	inc	al	; eax = 1 (root directory inode) ; runix v2 fs
 13379 00003475 A3[9C700000]        <1> 	mov	[rootdir], eax ; = 1 ; 28/10/2021 (32 bit)
 13380 0000347A A3[B8700000]        <1> 	mov	[u.cdir], eax ; 28/10/2021 (32 bit)
 13381                              <1> 
 13382 0000347F A2[09710000]        <1> 	mov	[u.uno], al ; = 1
 13383 00003484 66A3[9A700000]      <1> 	mov	[mpid], ax ; 1 
 13384 0000348A 66A3[906D0000]      <1> 	mov	[p.pid], ax ; 1
 13385 00003490 A2[206E0000]        <1> 	mov	[p.stat], al ; SRUN, 05/02/2014
 13386                              <1> 	;
 13387 00003495 B004                <1> 	mov	al, time_count ; 30/08/2013
 13388 00003497 A2[00710000]        <1> 	mov	[u.quant], al ; 14/07/2013
 13389                              <1> 	; 02/07/2015
 13390 0000349C A1[B86F0000]        <1> 	mov	eax, [k_page_dir]
 13391                              <1> 	;sub	eax, eax
 13392 000034A1 A3[18710000]        <1> 	mov	[u.pgdir], eax ; reset
 13393                              <1> 	; 18/10/2015
 13394                              <1> 	;mov	[u.ppgdir], eax ; 0
 13395                              <1>         ;
 13396 000034A6 E84E030000          <1>  	call	epoch
 13397 000034AB A3[44820000]        <1> 	mov	[s.time], eax ; 13/03/2015
 13398                              <1> 	; 17/07/2013
 13399 000034B0 E8A6060000          <1> 	call 	bf_init ; buffer initialization 
 13400                              <1> 	; 23/06/2015
 13401 000034B5 E8B8FAFFFF          <1> 	call	allocate_page
 13402                              <1> 	;;jc	error
 13403                              <1> 	;jc	panic   ; jc short panic (01/07/2015)
 13404                              <1> 	; 05/12/2021
 13405 000034BA 7305                <1> 	jnc	short sysinit_1
 13406 000034BC E997000000          <1> 	jmp	panic
 13407                              <1> sysinit_1:
 13408 000034C1 A3[14710000]        <1> 	mov	[u.upage], eax ; user structure page	
 13409 000034C6 A3[306E0000]        <1> 	mov	[p.upage], eax
 13410                              <1> 	;
 13411 000034CB E813FBFFFF          <1> 	call	clear_page
 13412                              <1> 	;
 13413                              <1> 	; 14/08/2015
 13414 000034D0 FA                  <1> 	cli
 13415                              <1> 	; 14/03/2015
 13416                              <1> 	; 17/01/2014
 13417 000034D1 E8D5010000          <1> 	call	sp_init ; serial port initialization
 13418                              <1> 	; 14/08/2015
 13419 000034D6 FB                  <1> 	sti
 13420                              <1> 	;
 13421                              <1> 	; 30/06/2015
 13422                              <1> 	;mov	esi, kernel_init_ok_msg
 13423                              <1> 	;call 	print_msg
 13424                              <1> 	;
 13425 000034D7 30DB                <1> 	xor	bl, bl ; video page 0
 13426                              <1> vp_clr_nxt:  ; clear video pages (reset cursor positions)
 13427 000034D9 E804310000          <1> 	call 	vp_clr  ; 17/07/2013
 13428 000034DE FEC3                <1> 	inc	bl
 13429 000034E0 80FB08              <1> 	cmp	bl, 8
 13430 000034E3 72F4                <1> 	jb	short vp_clr_nxt
 13431                              <1> 	;
 13432                              <1> 	; 24/07/2015
 13433                              <1> 	;push	KDATA
 13434                              <1>         ;push	esp
 13435                              <1> 	;mov	[tss.esp0], esp
 13436                              <1>         ;mov	word [tss.ss0], KDATA
 13437                              <1> 	;
 13438                              <1> 	; 24/08/2015
 13439                              <1> 	;; temporary (01/07/2015)
 13440 000034E5 C605[00710000]04    <1> 	mov	byte [u.quant], time_count ; 4 
 13441                              <1> 			       ; it is not needed here !
 13442                              <1> 	;;inc	byte [u.kcall] ; 'the caller is kernel' sign
 13443 000034EC FE0D[A9700000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
 13444                              <1> 			      ; 0 = executing a system call
 13445                              <1> 	;;sys 	_msg, kernel_init_ok_msg, 255, 0
 13446                              <1> 	;
 13447                              <1> 	;;; 06/08/2015
 13448                              <1> 	;;;call	getch ; wait for a key stroke
 13449                              <1> 	;;mov 	ecx, 0FFFFFFFh	
 13450                              <1> ;;sys_init_msg_wait:
 13451                              <1> ;;	push 	ecx
 13452                              <1> ;;	mov	al, 1
 13453                              <1> ;;	mov 	ah, [ptty] ; active (current) video page
 13454                              <1> ;;	call	getc_n
 13455                              <1> ;;	pop	ecx
 13456                              <1> ;;	jnz	short sys_init_msg_ok
 13457                              <1> ;;	loop	sys_init_msg_wait
 13458                              <1> 	;
 13459                              <1> ;;sys_init_msg_ok:
 13460                              <1> 	; 28/08/2015 (initial settings for the 1st 'rswap')
 13461 000034F2 6A10                <1> 	push	KDATA ; ss
 13462 000034F4 54                  <1> 	push	esp
 13463 000034F5 9C                  <1> 	pushfd
 13464 000034F6 6A08                <1> 	push	KCODE ; cs
 13465 000034F8 68[2C350000]        <1> 	push	init_exec ; eip
 13466 000034FD 8925[AC700000]      <1> 	mov	[u.sp], esp
 13467 00003503 1E                  <1> 	push	ds
 13468 00003504 06                  <1> 	push	es
 13469 00003505 0FA0                <1> 	push	fs
 13470 00003507 0FA8                <1> 	push	gs	
 13471 00003509 60                  <1> 	pushad
 13472 0000350A 8925[B0700000]      <1> 	mov	[u.usp], esp
 13473 00003510 E8951B0000          <1> 	call	wswap ; save current user (u) structure, user registers
 13474                              <1> 		      ; and interrupt return components (for IRET)
 13475 00003515 61                  <1> 	popad
 13476 00003516 6658                <1> 	pop	ax ; gs
 13477 00003518 6658                <1> 	pop	ax ; fs
 13478 0000351A 6658                <1> 	pop	ax ; es
 13479 0000351C 6658                <1> 	pop	ax ; ds	
 13480 0000351E 58                  <1> 	pop	eax ; eip (init_exec)
 13481 0000351F 6658                <1> 	pop	ax ; cs (KCODE)
 13482 00003521 58                  <1> 	pop	eax ; E-FLAGS
 13483 00003522 58                  <1> 	pop	eax ; esp
 13484 00003523 6658                <1> 	pop	ax ; ss (KDATA)
 13485                              <1> 	;
 13486 00003525 31C0                <1> 	xor	eax, eax ; 0
 13487 00003527 A3[1C710000]        <1> 	mov	[u.ppgdir], eax ; reset (to zero) for '/etc/init'
 13488                              <1> 	;
 13489                              <1> 	; 02/07/2015
 13490                              <1> 	; [u.pgdir ] = [k_page_dir]
 13491                              <1> 	; [u.ppgdir] = 0 (page dir of the parent process)
 13492                              <1> 	;     (The caller is os kernel sign for 'sysexec')
 13493                              <1> init_exec:
 13494                              <1> 	; 13/03/2013
 13495                              <1> 	; 24/07/2013
 13496 0000352C BB[4E350000]        <1> 	mov	ebx, init_file
 13497 00003531 B9[46350000]        <1> 	mov	ecx, init_argp
 13498                              <1> 	; EBX contains 'etc/init' asciiz file name address  
 13499                              <1> 	; ECX contains address of argument list pointer
 13500                              <1> 	;
 13501                              <1> 	;dec 	byte [sysflg] ; FFh = ready for system call
 13502                              <1> 			      ; 0 = executing a system call
 13503                              <1> 	sys	_exec  ; execute file
 13504                              <2> 
 13505                              <2> 
 13506 00003536 B80B000000          <2>  mov eax, %1
 13507                              <2>  %if %0 >= 2
 13508                              <2>  mov ebx, %2
 13509                              <2>  %if %0 >= 3
 13510                              <2>  mov ecx, %3
 13511                              <2>  %if %0 = 4
 13512                              <2>  mov edx, %4
 13513                              <2>  %endif
 13514                              <2>  %endif
 13515                              <2>  %endif
 13516 0000353B CD30                <2>  int 30h
 13517 0000353D 7319                <1> 	jnc	short panic
 13518                              <1> 	;
 13519 0000353F BE[CC6C0000]        <1> 	mov	esi, etc_init_err_msg
 13520                              <1> 	; 22/11/2021
 13521                              <1> 	;call 	print_msg
 13522 00003544 EB17                <1> 	jmp	short key_to_reboot
 13523                              <1> 
 13524                              <1> ;align 4
 13525                              <1> init_argp:
 13526 00003546 [4E350000]00000000  <1> 	dd 	init_file, 0  ; 23/06/2015 (dw -> dd)
 13527                              <1> init_file:
 13528                              <1> 	; 24/08/2015
 13529 0000354E 2F6574632F696E6974- <1> 	db 	'/etc/init', 0
 13530 00003557 00                  <1>
 13531                              <1> panic:
 13532                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13533                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13534 00003558 BE[B16C0000]        <1> 	mov 	esi, panic_msg
 13535                              <1> key_to_reboot: ; 22/11/2021
 13536 0000355D E819000000          <1> 	call 	print_msg
 13537                              <1> ;key_to_reboot:
 13538                              <1> 	; 15/11/2015
 13539 00003562 E8BE2E0000          <1> 	call 	getch 
 13540                              <1> 		; wait for a character from the current tty
 13541                              <1> 	;
 13542 00003567 B00A                <1> 	mov	al, 0Ah
 13543 00003569 8A1D[E66F0000]      <1> 	mov	bl, [ptty] ; [active_page]
 13544 0000356F B407                <1> 	mov	ah, 07h ; Black background, 
 13545                              <1> 			; light gray forecolor
 13546 00003571 E84ADFFFFF          <1> 	call 	write_tty
 13547 00003576 E9E5DBFFFF          <1> 	jmp	cpu_reset 
 13548                              <1> 
 13549                              <1> print_msg:
 13550                              <1> 	; 01/07/2015
 13551                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13552                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
 13553                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
 13554                              <1> 	;
 13555                              <1> 	;
 13556 0000357B AC                  <1> 	lodsb
 13557                              <1> pmsg1:
 13558 0000357C 56                  <1> 	push 	esi
 13559 0000357D 0FB61D[E66F0000]    <1> 	movzx	ebx, byte [ptty]
 13560 00003584 B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
 13561 00003586 E835DFFFFF          <1> 	call 	write_tty
 13562 0000358B 5E                  <1> 	pop	esi
 13563 0000358C AC                  <1> 	lodsb
 13564 0000358D 20C0                <1> 	and 	al, al
 13565 0000358F 75EB                <1> 	jnz 	short pmsg1
 13566 00003591 C3                  <1> 	retn
 13567                              <1> 	
 13568                              <1> ctrlbrk:
 13569                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 13570                              <1> 	; 12/11/2015
 13571                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
 13572                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
 13573                              <1> 	;
 13574                              <1> 	; INT 1Bh (control+break) handler		
 13575                              <1> 	;
 13576                              <1>       	; Retro Unix 8086 v1 feature only!
 13577                              <1>       	;
 13578 00003592 66833D[04710000]00  <1> 	cmp 	word [u.intr], 0
 13579 0000359A 7641                <1> 	jna 	short cbrk4
 13580                              <1> cbrk0:
 13581                              <1> 	; 12/11/2015
 13582                              <1> 	; 06/12/2013
 13583 0000359C 66833D[06710000]00  <1> 	cmp 	word [u.quit], 0
 13584 000035A4 7437                <1> 	jz	short cbrk4
 13585                              <1> 	;
 13586                              <1> 	; 20/09/2013	
 13587                              <1> 	;push 	ax
 13588                              <1> 	; 04/12/2021
 13589 000035A6 50                  <1> 	push	eax
 13590 000035A7 A0[E66F0000]        <1> 	mov	al, [ptty]
 13591                              <1> 	;
 13592                              <1> 	; 12/11/2015
 13593                              <1> 	;
 13594                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
 13595                              <1> 	; or ctrl+break from console (pseudo) tty
 13596                              <1> 	; (!redirection!)
 13597                              <1> 	;
 13598 000035AC 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
 13599 000035AE 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
 13600                              <1> 	;	
 13601                              <1> 	; Serial port interrupt handler sets [ptty]
 13602                              <1> 	; to the port's tty number (as temporary).
 13603                              <1> 	;
 13604                              <1> 	; If active process is using a stdin or 
 13605                              <1> 	; stdout redirection (by the shell),
 13606                              <1>         ; console tty keyboard must be available
 13607                              <1> 	; to terminate running process,
 13608                              <1> 	; in order to prevent a deadlock. 
 13609                              <1> 	;
 13610 000035B0 52                  <1> 	push	edx
 13611 000035B1 0FB615[09710000]    <1> 	movzx	edx, byte [u.uno]
 13612 000035B8 3A82[EF6D0000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
 13613 000035BE 5A                  <1> 	pop	edx
 13614 000035BF 7412                <1> 	je	short cbrk2
 13615                              <1> cbrk1:
 13616 000035C1 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
 13617                              <1> 	; 06/12/2013
 13618 000035C3 3A05[EE700000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
 13619 000035C9 7408                <1> 	je	short cbrk2	
 13620 000035CB 3A05[EF700000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
 13621 000035D1 7509                <1> 	jne	short cbrk3	
 13622                              <1> cbrk2:
 13623                              <1> 	;; 06/12/2013
 13624                              <1> 	;mov	ax, [u.quit]
 13625                              <1> 	;and	ax, ax
 13626                              <1> 	;jz	short cbrk3
 13627                              <1> 	;
 13628                              <1> 	;xor	ax, ax ; 0
 13629                              <1> 	;dec	ax
 13630                              <1> 	; 04/12/2021
 13631 000035D3 31C0                <1> 	xor	eax, eax ; 0
 13632 000035D5 48                  <1> 	dec	eax ; 0FFFFFFFFg
 13633                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
 13634 000035D6 66A3[06710000]      <1> 	mov	[u.quit], ax
 13635                              <1> cbrk3:
 13636                              <1> 	;pop	ax
 13637                              <1> 	; 04/12/2021
 13638 000035DC 58                  <1> 	pop	eax
 13639                              <1> cbrk4:
 13640 000035DD C3                  <1> 	retn
 13641                              <1> 
 13642                              <1> com2_int:
 13643                              <1> 	; 07/11/2015 
 13644                              <1> 	; 24/10/2015
 13645                              <1> 	; 23/10/2015
 13646                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13647                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13648                              <1> 	; < serial port 2 interrupt handler >
 13649                              <1> 	;
 13650 000035DE 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13651                              <1> 	;push	eax
 13652 000035E1 66B80900            <1> 	mov	ax, 9
 13653 000035E5 EB07                <1> 	jmp	short comm_int
 13654                              <1> com1_int:
 13655                              <1> 	; 07/11/2015
 13656                              <1> 	; 24/10/2015
 13657 000035E7 890424              <1> 	mov 	[esp], eax ; overwrite call return address
 13658                              <1> 	; 23/10/2015
 13659                              <1> 	;push	eax
 13660 000035EA 66B80800            <1> 	mov	ax, 8
 13661                              <1> comm_int:
 13662                              <1> 	; 20/11/2015
 13663                              <1> 	; 18/11/2015
 13664                              <1> 	; 17/11/2015
 13665                              <1> 	; 16/11/2015
 13666                              <1> 	; 09/11/2015
 13667                              <1> 	; 08/11/2015
 13668                              <1> 	; 07/11/2015
 13669                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
 13670                              <1> 	; 01/11/2015
 13671                              <1> 	; 26/10/2015
 13672                              <1> 	; 23/10/2015
 13673 000035EE 53                  <1> 	push	ebx
 13674 000035EF 56                  <1> 	push	esi
 13675 000035F0 57                  <1> 	push	edi
 13676 000035F1 1E                  <1> 	push 	ds
 13677 000035F2 06                  <1> 	push 	es
 13678                              <1> 	; 18/11/2015
 13679 000035F3 0F20DB              <1> 	mov	ebx, cr3
 13680 000035F6 53                  <1> 	push	ebx ; ****
 13681                              <1> 	;
 13682 000035F7 51                  <1> 	push	ecx ; ***
 13683 000035F8 52                  <1> 	push	edx ; **
 13684                              <1> 	;
 13685 000035F9 BB10000000          <1> 	mov	ebx, KDATA
 13686 000035FE 8EDB                <1> 	mov	ds, bx
 13687 00003600 8EC3                <1> 	mov	es, bx
 13688                              <1> 	;
 13689 00003602 8B0D[B86F0000]      <1> 	mov	ecx, [k_page_dir]
 13690 00003608 0F22D9              <1> 	mov	cr3, ecx
 13691                              <1> 	; 20/11/2015
 13692                              <1> 	; Interrupt identification register
 13693 0000360B 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
 13694                              <1> 	;
 13695 0000360F 3C08                <1> 	cmp 	al, 8 
 13696 00003611 7702                <1> 	ja 	short com_i0
 13697                              <1> 	;
 13698                              <1> 	; 20/11/2015
 13699                              <1> 	; 17/11/2015
 13700                              <1> 	; 16/11/2015
 13701                              <1> 	; 15/11/2015
 13702                              <1> 	; 24/10/2015
 13703                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
 13704                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
 13705                              <1> 	; < serial port 1 interrupt handler >
 13706                              <1> 	;
 13707 00003613 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
 13708                              <1> com_i0:
 13709                              <1> 	;push	eax ; *
 13710                              <1> 	; 07/11/2015
 13711 00003615 A2[26700000]        <1> 	mov 	byte [ccomport], al
 13712                              <1> 	; 09/11/2015
 13713 0000361A 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
 13714                              <1> 	; 17/11/2015
 13715                              <1>  	; reset request for response status
 13716 0000361D 88A3[1C700000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
 13717                              <1> 	;
 13718                              <1> 	; 20/11/2015
 13719 00003623 EC                  <1> 	in	al, dx		; read interrupt id. register
 13720 00003624 EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13721 00003626 2404                <1> 	and	al, 4		; received data available?	
 13722 00003628 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
 13723                              <1> 	;
 13724                              <1> 	; 20/11/2015
 13725 0000362A 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
 13726 0000362D EC                  <1> 	in	al, dx     	; read character
 13727                              <1> 	;JMP	$+2	   	; I/O DELAY
 13728                              <1> 	; 08/11/2015
 13729                              <1> 	; 07/11/2015
 13730 0000362E 89DE                <1> 	mov	esi, ebx 
 13731 00003630 89DF                <1> 	mov	edi, ebx
 13732 00003632 81C6[20700000]      <1> 	add 	esi, rchar - 8 ; points to last received char
 13733 00003638 81C7[22700000]      <1> 	add	edi, schar - 8 ; points to last sent char
 13734 0000363E 8806                <1> 	mov	[esi], al ; received char (current char)
 13735                              <1> 	; query
 13736 00003640 20C0                <1> 	and	al, al
 13737 00003642 7527                <1> 	jnz	short com_i2
 13738                              <1>    	; response
 13739                              <1> 	; 17/11/2015
 13740                              <1> 	; set request for response status
 13741 00003644 FE83[1C700000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
 13742                              <1> 	;
 13743 0000364A 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
 13744 0000364E EC                  <1> 	in	al, dx	   	; read line status register 
 13745 0000364F EB00                <1> 	JMP	$+2	   	; I/O DELAY
 13746 00003651 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
 13747 00003653 7445                <1> 	jz	short com_eoi 	; no
 13748 00003655 B0FF                <1> 	mov 	al, 0FFh   	; response			
 13749 00003657 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
 13750 0000365B EE                  <1> 	out	dx, al	   	; send on serial port
 13751                              <1> 	; 17/11/2015
 13752 0000365C 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
 13753 0000365F 7502                <1> 	jne 	short com_i1    ; no
 13754 00003661 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
 13755                              <1> com_i1:
 13756                              <1> 	; 17/11/2015
 13757                              <1> 	; reset request for response status (again)
 13758 00003663 FE8B[1C700000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
 13759 00003669 EB2F                <1> 	jmp	short com_eoi
 13760                              <1> com_i2:	
 13761                              <1> 	; 08/11/2015
 13762 0000366B 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
 13763 0000366D 7417                <1> 	je	short com_i3	; (check for response signal)
 13764                              <1> 	; 07/11/2015
 13765 0000366F 3C04                <1> 	cmp	al, 04h	; EOT
 13766 00003671 751C                <1> 	jne	short com_i4	
 13767                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
 13768                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
 13769                              <1> 	; 08/11/2015
 13770                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
 13771 00003673 861D[E66F0000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
 13772 00003679 E814FFFFFF          <1> 	call 	ctrlbrk
 13773 0000367E 861D[E66F0000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
 13774                              <1> 	;mov	al, 04h ; EOT
 13775                              <1> 	; 08/11/2015
 13776 00003684 EB09                <1> 	jmp	short com_i4	
 13777                              <1> com_i3:
 13778                              <1> 	; 08/11/2015
 13779                              <1> 	; If 0FFh has been received just after a query
 13780                              <1> 	; (schar, ZERO), it is a response signal.
 13781                              <1> 	; 17/11/2015
 13782 00003686 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
 13783 00003689 7704                <1> 	ja	short com_i4 ; no
 13784                              <1> 	; reset query status (schar)
 13785 0000368B 8807                <1> 	mov	[edi], al ; 0FFh
 13786 0000368D FEC0                <1> 	inc	al ; 0
 13787                              <1> com_i4:
 13788                              <1> 	; 27/07/2014
 13789                              <1> 	; 09/07/2014
 13790 0000368F D0E3                <1> 	shl	bl, 1	
 13791 00003691 81C3[E86F0000]      <1> 	add	ebx, ttychr
 13792                              <1> 	; 23/07/2014 (always overwrite)
 13793                              <1> 	;;cmp	word [ebx], 0
 13794                              <1> 	;;ja	short com_eoi
 13795                              <1> 	;
 13796 00003697 668903              <1> 	mov	[ebx], ax   ; Save ascii code
 13797                              <1> 			    ; scan code = 0
 13798                              <1> com_eoi:
 13799                              <1> 	;mov	al, 20h
 13800                              <1> 	;out	20h, al	   ; end of interrupt
 13801                              <1> 	;
 13802                              <1> 	; 07/11/2015
 13803                              <1>       	;pop	eax ; *
 13804 0000369A A0[26700000]        <1> 	mov	al, byte [ccomport] ; current COM port
 13805                              <1> 	 ; al = tty number (8 or 9)
 13806 0000369F E8E11A0000          <1>         call	wakeup
 13807                              <1> com_iret:
 13808                              <1> 	; 23/10/2015
 13809 000036A4 5A                  <1> 	pop	edx ; **
 13810 000036A5 59                  <1> 	pop	ecx ; ***
 13811                              <1> 	; 18/11/2015
 13812                              <1> 	;pop	eax ; ****
 13813                              <1> 	;mov	cr3, eax
 13814                              <1> 	;jmp	iiret
 13815 000036A6 E9F6D3FFFF          <1> 	jmp	iiretp
 13816                              <1> 
 13817                              <1> ;iiretp: ; 01/09/2015
 13818                              <1> ;	; 28/08/2015
 13819                              <1> ;	pop	eax ; (*) page directory
 13820                              <1> ;	mov	cr3, eax
 13821                              <1> ;iiret:
 13822                              <1> ;	; 22/08/2014
 13823                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
 13824                              <1> ;	out	20h, al	; 8259 PORT
 13825                              <1> ;	;
 13826                              <1> ;	pop	es
 13827                              <1> ;	pop	ds
 13828                              <1> ;	pop	edi
 13829                              <1> ;	pop	esi
 13830                              <1> ;	pop	ebx ; 29/08/2014
 13831                              <1> ;	pop 	eax
 13832                              <1> ;	iretd
 13833                              <1> 
 13834                              <1> sp_init:
 13835                              <1> 	; 07/11/2015
 13836                              <1> 	; 29/10/2015
 13837                              <1> 	; 26/10/2015
 13838                              <1> 	; 23/10/2015
 13839                              <1> 	; 29/06/2015
 13840                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
 13841                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
 13842                              <1> 	; Initialization of Serial Port Communication Parameters
 13843                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 13844                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 13845                              <1> 	;
 13846                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 13847                              <1> 	;
 13848                              <1> 	; INPUT:  (29/06/2015)
 13849                              <1> 	;	AL = 0 for COM1
 13850                              <1> 	;	     1 for COM2
 13851                              <1> 	;	AH = Communication parameters	
 13852                              <1> 	;
 13853                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 13854                              <1> 	;	Bit	4	3	2	1	0
 13855                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 13856                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 13857                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 13858                              <1> 	;		11 = even
 13859                              <1> 	;  Baud rate setting bits: (29/06/2015)
 13860                              <1> 	;		Retro UNIX 386 v1 feature only !
 13861                              <1> 	;	Bit	7    6    5  | Baud rate
 13862                              <1> 	;		------------------------
 13863                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 13864                              <1> 	;		0    0    1  | 9600 (12)
 13865                              <1> 	;		0    1    0  | 19200 (6) 
 13866                              <1> 	;		0    1	  1  | 38400 (3) 
 13867                              <1> 	;		1    0	  0  | 14400 (8)
 13868                              <1> 	;		1    0	  1  | 28800 (4)
 13869                              <1> 	;		1    1    0  | 57600 (2)
 13870                              <1> 	;		1    1    1  | 115200 (1) 	
 13871                              <1> 	
 13872                              <1> 	; References:	
 13873                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
 13874                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
 13875                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
 13876                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
 13877                              <1> 	;
 13878                              <1> 	; Set communication parameters for COM1 (= 03h)	
 13879                              <1> 	;
 13880 000036AB BB[22700000]        <1> 	mov	ebx, com1p		; COM1 parameters  
 13881 000036B0 66BAF803            <1> 	mov	dx, 3F8h		; COM1
 13882                              <1> 	 ; 29/10/2015
 13883 000036B4 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13884 000036B8 E86F000000          <1> 	call	sp_i3	; call A4	
 13885 000036BD A880                <1> 	test	al, 80h
 13886 000036BF 7410                <1> 	jz	short sp_i0 ; OK..
 13887                              <1> 		; Error !
 13888                              <1> 	;mov	dx, 3F8h
 13889 000036C1 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
 13890 000036C4 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13891 000036C8 E85F000000          <1> 	call	sp_i3	; call A4	
 13892 000036CD A880                <1> 	test	al, 80h
 13893 000036CF 7508                <1> 	jnz	short sp_i1
 13894                              <1> sp_i0:
 13895                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
 13896                              <1>         ; (INT 14h initialization code disables interrupts.)
 13897                              <1> 	;
 13898 000036D1 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13899 000036D4 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
 13900                              <1> sp_i1:
 13901 000036D9 43                  <1> 	inc	ebx
 13902 000036DA 66BAF802            <1> 	mov	dx, 2F8h		; COM2
 13903                              <1> 	 ; 29/10/2015
 13904 000036DE 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
 13905 000036E2 E845000000          <1> 	call	sp_i3	; call A4	
 13906 000036E7 A880                <1> 	test	al, 80h
 13907 000036E9 7410                <1> 	jz	short sp_i2 ; OK..
 13908                              <1> 		; Error !
 13909                              <1> 	;mov	dx, 2F8h
 13910 000036EB 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
 13911 000036EE 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
 13912 000036F2 E835000000          <1> 	call	sp_i3	; call A4	
 13913 000036F7 A880                <1> 	test	al, 80h
 13914 000036F9 7530                <1> 	jnz	short sp_i7
 13915                              <1> sp_i2:
 13916 000036FB C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
 13917                              <1> sp_i6:
 13918                              <1> 	;; COM2 - enabling IRQ 3
 13919                              <1> 	; 07/11/2015
 13920                              <1> 	; 26/10/2015
 13921 000036FE 9C                  <1> 	pushf
 13922 000036FF FA                  <1> 	cli
 13923                              <1> 	;
 13924 00003700 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
 13925 00003704 EC                  <1> 	in	al, dx 	   		; read register
 13926 00003705 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13927 00003707 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 13928 00003709 EE                  <1> 	out	dx, al     		; write back to register
 13929 0000370A EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13930 0000370C 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
 13931 00003710 EC                  <1> 	in	al, dx     		; read register
 13932 00003711 EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13933                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 13934 00003713 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 13935 00003715 EE                  <1> 	out	dx, al 	   		; write back to register
 13936 00003716 EB00                <1> 	JMP	$+2        		; I/O DELAY
 13937 00003718 E421                <1> 	in	al, 21h    		; read interrupt mask register
 13938 0000371A EB00                <1> 	JMP	$+2	   		; I/O DELAY
 13939 0000371C 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
 13940 0000371E E621                <1> 	out	21h, al    		; write back to register
 13941                              <1> 	;
 13942                              <1> 	; 23/10/2015
 13943 00003720 B8[DE350000]        <1> 	mov 	eax, com2_int
 13944 00003725 A3[D33B0000]        <1> 	mov	[com2_irq3], eax
 13945                              <1> 	; 26/10/2015
 13946 0000372A 9D                  <1> 	popf	
 13947                              <1> sp_i7:
 13948 0000372B C3                  <1> 	retn
 13949                              <1> 
 13950                              <1> sp_i3:
 13951                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
 13952                              <1> 	; 28/10/2015
 13953 0000372C FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
 13954 0000372E B000                <1> 	mov	al, 0
 13955 00003730 EE                  <1> 	out	dx, al			; disable serial port interrupt
 13956 00003731 EB00                <1> 	JMP	$+2			; I/O DELAY
 13957 00003733 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
 13958 00003736 B080                <1> 	mov	al, 80h			
 13959 00003738 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
 13960                              <1> 	;-----	SET BAUD RATE DIVISOR
 13961                              <1> 	; 26/10/2015
 13962 00003739 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
 13963                              <1> 					; of the divisor value
 13964 0000373C 88C8                <1> 	mov	al, cl	; 1
 13965 0000373E EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
 13966                              <1> 					; 2 = 57600 baud
 13967                              <1> 					; 3 = 38400 baud
 13968                              <1> 					; 6 = 19200 baud
 13969                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
 13970 0000373F EB00                <1> 	JMP	$+2			; I/O DELAY
 13971 00003741 28C0                <1> 	sub	al, al
 13972 00003743 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
 13973                              <1> 					; of the divisor value
 13974 00003745 EE                  <1> 	out	dx, al ; 0
 13975 00003746 EB00                <1> 	JMP	$+2			; I/O DELAY
 13976                              <1> 	;	
 13977 00003748 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
 13978                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
 13979 0000374A 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
 13980 0000374D EE                  <1> 	out	dx, al			
 13981 0000374E EB00                <1> 	JMP	$+2			; I/O DELAY
 13982                              <1> 	; 29/10/2015
 13983 00003750 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
 13984 00003752 30C0                <1> 	xor	al, al			; 0
 13985 00003754 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
 13986 00003755 EB00                <1> 	JMP	$+2	
 13987                              <1> sp_i4:
 13988                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
 13989                              <1> 	; 29/06/2015 (line status after modem status)
 13990 00003757 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
 13991                              <1> sp_i4s:
 13992 0000375A EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
 13993 0000375B EB00                <1> 	JMP	$+2			; I/O DELAY
 13994 0000375D 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
 13995 0000375F FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
 13996                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
 13997 00003761 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
 13998                              <1> 	; AL = Line status, AH = Modem status
 13999 00003762 C3                  <1> 	retn
 14000                              <1> 
 14001                              <1> sp_status:
 14002                              <1> 	; 29/06/2015
 14003                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
 14004                              <1> 	; Get serial port status
 14005 00003763 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
 14006 00003767 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
 14007                              <1> 					; dx = 2FEh for COM2
 14008 00003769 EBEF                <1> 	jmp	short sp_i4s
 14009                              <1> 
 14010                              <1> sp_setp: ; Set serial port communication parameters
 14011                              <1> 	; 07/11/2015
 14012                              <1> 	; 29/10/2015
 14013                              <1> 	; 29/06/2015
 14014                              <1> 	; Retro UNIX 386 v1 feature only !	
 14015                              <1> 	;
 14016                              <1> 	; INPUT:
 14017                              <1> 	;	AL = 0 for COM1
 14018                              <1> 	;	     1 for COM2
 14019                              <1> 	;	AH = Communication parameters (*)
 14020                              <1> 	; OUTPUT:
 14021                              <1> 	;	CL = Line status
 14022                              <1> 	;	CH = Modem status
 14023                              <1> 	;   If cf = 1 -> Error code in [u.error]
 14024                              <1> 	;		 'invalid parameter !' 
 14025                              <1> 	;		 	 or
 14026                              <1> 	;		 'device not ready !' error
 14027                              <1> 	;	
 14028                              <1> 	;  (*) Communication parameters (except BAUD RATE):
 14029                              <1> 	;	Bit	4	3	2	1	0
 14030                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
 14031                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
 14032                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
 14033                              <1> 	;		11 = even
 14034                              <1> 	;  Baud rate setting bits: (29/06/2015)
 14035                              <1> 	;		Retro UNIX 386 v1 feature only !
 14036                              <1> 	;	Bit	7    6    5  | Baud rate
 14037                              <1> 	;		------------------------
 14038                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
 14039                              <1> 	;		0    0    1  | 9600 (12)
 14040                              <1> 	;		0    1    0  | 19200 (6) 
 14041                              <1> 	;		0    1	  1  | 38400 (3) 
 14042                              <1> 	;		1    0	  0  | 14400 (8)
 14043                              <1> 	;		1    0	  1  | 28800 (4)
 14044                              <1> 	;		1    1    0  | 57600 (2)
 14045                              <1> 	;		1    1    1  | 115200 (1) 
 14046                              <1> 	;
 14047                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
 14048                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
 14049                              <1> 	;
 14050                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
 14051                              <1> 	;
 14052 0000376B 66BAF803            <1> 	mov	dx, 3F8h
 14053 0000376F BB[22700000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
 14054 00003774 3C01                <1> 	cmp	al, 1
 14055 00003776 776B                <1> 	ja 	short sp_invp_err
 14056 00003778 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
 14057 0000377A FECE                <1> 	dec	dh ; 2F8h
 14058 0000377C 43                  <1> 	inc	ebx ; COM2 control byte offset
 14059                              <1> sp_setp1:
 14060                              <1> 	; 29/10/2015
 14061 0000377D 8823                <1> 	mov	[ebx], ah
 14062 0000377F 0FB6CC              <1> 	movzx 	ecx, ah
 14063 00003782 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
 14064 00003785 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
 14065 00003788 8A81[F2370000]      <1> 	mov	al, [ecx+b_div_tbl]
 14066 0000378E 6689C1              <1> 	mov	cx, ax
 14067 00003791 E896FFFFFF          <1> 	call	sp_i3
 14068 00003796 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
 14069 00003799 A880                <1> 	test	al, 80h
 14070 0000379B 740F                <1> 	jz	short sp_setp2
 14071 0000379D C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
 14072                              <1> stp_dnr_err:
 14073 000037A0 C705[2C710000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
 14074 000037A8 0000                <1>
 14075                              <1> 	; CL = Line status, CH = Modem status
 14076 000037AA F9                  <1> 	stc
 14077 000037AB C3                  <1> 	retn
 14078                              <1> sp_setp2:
 14079 000037AC 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
 14080 000037AF 0F8649FFFFFF        <1>         jna     sp_i6 
 14081                              <1> 		      ; COM1 (3F?h)
 14082                              <1> sp_i5: 
 14083                              <1> 	; 07/11/2015
 14084                              <1> 	; 26/10/2015
 14085                              <1> 	; 29/06/2015
 14086                              <1> 	;
 14087                              <1> 	;; COM1 - enabling IRQ 4
 14088 000037B5 9C                  <1> 	pushf
 14089 000037B6 FA                  <1> 	cli
 14090 000037B7 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
 14091 000037BB EC                  <1> 	in	al, dx 	   		; read register
 14092 000037BC EB00                <1> 	JMP	$+2			; I/O DELAY
 14093 000037BE 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
 14094 000037C0 EE                  <1> 	out	dx, al     		; write back to register
 14095 000037C1 EB00                <1> 	JMP	$+2			; I/O DELAY
 14096 000037C3 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
 14097 000037C7 EC                  <1> 	in	al, dx     		; read register
 14098 000037C8 EB00                <1> 	JMP	$+2			; I/O DELAY
 14099                              <1> 	;or	al, 1      		; receiver data interrupt enable and
 14100 000037CA 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
 14101 000037CC EE                  <1> 	out	dx, al 	   		; write back to register
 14102 000037CD EB00                <1> 	JMP	$+2        		; I/O DELAY
 14103 000037CF E421                <1> 	in	al, 21h    		; read interrupt mask register
 14104 000037D1 EB00                <1> 	JMP	$+2			; I/O DELAY
 14105 000037D3 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
 14106 000037D5 E621                <1> 	out	21h, al    		; write back to register
 14107                              <1> 	;
 14108                              <1> 	; 23/10/2015
 14109 000037D7 B8[E7350000]        <1> 	mov 	eax, com1_int
 14110 000037DC A3[CF3B0000]        <1> 	mov	[com1_irq4], eax
 14111                              <1> 	; 26/10/2015
 14112 000037E1 9D                  <1> 	popf
 14113 000037E2 C3                  <1> 	retn
 14114                              <1> 
 14115                              <1> sp_invp_err:
 14116 000037E3 C705[2C710000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 14117 000037EB 0000                <1>
 14118 000037ED 31C9                <1> 	xor	ecx, ecx
 14119 000037EF 49                  <1> 	dec	ecx ; 0FFFFh
 14120 000037F0 F9                  <1> 	stc
 14121 000037F1 C3                  <1> 	retn
 14122                              <1> 
 14123                              <1> ; 29/10/2015
 14124                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
 14125 000037F2 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
 14126                              <1> 
 14127                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014) 
 14128                              <1> epoch:
 14129                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 14130                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 14131                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
 14132                              <1> 	; 'epoch' procedure prototype: 
 14133                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 14134                              <1> 	; 14/11/2012
 14135                              <1> 	; unixboot.asm (boot file configuration)
 14136                              <1> 	; version of "epoch" procedure in "unixproc.asm"
 14137                              <1> 	; 21/7/2012
 14138                              <1> 	; 15/7/2012
 14139                              <1> 	; 14/7/2012		
 14140                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
 14141                              <1> 	; compute current date and time as UNIX Epoch/Time
 14142                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
 14143                              <1> 	;
 14144                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
 14145                              <1> 	;
 14146 000037F9 E81B010000          <1> 	call 	get_rtc_time		; Return Current Time
 14147 000037FE 86E9                <1>         xchg 	ch,cl
 14148 00003800 66890D[266D0000]    <1>         mov 	[hour], cx
 14149 00003807 86F2                <1>         xchg 	dh,dl
 14150 00003809 668915[2A6D0000]    <1>         mov 	[second], dx
 14151                              <1> 	;
 14152 00003810 E835010000          <1>         call 	get_rtc_date		; Return Current Date
 14153 00003815 86E9                <1>         xchg 	ch,cl
 14154 00003817 66890D[206D0000]    <1>         mov 	[year], cx
 14155 0000381E 86F2                <1>         xchg 	dh,dl
 14156 00003820 668915[226D0000]    <1>         mov 	[month], dx
 14157                              <1> 	;
 14158 00003827 66B93030            <1> 	mov 	cx, 3030h
 14159                              <1> 	;
 14160 0000382B A0[266D0000]        <1> 	mov 	al, [hour] ; Hour
 14161                              <1>         	; AL <= BCD number)
 14162 00003830 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 14163                              <1> 					; AH = AL / 10h
 14164                              <1> 					; AL = AL MOD 10h
 14165 00003832 D50A                <1>         aad 	; AX= AH*10+AL
 14166 00003834 A2[266D0000]        <1> 	mov 	[hour], al
 14167 00003839 A0[276D0000]        <1> 	mov 	al, [hour+1] ; Minute
 14168                              <1>         	; AL <= BCD number)
 14169 0000383E D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 14170                              <1> 					; AH = AL / 10h
 14171                              <1> 					; AL = AL MOD 10h
 14172 00003840 D50A                <1>         aad 	; AX= AH*10+AL
 14173 00003842 A2[286D0000]        <1> 	mov 	[minute], al
 14174 00003847 A0[2A6D0000]        <1> 	mov 	al, [second] ; Second
 14175                              <1>         	; AL <= BCD number)
 14176 0000384C D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 14177                              <1> 					; AH = AL / 10h
 14178                              <1> 					; AL = AL MOD 10h
 14179 0000384E D50A                <1>         aad 	; AX= AH*10+AL
 14180 00003850 A2[2A6D0000]        <1> 	mov 	[second], al
 14181 00003855 66A1[206D0000]      <1> 	mov 	ax, [year] ; Year (century)
 14182                              <1> 	;push 	ax
 14183                              <1> 	; 04/12/2021
 14184 0000385B 50                  <1> 	push	eax
 14185                              <1> 	   	; AL <= BCD number)
 14186 0000385C D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 14187                              <1> 					; AH = AL / 10h
 14188                              <1> 					; AL = AL MOD 10h
 14189 0000385E D50A                <1>         aad 	; AX= AH*10+AL
 14190 00003860 B464                <1> 	mov 	ah, 100
 14191 00003862 F6E4                <1> 	mul 	ah
 14192 00003864 66A3[206D0000]      <1> 	mov 	[year], ax
 14193                              <1> 	;pop	ax
 14194                              <1> 	; 04/12/2021
 14195 0000386A 58                  <1> 	pop	eax
 14196 0000386B 88E0                <1> 	mov	al, ah
 14197                              <1>         	; AL <= BCD number)
 14198 0000386D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 14199                              <1> 					; AH = AL / 10h
 14200                              <1> 					; AL = AL MOD 10h
 14201 0000386F D50A                <1>         aad 	; AX= AH*10+AL
 14202 00003871 660105[206D0000]    <1> 	add 	[year], ax
 14203 00003878 A0[226D0000]        <1> 	mov 	al, [month] ; Month
 14204                              <1>            	; AL <= BCD number)
 14205 0000387D D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 14206                              <1> 					; AH = AL / 10h
 14207                              <1> 					; AL = AL MOD 10h
 14208 0000387F D50A                <1>         aad 	; AX= AH*10+AL
 14209 00003881 A2[226D0000]        <1> 	mov 	[month], al	
 14210 00003886 A0[236D0000]        <1>         mov     al, [month+1]      	; Day
 14211                              <1>            	; AL <= BCD number)
 14212 0000388B D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
 14213                              <1> 					; AH = AL / 10h
 14214                              <1> 					; AL = AL MOD 10h
 14215 0000388D D50A                <1>         aad 	; AX= AH*10+AL
 14216 0000388F A2[246D0000]        <1>         mov     [day], al
 14217                              <1> 	
 14218                              <1> convert_to_epoch:
 14219                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
 14220                              <1> 	; 09/04/2013 (retro UNIX 8086 v1)
 14221                              <1> 	;
 14222                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
 14223                              <1> 	;
 14224                              <1> 	; Derived from DALLAS Semiconductor
 14225                              <1> 	; Application Note 31 (DS1602/DS1603)
 14226                              <1> 	; 6 May 1998
 14227 00003894 29C0                <1> 	sub 	eax, eax
 14228 00003896 66A1[206D0000]      <1> 	mov 	ax, [year]
 14229 0000389C 662DB207            <1> 	sub 	ax, 1970
 14230 000038A0 BA6D010000          <1> 	mov 	edx, 365
 14231 000038A5 F7E2                <1> 	mul 	edx
 14232 000038A7 31DB                <1> 	xor 	ebx, ebx
 14233 000038A9 8A1D[226D0000]      <1> 	mov 	bl, [month]
 14234 000038AF FECB                <1> 	dec 	bl
 14235 000038B1 D0E3                <1> 	shl 	bl, 1
 14236                              <1> 	;sub	edx, edx
 14237 000038B3 668B93[2C6D0000]    <1> 	mov 	dx, [EBX+DMonth]
 14238 000038BA 8A1D[246D0000]      <1>         mov     bl, [day]
 14239 000038C0 FECB                <1> 	dec 	bl
 14240 000038C2 01D0                <1> 	add 	eax, edx
 14241 000038C4 01D8                <1> 	add 	eax, ebx
 14242                              <1> 			; EAX = days since 1/1/1970
 14243 000038C6 668B15[206D0000]    <1> 	mov 	dx, [year]
 14244 000038CD 6681EAB107          <1> 	sub 	dx, 1969
 14245 000038D2 66D1EA              <1> 	shr 	dx, 1
 14246 000038D5 66D1EA              <1> 	shr 	dx, 1		
 14247                              <1> 		; (year-1969)/4
 14248 000038D8 01D0                <1> 	add 	eax, edx
 14249                              <1> 			; + leap days since 1/1/1970
 14250 000038DA 803D[226D0000]02    <1> 	cmp 	byte [month], 2	; if past february
 14251 000038E1 7610                <1> 	jna 	short cte1
 14252 000038E3 668B15[206D0000]    <1> 	mov 	dx, [year]
 14253 000038EA 6683E203            <1> 	and 	dx, 3 ; year mod 4
 14254 000038EE 7503                <1> 	jnz 	short cte1		
 14255                              <1> 			; and if leap year
 14256 000038F0 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
 14257                              <1> cte1: 			; compute seconds since 1/1/1970
 14258 000038F3 BA18000000          <1> 	mov 	edx, 24
 14259 000038F8 F7E2                <1> 	mul	edx
 14260 000038FA 8A15[266D0000]      <1> 	mov 	dl, [hour]
 14261 00003900 01D0                <1> 	add 	eax, edx
 14262                              <1> 		; EAX = hours since 1/1/1970 00:00:00
 14263                              <1> 	;mov	ebx, 60
 14264 00003902 B33C                <1> 	mov	bl, 60
 14265 00003904 F7E3                <1> 	mul	ebx
 14266 00003906 8A15[286D0000]      <1> 	mov 	dl, [minute]
 14267 0000390C 01D0                <1> 	add 	eax, edx
 14268                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
 14269                              <1> 	;mov 	ebx, 60
 14270 0000390E F7E3                <1> 	mul	ebx
 14271 00003910 8A15[2A6D0000]      <1> 	mov 	dl, [second]
 14272 00003916 01D0                <1> 	add 	eax, edx
 14273                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
 14274 00003918 C3                  <1> 	retn
 14275                              <1> 
 14276                              <1> get_rtc_time:
 14277                              <1> 	; 15/03/2015
 14278                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14279                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14280                              <1> 	; INT 1Ah
 14281                              <1> 	; (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,	:
 14282                              <1> 	;       (CH) = HOURS IN BCD (00-23)			:
 14283                              <1> 	;       (CL) = MINUTES IN BCD (00-59)			:
 14284                              <1> 	;       (DH) = SECONDS IN BCD (00-59)			:
 14285                              <1> 	;       (DL) = DAYLIGHT SAVINGS ENABLE (00-01).		:
 14286                              <1> 	;								
 14287                              <1> RTC_20: 				; GET RTC TIME
 14288 00003919 FA                  <1> 	cli
 14289 0000391A E819D3FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14290 0000391F 7227                <1> 	JC	short RTC_29		; EXIT IF ERROR (CY= 1)
 14291                              <1> 
 14292 00003921 B000                <1> 	MOV	AL,CMOS_SECONDS 	; SET ADDRESS OF SECONDS
 14293 00003923 E8FAD2FFFF          <1> 	CALL	CMOS_READ		; GET SECONDS
 14294 00003928 88C6                <1> 	MOV	DH,AL			; SAVE
 14295 0000392A B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 14296 0000392C E8F1D2FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 14297 00003931 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 14298 00003933 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 14299 00003935 B002                <1> 	MOV	AL,CMOS_MINUTES 	; SET ADDRESS OF MINUTES
 14300 00003937 E8E6D2FFFF          <1> 	CALL	CMOS_READ		; GET MINUTES
 14301 0000393C 88C1                <1> 	MOV	CL,AL			; SAVE
 14302 0000393E B004                <1> 	MOV	AL,CMOS_HOURS		; SET ADDRESS OF HOURS
 14303 00003940 E8DDD2FFFF          <1> 	CALL	CMOS_READ		; GET HOURS
 14304 00003945 88C5                <1> 	MOV	CH,AL			; SAVE
 14305 00003947 F8                  <1> 	CLC				; SET CY= 0
 14306                              <1> RTC_29:
 14307 00003948 FB                  <1> 	sti
 14308 00003949 C3                  <1> 	RETn				; RETURN WITH RESULT IN CARRY FLAG
 14309                              <1> 
 14310                              <1> get_rtc_date:
 14311                              <1> 	; 15/03/2015
 14312                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14313                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14314                              <1> 	; INT 1Ah
 14315                              <1> 	; (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,:
 14316                              <1> 	;      (CH) = CENTURY IN BCD (19 OR 20) 		       :
 14317                              <1> 	;      (CL) = YEAR IN BCD (00-99)			       :
 14318                              <1> 	;      (DH) = MONTH IN BCD (01-12)			       :
 14319                              <1> 	;      (DL) = DAY IN BCD (01-31).		
 14320                              <1> 	;
 14321                              <1> RTC_40: 				; GET RTC DATE
 14322 0000394A FA                  <1> 	cli
 14323 0000394B E8E8D2FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14324 00003950 7225                <1> 	JC	short RTC_49		; EXIT IF ERROR (CY= 1)
 14325                              <1> 
 14326 00003952 B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
 14327 00003954 E8C9D2FFFF          <1> 	CALL	CMOS_READ		; READ DAY OF MONTH
 14328 00003959 88C2                <1> 	MOV	DL,AL			; SAVE
 14329 0000395B B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH
 14330 0000395D E8C0D2FFFF          <1> 	CALL	CMOS_READ		; READ MONTH
 14331 00003962 88C6                <1> 	MOV	DH,AL			; SAVE
 14332 00003964 B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR
 14333 00003966 E8B7D2FFFF          <1> 	CALL	CMOS_READ		; READ YEAR
 14334 0000396B 88C1                <1> 	MOV	CL,AL			; SAVE
 14335 0000396D B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY LOCATION
 14336 0000396F E8AED2FFFF          <1> 	CALL	CMOS_READ		; GET CENTURY BYTE
 14337 00003974 88C5                <1> 	MOV	CH,AL			; SAVE
 14338 00003976 F8                  <1> 	CLC				; SET CY=0
 14339                              <1> RTC_49:
 14340 00003977 FB                  <1> 	sti
 14341 00003978 C3                  <1> 	RETn				; RETURN WITH RESULTS IN CARRY FLAG
 14342                              <1> 
 14343                              <1> set_date_time:
 14344                              <1> convert_from_epoch:
 14345                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 14346                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 14347                              <1> 	; 'convert_from_epoch' procedure prototype: 
 14348                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
 14349                              <1> 	;
 14350                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
 14351                              <1> 	;
 14352                              <1> 	; Derived from DALLAS Semiconductor
 14353                              <1> 	; Application Note 31 (DS1602/DS1603)
 14354                              <1> 	; 6 May 1998
 14355                              <1> 	;
 14356                              <1> 	; INPUT:
 14357                              <1> 	; EAX = Unix (Epoch) Time
 14358                              <1> 	;
 14359 00003979 31D2                <1> 	xor 	edx, edx
 14360 0000397B B93C000000          <1> 	mov 	ecx, 60
 14361 00003980 F7F1                <1> 	div	ecx
 14362                              <1> 	;mov 	[imin], eax   ; whole minutes
 14363                              <1> 			  ; since 1/1/1970
 14364 00003982 668915[2A6D0000]    <1> 	mov 	[second], dx  ; leftover seconds
 14365 00003989 29D2                <1> 	sub 	edx, edx
 14366 0000398B F7F1                <1> 	div	ecx
 14367                              <1> 	;mov 	[ihrs], eax   ; whole hours
 14368                              <1> 	;		      ; since 1/1/1970
 14369 0000398D 668915[286D0000]    <1> 	mov 	[minute], dx  ; leftover minutes
 14370 00003994 31D2                <1> 	xor	edx, edx
 14371                              <1> 	;mov 	cx, 24
 14372 00003996 B118                <1> 	mov 	cl, 24
 14373 00003998 F7F1                <1> 	div	ecx
 14374                              <1> 	;mov 	[iday], ax   ; whole days
 14375                              <1> 			     ; since 1/1/1970
 14376 0000399A 668915[266D0000]    <1> 	mov 	[hour], dx   ; leftover hours
 14377 000039A1 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
 14378                              <1> 			     ; 1/1/1968 	
 14379                              <1> 	;mov 	[iday], ax
 14380 000039A6 50                  <1> 	push 	eax
 14381 000039A7 29D2                <1> 	sub	edx, edx
 14382 000039A9 B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
 14383 000039AE F7F1                <1> 	div	ecx
 14384 000039B0 59                  <1> 	pop 	ecx
 14385                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
 14386 000039B1 6652                <1> 	push 	dx
 14387                              <1> 	;mov 	[qday], dx   ; days since quadyr began
 14388 000039B3 6683FA3C            <1> 	cmp 	dx, 31 + 29  ; if past feb 29 then
 14389 000039B7 F5                  <1> 	cmc		     ; add this quadyr's leap day
 14390 000039B8 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
 14391                              <1> 	;mov 	[lday], ax   ; since 1968			  
 14392                              <1> 	;mov 	cx, [iday]
 14393 000039BB 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
 14394 000039BC 29C8                <1> 	sub 	eax, ecx     ; iday - lday
 14395 000039BE B96D010000          <1> 	mov 	ecx, 365
 14396 000039C3 31D2                <1> 	xor	edx, edx
 14397                              <1> 	; EAX = iday-lday, EDX = 0
 14398 000039C5 F7F1                <1> 	div	ecx
 14399                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
 14400                              <1> 	;jday = iday - (iyrs*365) - lday
 14401                              <1> 	;mov [jday], dx      ; days since 1/1 of current year
 14402                              <1> 	;add	eax, 1968
 14403 000039C7 6605B007            <1> 	add 	ax, 1968     ; compute year
 14404 000039CB 66A3[206D0000]      <1> 	mov 	[year], ax
 14405 000039D1 6689D1              <1> 	mov 	cx, dx
 14406                              <1> 	;mov 	dx, [qday]
 14407 000039D4 665A                <1> 	pop 	dx
 14408 000039D6 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
 14409 000039DB 7709                <1> 	ja 	short cfe1   ; jday = jday +1
 14410 000039DD 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
 14411 000039E1 F5                  <1>         cmc		     ; add a leap day to the # of whole
 14412 000039E2 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
 14413                              <1> cfe1:			
 14414                              <1> 	;mov 	[jday], cx
 14415 000039E6 66BB0C00            <1> 	mov 	bx, 12       ; estimate month
 14416 000039EA 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
 14417 000039EE 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
 14418                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
 14419 000039F2 6639D1              <1> 	cmp 	cx, dx       ; mday = # of days passed from 1/1
 14420 000039F5 731D                <1> 	jnb 	short cfe3
 14421 000039F7 664B                <1> 	dec 	bx           ; month = month - 1
 14422 000039F9 66D1E3              <1> 	shl 	bx, 1 
 14423 000039FC 668B93[2C6D0000]    <1> 	mov 	dx, [EBX+DMonth] ; # elapsed days at 1st of month
 14424 00003A03 66D1EB              <1> 	shr 	bx, 1        ; bx = month - 1 (0 to 11)
 14425 00003A06 6683FB01            <1> 	cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
 14426 00003A0A 76E6                <1> 	jna 	short cfe2   ; then mday = mday + 1
 14427 00003A0C 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
 14428 00003A0E 75E2                <1> 	jnz 	short cfe2   ; add leap day (to mday)
 14429 00003A10 6642                <1> 	inc 	dx           ; mday = mday + 1
 14430 00003A12 EBDE                <1> 	jmp 	short cfe2
 14431                              <1> cfe3:
 14432 00003A14 6643                <1> 	inc 	bx	     ; -> bx = month, 1 to 12
 14433 00003A16 66891D[226D0000]    <1> 	mov 	[month], bx
 14434 00003A1D 6629D1              <1> 	sub 	cx, dx	     ; day = jday - mday + 1	
 14435 00003A20 6641                <1> 	inc 	cx 			  
 14436 00003A22 66890D[246D0000]    <1> 	mov 	[day], cx
 14437                              <1> 	
 14438                              <1> 	; eax, ebx, ecx, edx is changed at return
 14439                              <1> 	; output ->
 14440                              <1> 	; [year], [month], [day], [hour], [minute], [second]
 14441                              <1> 	
 14442                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
 14443                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 14444                              <1> set_date:
 14445 00003A29 A0[216D0000]        <1>         mov     al, [year+1]
 14446 00003A2E D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14447 00003A30 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14448                              <1> 			     ; AL = AH * 10h + AL
 14449 00003A32 88C5                <1> 	mov 	ch, al ; century (BCD)
 14450 00003A34 A0[206D0000]        <1> 	mov 	al, [year]
 14451 00003A39 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14452 00003A3B D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14453                              <1> 			     ; AL = AH * 10h + AL
 14454 00003A3D 88C1                <1> 	mov 	cl, al ; year (BCD)
 14455 00003A3F A0[226D0000]        <1>         mov 	al, [month]
 14456 00003A44 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14457 00003A46 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14458                              <1> 			     ; AL = AH * 10h + AL
 14459 00003A48 88C6                <1> 	mov 	dh, al ; month (BCD)
 14460 00003A4A A0[246D0000]        <1> 	mov 	al, [day]
 14461 00003A4F D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14462 00003A51 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14463                              <1> 			     ; AL = AH * 10h + AL
 14464 00003A53 88C6                <1> 	mov 	dh, al ; day (BCD)
 14465                              <1> 	; Set real-time clock date
 14466 00003A55 E879000000          <1> 	call	set_rtc_date
 14467                              <1> set_time:
 14468                              <1>         ; Read real-time clock time 
 14469                              <1> 	; (get day light saving time bit status)
 14470 00003A5A FA                  <1>  	cli
 14471 00003A5B E8D8D1FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14472                              <1> 	; cf = 1 -> al = 0
 14473 00003A60 7207                <1>         jc      short stime1
 14474 00003A62 B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
 14475 00003A64 E8B9D1FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
 14476                              <1> stime1:
 14477 00003A69 FB                  <1> 	sti
 14478 00003A6A 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
 14479 00003A6C 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
 14480                              <1> 	; DL = 1 or 0 (day light saving time)
 14481                              <1> 	;	
 14482 00003A6E A0[266D0000]        <1> 	mov 	al, [hour]
 14483 00003A73 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14484 00003A75 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14485                              <1> 			     ; AL = AH * 10h + AL
 14486 00003A77 88C5                <1> 	mov 	ch, al ; hour (BCD)
 14487 00003A79 A0[286D0000]        <1>         mov     al, [minute]
 14488 00003A7E D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14489 00003A80 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14490                              <1> 			     ; AL = AH * 10h + AL
 14491 00003A82 88C1                <1> 	mov 	cl, al       ; minute (BCD)
 14492 00003A84 A0[2A6D0000]        <1>         mov     al, [second]
 14493 00003A89 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
 14494 00003A8B D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
 14495                              <1> 			     ; AL = AH * 10h + AL
 14496 00003A8D 88C6                <1> 	mov 	dh, al	     ; second (BCD)
 14497                              <1> 	; Set real-time clock time
 14498                              <1>  	; call	set_rtc_time
 14499                              <1> set_rtc_time:
 14500                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14501                              <1> 	; 15/03/2015
 14502                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14503                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14504                              <1> 	; INT 1Ah
 14505                              <1> 	; (AH) = 03H  SET THE REAL TIME CLOCK USING,			:
 14506                              <1> 	;      (CH) = HOURS IN BCD (00-23)			       	:
 14507                              <1> 	;      (CL) = MINUTES IN BCD (00-59)			       	:
 14508                              <1> 	;      (DH) = SECONDS IN BCD (00-59)			       	:
 14509                              <1> 	;      (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.    :
 14510                              <1> 	;								:
 14511                              <1> 	;  NOTE: (DL)= 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED. :
 14512                              <1> 	;        (DL)= 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN  :
 14513                              <1> 	;         APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN :
 14514                              <1> 	;         OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.	  :
 14515                              <1> 	;
 14516                              <1> RTC_30: 				; SET RTC TIME
 14517 00003A8F FA                  <1> 	cli
 14518 00003A90 E8A3D1FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14519 00003A95 7305                <1> 	JNC	short RTC_35		; GO AROUND IF CLOCK OPERATING
 14520 00003A97 E886000000          <1> 	CALL	RTC_STA 		; ELSE TRY INITIALIZING CLOCK
 14521                              <1> RTC_35:
 14522 00003A9C 88F4                <1> 	MOV	AH,DH			; GET TIME BYTE - SECONDS
 14523 00003A9E B000                <1> 	MOV	AL,CMOS_SECONDS 	; ADDRESS SECONDS
 14524 00003AA0 E89E000000          <1> 	CALL	CMOS_WRITE		; UPDATE SECONDS
 14525 00003AA5 88CC                <1> 	MOV	AH,CL			; GET TIME BYTE - MINUTES
 14526 00003AA7 B002                <1> 	MOV	AL,CMOS_MINUTES 	; ADDRESS MINUTES
 14527 00003AA9 E895000000          <1> 	CALL	CMOS_WRITE		; UPDATE MINUTES
 14528 00003AAE 88EC                <1> 	MOV	AH,CH			; GET TIME BYTE - HOURS
 14529 00003AB0 B004                <1> 	MOV	AL,CMOS_HOURS		; ADDRESS HOURS
 14530 00003AB2 E88C000000          <1> 	CALL	CMOS_WRITE		; UPDATE ADDRESS
 14531                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14532 00003AB7 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 14533 00003ABB E862D1FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT TIME
 14534 00003AC0 2462                <1> 	AND	AL,01100010B		; MASK FOR VALID BIT POSITIONS
 14535 00003AC2 0C02                <1> 	OR	AL,00000010B		; TURN ON 24 HOUR MODE
 14536 00003AC4 80E201              <1> 	AND	DL,00000001B		; USE ONLY THE DSE BIT
 14537 00003AC7 08D0                <1> 	OR	AL,DL			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
 14538 00003AC9 86E0                <1> 	XCHG	AH,AL			; PLACE IN WORK REGISTER AND GET ADDRESS
 14539 00003ACB E873000000          <1> 	CALL	CMOS_WRITE		; SET NEW ALARM BITS
 14540 00003AD0 F8                  <1> 	CLC				; SET CY= 0
 14541 00003AD1 FB                  <1> 	sti
 14542 00003AD2 C3                  <1> 	RETn				; RETURN WITH CY= 0
 14543                              <1> 
 14544                              <1> set_rtc_date:
 14545                              <1> 	; 15/04/2015 (257, POSTEQU.INC -> H EQU 256, X EQU H+1)
 14546                              <1> 	; 15/03/2015
 14547                              <1> 	; Derived from IBM PC-XT Model 286 BIOS Source Code
 14548                              <1> 	; BIOS2.ASM ---- 10/06/1985 BIOS INTERRUPT ROUTINES
 14549                              <1> 	; INT 1Ah
 14550                              <1> 	; (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING, :
 14551                              <1> 	;     (CH) = CENTURY IN BCD (19 OR 20)			   :
 14552                              <1> 	;     (CL) = YEAR IN BCD (00-99)			   :
 14553                              <1> 	;     (DH) = MONTH IN BCD (01-12)			   :
 14554                              <1> 	;     (DL) = DAY IN BCD (01-31).
 14555                              <1> 	;
 14556                              <1> RTC_50: 				; SET RTC DATE
 14557 00003AD3 FA                  <1> 	cli
 14558 00003AD4 E85FD1FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
 14559 00003AD9 7305                <1> 	JNC	short RTC_55		; GO AROUND IF NO ERROR
 14560 00003ADB E842000000          <1> 	CALL	RTC_STA 		; ELSE INITIALIZE CLOCK
 14561                              <1> RTC_55:
 14562 00003AE0 66B80600            <1> 	MOV	AX,CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
 14563 00003AE4 E85A000000          <1> 	CALL	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
 14564 00003AE9 88D4                <1> 	MOV	AH,DL			; GET DAY OF MONTH BYTE
 14565 00003AEB B007                <1> 	MOV	AL,CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
 14566 00003AED E851000000          <1> 	CALL	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
 14567 00003AF2 88F4                <1> 	MOV	AH,DH			; GET MONTH
 14568 00003AF4 B008                <1> 	MOV	AL,CMOS_MONTH		; ADDRESS MONTH BYTE
 14569 00003AF6 E848000000          <1> 	CALL	CMOS_WRITE		; WRITE MONTH REGISTER
 14570 00003AFB 88CC                <1> 	MOV	AH,CL			; GET YEAR BYTE
 14571 00003AFD B009                <1> 	MOV	AL,CMOS_YEAR		; ADDRESS YEAR REGISTER
 14572 00003AFF E83F000000          <1> 	CALL	CMOS_WRITE		; WRITE YEAR REGISTER
 14573 00003B04 88EC                <1> 	MOV	AH,CH			; GET CENTURY BYTE
 14574 00003B06 B032                <1> 	MOV	AL,CMOS_CENTURY 	; ADDRESS CENTURY BYTE
 14575 00003B08 E836000000          <1> 	CALL	CMOS_WRITE		; WRITE CENTURY LOCATION
 14576                              <1> 	;MOV	AX,X*CMOS_REG_B 	; ADDRESS ALARM REGISTER
 14577 00003B0D 66B80B0B            <1> 	MOV	AX,257*CMOS_REG_B 	; 
 14578 00003B11 E80CD1FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT SETTINGS
 14579 00003B16 247F                <1> 	AND	AL,07FH 		; CLEAR 'SET BIT'
 14580 00003B18 86E0                <1> 	XCHG	AH,AL			; MOVE TO WORK REGISTER
 14581 00003B1A E824000000          <1> 	CALL	CMOS_WRITE		; AND START CLOCK UPDATING
 14582 00003B1F F8                  <1> 	CLC				; SET CY= 0
 14583 00003B20 FB                  <1> 	sti
 14584 00003B21 C3                  <1> 	RETn				; RETURN CY=0
 14585                              <1> 
 14586                              <1> 	; 15/03/2015
 14587                              <1> RTC_STA:				; INITIALIZE REAL TIME CLOCK
 14588 00003B22 B426                <1> 	mov	ah, 26h
 14589 00003B24 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK
 14590 00003B26 E818000000          <1> 	CALL	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
 14591 00003B2B B482                <1> 	mov	ah, 82h
 14592 00003B2D B00B                <1> 	mov 	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION
 14593 00003B2F E80F000000          <1> 	CALL	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
 14594 00003B34 B00C                <1> 	MOV	AL,CMOS_REG_C		; ADDRESS REGISTER C
 14595 00003B36 E8E7D0FFFF          <1> 	CALL	CMOS_READ		; READ REGISTER C TO INITIALIZE
 14596 00003B3B B00D                <1> 	MOV	AL,CMOS_REG_D		; ADDRESS REGISTER D
 14597 00003B3D E8E0D0FFFF          <1> 	CALL	CMOS_READ		; READ REGISTER D TO INITIALIZE
 14598 00003B42 C3                  <1> 	RETn
 14599                              <1> 
 14600                              <1> 	; 15/03/2015
 14601                              <1> 	; IBM PC/XT Model 286 BIOS source code ----- 10/06/85 (test4.asm)
 14602                              <1> CMOS_WRITE:			; WRITE (AH) TO LOCATION (AL)
 14603 00003B43 9C                  <1> 	pushf			; SAVE INTERRUPT ENABLE STATUS AND FLAGS
 14604                              <1> 	;push	ax		; SAVE WORK REGISTER VALUES
 14605 00003B44 D0C0                <1> 	rol	al, 1		; MOVE NMI BIT TO LOW POSITION
 14606 00003B46 F9                  <1> 	stc			; FORCE NMI BIT ON IN CARRY FLAG
 14607 00003B47 D0D8                <1> 	rcr	al, 1		; HIGH BIT ON TO DISABLE NMI - OLD IN CY
 14608 00003B49 FA                  <1> 	cli			; DISABLE INTERRUPTS
 14609 00003B4A E670                <1> 	out	CMOS_PORT, al	; ADDRESS LOCATION AND DISABLE NMI
 14610 00003B4C 88E0                <1> 	mov	al, ah		; GET THE DATA BYTE TO WRITE
 14611 00003B4E E671                <1> 	out	CMOS_DATA, al	; PLACE IN REQUESTED CMOS LOCATION
 14612 00003B50 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
 14613 00003B52 D0D8                <1> 	rcr	al, 1		; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
 14614 00003B54 E670                <1> 	out	CMOS_PORT, al	; SET DEFAULT TO READ ONLY REGISTER
 14615 00003B56 90                  <1> 	nop			; I/O DELAY
 14616 00003B57 E471                <1> 	in	al, CMOS_DATA	; OPEN STANDBY LATCH
 14617                              <1> 	;pop	ax		; RESTORE WORK REGISTERS
 14618 00003B59 9D                  <1> 	popf	
 14619 00003B5A C3                  <1> 	RETn
 14620                              <1> 
 14621                              <1> bf_init:
 14622                              <1> 	; 28/11/2021
 14623                              <1> 	; 14/08/2015
 14624                              <1> 	; 02/07/2015
 14625                              <1> 	; 01/07/2015
 14626                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 14627                              <1> 	; Buffer (pointer) initialization !
 14628                              <1> 	; 
 14629                              <1> 	; 17/07/2013 - 24/07/2013
 14630                              <1> 	; Retro UNIX 8086 v1 (U9.ASM)
 14631                              <1> 	; (Retro UNIX 8086 v1 feature only !)
 14632                              <1> 	;
 14633 00003B5B BF[70700000]        <1> 	mov	edi, bufp 
 14634 00003B60 B8[287E0000]        <1> 	mov	eax, buffer + (nbuf*520) 
 14635 00003B65 29D2                <1> 	sub	edx, edx
 14636 00003B67 FECA                <1> 	dec	dl
 14637 00003B69 31C9                <1> 	xor	ecx, ecx
 14638 00003B6B 49                  <1> 	dec	ecx
 14639                              <1> bi0:
 14640 00003B6C 2D08020000          <1> 	sub	eax, 520 ; 8 header + 512 data
 14641 00003B71 AB                  <1> 	stosd
 14642 00003B72 89C6                <1> 	mov	esi, eax
 14643 00003B74 8916                <1> 	mov	[esi], edx ; 000000FFh
 14644                              <1> 			    ; Not a valid device sign
 14645 00003B76 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14646                              <1> 		      ; Not a valid block number sign 	 	
 14647 00003B79 3D[F8710000]        <1> 	cmp	eax, buffer
 14648 00003B7E 77EC                <1> 	ja	short bi0
 14649 00003B80 B8[287E0000]        <1> 	mov	eax, sb0
 14650 00003B85 AB                  <1> 	stosd
 14651 00003B86 B8[30800000]        <1> 	mov	eax, sb1
 14652 00003B8B AB                  <1> 	stosd
 14653 00003B8C 89C6                <1> 	mov	esi, eax ; offset sb1
 14654 00003B8E 8916                <1> 	mov	[esi], edx ; 000000FFh
 14655                              <1> 			    ; Not a valid device sign
 14656 00003B90 894E04              <1> 	mov	[esi+4], ecx ; 0FFFFFFFFh
 14657                              <1> 		      ; Not a valid block number sign 	 
 14658                              <1> 	; 14/08/2015
 14659                              <1> 	;call 	rdev_init
 14660                              <1> 	;retn
 14661                              <1> 
 14662                              <1> 	; 28/11/2021
 14663                              <1> rdev_init: ; root device, super block buffer initialization
 14664                              <1> 	; 14/08/2015
 14665                              <1> 	; Retro UNIX 386 v1 feature only !
 14666                              <1> 	;
 14667                              <1> 	; NOTE: Disk partitions (file systems), logical
 14668                              <1> 	; drive initialization, partition's start sector etc.
 14669                              <1> 	; will be coded here, later in 'ldrv_init'	
 14670                              <1> 
 14671 00003B93 0FB605[AA6A0000]    <1> 	movzx	eax, byte [boot_drv]
 14672                              <1> rdi_0:
 14673 00003B9A 3C80                <1> 	cmp	al, 80h
 14674 00003B9C 7202                <1> 	jb	short rdi_1
 14675 00003B9E 2C7E                <1> 	sub	al, 7Eh ; 80h = 2 (hd0), 81h = 3 (hd1)
 14676                              <1> rdi_1:
 14677                              <1> ; temporary - 05/12/2021
 14678 00003BA0 20C0                <1> and	al, al
 14679 00003BA2 7515                <1> jnz	short rdi_2
 14680 00003BA4 C605[D06A0000]12    <1> mov	byte [drv.spt], 18
 14681 00003BAB C605[C26A0000]02    <1> mov	byte [drv.heads], 2
 14682 00003BB2 C605[B46A0000]50    <1> mov	byte [drv.cylinders], 80
 14683                              <1> rdi_2:
 14684 00003BB9 A2[96700000]        <1> 	mov	[rdev], al
 14685 00003BBE BB[287E0000]        <1>         mov	ebx, sb0 ; super block buffer
 14686 00003BC3 8903                <1> 	mov 	[ebx], eax
 14687 00003BC5 B001                <1> 	mov	al, 1 ; eax = 1
 14688 00003BC7 894304              <1> 	mov	[ebx+4], eax ; super block address on disk
 14689                              <1> 	;call 	diskio
 14690                              <1> 	;retn
 14691                              <1> 	; 28/11/2021
 14692 00003BCA E918270000          <1> 	jmp	diskio
 14693                              <1> 
 14694                              <1> ; 23/10/2015
 14695                              <1> com1_irq4:
 14696 00003BCF [D73B0000]          <1> 	dd dummy_retn
 14697                              <1> com2_irq3:
 14698 00003BD3 [D73B0000]          <1> 	dd dummy_retn
 14699                              <1> 
 14700                              <1> dummy_retn:
 14701 00003BD7 C3                  <1> 	retn
 14702                                  %include 'u1.s'      ; 10/05/2015
 14703                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 14704                              <1> ; (re-write kernel for test by using previous version without a major defect)
 14705                              <1> ; ****************************************************************************
 14706                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS1.INC
 14707                              <1> ; Last Modification: 11/12/2021
 14708                              <1> ; ----------------------------------------------------------------------------
 14709                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 14710                              <1> ; (v0.1 - Beginning: 11/07/2012)
 14711                              <1> ;
 14712                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 14713                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 14714                              <1> ; <Bell Laboratories (17/3/1972)>
 14715                              <1> ; <Preliminary Release of UNIX Implementation Document>
 14716                              <1> ;
 14717                              <1> ; Retro UNIX 8086 v1 - U1.ASM (12/07/2014) //// UNIX v1 -> u1.s
 14718                              <1> ;
 14719                              <1> ; ****************************************************************************
 14720                              <1> 
 14721                              <1> unkni: ; / used for all system calls
 14722                              <1> sysent: ; < enter to system call >
 14723                              <1> 	; 19/10/2015
 14724                              <1> 	; 21/09/2015
 14725                              <1> 	; 01/07/2015
 14726                              <1> 	; 19/05/2015
 14727                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14728                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 14729                              <1> 	;
 14730                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
 14731                              <1> 	; The trap type is determined and an indirect jump is made to 
 14732                              <1> 	; the appropriate system call handler. If there is a trap inside
 14733                              <1> 	; the system a jump to panic is made. All user registers are saved 
 14734                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
 14735                              <1> 	; instructor is decoded to get the the system code part (see
 14736                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
 14737                              <1> 	; the indirect jump address is calculated. If a bad system call is
 14738                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
 14739                              <1> 	; is called. If the call is legitimate control passes to the
 14740                              <1> 	; appropriate system routine.
 14741                              <1> 	;
 14742                              <1> 	; Calling sequence:
 14743                              <1> 	;	Through a trap caused by any sys call outside the system.
 14744                              <1> 	; Arguments:
 14745                              <1> 	;	Arguments of particular system call.	
 14746                              <1> 	; ...............................................................
 14747                              <1> 	;	
 14748                              <1> 	; Retro UNIX 8086 v1 modification: 
 14749                              <1> 	;       System call number is in EAX register.
 14750                              <1> 	;
 14751                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 14752                              <1> 	;	registers depending of function details.
 14753                              <1>   	;
 14754                              <1> 	; 16/04/2015
 14755 00003BD8 368925[AC700000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
 14756                              <1> 	; save user registers
 14757 00003BDF 1E                  <1> 	push	ds
 14758 00003BE0 06                  <1> 	push	es
 14759 00003BE1 0FA0                <1> 	push	fs
 14760 00003BE3 0FA8                <1> 	push	gs
 14761 00003BE5 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
 14762                              <1> 	;
 14763                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
 14764                              <1> 	; 	(ESPACE is size of space in kernel stack 
 14765                              <1> 	;	for saving/restoring user registers.)
 14766                              <1> 	;
 14767 00003BE6 50                  <1> 	push	eax ; 01/07/2015
 14768 00003BE7 66B81000            <1> 	mov     ax, KDATA
 14769 00003BEB 8ED8                <1>         mov     ds, ax
 14770 00003BED 8EC0                <1>         mov     es, ax
 14771 00003BEF 8EE0                <1>         mov     fs, ax
 14772 00003BF1 8EE8                <1>         mov     gs, ax
 14773 00003BF3 A1[B86F0000]        <1> 	mov	eax, [k_page_dir]
 14774 00003BF8 0F22D8              <1> 	mov	cr3, eax
 14775 00003BFB 58                  <1> 	pop	eax ; 01/07/2015
 14776                              <1> 	; 19/10/2015
 14777 00003BFC FC                  <1> 	cld
 14778                              <1> 	;
 14779 00003BFD FE05[A9700000]      <1> 	inc	byte [sysflg]
 14780                              <1> 		; incb sysflg / indicate a system routine is in progress
 14781 00003C03 FB                  <1>         sti 	; 18/01/2014
 14782                              <1> 	;jnz     panic ; 24/05/2013
 14783                              <1> 	; 04/12/2021
 14784 00003C04 7405                <1> 	jz	short _1
 14785 00003C06 E94DF9FFFF          <1> 	jmp	panic
 14786                              <1> 		; beq 1f
 14787                              <1> 		; jmp panic ; / called if trap inside system
 14788                              <1> ;1:
 14789                              <1> _1:	; 04/12/2021
 14790                              <1> 	; 16/04/2015
 14791 00003C0B A3[B4700000]        <1> 	mov	[u.r0], eax
 14792 00003C10 8925[B0700000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
 14793                              <1> 	;
 14794                              <1> 		; mov $s.syst+2,clockp
 14795                              <1> 		; mov r0,-(sp) / save user registers 
 14796                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
 14797                              <1> 			   ; / in u.r0
 14798                              <1> 		; mov r1,-(sp)
 14799                              <1> 		; mov r2,-(sp)
 14800                              <1> 		; mov r3,-(sp)
 14801                              <1> 		; mov r4,-(sp)
 14802                              <1> 		; mov r5,-(sp)
 14803                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
 14804                              <1> 		             ; / arithmetic unit
 14805                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
 14806                              <1> 		             ; / extended arithmetic unit
 14807                              <1> 		; mov sc,-(sp) / "step count" register for the extended
 14808                              <1> 		             ; / arithmetic unit
 14809                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
 14810                              <1> 		; mov 18.(sp),r0 / store pc in r0
 14811                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
 14812                              <1> 		; sub $sys,r0 / get xxx code
 14813 00003C16 C1E002              <1> 	shl	eax, 2
 14814                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
 14815 00003C19 3D94000000          <1> 	cmp	eax, end_of_syscalls - syscalls
 14816                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
 14817                              <1> 	;jnb	short badsys
 14818                              <1> 		; bhis badsys / yes, bad system call
 14819 00003C1E F5                  <1> 	cmc
 14820 00003C1F 9C                  <1> 	pushf	
 14821 00003C20 50                  <1> 	push	eax
 14822 00003C21 8B2D[AC700000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
 14823 00003C27 B0FE                <1> 	mov	al, 0FEh ; 11111110b
 14824 00003C29 1400                <1> 	adc	al, 0 ; al = al + cf
 14825 00003C2B 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
 14826                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
 14827                              <1> 				 ; / and clear carry bit
 14828 00003C2E 5D                  <1> 	pop	ebp ; eax
 14829 00003C2F 9D                  <1> 	popf
 14830                              <1>         ;jc	badsys
 14831                              <1> 	; 04/12/2021
 14832 00003C30 7305                <1> 	jnc	short _2
 14833 00003C32 E951010000          <1> 	jmp	badsys
 14834                              <1> _2:
 14835 00003C37 A1[B4700000]        <1> 	mov	eax, [u.r0]
 14836                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
 14837 00003C3C FFA5[423C0000]      <1> 	jmp	dword [ebp+syscalls]
 14838                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
 14839                              <1> 		            ; / to proper system routine.
 14840                              <1> syscalls: ; 1:
 14841                              <1> 	; 21/09/2015
 14842                              <1> 	; 01/07/2015
 14843                              <1> 	; 16/04/2015 (32 bit address modification) 
 14844 00003C42 [523D0000]          <1> 	dd sysrele	; / 0
 14845 00003C46 [0F3E0000]          <1> 	dd sysexit 	; / 1
 14846 00003C4A [333F0000]          <1> 	dd sysfork 	; / 2
 14847 00003C4E [46400000]          <1> 	dd sysread 	; / 3
 14848 00003C52 [5B400000]          <1> 	dd syswrite 	; / 4
 14849 00003C56 [BE400000]          <1> 	dd sysopen 	; / 5
 14850 00003C5A [DD410000]          <1> 	dd sysclose 	; / 6
 14851 00003C5E [B53E0000]          <1> 	dd syswait 	; / 7
 14852 00003C62 [57410000]          <1> 	dd syscreat 	; / 8
 14853 00003C66 [08450000]          <1> 	dd syslink 	; / 9
 14854 00003C6A [CA450000]          <1> 	dd sysunlink 	; / 10
 14855 00003C6E [9D460000]          <1> 	dd sysexec 	; / 11
 14856 00003C72 [394D0000]          <1> 	dd syschdir 	; / 12
 14857 00003C76 [1D4E0000]          <1> 	dd systime 	; / 13
 14858 00003C7A [AE410000]          <1> 	dd sysmkdir 	; / 14
 14859 00003C7E [8B4D0000]          <1> 	dd syschmod 	; / 15
 14860 00003C82 [ED4D0000]          <1> 	dd syschown 	; / 16
 14861 00003C86 [504E0000]          <1> 	dd sysbreak 	; / 17
 14862 00003C8A [894A0000]          <1> 	dd sysstat 	; / 18
 14863 00003C8E [154F0000]          <1> 	dd sysseek 	; / 19
 14864 00003C92 [274F0000]          <1> 	dd systell 	; / 20
 14865 00003C96 [965C0000]          <1> 	dd sysmount 	; / 21
 14866 00003C9A [485D0000]          <1> 	dd sysumount 	; / 22
 14867 00003C9E [A54F0000]          <1> 	dd syssetuid 	; / 23
 14868 00003CA2 [D64F0000]          <1> 	dd sysgetuid 	; / 24
 14869 00003CA6 [2C4E0000]          <1> 	dd sysstime 	; / 25
 14870 00003CAA [994F0000]          <1> 	dd sysquit 	; / 26
 14871 00003CAE [8D4F0000]          <1> 	dd sysintr 	; / 27
 14872 00003CB2 [654A0000]          <1> 	dd sysfstat 	; / 28
 14873 00003CB6 [F8410000]          <1> 	dd sysemt 	; / 29
 14874 00003CBA [28420000]          <1> 	dd sysmdate 	; / 30
 14875 00003CBE [76420000]          <1> 	dd sysstty 	; / 31
 14876 00003CC2 [F5430000]          <1> 	dd sysgtty 	; / 32
 14877 00003CC6 [23420000]          <1> 	dd sysilgins 	; / 33
 14878 00003CCA [CB650000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
 14879                              <1> 			     ; 11/06/2014
 14880 00003CCE [F8650000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
 14881                              <1> 			     ; 01/07/2015
 14882 00003CD2 [D0660000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
 14883                              <1> 			     ; 21/09/2015 - get last error number
 14884                              <1> end_of_syscalls:
 14885                              <1> 
 14886                              <1> error:
 14887                              <1> 	; 11/12/2021 (Retro UNIX 386 v1.2)
 14888                              <1> 	; 17/09/2015
 14889                              <1> 	; 03/09/2015
 14890                              <1> 	; 01/09/2015
 14891                              <1> 	; 09/06/2015
 14892                              <1> 	; 13/05/2015
 14893                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14894                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 14895                              <1> 	;
 14896                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
 14897                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
 14898                              <1> 	;
 14899                              <1> 	; INPUTS -> none
 14900                              <1> 	; OUTPUTS ->
 14901                              <1> 	;	processor status - carry (c) bit is set (means error)
 14902                              <1> 	;
 14903                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
 14904                              <1> 	; 	      Because, jumps to error procedure
 14905                              <1> 	;	      disrupts push-pop nesting balance)
 14906                              <1> 	;
 14907 00003CD6 8B2D[AC700000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
 14908 00003CDC 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
 14909                              <1> 				 ; (system call will return with cf = 1)
 14910                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
 14911                              <1> 		               ; / users stack
 14912                              <1> 	; 17/09/2015
 14913 00003CE0 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
 14914                              <1> 				 ; for saving/restoring user registers	
 14915                              <1> 	;cmp	ebp, [u.usp]
 14916                              <1> 	;je	short err0	
 14917 00003CE3 892D[B0700000]      <1> 	mov	[u.usp], ebp
 14918                              <1> ;err0:
 14919                              <1> 	; 01/09/2015
 14920 00003CE9 8B25[B0700000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
 14921                              <1> 				    ; 10/04/2013
 14922                              <1> 				    ; (If an I/O error occurs during disk I/O,
 14923                              <1> 				    ; related procedures will jump to 'error'
 14924                              <1> 				    ; procedure directly without returning to 
 14925                              <1> 				    ; the caller procedure. So, stack pointer
 14926                              <1>                                     ; must be restored here.)
 14927                              <1> 	; 13/05/2015
 14928                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
 14929                              <1> 	;	'get last error' system call later. 	
 14930                              <1> 
 14931                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
 14932 00003CEF C605[2A710000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
 14933                              <1> 
 14934                              <1> sysret: ; < return from system call>
 14935                              <1> 	; 11/12/2021
 14936                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 14937                              <1> 	; 30/11/2021
 14938                              <1> 	; 10/09/2015
 14939                              <1> 	; 29/07/2015
 14940                              <1> 	; 25/06/2015
 14941                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 14942                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 14943                              <1> 	;
 14944                              <1> 	; 'sysret' first checks to see if process is about to be 
 14945                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
 14946                              <1> 	; If not, following happens:	 
 14947                              <1> 	; 	1) The user's stack pointer is restored.
 14948                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
 14949                              <1> 	;	   i-node has been modified. If it has, it is written out
 14950                              <1> 	;	   via 'ppoke'.
 14951                              <1> 	;	3) If the super block has been modified, it is written out
 14952                              <1> 	;	   via 'ppoke'.				
 14953                              <1> 	;	4) If the dismountable file system's super block has been
 14954                              <1> 	;	   modified, it is written out to the specified device
 14955                              <1> 	;	   via 'ppoke'.
 14956                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
 14957                              <1> 	;	   during his execution. If so, 'tswap' is called to give
 14958                              <1> 	;	   another user a chance to run.
 14959                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
 14960                              <1> 	;	    (See 'sysrele' for conclusion.)		
 14961                              <1> 	;
 14962                              <1> 	; Calling sequence:
 14963                              <1> 	;	jump table or 'br sysret'
 14964                              <1> 	; Arguments: 
 14965                              <1> 	;	-	
 14966                              <1> 	; ...............................................................
 14967                              <1> 	;	
 14968                              <1> 	; ((AX=r1 for 'iget' input))
 14969                              <1> 	;	
 14970                              <1> 	;xor	ax, ax ; 04/05/2013
 14971                              <1> 	; 30/11/2021
 14972 00003CF6 31C0                <1> 	xor	eax, eax
 14973                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
 14974 00003CF8 FEC0                <1> 	inc	al ; 04/05/2013
 14975 00003CFA 3805[08710000]      <1> 	cmp	[u.bsys], al ; 1
 14976                              <1> 		; tstb u.bsys / is a process about to be terminated because
 14977                              <1> 	;jnb	sysexit ; 04/05/2013
 14978                              <1> 	;	; bne sysexit / of an error? yes, go to sysexit
 14979                              <1> 	; 04/12/2021
 14980 00003D00 720F                <1> 	jb	short _3
 14981                              <1> 	; 11/12/2021
 14982 00003D02 C705[2C710000]0100- <1> 	mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
 14983 00003D0A 0000                <1>
 14984 00003D0C E9FE000000          <1> 	jmp	sysexit
 14985                              <1> _3:
 14986                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
 14987                              <1> 		; mov u.sp,sp / no point stack to users stack
 14988 00003D11 FEC8                <1> 	dec 	al ; mov ax, 0
 14989                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
 14990 00003D13 E853180000          <1> 	call	iget
 14991                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
 14992                              <1> 		            ; / it is written out
 14993                              <1> 	;xor 	ax, ax ; 0
 14994                              <1> 	; 30/11/2021
 14995 00003D18 31C0                <1> 	xor	eax, eax
 14996 00003D1A 3805[A7700000]      <1> 	cmp	[smod], al ; 0
 14997                              <1> 		; tstb	smod / has the super block been modified
 14998 00003D20 7614                <1> 	jna	short sysret1
 14999                              <1> 		; beq	1f / no, 1f
 15000 00003D22 A2[A7700000]        <1> 	mov	[smod], al ; 0
 15001                              <1> 		; clrb smod / yes, clear smod
 15002 00003D27 BB[287E0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
 15003 00003D2C 66810B0002          <1>    	or	word [ebx], 200h ;;
 15004                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
 15005                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
 15006                              <1> 		      	      ; / output
 15007                              <1> 	; AX = 0
 15008 00003D31 E88F240000          <1> 	call 	poke ; 07/08/2013
 15009                              <1> 	;call	ppoke
 15010                              <1> 	; AX = 0
 15011                              <1> 		; jsr r0,ppoke / write out modified super block to disk
 15012                              <1> sysret1: ;1:
 15013 00003D36 3805[A8700000]      <1> 	cmp	[mmod], al ; 0
 15014                              <1> 		; tstb	mmod / has the super block for the dismountable file
 15015                              <1> 		           ; / system
 15016 00003D3C 7614                <1> 	jna	short sysrel0
 15017                              <1> 		; beq 1f / been modified?  no, 1f
 15018 00003D3E A2[A8700000]        <1> 	mov	[mmod], al ; 0	
 15019                              <1> 		; clrb	mmod / yes, clear mmod
 15020                              <1>         ;mov    ax, [mntd]
 15021                              <1>         ;;mov   al, [mdev] ; 26/04/2013
 15022 00003D43 BB[30800000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
 15023                              <1>         ;;mov	[ebx], al
 15024                              <1> 	;mov    [sb1], al
 15025                              <1> 		; movb	mntd,sb1 / set the I/O queue
 15026 00003D48 66810B0002          <1> 	or	word [ebx], 200h
 15027                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
 15028                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
 15029 00003D4D E873240000          <1> 	call	poke ; 07/08/2013
 15030                              <1> 	;call	ppoke 
 15031                              <1> 		; jsr r0,ppoke / write it out to its device
 15032                              <1>         ;xor    al, al ; 26/04/2013       
 15033                              <1> ;1:
 15034                              <1> 		; tstb uquant / is the time quantum 0?
 15035                              <1> 		; bne 1f / no, don't swap it out
 15036                              <1> 
 15037                              <1> sysrele: ; < release >
 15038                              <1> 	; 14/10/2015
 15039                              <1> 	; 01/09/2015
 15040                              <1> 	; 24/07/2015
 15041                              <1> 	; 14/05/2015
 15042                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15043                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
 15044                              <1> 	;
 15045                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
 15046                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
 15047                              <1> 	; turns off the system flag. It then checked to see if there is
 15048                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
 15049                              <1> 	; the output gets flashed (see isintr) and interrupt action is
 15050                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
 15051                              <1> 	; the user, a rti is made.
 15052                              <1> 	;
 15053                              <1> 	; Calling sequence:
 15054                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
 15055                              <1> 	; Arguments:
 15056                              <1> 	;	-	
 15057                              <1> 	; ...............................................................
 15058                              <1> 	;	
 15059                              <1> 	; 23/02/2014 (swapret)
 15060                              <1> 	; 22/09/2013
 15061                              <1> sysrel0: ;1:
 15062 00003D52 803D[00710000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
 15063                              <1> 		; tstb uquant / is the time quantum 0?
 15064 00003D59 7705                <1>         ja      short swapret
 15065                              <1> 		; bne 1f / no, don't swap it out
 15066                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
 15067 00003D5B E8C8120000          <1> 	call	tswap
 15068                              <1> 		; jsr r0,tswap / yes, swap it out
 15069                              <1> ;
 15070                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
 15071                              <1> swapret: ;1:
 15072                              <1> 	; 10/09/2015
 15073                              <1> 	; 01/09/2015
 15074                              <1> 	; 14/05/2015
 15075                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
 15076                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
 15077                              <1> 	; cli
 15078                              <1> 	; 24/07/2015
 15079                              <1> 	;
 15080                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
 15081                              <1> 	;; mov	esp, [u.usp]
 15082                              <1> 
 15083                              <1> 	; 22/09/2013
 15084 00003D60 E8AA140000          <1> 	call	isintr
 15085                              <1> 	; 20/10/2013
 15086 00003D65 7405                <1> 	jz	short sysrel1
 15087 00003D67 E88C000000          <1> 	call	intract
 15088                              <1> 		; jsr r0,isintr / is there an interrupt from the user
 15089                              <1> 		;     br intract / yes, output gets flushed, take interrupt
 15090                              <1> 		               ; / action
 15091                              <1> sysrel1:
 15092 00003D6C FA                  <1> 	cli ; 14/10/2015
 15093 00003D6D FE0D[A9700000]      <1> 	dec	byte [sysflg]
 15094                              <1> 		; decb sysflg / turn system flag off
 15095 00003D73 A1[18710000]        <1> 	mov     eax, [u.pgdir]
 15096 00003D78 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
 15097                              <1> 			  ; (others are different than kernel page tables) 
 15098                              <1> 	; 10/09/2015
 15099 00003D7B 61                  <1> 	popad ; edi, esi, ebp, temp (increment esp by 4), ebx, edx, ecx, eax
 15100                              <1> 		; mov (sp)+,sc / restore user registers
 15101                              <1> 		; mov (sp)+,mq
 15102                              <1> 		; mov (sp)+,ac
 15103                              <1> 		; mov (sp)+,r5
 15104                              <1> 		; mov (sp)+,r4
 15105                              <1> 		; mov (sp)+,r3
 15106                              <1> 		; mov (sp)+,r2
 15107                              <1> 	;
 15108 00003D7C A1[B4700000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
 15109 00003D81 0FA9                <1> 	pop	gs
 15110 00003D83 0FA1                <1> 	pop	fs
 15111 00003D85 07                  <1> 	pop	es
 15112 00003D86 1F                  <1> 	pop	ds
 15113 00003D87 CF                  <1> 	iretd	
 15114                              <1> 		; rti / no, return from interrupt
 15115                              <1> 
 15116                              <1> badsys:
 15117                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15118                              <1> 	; (Major Modification: 'core' dumping procedure in
 15119                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
 15120                              <1> 	;	has been changed to print 'Invalid System Call !'
 15121                              <1> 	;	message on the user's console tty.)
 15122                              <1> 	; (EIP, EAX values will be shown on screen with error message)
 15123                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
 15124                              <1> 	; (EAX = Function number)  
 15125                              <1> 	;
 15126 00003D88 FE05[08710000]      <1> 	inc	byte [u.bsys]
 15127                              <1> 	;
 15128 00003D8E 8B1D[AC700000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
 15129 00003D94 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
 15130 00003D96 E813DBFFFF          <1> 	call	dwordtohex
 15131 00003D9B 8915[146D0000]      <1> 	mov	[bsys_msg_eip], edx
 15132 00003DA1 A3[186D0000]        <1> 	mov	[bsys_msg_eip+4], eax
 15133 00003DA6 A1[B4700000]        <1> 	mov	eax, [u.r0]
 15134 00003DAB E8FEDAFFFF          <1> 	call	dwordtohex
 15135 00003DB0 8915[046D0000]      <1> 	mov	[bsys_msg_eax], edx
 15136 00003DB6 A3[086D0000]        <1> 	mov	[bsys_msg_eax+4], eax
 15137                              <1> 	; 11/12/2021
 15138                              <1> 	;xor	eax, eax
 15139                              <1> 	;mov	dword [u.base], badsys_msg ; "Invalid System call !"
 15140                              <1> 	;mov	ebx, [u.fofp]
 15141                              <1> 	;mov	[ebx], eax
 15142                              <1> 	;;mov	eax, 1 ; inode number of console tty (for user)	
 15143                              <1> 	;inc	eax
 15144                              <1> 	; 11/12/2021 - Retro UNIX 386 v2 fs compatibility 
 15145                              <1> 	; (Retro UNIX 386 v1.2)
 15146                              <1> 	;mov	al, 8 ; /dev/tty inode number (runix v2 fs)
 15147                              <1> 	;; eax = 8 ; inode number of console tty (for user)	
 15148                              <1> 	;mov	dword [u.count], BSYS_M_SIZE
 15149                              <1> 		; writei
 15150                              <1> 		; INPUTS ->
 15151                              <1> 		;    r1 - inode number
 15152                              <1> 		;    u.count - byte count to be written
 15153                              <1> 		;    u.base - points to user buffer
 15154                              <1> 		;    u.fofp - points to word with current file offset
 15155                              <1> 		; OUTPUTS ->
 15156                              <1> 		;    u.count - cleared
 15157                              <1> 		;    u.nread - accumulates total bytes passed back	
 15158                              <1> 		;
 15159                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
 15160                              <1> 	;call	writei
 15161                              <1> 	;;mov	eax, 1
 15162                              <1> 	;jmp	sysexit
 15163                              <1> 
 15164                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 15165 00003DBB BE[E56C0000]        <1> 	mov	esi, badsys_msg ; "Invalid System call !"
 15166 00003DC0 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 15167                              <1> ; temporary - 12/12/2021
 15168                              <1> ;mov bl, 1
 15169                              <1> 	;mov	al, [ebx+p.ttyc-1] ; current/console tty
 15170                              <1> ;mov al, 0
 15171 00003DC7 FECB                <1> dec bl
 15172 00003DC9 8A83[F06D0000]      <1> mov al, [ebx+p.ttyc]
 15173 00003DCF C605[E76F0000]0F    <1> 	mov	byte [ccolor], 0Fh ; white (message) color
 15174 00003DD6 A2[ED700000]        <1> 	mov 	[u.ttyn], al ; current (active) tty (for user)
 15175 00003DDB E8D5280000          <1> 	call	print_cmsg
 15176                              <1> 	;mov	dword [u.error], ERR_INV_FUNC ; 1 ; 'invalid system call !'
 15177                              <1> 
 15178                              <1> ; temporary - 11/12/2021
 15179 00003DE0 C70500800B00324E32- <1> mov dword [0B8000h], 4E324E32h
 15180 00003DE9 4E                  <1>
 15181 00003DEA B9FFFF0000          <1> mov ecx, 0FFFFh
 15182                              <1> abovexfx:
 15183 00003DEF 4A                  <1> dec edx
 15184 00003DF0 42                  <1> inc edx
 15185 00003DF1 E2FC                <1> loop abovexfx
 15186                              <1> 
 15187 00003DF3 E9DEFEFFFF          <1> 	jmp	error
 15188                              <1> 
 15189                              <1> 		; incb u.bsys / turn on the user's bad-system flag
 15190                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
 15191                              <1> 		; jsr r0,namei / get the i-number for the core image file
 15192                              <1> 		; br 1f / error
 15193                              <1> 		; neg r1 / negate the i-number to open the core image file
 15194                              <1> 		       ; / for writing
 15195                              <1> 		; jsr r0,iopen / open the core image file
 15196                              <1> 		; jsr r0,itrunc / free all associated blocks
 15197                              <1> 		; br 2f
 15198                              <1> ;1:
 15199                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
 15200                              <1> 		; jsr r0,maknod / make an i-node
 15201                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
 15202                              <1> ;2:
 15203                              <1> 		; mov $core,u.base / move address core to u.base
 15204                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
 15205                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
 15206                              <1> 		; clr u.off / clear user offset
 15207                              <1> 		; jsr r0,writei / write out the core image to the user
 15208                              <1> 		; mov $user,u.base / pt. u.base to user
 15209                              <1> 		; mov $64.,u.count / u.count = 64
 15210                              <1> 		; jsr r0,writei / write out all the user parameters
 15211                              <1> 		; neg r1 / make i-number positive
 15212                              <1> 		; jsr r0,iclose / close the core image file
 15213                              <1> 		; br sysexit /
 15214                              <1> ;3:
 15215                              <1> 		; <core\0\0>
 15216                              <1> 
 15217                              <1> intract: ; / interrupt action
 15218                              <1> 	; 14/10/2015
 15219                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15220                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
 15221                              <1> 	;
 15222                              <1> 	; Retro UNIX 8086 v1 modification !
 15223                              <1> 	; (Process/task switching and quit routine by using
 15224                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 15225                              <1> 	;
 15226                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
 15227                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
 15228                              <1> 	;		'intract' will jump to 'sysexit'.
 15229                              <1> 	;	    Intract will return to the caller 
 15230                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
 15231                              <1> 	; 14/10/2015
 15232 00003DF8 FB                  <1> 	sti
 15233                              <1> 	; 07/12/2013	
 15234 00003DF9 66FF05[06710000]    <1> 	inc 	word [u.quit]
 15235 00003E00 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
 15236 00003E02 66FF0D[06710000]    <1> 	dec	word [u.quit]
 15237                              <1> 	; 16/04/2015
 15238 00003E09 C3                  <1> 	retn
 15239                              <1> intrct0:	
 15240 00003E0A 58                  <1> 	pop	eax ; call intract -> retn
 15241                              <1> 	;
 15242 00003E0B 31C0                <1> 	xor 	eax, eax
 15243 00003E0D FEC0                <1> 	inc	al  ; mov ax, 1
 15244                              <1> ;;;
 15245                              <1> 	; UNIX v1 original 'intract' routine... 
 15246                              <1> 	; / interrupt action
 15247                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
 15248                              <1> 		; bne 1f / no, 1f
 15249                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
 15250                              <1> 	; 1: / now in user area
 15251                              <1> 		; mov r1,-(sp) / save r1
 15252                              <1> 		; mov u.ttyp,r1 
 15253                              <1> 			; / pointer to tty buffer in control-to r1
 15254                              <1> 		; cmpb 6(r1),$177
 15255                              <1> 			; / is the interrupt char equal to "del"
 15256                              <1> 		; beq 1f / yes, 1f
 15257                              <1> 		; clrb 6(r1) 
 15258                              <1> 		        ; / no, clear the byte 
 15259                              <1> 			; / (must be a quit character)
 15260                              <1> 		; mov (sp)+,r1 / restore r1
 15261                              <1> 		; clr u.quit / clear quit flag
 15262                              <1> 		; bis $20,2(sp) 
 15263                              <1> 		    	; / set trace for quit (sets t bit of 
 15264                              <1> 			; / ps-trace trap)
 15265                              <1> 		; rti   ;  / return from interrupt
 15266                              <1> 	; 1: / interrupt char = del
 15267                              <1> 		; clrb 6(r1) / clear the interrupt byte 
 15268                              <1> 			   ; / in the buffer
 15269                              <1> 		; mov (sp)+,r1 / restore r1
 15270                              <1> 		; cmp u.intr,$core / should control be 
 15271                              <1> 				; / transferred to loc core?
 15272                              <1> 		; blo 1f
 15273                              <1> 		; jmp *u.intr / user to do rti yes, 
 15274                              <1> 				; / transfer to loc core
 15275                              <1> 	; 1:
 15276                              <1> 		; sys 1 / exit
 15277                              <1> 
 15278                              <1> sysexit: ; <terminate process>
 15279                              <1> 	; 30/11/2021 - etro UNIX 386 v1.2
 15280                              <1> 	; 01/09/2015
 15281                              <1> 	; 31/08/2015
 15282                              <1> 	; 14/05/2015
 15283                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15284                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 15285                              <1> 	;
 15286                              <1> 	; 'sysexit' terminates a process. First each file that
 15287                              <1> 	; the process has opened is closed by 'flose'. The process
 15288                              <1> 	; status is then set to unused. The 'p.pid' table is then
 15289                              <1> 	; searched to find children of the dying process. If any of
 15290                              <1> 	; children are zombies (died by not waited for), they are
 15291                              <1> 	; set free. The 'p.pid' table is then searched to find the
 15292                              <1> 	; dying process's parent. When the parent is found, it is
 15293                              <1> 	; checked to see if it is free or it is a zombie. If it is
 15294                              <1> 	; one of these, the dying process just dies. If it is waiting
 15295                              <1> 	; for a child process to die, it notified that it doesn't 
 15296                              <1> 	; have to wait anymore by setting it's status from 2 to 1
 15297                              <1> 	; (waiting to active). It is awakened and put on runq by
 15298                              <1> 	; 'putlu'. The dying process enters a zombie state in which
 15299                              <1> 	; it will never be run again but stays around until a 'wait'
 15300                              <1> 	; is completed by it's parent process. If the parent is not
 15301                              <1> 	; found, process just dies. This means 'swap' is called with
 15302                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
 15303                              <1> 	; to write out the process and 'rswap' reads the new process
 15304                              <1> 	; over the one that dies..i.e., the dying process is 
 15305                              <1> 	; overwritten and destroyed.	
 15306                              <1>  	;
 15307                              <1> 	; Calling sequence:
 15308                              <1> 	;	sysexit or conditional branch.
 15309                              <1> 	; Arguments:
 15310                              <1> 	;	-	
 15311                              <1> 	; ...............................................................
 15312                              <1> 	;	
 15313                              <1> 	; Retro UNIX 8086 v1 modification: 
 15314                              <1> 	;       System call number (=1) is in EAX register.
 15315                              <1> 	;
 15316                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
 15317                              <1> 	;       registers depending of function details.
 15318                              <1> 	;
 15319                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
 15320                              <1> 	;
 15321                              <1> ; / terminate process
 15322                              <1> 	; AX = 1
 15323                              <1> 	;dec 	ax ; 0
 15324                              <1> 	; 30/11/2021
 15325 00003E0F 48                  <1> 	dec	eax ; 0
 15326 00003E10 66A3[04710000]      <1> 	mov	[u.intr], ax ; 0
 15327                              <1> 		; clr u.intr / clear interrupt control word
 15328                              <1> 		; clr r1 / clear r1
 15329                              <1> 	; AX = 0
 15330                              <1> sysexit_1: ; 1:
 15331                              <1> 	; AX = File descriptor
 15332                              <1> 		; / r1 has file descriptor (index to u.fp list)
 15333                              <1> 		; / Search the whole list
 15334 00003E16 E8040D0000          <1> 	call	fclose
 15335                              <1> 		; jsr r0,fclose / close all files the process opened
 15336                              <1> 	;; ignore error return
 15337                              <1> 		; br .+2 / ignore error return
 15338                              <1> 	;inc	ax
 15339 00003E1B FEC0                <1> 	inc	al
 15340                              <1> 		; inc r1 / increment file descriptor
 15341                              <1> 	;cmp	ax, 10
 15342 00003E1D 3C0A                <1> 	cmp	al, 10
 15343                              <1> 		; cmp r1,$10. / end of u.fp list?
 15344 00003E1F 72F5                <1> 	jb	short sysexit_1
 15345                              <1> 		; blt 1b / no, go back
 15346 00003E21 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 15347                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
 15348 00003E28 88A3[1F6E0000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 15349                              <1> 		; clrb p.stat-1(r1) / free the process
 15350                              <1> 	;shl	bx, 1
 15351 00003E2E D0E3                <1> 	shl	bl, 1
 15352                              <1> 		; asl r1 / use r1 for index into the below tables
 15353 00003E30 668B8B[8E6D0000]    <1> 	mov	cx, [ebx+p.pid-2]
 15354                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
 15355 00003E37 668B93[AE6D0000]    <1> 	mov	dx, [ebx+p.ppid-2]
 15356                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
 15357                              <1> 	; xor 	bx, bx ; 0
 15358 00003E3E 30DB                <1> 	xor	bl, bl ; 0
 15359                              <1> 		; clr r2
 15360 00003E40 31F6                <1> 	xor	esi, esi ; 0
 15361                              <1> 		; clr r5 / initialize reg
 15362                              <1> sysexit_2: ; 1:
 15363                              <1> 	        ; / find children of this dying process, 
 15364                              <1> 		; / if they are zombies, free them
 15365                              <1> 	;add	bx, 2
 15366 00003E42 80C302              <1> 	add	bl, 2
 15367                              <1> 		; add $2,r2 / search parent process table 
 15368                              <1> 		          ; / for dying process's name
 15369 00003E45 66398B[AE6D0000]    <1> 	cmp	[ebx+p.ppid-2], cx
 15370                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
 15371 00003E4C 7513                <1> 	jne	short sysexit_4
 15372                              <1> 		; bne 3f / no
 15373                              <1> 	;shr	bx, 1
 15374 00003E4E D0EB                <1> 	shr	bl, 1
 15375                              <1> 		; asr r2 / yes, it is a parent
 15376 00003E50 80BB[1F6E0000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
 15377                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
 15378                              <1> 				     ; / dying process a zombie
 15379 00003E57 7506                <1> 	jne	short sysexit_3 
 15380                              <1> 		; bne 2f / no
 15381 00003E59 88A3[1F6E0000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
 15382                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
 15383                              <1> sysexit_3: ; 2:
 15384                              <1> 	;shr	bx, 1
 15385 00003E5F D0E3                <1> 	shl	bl, 1
 15386                              <1> 		; asl r2
 15387                              <1> sysexit_4: ; 3:
 15388                              <1> 		; / search the process name table 
 15389                              <1> 		; / for the dying process's parent
 15390 00003E61 663993[8E6D0000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
 15391                              <1> 		; cmp p.pid-2(r2),r4 / found it?
 15392 00003E68 7502                <1> 	jne	short sysexit_5
 15393                              <1> 		; bne 3f / no
 15394 00003E6A 89DE                <1> 	mov	esi, ebx
 15395                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
 15396                              <1> 		          ; / process # x2) in r5
 15397                              <1> sysexit_5: ; 3:
 15398                              <1> 	;cmp	bx, nproc + nproc
 15399 00003E6C 80FB20              <1> 	cmp	bl, nproc + nproc
 15400                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
 15401 00003E6F 72D1                <1> 	jb	short sysexit_2
 15402                              <1> 		; blt 1b / no, go back
 15403                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
 15404 00003E71 21F6                <1> 	and	esi, esi ; r5=r1
 15405 00003E73 7431                <1> 	jz	short sysexit_6
 15406                              <1> 		; beq 2f / no parent has been found. 
 15407                              <1> 		       ; / The process just dies
 15408 00003E75 66D1EE              <1> 	shr	si, 1
 15409                              <1> 		; asr r1 / set up index to p.stat
 15410 00003E78 8A86[1F6E0000]      <1> 	mov	al, [esi+p.stat-1]
 15411                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
 15412 00003E7E 20C0                <1> 	and	al, al
 15413 00003E80 7424                <1> 	jz	short sysexit_6
 15414                              <1> 		; beq 2f / if its been freed, 2f
 15415 00003E82 3C03                <1> 	cmp	al, 3
 15416                              <1> 		; cmp r2,$3 / is parent a zombie?
 15417 00003E84 7420                <1> 	je	short sysexit_6
 15418                              <1> 		; beq 2f / yes, 2f
 15419                              <1> 	; BH = 0
 15420 00003E86 8A1D[09710000]      <1> 	mov	bl, [u.uno]
 15421                              <1> 		; movb u.uno,r3 / move dying process's number to r3
 15422 00003E8C C683[1F6E0000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
 15423                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
 15424                              <1> 	; 05/02/2014
 15425 00003E93 3C01                <1> 	cmp	al, 1 ; SRUN
 15426 00003E95 740F                <1> 	je	short sysexit_6
 15427                              <1> 	;cmp	al, 2
 15428                              <1> 		; cmp r2,$2 / is the parent waiting for 
 15429                              <1> 			  ; / this child to die
 15430                              <1> 	;jne	short sysexit_6	
 15431                              <1> 		; bne 2f / yes, notify parent not to wait any more
 15432                              <1> 	; 05/02/2014
 15433                              <1> 	; p.stat = 2 --> waiting
 15434                              <1> 	; p.stat = 4 --> sleeping
 15435 00003E97 C686[1F6E0000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
 15436                              <1> 	;dec	byte [esi+p.stat-1]
 15437                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
 15438 00003E9E 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
 15439                              <1> 	; 
 15440                              <1> 	;mov	ebx, runq + 4
 15441                              <1> 		; mov $runq+4,r2 / on the runq
 15442 00003EA1 E85A120000          <1> 	call	putlu
 15443                              <1> 		; jsr r0, putlu
 15444                              <1> sysexit_6: ; 2:
 15445                              <1> 	; 31/08/2015
 15446                              <1> 		; / the process dies
 15447 00003EA6 C605[09710000]00    <1> 	mov	byte [u.uno], 0
 15448                              <1> 		; clrb u.uno / put zero as the process number, 
 15449                              <1> 	           ; / so "swap" will
 15450 00003EAD E880110000          <1> 	call	swap
 15451                              <1> 		; jsr r0,swap / overwrite process with another process
 15452                              <1> hlt_sys:
 15453                              <1> 	;sti ; 18/01/2014
 15454                              <1> hlts0:
 15455 00003EB2 F4                  <1> 	hlt
 15456 00003EB3 EBFD                <1> 	jmp	short hlts0
 15457                              <1> 		; 0 / and thereby kill it; halt?
 15458                              <1> 
 15459                              <1> 
 15460                              <1> syswait: ; < wait for a processs to die >
 15461                              <1> 	; 17/09/2015
 15462                              <1> 	; 02/09/2015
 15463                              <1> 	; 01/09/2015
 15464                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
 15465                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
 15466                              <1> 	;
 15467                              <1> 	; 'syswait' waits for a process die. 
 15468                              <1> 	; It works in following way:
 15469                              <1> 	;    1) From the parent process number, the parent's 
 15470                              <1> 	; 	process name is found. The p.ppid table of parent
 15471                              <1> 	;	names is then searched for this process name.
 15472                              <1> 	;	If a match occurs, r2 contains child's process
 15473                              <1> 	;	number. The child status is checked to see if it is
 15474                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
 15475                              <1> 	;	If it is, the child process is freed and it's name
 15476                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
 15477                              <1> 	;	If the child is not a zombie, nothing happens and
 15478                              <1> 	;	the search goes on through the p.ppid table until
 15479                              <1> 	;	all processes are checked or a zombie is found.
 15480                              <1> 	;    2) If no zombies are found, a check is made to see if
 15481                              <1> 	;	there are any children at all. If there are none,
 15482                              <1> 	;	an error return is made. If there are, the parent's
 15483                              <1> 	;	status is set to 2 (waiting for child to die),
 15484                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
 15485                              <1> 	;	is made to wait on the next process.
 15486                              <1> 	;
 15487                              <1> 	; Calling sequence:
 15488                              <1> 	;	?
 15489                              <1> 	; Arguments:
 15490                              <1> 	;	-
 15491                              <1> 	; Inputs: - 
 15492                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
 15493                              <1> 	; ...............................................................
 15494                              <1> 	;				
 15495                              <1> 	
 15496                              <1> ; / wait for a process to die
 15497                              <1> 
 15498                              <1> syswait_0:
 15499 00003EB5 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
 15500                              <1> 		; movb u.uno,r1 / put parents process number in r1
 15501 00003EBC D0E3                <1> 	shl	bl, 1
 15502                              <1> 	;shl	bx, 1
 15503                              <1> 		; asl r1 / x2 to get index into p.pid table
 15504 00003EBE 668B83[8E6D0000]    <1> 	mov	ax, [ebx+p.pid-2]
 15505                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
 15506 00003EC5 31F6                <1> 	xor	esi, esi
 15507                              <1> 		; clr r2
 15508 00003EC7 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
 15509                              <1> 	;xor 	cl, cl
 15510                              <1> 		; clr r3 / initialize reg 3
 15511                              <1> syswait_1: ; 1:
 15512 00003EC9 6683C602            <1> 	add	si, 2
 15513                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
 15514                              <1> 			  ; / search table of parent processes 
 15515                              <1> 			  ; / for this process name
 15516 00003ECD 663B86[AE6D0000]    <1> 	cmp	ax, [esi+p.ppid-2]
 15517                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
 15518                              <1> 			            ; / process number
 15519 00003ED4 7535                <1> 	jne	short syswait_3
 15520                              <1> 		;bne 3f / branch if no match of parent process name
 15521                              <1> 	;inc	cx
 15522 00003ED6 FEC1                <1> 	inc	cl
 15523                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
 15524 00003ED8 66D1EE              <1> 	shr	si, 1
 15525                              <1> 		; asr r2 / r2/2 to get index to p.stat table
 15526                              <1> 	; The possible states ('p.stat' values) of a process are:
 15527                              <1> 	;	0 = free or unused
 15528                              <1> 	;	1 = active
 15529                              <1> 	;	2 = waiting for a child process to die
 15530                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
 15531 00003EDB 80BE[1F6E0000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
 15532                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
 15533 00003EE2 7524                <1> 	jne	short syswait_2
 15534                              <1> 		; bne 2f / no, skip it
 15535 00003EE4 88BE[1F6E0000]      <1> 	mov	[esi+p.stat-1], bh ; 0
 15536                              <1> 		; clrb p.stat-1(r2) / yes, free it
 15537 00003EEA 66D1E6              <1> 	shl	si, 1
 15538                              <1> 		; asl r2 / r2x2 to get index into p.pid table
 15539 00003EED 0FB786[8E6D0000]    <1> 	movzx	eax, word [esi+p.pid-2]
 15540 00003EF4 A3[B4700000]        <1> 	mov	[u.r0], eax
 15541                              <1> 		; mov p.pid-2(r2),*u.r0 
 15542                              <1> 			      ; / put childs process name in (u.r0)
 15543                              <1> 	;
 15544                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
 15545                              <1> 	;
 15546                              <1> 	; Parent process ID -p.ppid- field (of the child process)
 15547                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
 15548                              <1> 	; system call loop from the application/program if it calls
 15549                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
 15550                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
 15551                              <1> 	;
 15552                              <1> 	; Note: syswait will return with error if there is not a
 15553                              <1> 	;       zombie or running process to wait.	
 15554                              <1> 	;
 15555 00003EF9 6629C0              <1> 	sub	ax, ax
 15556 00003EFC 668986[AE6D0000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
 15557 00003F03 E9F0FDFFFF          <1> 	jmp	sysret0 ; ax = 0
 15558                              <1> 	;
 15559                              <1> 	;jmp	sysret
 15560                              <1> 		; br sysret1 / return cause child is dead
 15561                              <1> syswait_2: ; 2:
 15562 00003F08 66D1E6              <1> 	shl	si, 1
 15563                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
 15564                              <1> syswait_3: ; 3:
 15565 00003F0B 6683FE20            <1> 	cmp	si, nproc+nproc
 15566                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
 15567 00003F0F 72B8                <1> 	jb	short syswait_1
 15568                              <1> 		; blt 1b / no, continue search
 15569                              <1> 	;and	cx, cx
 15570 00003F11 20C9                <1> 	and	cl, cl
 15571                              <1> 		; tst r3 / one gets here if there are no children 
 15572                              <1> 		       ; / or children that are still active
 15573                              <1> 	; 30/10/2013
 15574 00003F13 750B                <1> 	jnz	short syswait_4
 15575                              <1> 	;jz	error
 15576                              <1> 		; beq error1 / there are no children, error
 15577 00003F15 890D[B4700000]      <1> 	mov	[u.r0], ecx ; 0
 15578 00003F1B E9B6FDFFFF          <1> 	jmp	error
 15579                              <1> syswait_4:
 15580 00003F20 8A1D[09710000]      <1> 	mov	bl, [u.uno]
 15581                              <1> 		; movb u.uno,r1 / there are children so put 
 15582                              <1> 			      ; / parent process number in r1
 15583 00003F26 FE83[1F6E0000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
 15584                              <1> 		; incb p.stat-1(r1) / it is waiting for 
 15585                              <1> 				  ; / other children to die
 15586                              <1> 	; 04/11/2013
 15587 00003F2C E801110000          <1> 	call	swap
 15588                              <1> 		; jsr r0,swap / swap it out, because it's waiting
 15589 00003F31 EB82                <1> 	jmp	syswait_0
 15590                              <1> 		; br syswait / wait on next process
 15591                              <1> 
 15592                              <1> sysfork: ; < create a new process >
 15593                              <1> 	; 18/09/2015
 15594                              <1> 	; 04/09/2015
 15595                              <1> 	; 02/09/2015
 15596                              <1> 	; 01/09/2015
 15597                              <1> 	; 28/08/2015
 15598                              <1> 	; 14/05/2015
 15599                              <1> 	; 10/05/2015
 15600                              <1> 	; 09/05/2015
 15601                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
 15602                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 15603                              <1> 	;
 15604                              <1> 	; 'sysfork' creates a new process. This process is referred
 15605                              <1> 	; to as the child process. This new process core image is
 15606                              <1> 	; a copy of that of the caller of 'sysfork'. The only
 15607                              <1> 	; distinction is the return location and the fact that (u.r0)
 15608                              <1> 	; in the old process (parent) contains the process id (p.pid)
 15609                              <1> 	; of the new process (child). This id is used by 'syswait'.
 15610                              <1> 	; 'sysfork' works in the following manner: 	
 15611                              <1> 	;    1) The process status table (p.stat) is searched to find
 15612                              <1> 	;	a process number that is unused. If none are found
 15613                              <1> 	;	an error occurs.
 15614                              <1> 	;    2) when one is found, it becomes the child process number
 15615                              <1> 	;	and it's status (p.stat) is set to active.
 15616                              <1> 	;    3) If the parent had a control tty, the interrupt 
 15617                              <1> 	;	character in that tty buffer is cleared.
 15618                              <1> 	;    4) The child process is put on the lowest priority run 
 15619                              <1> 	;	queue via 'putlu'.
 15620                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
 15621                              <1> 	;	it is a unique number) and is put in the child's unique
 15622                              <1> 	;	identifier; process id (p.pid).
 15623                              <1> 	;    6) The process name of the parent is then obtained and
 15624                              <1> 	;	placed in the unique identifier of the parent process
 15625                              <1> 	;	name is then put in 'u.r0'.	
 15626                              <1> 	;    7) The child process is then written out on disk by
 15627                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
 15628                              <1> 	;	and the child is born. (The child process is written 
 15629                              <1> 	;	out on disk/drum with 'u.uno' being the child process
 15630                              <1> 	;	number.)
 15631                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
 15632                              <1> 	;    9) The child process name is put in 'u.r0'.
 15633                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
 15634                              <1> 	;	create the return address for the parent process.
 15635                              <1> 	;   11) The 'u.fp' list as then searched to see what files
 15636                              <1> 	;	the parent has opened. For each file the parent has
 15637                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
 15638                              <1> 	;	to indicate that the child process also has opened
 15639                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
 15640                              <1> 	;
 15641                              <1> 	; Calling sequence:
 15642                              <1> 	;	from shell ?
 15643                              <1> 	; Arguments:
 15644                              <1> 	;	-
 15645                              <1> 	; Inputs: -
 15646                              <1> 	; Outputs: *u.r0 - child process name
 15647                              <1> 	; ...............................................................
 15648                              <1> 	;	
 15649                              <1> 	; Retro UNIX 8086 v1 modification: 
 15650                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
 15651                              <1> 	;	= process id of child a parent process returns
 15652                              <1> 	;	= process id of parent when a child process returns
 15653                              <1> 	;
 15654                              <1> 	;       In original UNIX v1, sysfork is called and returns as
 15655                              <1> 	;	in following manner: (with an example: c library, fork)
 15656                              <1> 	;	
 15657                              <1> 	;	1:
 15658                              <1> 	;		sys	fork
 15659                              <1> 	;			br 1f  / child process returns here
 15660                              <1> 	;		bes	2f     / parent process returns here
 15661                              <1> 	;		/ pid of new process in r0
 15662                              <1> 	;		rts	pc
 15663                              <1> 	;	2: / parent process condionally branches here
 15664                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
 15665                              <1> 	;		rts	pc
 15666                              <1> 	;
 15667                              <1> 	;	1: / child process brances here
 15668                              <1> 	;		clr	r0   / pid = 0 in child process
 15669                              <1> 	;		rts	pc
 15670                              <1> 	;
 15671                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
 15672                              <1> 	;		// pid = fork();
 15673                              <1> 	;		//
 15674                              <1> 	;		// pid == 0 in child process; 
 15675                              <1> 	;		// pid == -1 means error return
 15676                              <1> 	;		// in child, 
 15677                              <1> 	;		//	parents id is in par_uid if needed
 15678                              <1> 	;		
 15679                              <1> 	;		_fork:
 15680                              <1> 	;			mov	$.fork,eax
 15681                              <1> 	;			int	$0x30
 15682                              <1> 	;			jmp	1f
 15683                              <1> 	;			jnc	2f
 15684                              <1> 	;			jmp	cerror
 15685                              <1> 	;		1:
 15686                              <1> 	;			mov	eax,_par_uid
 15687                              <1> 	;			xor	eax,eax
 15688                              <1> 	;		2:
 15689                              <1> 	;			ret
 15690                              <1> 	;
 15691                              <1> 	;	In Retro UNIX 8086 v1,
 15692                              <1> 	;	'sysfork' returns in following manner:
 15693                              <1> 	;	
 15694                              <1> 	;		mov	ax, sys_fork
 15695                              <1> 	;		mov	bx, offset @f ; routine for child
 15696                              <1> 	;		int	20h
 15697                              <1> 	;		jc	error
 15698                              <1> 	;		
 15699                              <1> 	;	; Routine for parent process here (just after 'jc')
 15700                              <1> 	;		mov	word ptr [pid_of_child], ax
 15701                              <1> 	;		jmp	next_routine_for_parent	
 15702                              <1> 	;
 15703                              <1> 	;	@@: ; routine for child process here				
 15704                              <1> 	;		....	
 15705                              <1> 	;	NOTE: 'sysfork' returns to specified offset
 15706                              <1> 	;	       for child process by using BX input.
 15707                              <1> 	;	      (at first, parent process will return then 
 15708                              <1> 	;	      child process will return -after swapped in-
 15709                              <1> 	;	      'syswait' is needed in parent process
 15710                              <1> 	;	      if return from child process will be waited for.)
 15711                              <1> 	;	  				
 15712                              <1> 	
 15713                              <1> ; / create a new process
 15714                              <1> 	; EBX = return address for child process 
 15715                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
 15716 00003F33 31F6                <1> 	xor 	esi, esi
 15717                              <1> 		; clr r1
 15718                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
 15719 00003F35 46                  <1> 	inc	esi
 15720                              <1> 		; inc r1
 15721 00003F36 80BE[1F6E0000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
 15722                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
 15723 00003F3D 760B                <1> 	jna	short sysfork_2	
 15724                              <1> 		; beq 1f / it's unused so branch
 15725 00003F3F 6683FE10            <1> 	cmp	si, nproc
 15726                              <1> 		; cmp r1,$nproc / all processes checked
 15727 00003F43 72F0                <1> 	jb	short sysfork_1
 15728                              <1> 		; blt 1b / no, branch back
 15729                              <1> 	;
 15730                              <1> 	; Retro UNIX 8086 v1. modification:
 15731                              <1> 	;	Parent process returns from 'sysfork' to address 
 15732                              <1> 	;	which is just after 'sysfork' system call in parent
 15733                              <1> 	;	process. Child process returns to address which is put
 15734                              <1> 	;	in BX register by parent process for 'sysfork'. 
 15735                              <1> 	;
 15736                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
 15737                              <1> 		             ; / to old process return
 15738                              <1> 		; br error1 / no room for a new process
 15739 00003F45 E98CFDFFFF          <1> 	jmp	error
 15740                              <1> sysfork_2: ; 1:
 15741 00003F4A E823F0FFFF          <1> 	call	allocate_page
 15742 00003F4F 0F8281FDFFFF        <1> 	jc	error
 15743 00003F55 50                  <1> 	push	eax   ; UPAGE (user structure page) address
 15744                              <1> 	; Retro UNIX 386 v1 modification!
 15745 00003F56 E810F2FFFF          <1> 	call	duplicate_page_dir
 15746                              <1> 		; EAX = New page directory 
 15747 00003F5B 730B                <1> 	jnc	short sysfork_3
 15748 00003F5D 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15749 00003F5E E8D7F1FFFF          <1> 	call 	deallocate_page
 15750 00003F63 E96EFDFFFF          <1> 	jmp	error
 15751                              <1> sysfork_3:
 15752                              <1> 	; Retro UNIX 386 v1 modification !
 15753 00003F68 56                  <1> 	push	esi
 15754 00003F69 E83C110000          <1> 	call	wswap ; save current user (u) structure, user registers
 15755                              <1> 		      ; and interrupt return components (for IRET)
 15756 00003F6E 8705[18710000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
 15757 00003F74 A3[1C710000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
 15758 00003F79 5E                  <1> 	pop	esi
 15759 00003F7A 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
 15760                              <1> 		; [u.usp] = esp
 15761 00003F7B 89F7                <1> 	mov	edi, esi
 15762 00003F7D 66C1E702            <1> 	shl	di, 2
 15763 00003F81 8987[2C6E0000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
 15764 00003F87 A3[14710000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
 15765                              <1> 	; 28/08/2015
 15766 00003F8C 0FB605[09710000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
 15767                              <1> 		; movb u.uno,-(sp) / save parent process number
 15768 00003F93 89C7                <1> 	mov	edi, eax
 15769 00003F95 50                  <1>         push	eax ; ** 
 15770 00003F96 8A87[EF6D0000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
 15771                              <1> 	; 18/09/2015
 15772                              <1> 	;mov	[esi+p.ttyc-1], al ; set child's console tty
 15773                              <1> 	;mov	[esi+p.waitc-1], ah ; 0 ; reset child's wait channel
 15774 00003F9C 668986[EF6D0000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
 15775                              <1> 				   ; ah - reset child's wait channel	
 15776 00003FA3 89F0                <1> 	mov	eax, esi
 15777 00003FA5 A2[09710000]        <1> 	mov	[u.uno], al ; child process number
 15778                              <1> 		;movb r1,u.uno / set child process number to r1
 15779 00003FAA FE86[1F6E0000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
 15780                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
 15781                              <1> 				; / process to active status
 15782                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
 15783                              <1> 			      ; / control tty buffer in r2
 15784                              <1>                 ; beq 2f / branch, if no such tty assigned
 15785                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
 15786                              <1> 	; 2:
 15787 00003FB0 53                  <1> 	push	ebx  ; * return address for the child process
 15788                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15789                              <1> 	; (Retro UNIX 8086 v1 modification!)
 15790                              <1> 		; mov $runq+4,r2
 15791 00003FB1 E84A110000          <1> 	call	putlu 
 15792                              <1>  		; jsr r0,putlu / put child process on lowest priority 
 15793                              <1> 			   ; / run queue
 15794 00003FB6 66D1E6              <1> 	shl	si, 1
 15795                              <1> 		; asl r1 / multiply r1 by 2 to get index 
 15796                              <1> 		       ; / into p.pid table
 15797 00003FB9 66FF05[9A700000]    <1> 	inc	word [mpid]
 15798                              <1> 		; inc mpid / increment m.pid; get a new process name
 15799 00003FC0 66A1[9A700000]      <1> 	mov	ax, [mpid]
 15800 00003FC6 668986[8E6D0000]    <1> 	mov	[esi+p.pid-2], ax
 15801                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
 15802                              <1> 				    ; / in child process' name slot
 15803 00003FCD 5A                  <1> 	pop	edx  ; * return address for the child process
 15804                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
 15805 00003FCE 5B                  <1>   	pop	ebx  ; **
 15806                              <1> 	;mov	ebx, [esp] ; ** parent process number
 15807                              <1> 		; movb (sp),r2 / put parent process number in r2
 15808 00003FCF 66D1E3              <1> 	shl 	bx, 1
 15809                              <1> 		;asl r2 / multiply by 2 to get index into below tables
 15810                              <1> 	;movzx eax, word [ebx+p.pid-2]
 15811 00003FD2 668B83[8E6D0000]    <1> 	mov	ax, [ebx+p.pid-2]
 15812                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
 15813                              <1> 				   ; / process
 15814 00003FD9 668986[AE6D0000]    <1> 	mov	[esi+p.ppid-2], ax
 15815                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
 15816                              <1> 			  ; / in parent process slot for child
 15817 00003FE0 A3[B4700000]        <1> 	mov	[u.r0], eax	
 15818                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
 15819                              <1> 			     ; / at location where r0 was saved
 15820 00003FE5 8B2D[AC700000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
 15821 00003FEB 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
 15822                              <1> 			   ; * return address for the child process
 15823                              <1> 		; mov $sysret1,-(sp) /
 15824                              <1> 		; mov sp,u.usp / contents of sp at the time when 
 15825                              <1> 			      ; / user is swapped out
 15826                              <1> 		; mov $sstack,sp / point sp to swapping stack space
 15827                              <1> 	; 04/09/2015 - 01/09/2015
 15828                              <1> 	; [u.usp] = esp
 15829 00003FEE 68[F63C0000]        <1> 	push	sysret ; ***
 15830 00003FF3 8925[B0700000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
 15831                              <1> 			     ; (for child process)	
 15832 00003FF9 31C0                <1> 	xor 	eax, eax
 15833 00003FFB 66A3[EE700000]      <1> 	mov 	[u.ttyp], ax ; 0
 15834                              <1> 	;
 15835 00004001 E8A4100000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
 15836                              <1> 		;jsr r0,wswap / put child process out on drum
 15837                              <1> 		;jsr r0,unpack / unpack user stack
 15838                              <1> 		;mov u.usp,sp / restore user stack pointer
 15839                              <1> 		; tst (sp)+ / bump stack pointer
 15840                              <1> 	; Retro UNIX 386 v1 modification !
 15841 00004006 58                  <1> 	pop	eax ; ***
 15842 00004007 66D1E3              <1> 	shl	bx, 1
 15843 0000400A 8B83[2C6E0000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
 15844 00004010 E8BE100000          <1> 	call	rswap ; restore parent process 'u' structure, 
 15845                              <1> 		      ; registers and return address (for IRET)
 15846                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
 15847 00004015 0FB705[9A700000]    <1>         movzx   eax, word [mpid]
 15848 0000401C A3[B4700000]        <1> 	mov	[u.r0], eax
 15849                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
 15850                              <1> 			       ; / where r0 was saved
 15851                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
 15852                              <1> 			          ; / process return
 15853                              <1> 	;xor	ebx, ebx
 15854 00004021 31F6                <1> 	xor     esi, esi
 15855                              <1> 		;clr r1
 15856                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
 15857                              <1> 	      ; / opened by the parent process
 15858                              <1> 	; 01/09/2015
 15859                              <1> 	;xor	bh, bh
 15860                              <1> 	;mov 	bl, [esi+u.fp]
 15861 00004023 8A86[BE700000]      <1> 	mov 	al, [esi+u.fp]
 15862                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
 15863                              <1>         ;or	bl, bl
 15864 00004029 08C0                <1> 	or	al, al
 15865 0000402B 740D                <1> 	jz	short sysfork_5	
 15866                              <1> 		; beq 2f / file has not been opened by parent, 
 15867                              <1> 		       ; / so branch
 15868 0000402D B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
 15869 0000402F F6E4                <1> 	mul	ah
 15870                              <1> 	;movzx	ebx, ax
 15871 00004031 6689C3              <1> 	mov	bx, ax
 15872                              <1> 	;shl	bx, 3
 15873                              <1> 		; asl r2 / multiply by 8
 15874                              <1>        		; asl r2 / to get index into fsp table
 15875                              <1>        		; asl r2
 15876 00004034 FE83[4E6D0000]      <1>   	inc     byte [ebx+fsp-2]
 15877                              <1> 		; incb fsp-2(r2) / increment number of processes
 15878                              <1> 			     ; / using file, because child will now be
 15879                              <1> 			     ; / using this file
 15880                              <1> sysfork_5: ; 2:
 15881 0000403A 46                  <1>         inc     esi
 15882                              <1> 		; inc r1 / get next open file
 15883 0000403B 6683FE0A            <1>         cmp     si, 10
 15884                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
 15885                              <1> 			  ; / can be opened
 15886 0000403F 72E2                <1> 	jb	short sysfork_4	
 15887                              <1> 		; blt 1b / check next entry
 15888 00004041 E9B0FCFFFF          <1> 	jmp	sysret
 15889                              <1> 		; br sysret1
 15890                              <1> 
 15891                              <1> sysread: ; < read from file >
 15892                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 15893                              <1> 	; 27/03/2020
 15894                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15895                              <1> 	; 13/05/2015
 15896                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15897                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15898                              <1> 	;
 15899                              <1> 	; 'sysread' is given a buffer to read into and the number of
 15900                              <1> 	; characters to be read. If finds the file from the file
 15901                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
 15902                              <1> 	; is returned from a successful open call (sysopen).
 15903                              <1> 	; The i-number of file is obtained via 'rw1' and the data
 15904                              <1> 	; is read into core via 'readi'.
 15905                              <1> 	;
 15906                              <1> 	; Calling sequence:
 15907                              <1> 	;	sysread; buffer; nchars
 15908                              <1> 	; Arguments:
 15909                              <1> 	;	buffer - location of contiguous bytes where 
 15910                              <1> 	;		 input will be placed.
 15911                              <1> 	;	nchars - number of bytes or characters to be read.
 15912                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15913                              <1> 	; Outputs: *u.r0 - number of bytes read.	
 15914                              <1> 	; ...............................................................
 15915                              <1> 	;				
 15916                              <1> 	; Retro UNIX 8086 v1 modification: 
 15917                              <1> 	;       'sysread' system call has three arguments; so,
 15918                              <1> 	;	* 1st argument, file descriptor is in BX register
 15919                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15920                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15921                              <1> 	;
 15922                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15923                              <1> 	;	to the user with number of bytes read. 
 15924                              <1> 	;
 15925 00004046 E839000000          <1> 	call	rw1
 15926                              <1> 	;jc	error ; 13/05/2015, ax < 1
 15927                              <1> 	;	; jsr r0,rw1 / get i-number of file to be read into r1
 15928                              <1>        	; 04/12/2021
 15929 0000404B 7209                <1> 	jc	short sysread_err
 15930 0000404D 7529                <1> 	jnz	short rw3 ; error ! (permission denied)
 15931                              <1> 			; read a file while it is open for write!
 15932                              <1> 	; eax = inode number
 15933                              <1> 
 15934                              <1> 	; 04/12/2021
 15935                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
 15936                              <1> 	;test	ah, 80h
 15937                              <1> 	;	; tst r1 / negative i-number?
 15938                              <1> 	;;jnz	error
 15939                              <1> 	;;	; ble error1 / yes, error 1 to read
 15940                              <1> 	;;		   ; / it should be positive
 15941                              <1> 	;; 04/12/2021
 15942                              <1> 	;jnz	short sysread_err
 15943                              <1> 	
 15944 0000404F E877170000          <1> 	call	readi
 15945                              <1> 		; jsr r0,readi / read data into core
 15946 00004054 EB13                <1> 	jmp	short rw0
 15947                              <1> 		; br 1f
 15948                              <1> sysread_err:
 15949                              <1> syswrite_err:
 15950                              <1> 	; 04/12/2021
 15951 00004056 E97BFCFFFF          <1> 	jmp	error
 15952                              <1> 
 15953                              <1> syswrite: ; < write to file >
 15954                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 15955                              <1> 	; 27/03/2020
 15956                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 15957                              <1> 	; 13/05/2015
 15958                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 15959                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
 15960                              <1> 	;
 15961                              <1> 	; 'syswrite' is given a buffer to write onto an output file
 15962                              <1> 	; and the number of characters to write. If finds the file
 15963                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
 15964                              <1> 	; descriptor is returned from a successful open or create call
 15965                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
 15966                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
 15967                              <1> 	;
 15968                              <1> 	; Calling sequence:
 15969                              <1> 	;	syswrite; buffer; nchars
 15970                              <1> 	; Arguments:
 15971                              <1> 	;	buffer - location of contiguous bytes to be writtten.
 15972                              <1> 	;	nchars - number of characters to be written.
 15973                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
 15974                              <1> 	; Outputs: *u.r0 - number of bytes written.	
 15975                              <1> 	; ...............................................................
 15976                              <1> 	;				
 15977                              <1> 	; Retro UNIX 8086 v1 modification: 
 15978                              <1> 	;       'syswrite' system call has three arguments; so,
 15979                              <1> 	;	* 1st argument, file descriptor is in BX register
 15980                              <1> 	;	* 2nd argument, buffer address/offset in CX register
 15981                              <1> 	;	* 3rd argument, number of bytes is in DX register
 15982                              <1> 	;
 15983                              <1> 	;	AX register (will be restored via 'u.r0') will return
 15984                              <1> 	;	to the user with number of bytes written. 
 15985                              <1> 	;
 15986 0000405B E824000000          <1> 	call	rw1
 15987                              <1> 	;jc	error ; 13/05/2015, ax < 1
 15988                              <1> 	;	; jsr r0,rw1 / get i-number in r1 of file to write
 15989                              <1>        	; 04/12/2021
 15990 00004060 72F4                <1> 	jc	short syswrite_err
 15991 00004062 7414                <1> 	jz	short rw3 ; error ! (permission denied)
 15992                              <1> 			; write to a file while it is open for read
 15993                              <1> 	; eax = inode number
 15994                              <1> 	
 15995                              <1> 	; 04/12/2021
 15996                              <1> 	;((Retro Unix 386 v1 code)) (old code below)
 15997                              <1> 	;test	ah, 80h
 15998                              <1> 	;	; tst r1 / positive i-number ?
 15999                              <1>         ;jz	short rw3 ; 13/05/2015
 16000                              <1> 	;;jz	error
 16001                              <1> 	;	; bge error1 / yes, error 1 
 16002                              <1> 	;		   ; / negative i-number means write
 16003                              <1>         ;neg	ax
 16004                              <1> 	;	; neg r1 / make it positive
 16005                              <1> 	
 16006 00004064 E870190000          <1> 	call	writei
 16007                              <1>         	; jsr r0,writei / write data
 16008                              <1> rw0: ; 1:
 16009 00004069 A1[E4700000]        <1>         mov	eax, [u.nread]
 16010 0000406E A3[B4700000]        <1> 	mov	[u.r0], eax
 16011                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
 16012                              <1> 				  ; / into (u.r0)
 16013 00004073 E97EFCFFFF          <1> 	jmp	sysret
 16014                              <1>         	; br sysret1
 16015                              <1> rw3: 
 16016                              <1> 	; 13/05/2015
 16017 00004078 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 16018 00004080 0000                <1>
 16019 00004082 F9                  <1> 	stc
 16020 00004083 C3                  <1> 	retn
 16021                              <1> rw1:	
 16022                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 16023                              <1> 	; 27/03/2020
 16024                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 16025                              <1> 	; 14/05/2015
 16026                              <1> 	; 13/05/2015
 16027                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 16028                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
 16029                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
 16030                              <1> 	;
 16031                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
 16032                              <1> 				;(in the user's virtual memory space)
 16033                              <1> 	;mov	[u.count], edx 
 16034                              <1> 		; jsr r0,arg; u.base / get buffer pointer
 16035                              <1>         	; jsr r0,arg; u.count / get no. of characters
 16036                              <1> 	;;mov	eax, ebx ; file descriptor
 16037                              <1> 		; mov *u.r0,r1 / put file descriptor 
 16038                              <1> 		             ; / (index to u.fp table) in r1
 16039                              <1> 	; 13/05/2015
 16040 00004084 C705[B4700000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
 16041 0000408C 0000                <1>
 16042                              <1> 	;
 16043                              <1> 	;; call	getf
 16044                              <1>         ; ebx = File descriptor
 16045 0000408E E8D80A0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
 16046                              <1> 		; jsr r0,getf / get i-number of the file in r1
 16047                              <1> 	; AX = I-number of the file ; negative i-number means write
 16048                              <1> 
 16049                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 16050                              <1> 	; 26/03/2020 - Retro UNIX 386 v2
 16051                              <1> 	; BL = open mode & status flag (0 = read, 1 = write)
 16052                              <1> 	; eax = inode number (ax)
 16053                              <1> 	; 27/03/2020
 16054                              <1> 	; [cdev] = logical drive number 	
 16055                              <1> 
 16056                              <1> 	; 13/05/2015
 16057 00004093 6683F801            <1> 	cmp 	ax, 1
 16058 00004097 721A                <1> 	jb	short rw2
 16059                              <1> 	;
 16060 00004099 890D[DC700000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
 16061                              <1> 				;(in the user's virtual memory space)
 16062 0000409F 8915[E0700000]      <1> 	mov	[u.count], edx 
 16063                              <1> 	; 14/05/2015
 16064 000040A5 C705[2C710000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
 16065 000040AD 0000                <1>
 16066                              <1> 
 16067                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 16068                              <1> 	; 27/03/2020 - Retro UNIX 386 v2
 16069 000040AF 80E301              <1> 	and	bl, 1
 16070                              <1> 		; zf = 0 -> open for write	
 16071                              <1> 		; zf = 1 -> open for read
 16072                              <1> 	;
 16073 000040B2 C3                  <1> 	retn
 16074                              <1>         	; rts r0
 16075                              <1> rw2:
 16076                              <1> 	; 13/05/2015
 16077 000040B3 C705[2C710000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 16078 000040BB 0000                <1>
 16079 000040BD C3                  <1> 	retn
 16080                              <1> 
 16081                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility code
 16082                              <1> sysopen: ;<open file>
 16083                              <1> 	; 04/12/2021
 16084                              <1> 	; 07/08/2020 (Retro UNIX 386 v2)
 16085                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16086                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
 16087                              <1> 	;
 16088                              <1> 	; 'sysopen' opens a file in following manner:
 16089                              <1> 	;    1) The second argument in a sysopen says whether to
 16090                              <1> 	;	open the file ro read (0) or write (>0).
 16091                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
 16092                              <1> 	;    3) The file is opened by 'iopen'.
 16093                              <1> 	;    4) Next housekeeping is performed on the fsp table
 16094                              <1> 	;	and the user's open file list - u.fp.
 16095                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
 16096                              <1> 	;	b) An entry for the file is created in the fsp table.
 16097                              <1> 	;	c) The number of this entry is put on u.fp list.
 16098                              <1> 	;	d) The file descriptor index to u.fp list is pointed
 16099                              <1> 	;	   to by u.r0.
 16100                              <1> 	;
 16101                              <1> 	; Calling sequence:
 16102                              <1> 	;	sysopen; name; mode
 16103                              <1> 	; Arguments:
 16104                              <1> 	;	name - file name or path name
 16105                              <1> 	;	mode - 0 to open for reading
 16106                              <1> 	;	       1 to open for writing
 16107                              <1> 	; Inputs: (arguments)
 16108                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
 16109                              <1> 	;		  is put into r0's location on the stack.	
 16110                              <1> 	; ...............................................................
 16111                              <1> 	;				
 16112                              <1> 	; Retro UNIX 8086 v1 modification: 
 16113                              <1> 	;       'sysopen' system call has two arguments; so,
 16114                              <1> 	;	* 1st argument, name is pointed to by BX register
 16115                              <1> 	;	* 2nd argument, mode is in CX register
 16116                              <1> 	;
 16117                              <1> 	;	AX register (will be restored via 'u.r0') will return
 16118                              <1> 	;	to the user with the file descriptor/number 
 16119                              <1> 	;	(index to u.fp list).
 16120                              <1> 	;
 16121                              <1> 	;call	arg2
 16122                              <1> 	; * name - 'u.namep' points to address of file/path name
 16123                              <1> 	;          in the user's program segment ('u.segmnt')
 16124                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16125                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16126                              <1> 	;          which is on top of stack.
 16127                              <1> 	;
 16128                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
 16129                              <1> 	;
 16130                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
 16131                              <1> 
 16132 000040BE 891D[D0700000]      <1> 	mov	[u.namep], ebx
 16133 000040C4 51                  <1> 	push	ecx ; * ; 04/12/2021 (cx -> ecx)
 16134 000040C5 E8D50A0000          <1> 	call	namei
 16135                              <1> 		; jsr r0,namei / i-number of file in r1
 16136                              <1>      	;and	ax, ax
 16137                              <1> 	;jz	error ; File not found
 16138 000040CA 722B                <1> 	jc	short fnotfound ; 14/05/2015
 16139                              <1> 	;jc	error ; 27/05/2013
 16140                              <1> 		; br  error2 / file not found
 16141                              <1>    	;pop	edx ; * ; mode ; 04/12/2021
 16142                              <1> 	;push	edx ; *
 16143                              <1> 	;;or	dx, dx
 16144                              <1> 	;or	dl, dl
 16145                              <1> 	;	; tst (sp) / is mode = 0 (2nd arg of call;
 16146                              <1> 	;	         ; / 0 means, open for read)
 16147                              <1> 	;;jz	short sysopen_0
 16148                              <1> 	;;	; beq 1f / yes, leave i-number positive
 16149                              <1> 	
 16150 000040CC 8B1424              <1> 	mov	edx, [esp] ; *
 16151                              <1> 	; edx = open mode (0 or 1)
 16152                              <1> 
 16153                              <1> ;syscreat_0: ;op0: ; 27/12/2015
 16154                              <1> ;	neg	ax
 16155                              <1> ;        	; neg r1 / open for writing so make i-number negative
 16156                              <1> 
 16157                              <1> sysopen_0: ;1:
 16158 000040CF E8CF1C0000          <1> 	call	iopen
 16159                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
 16160 000040D4 5A                  <1> 	pop	edx ; * ; mode ; 04/12/2021
 16161                              <1> 	;;and	dx, dx
 16162                              <1> 	;and	dl, dl
 16163                              <1>         ;	; tst (sp)+ / pop the stack and test the mode
 16164                              <1> 	;jz	short sysopen_2
 16165                              <1>         ;	; beq op1 / is open for read op1
 16166                              <1> ;sysopen_1: ;op0:
 16167                              <1> 	;neg	ax
 16168                              <1>         ;	; neg r1 
 16169                              <1> 	;	     ;/ make i-number positive if open for writing [???]
 16170                              <1> 
 16171                              <1> 	;; NOTE: iopen always make i-number positive.
 16172                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
 16173                              <1> sysopen_1: ; 04/12/2021
 16174                              <1> sysopen_2: ;op1:
 16175 000040D5 31F6                <1>         xor     esi, esi
 16176                              <1>         	; clr r2 / clear registers
 16177 000040D7 31DB                <1>         xor     ebx, ebx
 16178                              <1> 		; clr r3
 16179                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
 16180 000040D9 389E[BE700000]      <1>         cmp     [esi+u.fp], bl ; 0
 16181                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
 16182 000040DF 7625                <1>         jna      short sysopen_4
 16183                              <1> 		; beq 1f / if byte in list is 0 branch
 16184 000040E1 46                  <1>         inc     esi
 16185                              <1> 		; inc r2 / bump r2 so next byte can be checked
 16186 000040E2 6683FE0A            <1> 	cmp	si, OPENFILES ; 04/12/2021
 16187                              <1> 	;cmp	si, 10
 16188                              <1> 		; cmp r2,$10. / reached end of list?
 16189 000040E6 72F1                <1> 	jb	short sysopen_3
 16190                              <1> 		; blt 1b / no, go back
 16191                              <1> toomanyf:
 16192                              <1> 	; 14/05/2015
 16193 000040E8 C705[2C710000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
 16194 000040F0 0000                <1>
 16195 000040F2 E9DFFBFFFF          <1> 	jmp	error
 16196                              <1>         	; br error2 / yes, error (no files open)
 16197                              <1> fnotfound: 
 16198                              <1> 	; 14/05/2015
 16199 000040F7 C705[2C710000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
 16200 000040FF 0000                <1>
 16201 00004101 E9D0FBFFFF          <1> 	jmp	error
 16202                              <1> 
 16203                              <1> sysopen_4: ; 1:
 16204 00004106 6683BB[506D0000]00  <1>         cmp     word [ebx+fsp], 0
 16205                              <1> 		; tst fsp(r3) / scan fsp entries
 16206 0000410E 760D                <1>         jna     short sysopen_5
 16207                              <1> 		; beq 1f / if 0 branch
 16208                              <1> 	;; 14/05/2015 - Retro UNIX 386 v1 modification !
 16209                              <1> 	;add	bx, 10 ; fsp structure size = 10 bytes/entry
 16210                              <1> 		; add $8.,r3 / add 8 to r3 
 16211                              <1> 			; / to bump it to next entry mfsp table
 16212                              <1> 	; 07/08/2020 - Retro UNIX 386 v2
 16213 00004110 6683C310            <1> 	add	bx, 16 ; fsp structure size = 16 bytes/entry ; runix v2
 16214                              <1> 	; 22/11/2021
 16215 00004114 6681FB2003          <1> 	cmp	bx, NFILES*fp.size ; NFILES*16
 16216                              <1> 	;cmp	bx, nfiles*10
 16217                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
 16218 00004119 72EB                <1> 	jb	short sysopen_4
 16219                              <1>        		; blt 1b / no, back
 16220                              <1> 	;jmp	error
 16221                              <1>         ;	; br error2 / yes, error
 16222                              <1> 	; 04/12/2021
 16223                              <1> 	; 07/08/2020
 16224 0000411B EBCB                <1> 	jmp	short toomanyf
 16225                              <1> 
 16226                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
 16227 0000411D 668983[506D0000]    <1>         mov     [ebx+fsp], ax
 16228                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
 16229                              <1> 			; / into next available entry in fsp table,
 16230                              <1> 	;mov	di, [cdev] ; word ? byte ?
 16231                              <1>         ;mov	[ebx+fsp+2], di ; device number
 16232                              <1> 	;	; mov cdev,fsp+2(r3) / put # of device in next word
 16233                              <1> 	; 04/12/2021        
 16234 00004124 A0[95700000]        <1> 	mov	al, [cdev]
 16235 00004129 88D4                <1> 	mov	ah, dl ; open mode, 0 = read, 1 = write
 16236 0000412B 668983[546D0000]    <1> 	mov	[ebx+fsp+4], ax ; device number & open mode
 16237                              <1> 
 16238                              <1> 	;xor	edi, edi
 16239                              <1>         ;mov	[ebx+fsp+4], edi ; offset pointer (0)
 16240                              <1> 	;	; clr fsp+4(r3)
 16241                              <1>         ;mov	[ebx+fsp+8], di ; open count (0), deleted flag (0)
 16242                              <1>        	;	; clr fsp+6(r3) / clear the next two words
 16243                              <1> 
 16244                              <1> 	; 04/12/2021
 16245 00004132 31C0                <1> 	xor	eax, eax
 16246 00004134 8983[586D0000]      <1>   	mov	[ebx+fsp+8], eax ; offset pointer = 0
 16247                              <1> 	;inc	word [ebx+fsp+6]
 16248 0000413A FE83[566D0000]      <1> 	inc	byte [ebx+fsp+6] ; open count = open count + 1	
 16249                              <1> 
 16250                              <1>   	;mov	eax, ebx
 16251                              <1> 	;mov	bl, 10
 16252                              <1> 	;div	bl 
 16253                              <1> 	;	; asr r3
 16254                              <1> 	;	; asr r3 / divide by 8 
 16255                              <1> 	;	; asr r3 ; / to get number of the fsp entry-1
 16256                              <1> 	;inc	al
 16257                              <1>         ;	; inc r3 / add 1 to get fsp entry number
 16258                              <1>         ;mov	[esi+u.fp], al
 16259                              <1> 	;	; movb r3,u.fp(r2) / move entry number into 
 16260                              <1> 			; / next available slot in u.fp list
 16261                              <1> 	; 04/12/2021
 16262                              <1> 	;shr	ebx, 4	; / 16
 16263 00004140 66C1EB04            <1> 	shr	bx, 4	; bx = fsp entry number (index)	
 16264                              <1> 			; bx <= 49 for current runix 386 version
 16265 00004144 FEC3                <1> 	inc 	bl	; bl = 1 to 50
 16266 00004146 889E[BE700000]      <1> 	mov	[esi+u.fp], bl 	
 16267                              <1> 
 16268 0000414C 8935[B4700000]      <1>         mov     [u.r0], esi
 16269                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
 16270                              <1> 			     ; / into r0 loc on stack
 16271 00004152 E99FFBFFFF          <1>         jmp	sysret
 16272                              <1> 		; br sysret2
 16273                              <1> 
 16274                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
 16275                              <1> ;
 16276                              <1> ;         15                    7                   0
 16277                              <1> ;  1     |-------------------------------------------|
 16278                              <1> ;        |   	     i-number of open file           |
 16279                              <1> ;        |-------------------------------------------| 
 16280                              <1> ;        |        high word of 32 bit i-number       |
 16281                              <1> ;        |-------------------------------------------|
 16282                              <1> ;        | open mode & status  |   device number     |
 16283                              <1> ;        |-------------------------------------------|			
 16284                              <1> ;        |    reserved byte    |     open count      |
 16285                              <1> ;        |-------------------------------------------| 
 16286                              <1> ;        | offset pointer, i.e., r/w pointer to file |
 16287                              <1> ;        |-------------------------------------------|
 16288                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
 16289                              <1> ;        |-------------------------------------------|
 16290                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
 16291                              <1> ;        |-------------------------------------------|
 16292                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
 16293                              <1> ;        |-------------------------------------------|
 16294                              <1> ;  2     |                                           |
 16295                              <1> ;        |-------------------------------------------| 
 16296                              <1> ;        |                                           |
 16297                              <1> ;        |-------------------------------------------|
 16298                              <1> ;        |                                           |
 16299                              <1> ;        |-------------------------------------------|
 16300                              <1> ;        |                                           |
 16301                              <1> ;        |-------------------------------------------| 
 16302                              <1> ;        |                                           | 
 16303                              <1> 
 16304                              <1> 	;
 16305                              <1> 	; 'fsp' table (10 bytes/entry)
 16306                              <1> 	; bit 15				   bit 0
 16307                              <1> 	; ---|-------------------------------------------
 16308                              <1> 	; r/w|		i-number of open file
 16309                              <1> 	; ---|-------------------------------------------
 16310                              <1> 	;		   device number
 16311                              <1> 	; -----------------------------------------------
 16312                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 16313                              <1> 	; -----------------------------------------------
 16314                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 16315                              <1> 	; ----------------------|------------------------
 16316                              <1> 	;  flag that says file 	| number of processes
 16317                              <1> 	;   has been deleted	| that have file open 
 16318                              <1> 	; ----------------------|------------------------
 16319                              <1> 	;
 16320                              <1> 
 16321                              <1> 
 16322                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16323                              <1> syscreat: ; < create file >
 16324                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16325                              <1> 	; 04/04/2021
 16326                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
 16327                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
 16328                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16329                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
 16330                              <1> 	;
 16331                              <1> 	; 'syscreat' called with two arguments; name and mode.
 16332                              <1> 	; u.namep points to name of the file and mode is put
 16333                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
 16334                              <1> 	; If the file aready exists, it's mode and owner remain 
 16335                              <1> 	; unchanged, but it is truncated to zero length. If the file
 16336                              <1> 	; did not exist, an i-node is created with the new mode via
 16337                              <1> 	; 'maknod' whether or not the file already existed, it is
 16338                              <1> 	; open for writing. The fsp table is then searched for a free
 16339                              <1> 	; entry. When a free entry is found, proper data is placed
 16340                              <1> 	; in it and the number of this entry is put in the u.fp list.
 16341                              <1> 	; The index to the u.fp (also know as the file descriptor)
 16342                              <1> 	; is put in the user's r0. 			
 16343                              <1> 	;
 16344                              <1> 	; Calling sequence:
 16345                              <1> 	;	syscreate; name; mode
 16346                              <1> 	; Arguments:
 16347                              <1> 	;	name - name of the file to be created
 16348                              <1> 	;	mode - mode of the file to be created
 16349                              <1> 	; Inputs: (arguments)
 16350                              <1> 	; Outputs: *u.r0 - index to u.fp list 
 16351                              <1> 	;		   (the file descriptor of new file)
 16352                              <1> 	; ...............................................................
 16353                              <1> 	;				
 16354                              <1> 	; Retro UNIX 8086 v1 modification: 
 16355                              <1> 	;       'syscreate' system call has two arguments; so,
 16356                              <1> 	;	* 1st argument, name is pointed to by BX register
 16357                              <1> 	;	* 2nd argument, mode is in CX register
 16358                              <1> 	;
 16359                              <1> 	;	AX register (will be restored via 'u.r0') will return
 16360                              <1> 	;	to the user with the file descriptor/number 
 16361                              <1> 	;	(index to u.fp list).
 16362                              <1> 	;
 16363                              <1> 	;call	arg2
 16364                              <1> 	; * name - 'u.namep' points to address of file/path name
 16365                              <1> 	;          in the user's program segment ('u.segmnt')
 16366                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16367                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16368                              <1> 	;          which is on top of stack.
 16369                              <1> 	;
 16370                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
 16371                              <1> 			    ; / on stack
 16372 00004157 891D[D0700000]      <1> 	mov	[u.namep], ebx ; file name address
 16373                              <1> 	;push	cx ; mode
 16374                              <1> 	; 04/12/2021
 16375 0000415D 51                  <1> 	push	ecx ; cx = mode (permission flags)
 16376 0000415E E83C0A0000          <1> 	call 	namei        	
 16377                              <1> 		; jsr r0,namei / get the i-number
 16378                              <1>         ;and	ax, ax
 16379                              <1> 	;jz	short syscreat_1	       	
 16380 00004163 7226                <1> 	jc	short syscreat_1
 16381                              <1> 		; br  2f / if file doesn't exist 2f
 16382                              <1> 	; 27/12/2015
 16383                              <1> 	;cmp	ax, 41 ; device inode ?
 16384                              <1>         ;jb	syscreat_0 ; yes
 16385                              <1> 	;
 16386                              <1> 	;neg 	ax
 16387                              <1>         ;	; neg r1 / if file already exists make i-number 
 16388                              <1> 		       ; / negative (open for writing)
 16389                              <1> 	; 27/03/2021
 16390 00004165 F605[506D0000]80    <1> 	test	byte [i.flgs], 80h ; regular file
 16391 0000416C 7431                <1> 	jz	short f_create_error ; device inode !!!
 16392 0000416E F605[506D0000]40    <1> 	test	byte [i.flgs], 40h ; directory
 16393 00004175 7528                <1> 	jnz	short f_create_error ; directory inode !!!
 16394                              <1> 
 16395                              <1> 	; Truncate existing file
 16396                              <1> ;syscreate_2:
 16397                              <1> 	; 27/03/2021
 16398                              <1> 	;xor	edx, edx ; 0
 16399                              <1> 	;inc	dl ; DL = 1 ; create/truncate (open for write)
 16400 00004177 B201                <1> 	mov	dl, 1
 16401                              <1> 	;
 16402 00004179 E8251C0000          <1> 	call	iopen
 16403                              <1>         	; jsr r0,iopen /
 16404 0000417E E89D150000          <1> 	call	itrunc
 16405                              <1>         	; jsr r0,itrunc / truncate to 0 length
 16406                              <1> 	;pop	cx ; pop mode (did not exist in original Unix v1 !?)
 16407                              <1> 	; 04/12/2021
 16408 00004183 59                  <1> 	pop	ecx 
 16409                              <1> syscreat_2:
 16410 00004184 B201                <1> 	mov	dl, 1 ; open for writing
 16411 00004186 E94AFFFFFF          <1>         jmp     sysopen_1
 16412                              <1>         	; br op0
 16413                              <1> syscreat_1: ; 2: / file doesn't exist
 16414                              <1> 	;pop	ax
 16415                              <1>         ;	; mov (sp)+,r1 / put the mode in r1
 16416                              <1> 	; 27/03/2021
 16417 0000418B 58                  <1> 	pop	eax  ; ax = mode (permission flags)
 16418                              <1> 	;xor	ah, ah	
 16419                              <1>         ;	; bic $!377,r1 / clear upper byte
 16420                              <1> 	; 27/03/2021
 16421                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
 16422                              <1> 	; clear bits 15,14,13,12,9 of mode (input from user)
 16423 0000418C 80E40D              <1> 	and	ah, 0Dh ; ISUID (800h) & ISGID (400h) & IREAD (100h)
 16424 0000418F 80CC8D              <1> 	or	ah, 8Dh	; IFREG (8000h) ; Regular file
 16425 00004192 E8FE0C0000          <1> 	call 	maknod
 16426                              <1>         	; jsr r0,maknod / make an i-node for this file
 16427                              <1> 	;sub	eax, eax ; 04/12/2021
 16428 00004197 66A1[F0700000]      <1> 	mov	ax, [u.dirbuf]
 16429                              <1>         	; mov u.dirbuf,r1 / put i-number 
 16430                              <1> 			        ; / for this new file in r1
 16431                              <1> 	; 04/04/2021
 16432                              <1> 	;mov	dl, 1 ; open for writing
 16433                              <1>         ;
 16434                              <1> 	;jmp	sysopen_1
 16435                              <1>         ;	; br op0 / open the file
 16436                              <1> 	; 04/04/2021
 16437 0000419D EBE5                <1> 	jmp	short syscreat_2
 16438                              <1> 
 16439                              <1> 	; 04/12/2021
 16440                              <1> dir_access_err:
 16441                              <1> 	; 14/05/2015
 16442                              <1> 	;mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 16443                              <1> f_create_error:
 16444                              <1> 	; 27/03/2021
 16445 0000419F C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; permission denided !	
 16446 000041A7 0000                <1>
 16447 000041A9 E928FBFFFF          <1> 	jmp	error
 16448                              <1> 
 16449                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16450                              <1> sysmkdir: ; < make directory >
 16451                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16452                              <1> 	; 02/04/2021
 16453                              <1> 	; 27/03/2021 (Retro UNIX 386 v2 - Beginning)
 16454                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16455                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16456                              <1> 	;
 16457                              <1> 	; 'sysmkdir' creates an empty directory whose name is
 16458                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
 16459                              <1> 	; The special entries '.' and '..' are not present.
 16460                              <1> 	; Errors are indicated if the directory already exists or		
 16461                              <1> 	; user is not the super user. 
 16462                              <1> 	;
 16463                              <1> 	; Calling sequence:
 16464                              <1> 	;	sysmkdir; name; mode
 16465                              <1> 	; Arguments:
 16466                              <1> 	;	name - points to the name of the directory
 16467                              <1> 	;	mode - mode of the directory
 16468                              <1> 	; Inputs: (arguments)
 16469                              <1> 	; Outputs: -
 16470                              <1> 	;    (sets 'directory' flag to 1; 
 16471                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
 16472                              <1> 	; ...............................................................
 16473                              <1> 	;				
 16474                              <1> 	; Retro UNIX 8086 v1 modification: 
 16475                              <1> 	;       'sysmkdir' system call has two arguments; so,
 16476                              <1> 	;	* 1st argument, name is pointed to by BX register
 16477                              <1> 	;	* 2nd argument, mode is in CX register
 16478                              <1> 	;
 16479                              <1> 		
 16480                              <1> ; / make a directory
 16481                              <1> 
 16482                              <1> 	;call	arg2
 16483                              <1> 	; * name - 'u.namep' points to address of file/path name
 16484                              <1> 	;          in the user's program segment ('u.segmnt')
 16485                              <1> 	;          with offset in BX register (as sysopen argument 1).
 16486                              <1> 	; * mode - sysopen argument 2 is in CX register 
 16487                              <1> 	;          which is on top of stack.
 16488                              <1> 
 16489                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
 16490                              <1> 			    ; / on stack
 16491 000041AE 891D[D0700000]      <1> 	mov	[u.namep], ebx
 16492                              <1> 	;push	cx ; mode
 16493                              <1> 	; 27/03/2021
 16494 000041B4 51                  <1> 	push	ecx ; cx = mode
 16495 000041B5 E8E5090000          <1> 	call	namei
 16496                              <1>         	; jsr r0,namei / get the i-number
 16497                              <1>         	;     br .+4 / if file not found branch around error
 16498                              <1>         ;xor 	ax, ax
 16499                              <1> 	;jnz	error
 16500 000041BA 7312                <1> 	jnc	short dir_exists ; 14/05/2015
 16501                              <1> 	;jnc	error	
 16502                              <1> 		; br  error2 / directory already exists (error)
 16503                              <1> 
 16504                              <1> 	;cmp	byte [u.uid], 0 ; 02/08/2013
 16505                              <1>         ;	;tstb u.uid / is user the super user
 16506                              <1> 	;jna	short dir_access_err ; 14/05/2015
 16507                              <1> 	;;jna	error
 16508                              <1>         ;	;bne error2 / no, not allowed
 16509                              <1> 	;pop	ax
 16510                              <1>         ;	;mov (sp)+,r1 / put the mode in r1
 16511                              <1> 	;and	ax, 0FFCFh ; 1111111111001111b
 16512                              <1>         ;	;bic $!317,r1 / all but su and ex
 16513                              <1> 	;;or	ax, 4000h ; 1011111111111111b
 16514                              <1> 	;or	ah, 40h ; Set bit 14 to 1
 16515                              <1>         ; 	;bis $40000,r1 / directory flag
 16516                              <1> 
 16517                              <1> 	; 02/04/2021
 16518                              <1> 	;cmp	word [u.uid], 0
 16519                              <1> 	;ja	error
 16520                              <1> 
 16521                              <1> 	; 02/04/2021
 16522                              <1> 	; ('mkdir' procedure will be called from 'maknod'
 16523                              <1> 	; and then 'mkdir' will check write access permission) 
 16524                              <1> 	; ((so, 'access_w' call is not needed here.))
 16525                              <1> 
 16526                              <1> 	;; 02/04/2021
 16527                              <1> 	;; ('make directory' user permission check)
 16528                              <1> 	;; ((current directory's write permission flags
 16529                              <1> 	;;  will be checked against user's 'uid' & gid'))
 16530                              <1> 	;mov	dx, 80h ; IWRITE
 16531                              <1> 	;call	access_w  ; (in 'access', 'u5.s')
 16532                              <1> 	;; (If cpu will return here, the user has write permission)
 16533                              <1> 		
 16534                              <1> 	; 27/03/2021
 16535 000041BC 58                  <1> 	pop	eax  ; ax = mode
 16536                              <1> 	; [ii] = current directory's inode number
 16537                              <1> 
 16538                              <1> 	; 27/03/2021
 16539                              <1> 	;(ref: Retro UNIX 386 v2 inode flags,'ux.s')
 16540                              <1> 	; clear bits 13,12,11,10,9,6,3,0 of mode (input from user)
 16541                              <1> 	;and	ax, 0C1B6h  ; bits 15,14,8,7,5,4,2,1
 16542 000041BD 6625B601            <1> 	and	ax, 01B6h
 16543 000041C1 80CCC0              <1> 	or	ah, 0C0h ; IFREG (8000h) + IFDIR (4000h) 
 16544                              <1> 			 ; Directory
 16545 000041C4 E8CC0C0000          <1> 	call	maknod
 16546                              <1>         	;jsr r0,maknod / make the i-node for the directory
 16547 000041C9 E928FBFFFF          <1> 	jmp	sysret
 16548                              <1>         	;br sysret2 /
 16549                              <1> dir_exists:
 16550                              <1> 	; 27/03/2021
 16551                              <1> 	; (same error number for files and directories)
 16552                              <1> 	; Error Number: 14 (ERR_DIR_EXISTS)
 16553 000041CE C705[2C710000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS
 16554 000041D6 0000                <1>
 16555                              <1> 				; 'file already exists !' error
 16556                              <1> 	; 04/12/2021
 16557 000041D8 E9F9FAFFFF          <1> 	jmp	error
 16558                              <1> ;dir_access_err:
 16559                              <1> ;	; 14/05/2015
 16560                              <1> ;	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
 16561                              <1> ;	jmp	error
 16562                              <1> 
 16563                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16564                              <1> sysclose: ;<close file>
 16565                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16566                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16567                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
 16568                              <1> 	;
 16569                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
 16570                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
 16571                              <1> 	; is put in r1 and 'fclose' is called.
 16572                              <1> 	;
 16573                              <1> 	; Calling sequence:
 16574                              <1> 	;	sysclose
 16575                              <1> 	; Arguments:
 16576                              <1> 	;	-  
 16577                              <1> 	; Inputs: *u.r0 - file descriptor
 16578                              <1> 	; Outputs: -
 16579                              <1> 	; ...............................................................
 16580                              <1> 	;				
 16581                              <1> 	; Retro UNIX 8086 v1 modification:
 16582                              <1> 	;	 The user/application program puts file descriptor
 16583                              <1> 	;        in BX register as 'sysclose' system call argument.
 16584                              <1> 	; 	 (argument transfer method 1)
 16585                              <1> 
 16586                              <1> 	; / close the file
 16587                              <1> 	
 16588                              <1> 	;mov 	eax, ebx
 16589                              <1> 	; 04/12/2021
 16590                              <1> 	; ebx = file descriptor/number
 16591 000041DD E83D090000          <1> 	call 	fclose
 16592                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
 16593                              <1> 		; jsr r0,fclose / close the file
 16594                              <1>                	; br error2 / unknown file descriptor
 16595                              <1> 		; br sysret2
 16596                              <1> 	;; 14/05/2015
 16597                              <1> 	;jnc	sysret
 16598                              <1> 	; 04/12/2021
 16599 000041E2 7205                <1> 	jc	short sysclose_1
 16600 000041E4 E90DFBFFFF          <1> 	jmp	sysret
 16601                              <1> sysclose_1:
 16602 000041E9 C705[2C710000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
 16603 000041F1 0000                <1>
 16604 000041F3 E9DEFAFFFF          <1> 	jmp	error
 16605                              <1> 
 16606                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16607                              <1> sysemt:
 16608                              <1> 	; 04/12/2021 (Retro UNIX 286 v1.2)
 16609                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16610                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
 16611                              <1> 	;
 16612                              <1> 	; Retro UNIX 8086 v1 modification: 
 16613                              <1> 	;	'Enable Multi Tasking'  system call instead 
 16614                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
 16615                              <1> 	;
 16616                              <1> 	; Retro UNIX 8086 v1 feature only!
 16617                              <1> 	;	Using purpose: Kernel will start without time-out
 16618                              <1> 	;	(internal clock/timer) functionality.
 16619                              <1> 	;	Then etc/init will enable clock/timer for
 16620                              <1> 	;	multi tasking. (Then it will not be disabled again
 16621                              <1> 	;	except hardware reset/restart.)
 16622                              <1> 	;
 16623                              <1> 	
 16624                              <1> 	;cmp	byte [u.uid], 0 ; root ?
 16625                              <1> 	;;ja	error
 16626                              <1> 	;ja	badsys ; 14/05/2015
 16627                              <1> 	; 04/12/2021
 16628 000041F8 66833D[0A710000]00  <1> 	cmp	word [u.uid], 0 ; root ?
 16629 00004200 7605                <1> 	jna	short emt_0 
 16630 00004202 E981FBFFFF          <1> 	jmp	badsys
 16631                              <1> emt_0:
 16632 00004207 FA                  <1> 	cli
 16633 00004208 21DB                <1> 	and	ebx, ebx
 16634 0000420A 7410                <1> 	jz	short emt_2
 16635                              <1> 	; Enable multi tasking -time sharing-
 16636 0000420C B8[49510000]        <1> 	mov	eax, clock
 16637                              <1> emt_1:
 16638 00004211 A3[11080000]        <1> 	mov	[x_timer], eax
 16639 00004216 FB                  <1> 	sti
 16640 00004217 E9DAFAFFFF          <1> 	jmp	sysret
 16641                              <1> emt_2:
 16642                              <1> 	; Disable multi tasking -time sharing-
 16643 0000421C B8[19080000]        <1> 	mov	eax, u_timer
 16644 00004221 EBEE                <1> 	jmp	short emt_1
 16645                              <1> 
 16646                              <1> 	; Original UNIX v1 'sysemt' routine
 16647                              <1> ;sysemt:
 16648                              <1>         ;
 16649                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
 16650                              <1> 			 ; / in loc 30
 16651                              <1>         ;cmp    30,$core / was the argument a lower address 
 16652                              <1> 			; / than core
 16653                              <1>         ;blo    1f / yes, rtssym
 16654                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
 16655                              <1> 			; / and less than "ecore"
 16656                              <1>         ;blo    2f / yes, sysret2
 16657                              <1> ;1:
 16658                              <1>         ;mov    $rtssym,30
 16659                              <1> ;2:
 16660                              <1>         ;br     sysret2
 16661                              <1> 
 16662                              <1> sysilgins:
 16663                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 16664                              <1> 	; 03/06/2013
 16665                              <1> 	; Retro UNIX 8086 v1 modification: 
 16666                              <1> 	;	not a valid system call ! (not in use)
 16667                              <1> 	;
 16668 00004223 E960FBFFFF          <1> 	jmp	badsys
 16669                              <1> 	;jmp	error
 16670                              <1> 	;;jmp 	sysret
 16671                              <1> 
 16672                              <1> 	; Original UNIX v1 'sysemt' routine
 16673                              <1> ;sysilgins: / calculate proper illegal instruction trap address
 16674                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
 16675                              <1> 			  ;/ put it in loc 8.,
 16676                              <1>         ;cmp    10,$core / making it the illegal instruction 
 16677                              <1> 		       ; / trap address
 16678                              <1>         ;blo    1f / is the address a user core address?  
 16679                              <1> 		; / yes, go to 2f
 16680                              <1>         ;cmp    10,$ecore
 16681                              <1>         ;blo    2f
 16682                              <1> ;1:
 16683                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
 16684                              <1> 		    ; / instruction trap address for the system
 16685                              <1> ;2:
 16686                              <1>         ;br     sysret2 / return to the caller via 'sysret'
 16687                              <1> 
 16688                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 16689                              <1> sysmdate: ; < change the modification time of a file >
 16690                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 16691                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 16692                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 16693                              <1> 	;
 16694                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
 16695                              <1> 	; file into core. The user is checked if he is the owner 
 16696                              <1> 	; or super user. If he is neither an error occurs.
 16697                              <1> 	; 'setimod' is then called to set the i-node modification
 16698                              <1> 	; byte and the modification time, but the modification time
 16699                              <1> 	; is overwritten by whatever get put on the stack during
 16700                              <1> 	; a 'systime' system call. This calls are restricted to
 16701                              <1> 	; the super user.		
 16702                              <1> 	;
 16703                              <1> 	; Calling sequence:
 16704                              <1> 	;	sysmdate; name
 16705                              <1> 	; Arguments:
 16706                              <1> 	;	name - points to the name of file
 16707                              <1> 	; Inputs: (arguments)
 16708                              <1> 	; Outputs: -
 16709                              <1> 	; ...............................................................
 16710                              <1> 	;				
 16711                              <1> 	; Retro UNIX 8086 v1 modification: 
 16712                              <1> 	;	 The user/application program puts address 
 16713                              <1> 	;	 of the file name in BX register 
 16714                              <1> 	;	 as 'sysmdate' system call argument.
 16715                              <1> 	;
 16716                              <1> ; / change the modification time of a file
 16717                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
 16718 00004228 891D[D0700000]      <1>         mov	[u.namep], ebx
 16719 0000422E E86C090000          <1> 	call	namei
 16720                              <1> 		; jsr r0,namei / get its i-number
 16721 00004233 0F82BEFEFFFF        <1>         jc	fnotfound ; file not found !
 16722                              <1> 	;jc	error       
 16723                              <1> 		; br error2 / no, such file
 16724 00004239 E82D130000          <1> 	call	iget
 16725                              <1> 		; jsr r0,iget / get i-node into core
 16726                              <1> 	;mov	al, [u.uid]
 16727                              <1> 	;cmp	al, [i.uid]
 16728                              <1>         ;	; cmpb u.uid,i.uid / is user same as owner
 16729                              <1> 	;je	short mdate_1
 16730                              <1>         ;	; beq 1f / yes
 16731                              <1> 	;and	al, al
 16732                              <1> 	;	; tstb u.uid / no, is user the super user
 16733                              <1> 	;;jnz	error
 16734                              <1> 	;	; bne error2 / no, error
 16735                              <1> 	;jz	short mdate_1
 16736                              <1> 	; 04/12/2021
 16737 0000423E 66A1[0A710000]      <1> 	mov	ax, [u.uid]
 16738 00004244 663B05[546D0000]    <1> 	cmp	ax, [i.uid]
 16739 0000424B 7414                <1> 	je	short mdate_1	
 16740 0000424D 6621C0              <1> 	and	ax, ax
 16741 00004250 740F                <1> 	jz	short mdate_1
 16742                              <1> 
 16743 00004252 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 16744 0000425A 0000                <1>
 16745 0000425C E975FAFFFF          <1> 	jmp	error
 16746                              <1> mdate_1: ;1:
 16747 00004261 E898140000          <1> 	call	setimod
 16748                              <1>         	; jsr r0,setimod / fill in modification data,
 16749                              <1> 		               ; / time etc.
 16750 00004266 BE[00700000]        <1> 	mov	esi, p_time
 16751 0000426B BF[886D0000]        <1> 	mov	edi, i.mtim
 16752 00004270 A5                  <1> 	movsd
 16753                              <1> 		; mov 4(sp),i.mtim / move present time to
 16754                              <1>         	; mov 2(sp),i.mtim+2 / modification time
 16755 00004271 E980FAFFFF          <1>         jmp	sysret
 16756                              <1> 		; br sysret2
 16757                              <1> 
 16758                              <1> sysstty: ; < set tty status and mode >
 16759                              <1> 	; 17/11/2015
 16760                              <1> 	; 12/11/2015
 16761                              <1> 	; 29/10/2015
 16762                              <1> 	; 17/10/2015
 16763                              <1> 	; 13/10/2015
 16764                              <1> 	; 29/06/2015
 16765                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
 16766                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 16767                              <1> 	;
 16768                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
 16769                              <1> 	; whose file descriptor is in (u.r0).
 16770                              <1> 	;
 16771                              <1> 	; Calling sequence:
 16772                              <1> 	;	sysstty; arg
 16773                              <1> 	; Arguments:
 16774                              <1> 	;	arg - address of 3 consequitive words that contain
 16775                              <1> 	;	      the source of status data	
 16776                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
 16777                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 16778                              <1> 	; ...............................................................
 16779                              <1> 	;	
 16780                              <1> 	; Retro UNIX 8086 v1 modification: 
 16781                              <1> 	;	'sysstty' system call will set the tty
 16782                              <1> 	;	(clear keyboard buffer and set cursor position)
 16783                              <1> 	;	 in following manner:
 16784                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
 16785                              <1> 	;
 16786                              <1> 	; Inputs:
 16787                              <1> 	;	BX = 0 --> means
 16788                              <1> 	;	   If CL = FFh
 16789                              <1> 	;	      set cursor position for console tty, only 
 16790                              <1> 	;	      CH will be ignored (char. will not be written)	
 16791                              <1> 	;	   If CH = 0 (CL < FFh)
 16792                              <1> 	;	      set console tty for (current) process
 16793                              <1> 	;	      CL = tty number (0 to 9)
 16794                              <1> 	;	      (If CH = 0, character will not be written)			
 16795                              <1> 	;          If CH > 0 (CL < FFh)	
 16796                              <1> 	;             CL = tty number (0 to 9)
 16797                              <1> 	;	      CH = character will be written
 16798                              <1> 	;	        at requested cursor position (in DX)	
 16799                              <1> 	;	   DX = cursor position for tty number 0 to 7.	
 16800                              <1>   	;		(only tty number 0 to 7) 
 16801                              <1> 	;          DL = communication parameters (for serial ports) 
 16802                              <1> 	;	        (only for COM1 and COM2 serial ports)
 16803                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
 16804                              <1> 	;			or set cursor position	
 16805                              <1> 	;	   DH = 0FFh -> DL is not valid
 16806                              <1> 	;		do not set serial port parameters 
 16807                              <1> 	;		or do not set cursor position
 16808                              <1> 	;
 16809                              <1> 	;	BX > 0 --> points to name of tty
 16810                              <1> 	;    	   CH > 0 -->
 16811                              <1> 	;		CH = character will be written in current 
 16812                              <1> 	;            	cursor position (for tty number from 0 to 7)
 16813                              <1> 	;	     	or character will be sent to serial port
 16814                              <1> 	;	     	(for tty number 8 or 9)
 16815                              <1> 	;		CL = color of the character if tty number < 8.
 16816                              <1> 	;    	   CH = 0 --> Do not write a character, 
 16817                              <1> 	;		set mode (tty 8 to 9) or 
 16818                              <1> 	;		set current cursor positions (tty 0 to 7) only. 
 16819                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
 16820                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
 16821                              <1> 	;		(DL is not valid)
 16822                              <1> 	;	   DL = communication parameters 
 16823                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
 16824                              <1> 	; Outputs:
 16825                              <1> 	;	cf = 0 -> OK
 16826                              <1> 	;	     AL = tty number (0 to 9)
 16827                              <1> 	;	     AH = line status if tty number is 8 or 9
 16828                              <1> 	;	     AH = process number (of the caller) 	
 16829                              <1> 	;	cf = 1 means error (requested tty is not ready)
 16830                              <1> 	;	     AH = FFh if the tty is locked 
 16831                              <1> 	;		  (owned by another process)
 16832                              <1> 	;	        = process number (of the caller) 
 16833                              <1> 	;		  (if < FFh and tty number < 8)
 16834                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 16835                              <1> 	;	     AH = line status if tty number is 8 or 9
 16836                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
 16837                              <1> 	;
 16838                              <1> 	; 27/06/2015 (32 bit modifications)
 16839                              <1> 	; 14/01/2014
 16840 00004276 31C0                <1> 	xor 	eax, eax
 16841 00004278 6648                <1> 	dec	ax ; 17/10/2015
 16842 0000427A A3[B4700000]        <1> 	mov	[u.r0], eax ; 0FFFFh
 16843 0000427F 21DB                <1> 	and	ebx, ebx
 16844 00004281 0F85CB000000        <1>         jnz     sysstty_6
 16845                              <1> ; set console tty
 16846                              <1> 	; 29/10/2015
 16847                              <1> 	; 17/01/2014 
 16848 00004287 80F909              <1> 	cmp	cl, 9
 16849 0000428A 7613                <1> 	jna	short sysstty_0
 16850                              <1> 	; 17/11/2015
 16851 0000428C 80F9FF              <1> 	cmp	cl, 0FFh
 16852 0000428F 7202                <1> 	jb	short sysstty_13
 16853 00004291 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
 16854                              <1> sysstty_13:
 16855 00004293 8A1D[09710000]      <1> 	mov	bl, [u.uno] ; process number
 16856 00004299 8A8B[EF6D0000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
 16857                              <1> sysstty_0:
 16858                              <1> 	; 29/06/2015
 16859 0000429F 6652                <1> 	push	dx
 16860 000042A1 6651                <1> 	push	cx
 16861 000042A3 30D2                <1> 	xor 	dl, dl	; sysstty call sign
 16862 000042A5 88C8                <1> 	mov	al, cl
 16863 000042A7 A2[B4700000]        <1> 	mov	[u.r0], al ; tyy number (0 to 9)
 16864 000042AC E8B51B0000          <1> 	call	ottyp
 16865 000042B1 6659                <1> 	pop	cx
 16866 000042B3 665A                <1> 	pop	dx
 16867                              <1> 	;
 16868 000042B5 7257                <1> 	jc	short sysstty_pd_err
 16869                              <1> 	;
 16870 000042B7 80F908              <1> 	cmp	cl, 8
 16871 000042BA 7222                <1> 	jb	short sysstty_2
 16872                              <1> 	;
 16873 000042BC 80FEFF              <1> 	cmp	dh, 0FFh
 16874 000042BF 741D                <1> 	je	short sysstty_2
 16875                              <1> 		; set communication parameters for serial ports
 16876                              <1> 	; 29/10/2015
 16877 000042C1 88D4                <1> 	mov	ah, dl ; communication parameters
 16878                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
 16879                              <1> 		;			 THRE int + RDA int 
 16880                              <1> 		; ah = 23h = 00100011b = 9600 baud,
 16881                              <1> 		;			 THRE int + RDA int 
 16882 000042C3 28C0                <1> 	sub	al, al ; 0
 16883                              <1> 	; 12/07/2014
 16884 000042C5 80F909              <1> 	cmp	cl, 9
 16885 000042C8 7202                <1> 	jb	short sysstty_1
 16886 000042CA FEC0                <1> 	inc	al
 16887                              <1> sysstty_1:
 16888 000042CC 6651                <1> 	push	cx
 16889                              <1> 	; 29/06/2015	
 16890 000042CE E898F4FFFF          <1> 	call 	sp_setp ; Set serial port communication parameters
 16891 000042D3 66890D[B5700000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
 16892                              <1> 			     ; Modem status (EAX bits 16 to 23)
 16893 000042DA 6659                <1> 	pop	cx
 16894 000042DC 7265                <1>         jc      short sysstty_tmout_err ; 29/10/2015
 16895                              <1> sysstty_2:
 16896                              <1> 	; 17/01/2014
 16897 000042DE 20ED                <1> 	and	ch, ch 	; set cursor position 
 16898                              <1> 			; or comm. parameters ONLY
 16899 000042E0 750D                <1> 	jnz	short sysstty_3
 16900 000042E2 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16901 000042E9 888B[EF6D0000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
 16902                              <1> sysstty_3:
 16903                              <1> 	; 16/01/2014
 16904 000042EF 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
 16905                              <1> 	; 17/11/2015
 16906 000042F1 B507                <1> 	mov 	ch, 7  ; Default color (light gray)
 16907 000042F3 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
 16908 000042F5 0F86C5000000        <1>         jna     sysstty_9
 16909                              <1> sysstty_12:
 16910                              <1> 	;; BX = 0, CL = 8 or CL = 9
 16911                              <1> 	; (Set specified serial port as console tty port)
 16912                              <1> 	; CH = character to be written
 16913                              <1> 	; 15/04/2014
 16914                              <1> 	; CH = 0 --> initialization only
 16915                              <1> 	; AL = character
 16916                              <1> 	; 26/06/2014
 16917 000042FB 880D[ED700000]      <1> 	mov	[u.ttyn], cl
 16918                              <1> 	; 12/07/2014
 16919 00004301 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
 16920 00004303 20C0                <1> 	and	al, al
 16921 00004305 7416                <1> 	jz	short sysstty_4 ; al = ch = 0
 16922                              <1>  	; 04/07/2014
 16923 00004307 E8A0210000          <1> 	call 	sndc
 16924                              <1> 	; 12/07/2014
 16925 0000430C EB1B                <1> 	jmp	short sysstty_5
 16926                              <1> sysstty_pd_err: ; 29/06/2015
 16927                              <1> 	; 'permission denied !' error
 16928 0000430E C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
 16929 00004316 0000                <1>
 16930 00004318 E9B9F9FFFF          <1> 	jmp	error
 16931                              <1> sysstty_4:
 16932                              <1> 	; 12/07/2014
 16933                              <1> 	;xchg 	ah, al	; al = 0 -> al = ah, ah = 0
 16934 0000431D 88E0                <1> 	mov	al, ah ; 29/06/2015
 16935 0000431F 2C08                <1> 	sub	al, 8
 16936                              <1> 	; 27/06/2015
 16937 00004321 E83DF4FFFF          <1> 	call	sp_status ; get serial port status
 16938                              <1> 	; AL = Line status, AH = Modem status
 16939                              <1> 	; 12/11/2015
 16940 00004326 3C80                <1> 	cmp	al, 80h
 16941 00004328 F5                  <1> 	cmc
 16942                              <1> sysstty_5:
 16943 00004329 66A3[B5700000]      <1> 	mov	[u.r0+1], ax ; ah = line status
 16944                              <1> 		     ; EAX bits 16-23 = modem status	
 16945 0000432F 9C                  <1> 	pushf
 16946 00004330 30D2                <1> 	xor	dl, dl ; sysstty call sign
 16947 00004332 A0[ED700000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
 16948 00004337 E84B1C0000          <1> 	call	cttyp
 16949 0000433C 9D                  <1> 	popf
 16950 0000433D 0F83B3F9FFFF        <1> 	jnc	sysret	; time out error 
 16951                              <1> 
 16952                              <1> sysstty_tmout_err:
 16953 00004343 C705[2C710000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
 16954 0000434B 0000                <1>
 16955 0000434D E984F9FFFF          <1> 	jmp	error
 16956                              <1> sysstty_6:
 16957 00004352 6652                <1> 	push	dx
 16958 00004354 6651                <1> 	push	cx
 16959 00004356 891D[D0700000]      <1> 	mov	[u.namep], ebx
 16960 0000435C E83E080000          <1> 	call	namei
 16961 00004361 6659                <1> 	pop	cx
 16962 00004363 665A                <1> 	pop	dx
 16963 00004365 720E                <1> 	jc	short sysstty_inv_dn
 16964                              <1> 	;
 16965 00004367 6683F813            <1> 	cmp	ax, 19  ; inode number of /dev/COM2
 16966 0000436B 7708                <1> 	ja	short sysstty_inv_dn ; 27/06/2015
 16967                              <1> 	;
 16968 0000436D 3C0A                <1> 	cmp	al, 10 ; /dev/tty0 .. /dev/tty7
 16969                              <1> 		       ; /dev/COM1, /dev/COM2
 16970 0000436F 7213                <1> 	jb	short sysstty_7
 16971 00004371 2C0A                <1> 	sub	al, 10
 16972 00004373 EB20                <1> 	jmp	short sysstty_8
 16973                              <1> sysstty_inv_dn: 
 16974                              <1> 	; 27/06/2015
 16975                              <1> 	; Invalid device name (not a tty) ! error
 16976                              <1> 	; (Device is not a tty or device name not found)
 16977 00004375 C705[2C710000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 16978 0000437D 0000                <1>
 16979 0000437F E952F9FFFF          <1> 	jmp	error 
 16980                              <1> sysstty_7:
 16981 00004384 3C01                <1> 	cmp	al, 1 ; /dev/tty
 16982 00004386 75ED                <1> 	jne	short sysstty_inv_dn ; 27/06/2015
 16983 00004388 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 16984 0000438F 8A83[EF6D0000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
 16985                              <1> sysstty_8:	
 16986 00004395 A2[B4700000]        <1> 	mov	[u.r0], al
 16987 0000439A 6652                <1> 	push	dx
 16988 0000439C 6650                <1> 	push	ax
 16989 0000439E 6651                <1> 	push	cx	
 16990 000043A0 E8C11A0000          <1> 	call	ottyp
 16991 000043A5 6659                <1> 	pop	cx
 16992 000043A7 6658                <1> 	pop	ax
 16993 000043A9 665A                <1> 	pop	dx
 16994 000043AB 0F825DFFFFFF        <1>         jc      sysstty_pd_err ; 'permission denied !'
 16995                              <1> 	; 29/10/2015
 16996 000043B1 86E9                <1> 	xchg 	ch, cl
 16997                              <1> 		; cl = character, ch = color code
 16998 000043B3 86C1                <1> 	xchg	al, cl
 16999                              <1> 		; al = character, cl = tty number
 17000 000043B5 80F907              <1> 	cmp	cl, 7
 17001 000043B8 0F873DFFFFFF        <1>         ja      sysstty_12
 17002                              <1> 	;
 17003                              <1> 	; 16/01/2014
 17004 000043BE 30FF                <1> 	xor	bh, bh
 17005                              <1> 	;
 17006                              <1> sysstty_9: 	; tty 0 to tty 7
 17007                              <1> 	; al = character
 17008 000043C0 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
 17009 000043C3 740F                <1> 	je	short sysstty_10
 17010 000043C5 6651                <1> 	push	cx
 17011 000043C7 6650                <1> 	push	ax	
 17012                              <1> 	; movzx, ebx, cl
 17013 000043C9 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
 17014 000043CB E812D2FFFF          <1> 	call	set_cpos
 17015 000043D0 6658                <1> 	pop	ax
 17016 000043D2 6659                <1> 	pop	cx
 17017                              <1> sysstty_10: 
 17018                              <1> 	; 29/10/2015
 17019 000043D4 08C0                <1> 	or	al, al ; character
 17020 000043D6 740F                <1> 	jz      short sysstty_11 ; al = 0
 17021                              <1> 	; 17/11/2015
 17022 000043D8 3CFF                <1> 	cmp	al, 0FFh
 17023 000043DA 730B                <1> 	jnb	short sysstty_11
 17024                              <1> 		; ch > 0 and ch < FFh
 17025                              <1> 	; write a character at current cursor position
 17026 000043DC 88EC                <1> 	mov	ah, ch ; color/attribute
 17027                              <1> 	; 12/07/2014
 17028 000043DE 6651                <1> 	push	cx
 17029 000043E0 E83BD3FFFF          <1> 	call	write_c_current
 17030 000043E5 6659                <1> 	pop	cx
 17031                              <1> sysstty_11:
 17032                              <1> 	; 14/01/2014
 17033 000043E7 30D2                <1> 	xor	dl, dl ; sysstty call sign
 17034                              <1> 	; 18/01/2014
 17035                              <1> 	;movzx	eax, cl ; 27/06/2015
 17036 000043E9 88C8                <1> 	mov	al, cl
 17037 000043EB E8971B0000          <1> 	call	cttyp
 17038 000043F0 E901F9FFFF          <1> 	jmp	sysret
 17039                              <1> 
 17040                              <1> ; Original UNIX v1 'sysstty' routine:
 17041                              <1> ; gtty:
 17042                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
 17043                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
 17044                              <1> 	; 		/ r2 has source
 17045                              <1>         ;mov    r2,-(sp)
 17046                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
 17047                              <1> ;1: / flush the clist wait till typewriter is quiescent
 17048                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
 17049                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
 17050                              <1>         ;mov    $240,*$ps / set processor priority to 5
 17051                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
 17052                              <1>         ;       br .+4 / list empty, skip branch
 17053                              <1>         ;br     1b / get another character until list is empty
 17054                              <1>         ;mov    0b,r1 / move cc offset to r1
 17055                              <1>         ;inc    r1 / bump it for output clist
 17056                              <1>         ;tstb   cc(r1) / is it 0
 17057                              <1>         ;beq    1f / yes, no characters to output
 17058                              <1>  	;mov    r1,0f / no, put offset in sleep arg
 17059                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
 17060                              <1>         ;br     1b / try to calm it down again
 17061                              <1> ;1:
 17062                              <1>         ;mov    (sp)+,r1
 17063                              <1>         ;mov    (sp)+,r2 / restore registers
 17064                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
 17065                              <1>         ;beq    1f / if 0, 1f
 17066                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
 17067                              <1>         ;                   / control status register
 17068                              <1> ;1:
 17069                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
 17070                              <1>         ;beq    1f / if 0 1f
 17071                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
 17072                              <1> 	;		    / control status reg
 17073                              <1> ;1:
 17074                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
 17075                              <1>         ;jmp     sysret2 / return to user
 17076                              <1> 
 17077                              <1> sysgtty: ; < get tty status >
 17078                              <1> 	; 23/11/2015
 17079                              <1> 	; 29/10/2015
 17080                              <1> 	; 17/10/2015
 17081                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
 17082                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
 17083                              <1> 	;
 17084                              <1> 	; 'sysgtty' gets the status of tty in question. 
 17085                              <1> 	; It stores in the three words addressed by it's argument
 17086                              <1> 	; the status of the typewriter whose file descriptor
 17087                              <1> 	; in (u.r0).
 17088                              <1> 	;
 17089                              <1> 	; Calling sequence:
 17090                              <1> 	;	sysgtty; arg
 17091                              <1> 	; Arguments:
 17092                              <1> 	;	arg - address of 3 words destination of the status
 17093                              <1> 	; Inputs: ((*u.r0 - file descriptor))
 17094                              <1> 	; Outputs: ((status in address which is pointed to by arg))
 17095                              <1> 	; ...............................................................
 17096                              <1> 	;	
 17097                              <1> 	; Retro UNIX 8086 v1 modification: 
 17098                              <1> 	;	'sysgtty' system call will return status of tty
 17099                              <1> 	;	(keyboard, serial port and video page status)
 17100                              <1> 	;	 in following manner:
 17101                              <1> 	;
 17102                              <1> 	; Inputs:
 17103                              <1> 	;	BX = 0 --> means 
 17104                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
 17105                              <1> 	;	                 for (current) process
 17106                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
 17107                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
 17108                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
 17109                              <1> 	;	     CH > 0 -->	tty number + 1
 17110                              <1> 	;
 17111                              <1> 	;	BX > 0 --> points to name of tty
 17112                              <1> 	;	     CL = 0 --> return keyboard status
 17113                              <1> 	;	     CL = 1 --> return video page status
 17114                              <1> 	;	     CH = undefined		 
 17115                              <1> 	;
 17116                              <1> 	; Outputs:
 17117                              <1> 	;	cf = 0 ->
 17118                              <1> 	;
 17119                              <1> 	;	     AL = tty number from 0 to 9
 17120                              <1> 	;		  (0 to 7 is also the video page of the tty)	
 17121                              <1> 	;	     AH = 0 if the tty is free/unused
 17122                              <1> 	;	     AH = the process number of the caller 
 17123                              <1>  	;	     AH = FFh if the tty is locked by another process
 17124                              <1> 	;
 17125                              <1> 	;	  (if calling is for serial port status)
 17126                              <1> 	;	     BX = serial port status if tty number is 8 or 9
 17127                              <1> 	;		  (BH = modem status, BL = Line status)
 17128                              <1> 	;	     CX = 0FFFFh (if data is ready)
 17129                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
 17130                              <1> 	;
 17131                              <1> 	;	  (if calling is for keyboard status)
 17132                              <1> 	;	     BX = current character in tty/keyboard buffer
 17133                              <1> 	;		  (BH = scan code, BL = ascii code)
 17134                              <1> 	;		  (BX=0 if there is not a waiting character)
 17135                              <1> 	;	     CX  is undefined
 17136                              <1> 	;
 17137                              <1> 	;	  (if calling is for video page status)	
 17138                              <1> 	;	     BX = cursor position on the video page
 17139                              <1> 	;		  if tty number < 8
 17140                              <1> 	;		  (BH = row, BL = column)
 17141                              <1> 	;	     CX = current character (in cursor position)
 17142                              <1> 	;		  on the video page of the tty 
 17143                              <1> 	;		  if tty number < 8
 17144                              <1> 	;		  (CH = color, CL = character)
 17145                              <1> 	;	
 17146                              <1> 	;	cf = 1 means error (requested tty is not ready)
 17147                              <1> 	;
 17148                              <1> 	;	     AH = FFh if the caller is not owner of
 17149                              <1> 	;		  specified tty or console tty
 17150                              <1> 	;	     AL = tty number (0FFh if it does not exist)
 17151                              <1> 	;	     BX, CX are undefined if cf = 1
 17152                              <1> 	;
 17153                              <1> 	;	  (If tty number is 8 or 9)
 17154                              <1> 	;	     AL = tty number 
 17155                              <1> 	;	     AH = the process number of the caller 
 17156                              <1> 	;	     BX = serial port status
 17157                              <1> 	;  		 (BH = modem status, BL = Line status)
 17158                              <1> 	;	     CX = 0
 17159                              <1> 	;
 17160                              <1> 		
 17161                              <1> gtty:   ; get (requested) tty number
 17162                              <1> 	; 17/10/2015
 17163                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 17164                              <1> 	; 30/05/2013 - 12/07/2014
 17165                              <1> 	; Retro UNIX 8086 v1 modification ! 
 17166                              <1> 	;
 17167                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
 17168                              <1> 	;
 17169                              <1> 	; 28/06/2015 (32 bit modifications)
 17170                              <1> 	; 16/01/2014
 17171 000043F5 31C0                <1> 	xor 	eax, eax
 17172 000043F7 6648                <1> 	dec	ax ; 17/10/2015
 17173 000043F9 A3[B4700000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
 17174 000043FE 80F901              <1> 	cmp	cl, 1
 17175 00004401 760F                <1> 	jna	short sysgtty_0
 17176                              <1> sysgtty_invp:
 17177                              <1> 	; 28/06/2015
 17178 00004403 C705[2C710000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
 17179 0000440B 0000                <1>
 17180 0000440D E9C4F8FFFF          <1> 	jmp	error
 17181                              <1> sysgtty_0:	
 17182 00004412 21DB                <1> 	and	ebx, ebx
 17183 00004414 7430                <1> 	jz	short sysgtty_1
 17184                              <1> 	;
 17185 00004416 891D[D0700000]      <1> 	mov	[u.namep], ebx
 17186 0000441C 6651                <1> 	push	cx ; 23/11/2015
 17187 0000441E E87C070000          <1> 	call	namei
 17188 00004423 6659                <1> 	pop	cx ; 23/11/2015
 17189 00004425 7210                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
 17190                              <1> 	;
 17191 00004427 6683F801            <1> 	cmp	ax, 1
 17192 0000442B 7622                <1> 	jna	short sysgtty_2
 17193 0000442D 6683E80A            <1> 	sub	ax, 10
 17194 00004431 6683F809            <1> 	cmp	ax, 9
 17195                              <1> 	;ja	short sysgtty_inv_dn
 17196                              <1> 	;mov	ch, al
 17197                              <1> 	;jmp	short sysgtty_4
 17198                              <1> 	; 23/11/2015
 17199 00004435 7629                <1> 	jna	short sysgtty_4
 17200                              <1> sysgtty_inv_dn: 
 17201                              <1> 	; 28/06/2015
 17202                              <1> 	; Invalid device name (not a tty) ! error
 17203                              <1> 	; (Device is not a tty or device name not found)
 17204 00004437 C705[2C710000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
 17205 0000443F 0000                <1>
 17206 00004441 E990F8FFFF          <1> 	jmp	error 
 17207                              <1> sysgtty_1:
 17208                              <1> 	; 16/01/2014
 17209 00004446 80FD0A              <1> 	cmp	ch, 10
 17210 00004449 77B8                <1> 	ja	short sysgtty_invp ; 28/06/2015
 17211 0000444B FECD                <1> 	dec	ch ; 0 -> FFh (negative)
 17212 0000444D 790F                <1> 	jns	short sysgtty_3 ; not negative
 17213                              <1> 	;
 17214                              <1> sysgtty_2:
 17215                              <1> 	; get tty number of console tty
 17216 0000444F 8A25[09710000]      <1> 	mov	ah, [u.uno]
 17217                              <1>  	; 28/06/2015
 17218 00004455 0FB6DC              <1> 	movzx 	ebx, ah
 17219 00004458 8AAB[EF6D0000]      <1> 	mov	ch, [ebx+p.ttyc-1]
 17220                              <1> sysgtty_3:
 17221 0000445E 88E8                <1> 	mov	al, ch
 17222                              <1> sysgtty_4:
 17223 00004460 A2[B4700000]        <1> 	mov	[u.r0], al
 17224                              <1>  	; 28/06/2015
 17225                              <1> 	;cmp	al, 9
 17226                              <1> 	;ja	short sysgtty_invp
 17227 00004465 8B2D[B0700000]      <1> 	mov	ebp, [u.usp]
 17228                              <1> 	; 23/11/2015
 17229 0000446B 20C9                <1> 	and	cl, cl
 17230 0000446D 7436                <1> 	jz	short sysgtty_6 ; keyboard status
 17231 0000446F 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
 17232 00004471 7232                <1> 	jb	short sysgtty_6 ; video page status
 17233                              <1> 	; serial port status
 17234                              <1> 	; 12/07/2014
 17235                              <1> 	;mov	dx, 0
 17236                              <1> 	;je	short sysgtty_5
 17237                              <1> 	;inc	dl
 17238                              <1> ;sysgtty_5:
 17239                              <1> 	; 28/06/2015
 17240 00004473 2C08                <1> 	sub	al, 8
 17241 00004475 E8E9F2FFFF          <1> 	call	sp_status ; serial (COM) port (line) status
 17242                              <1> 	; AL = Line status, AH = Modem status
 17243 0000447A 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
 17244 0000447E 8A25[09710000]      <1> 	mov	ah, [u.uno]
 17245 00004484 8825[B5700000]      <1>         mov     [u.r0+1], ah
 17246 0000448A 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)	
 17247                              <1> 				; (in ECX)
 17248 00004490 A880                <1> 	test	al, 80h
 17249 00004492 7565                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
 17250 00004494 A801                <1> 	test	al, 1
 17251 00004496 0F845AF8FFFF        <1> 	jz	sysret
 17252 0000449C 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)	
 17253 000044A0 E951F8FFFF          <1> 	jmp	sysret
 17254                              <1> sysgtty_6:
 17255 000044A5 A2[ED700000]        <1> 	mov	[u.ttyn], al ; tty number
 17256                              <1> 	;movzx	ebx, al
 17257 000044AA 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
 17258 000044AC D0E3                <1> 	shl 	bl, 1  ; aligned to word
 17259                              <1> 	; 22/04/2014 - 29/06/2015
 17260 000044AE 81C3[04700000]      <1>         add     ebx, ttyl
 17261 000044B4 8A23                <1>  	mov	ah, [ebx]
 17262 000044B6 3A25[09710000]      <1> 	cmp	ah, [u.uno]
 17263 000044BC 7404                <1> 	je	short sysgtty_7
 17264 000044BE 20E4                <1> 	and	ah, ah
 17265                              <1> 	;jz	short sysgtty_7
 17266 000044C0 7506                <1> 	jnz	short sysgtty_8
 17267                              <1> 	;mov	ah, 0FFh
 17268                              <1> sysgtty_7:
 17269 000044C2 8825[B5700000]      <1>         mov     [u.r0+1], ah
 17270                              <1> sysgtty_8:
 17271 000044C8 08C9                <1> 	or	cl, cl
 17272 000044CA 7510                <1> 	jnz	short sysgtty_9
 17273 000044CC B001                <1> 	mov	al, 1  ; test a key is available
 17274 000044CE E85C1F0000          <1> 	call	getc
 17275 000044D3 66894510            <1> 	mov	[ebp+16], ax ; bx, character
 17276 000044D7 E91AF8FFFF          <1> 	jmp	sysret
 17277                              <1> sysgtty_9:
 17278 000044DC 8A1D[ED700000]      <1> 	mov	bl, [u.ttyn]
 17279                              <1> 	; bl = video page number
 17280 000044E2 E8C4200000          <1> 	call 	get_cpos
 17281                              <1> 	; dx = cursor position
 17282 000044E7 66895510            <1> 	mov	[ebp+16], dx ; bx
 17283                              <1> 	;mov	bl, [u.ttyn]
 17284                              <1> 	; bl = video page number
 17285 000044EB E8CC200000          <1> 	call	read_ac_current
 17286                              <1> 	; ax = character and attribute/color
 17287 000044F0 66894518            <1> 	mov	[ebp+24], ax ; cx
 17288 000044F4 E9FDF7FFFF          <1> 	jmp	sysret
 17289                              <1> sysgtty_dnr_err:
 17290                              <1> 	; 'device not responding !' error	
 17291                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
 17292 000044F9 C705[2C710000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ;  25				
 17293 00004501 0000                <1>
 17294 00004503 E9CEF7FFFF          <1> 	jmp	error	
 17295                              <1> 
 17296                              <1> ; Original UNIX v1 'sysgtty' routine:
 17297                              <1> ; sysgtty:
 17298                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
 17299                              <1> 	;	       / r2 has destination
 17300                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
 17301                              <1> 	;                     / in 1st word of dest
 17302                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
 17303                              <1> 	;                     / in 2nd word of dest
 17304                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
 17305                              <1>         ;jmp    sysret2 / return to user
 17306                              <1> 	
 17307                              <1> ; Original UNIX v1 'gtty' routine:
 17308                              <1> ; gtty:
 17309                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
 17310                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
 17311                              <1>         ;jsr    r0,getf / get the i-number of the file
 17312                              <1>         ;tst    r1 / is it open for reading
 17313                              <1>         ;bgt    1f / yes
 17314                              <1>         ;neg    r1 / no, i-number is negative, 
 17315                              <1> 	;          / so make it positive
 17316                              <1> ;1:
 17317                              <1>         ;sub    $14.,r1 / get i-number of tty0
 17318                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
 17319                              <1>         ;bhis   error9 / no, error
 17320                              <1>         ;asl    r1 / 0%2
 17321                              <1>         ;asl    r1 / 0%4 / yes
 17322                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
 17323                              <1> 	;	       ; / tty block
 17324                              <1>         ;mov    u.off,r2 / put argument in r2
 17325                              <1>         ;rts    r0 / return
 17326                                  %include 'u2.s'      ; 11/05/2015
 17327                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 17328                              <1> ; (re-write kernel for test by using previous version without a major defect)
 17329                              <1> ; ****************************************************************************
 17330                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS2.INC
 17331                              <1> ; Last Modification: 11/12/2021
 17332                              <1> ; ----------------------------------------------------------------------------
 17333                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 17334                              <1> ; (v0.1 - Beginning: 11/07/2012)
 17335                              <1> ;
 17336                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 17337                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 17338                              <1> ; <Bell Laboratories (17/3/1972)>
 17339                              <1> ; <Preliminary Release of UNIX Implementation Document>
 17340                              <1> ;
 17341                              <1> ; Retro UNIX 8086 v1 - U2.ASM (24/03/2014) //// UNIX v1 -> u2.s
 17342                              <1> ;
 17343                              <1> ; ****************************************************************************
 17344                              <1> 
 17345                              <1> syslink:
 17346                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17347                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17348                              <1> 	;
 17349                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
 17350                              <1> 	; name 1 is a file that already exists. name 2 is the name
 17351                              <1> 	; given to the entry that will go in the current directory.
 17352                              <1> 	; name2 will then be a link to the name 1 file. The i-number
 17353                              <1> 	; in the name 2 entry of current directory is the same
 17354                              <1> 	; i-number for the name 1 file.
 17355                              <1> 	;
 17356                              <1> 	; Calling sequence:
 17357                              <1> 	;	syslink; name 1; name 2
 17358                              <1> 	; Arguments:
 17359                              <1> 	;	name 1 - file name to which link will be created.
 17360                              <1> 	;	name 2 - name of entry in current directory that
 17361                              <1> 	;		 links to name 1.
 17362                              <1> 	; Inputs: -
 17363                              <1> 	; Outputs: -
 17364                              <1> 	; ...............................................................
 17365                              <1> 	;	
 17366                              <1> 	; Retro UNIX 8086 v1 modification: 
 17367                              <1> 	;       'syslink' system call has two arguments; so,
 17368                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
 17369                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
 17370                              <1> 	;
 17371                              <1> 		; / name1, name2
 17372                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
 17373 00004508 891D[D0700000]      <1> 	mov	[u.namep], ebx
 17374 0000450E 51                  <1> 	push	ecx
 17375 0000450F E88B060000          <1> 	call	namei
 17376                              <1> 		; jsr r0,namei / find the i-number associated with
 17377                              <1> 			     ; / the 1st path name
 17378                              <1>      	;;and	ax, ax
 17379                              <1> 	;;jz	error ; File not found
 17380                              <1> 	;jc	error 
 17381                              <1> 		; br error9 / cannot be found
 17382 00004514 730F                <1> 	jnc	short syslink0
 17383                              <1> 	;pop 	ecx
 17384                              <1> 	; 'file not found !' error
 17385 00004516 C705[2C710000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17386 0000451E 0000                <1>
 17387 00004520 E9B1F7FFFF          <1> 	jmp	error
 17388                              <1> syslink0:
 17389 00004525 E841100000          <1> 	call	iget
 17390                              <1> 		; jsr r0,iget / get the i-node into core
 17391 0000452A 8F05[D0700000]      <1> 	pop	dword [u.namep] ; ecx
 17392                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
 17393 00004530 6650                <1> 	push	ax
 17394                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
 17395                              <1> 			    ; / (a link to this file is to be created)
 17396 00004532 66FF35[95700000]    <1> 	push	word [cdev]
 17397                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
 17398 00004539 E855000000          <1> 	call	isdir
 17399                              <1> 		; jsr r0,isdir / is it a directory
 17400 0000453E E85C060000          <1> 	call	namei
 17401                              <1> 		; jsr r0,namei / no, get i-number of name2
 17402                              <1> 	;jnc	error
 17403                              <1> 		; br .+4   / not found 
 17404                              <1> 			 ; / so r1 = i-number of current directory
 17405                              <1> 			 ; / ii = i-number of current directory
 17406                              <1> 		; br error9 / file already exists., error
 17407 00004543 720F                <1> 	jc	short syslink1
 17408                              <1> 	; pop ax
 17409                              <1> 	; pop ax
 17410                              <1> 	; 'file exists !' error
 17411 00004545 C705[2C710000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
 17412 0000454D 0000                <1>
 17413 0000454F E982F7FFFF          <1> 	jmp	error
 17414                              <1> syslink1:
 17415 00004554 6659                <1> 	pop	cx
 17416                              <1> 	;cmp	cx, [cdev]
 17417 00004556 3A0D[95700000]      <1> 	cmp	cl, [cdev]
 17418                              <1> 	;jne	error
 17419                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
 17420                              <1> 			       ; / end of current directory
 17421                              <1> 	        ; bne error9
 17422 0000455C 740F                <1> 	je	short syslink2
 17423                              <1> 	; 'not same drive !' error
 17424 0000455E C705[2C710000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
 17425 00004566 0000                <1>
 17426 00004568 E969F7FFFF          <1> 	jmp	error
 17427                              <1> syslink2:
 17428 0000456D 6658                <1> 	pop	ax
 17429 0000456F 6650                <1> 	push	ax
 17430 00004571 66A3[F0700000]      <1> 	mov	[u.dirbuf], ax
 17431                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
 17432 00004577 E8A8000000          <1> 	call	mkdir
 17433                              <1> 		; jsr r0,mkdir / make directory entry for name2 
 17434                              <1> 		 	     ; / in current directory
 17435 0000457C 6658                <1> 	pop	ax
 17436                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
 17437 0000457E E8E80F0000          <1> 	call	iget
 17438                              <1> 		; jsr r0,iget / get i-node into core
 17439 00004583 FE05[526D0000]      <1> 	inc	byte [i.nlks]
 17440                              <1> 		; incb i.nlks / add 1 to its number of links
 17441 00004589 E870110000          <1> 	call	setimod
 17442                              <1> 		; jsr r0,setimod / set the i-node modified flag
 17443 0000458E E963F7FFFF          <1> 	jmp	sysret
 17444                              <1> 
 17445                              <1> isdir:
 17446                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 17447                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 17448                              <1> 	;
 17449                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
 17450                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
 17451                              <1> 	;  called by syslink and sysunlink to make sure directories
 17452                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
 17453                              <1> 	; 'isdir' does not bother checking. The current i-node
 17454                              <1> 	;  is not disturbed.			
 17455                              <1> 	;		
 17456                              <1> 	; INPUTS ->
 17457                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
 17458                              <1> 	;    u.uid - user id
 17459                              <1> 	; OUTPUTS ->
 17460                              <1> 	;    r1 - contains current i-number upon exit
 17461                              <1> 	;    	 (current i-node back in core) 
 17462                              <1> 	;	
 17463                              <1> 	; ((AX = R1))
 17464                              <1> 	;
 17465                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 17466                              <1> 	;
 17467                              <1> 
 17468                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
 17469                              <1> 	; / there is an error unless super user made the call
 17470                              <1> 	
 17471 00004593 803D[0A710000]00    <1> 	cmp	byte [u.uid], 0 
 17472                              <1> 		; tstb u.uid / super user
 17473 0000459A 762D                <1> 	jna	short isdir1
 17474                              <1> 		; beq 1f / yes, don't care
 17475 0000459C 66FF35[90700000]    <1> 	push	word [ii]
 17476                              <1> 		; mov ii,-(sp) / put current i-number on stack
 17477 000045A3 E8C30F0000          <1> 	call	iget
 17478                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
 17479 000045A8 66F705[506D0000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
 17480 000045B0 40                  <1>
 17481                              <1> 		; bit $40000,i.flgs / is it a directory
 17482                              <1> 	;jnz	error
 17483                              <1> 		; bne error9 / yes, error
 17484 000045B1 740F                <1> 	jz	short isdir0
 17485 000045B3 C705[2C710000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
 17486 000045BB 0000                <1>
 17487                              <1> 				; 'permission denied !' error
 17488                              <1> 	; pop	ax
 17489 000045BD E914F7FFFF          <1> 	jmp	error	
 17490                              <1> isdir0:	
 17491 000045C2 6658                <1> 	pop	ax
 17492                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
 17493 000045C4 E8A20F0000          <1> 	call	iget
 17494                              <1> 		; jsr r0,iget / get it back in
 17495                              <1> isdir1: ; 1:
 17496 000045C9 C3                  <1> 	retn
 17497                              <1> 		; rts r0
 17498                              <1> 
 17499                              <1> sysunlink:
 17500                              <1> 	; 04/12/2015 (14 byte file names)
 17501                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17502                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 17503                              <1> 	;
 17504                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
 17505                              <1> 	; name from its directory. If this entry was the last link
 17506                              <1> 	; to the file, the contents of the file are freed and the
 17507                              <1> 	; file is destroyed. If, however, the file was open in any
 17508                              <1> 	; process, the actual destruction is delayed until it is 
 17509                              <1> 	; closed, even though the directory entry has disappeared.
 17510                              <1> 	; 
 17511                              <1> 	; The error bit (e-bit) is set to indicate that the file	
 17512                              <1> 	; does not exist or that its directory can not be written.
 17513                              <1> 	; Write permission is not required on the file itself.
 17514                              <1> 	; It is also illegal to unlink a directory (except for
 17515                              <1> 	; the superuser).
 17516                              <1> 	;
 17517                              <1> 	; Calling sequence:
 17518                              <1> 	;	sysunlink; name
 17519                              <1> 	; Arguments:
 17520                              <1> 	;	name - name of directory entry to be removed 
 17521                              <1> 	; Inputs: -
 17522                              <1> 	; Outputs: -
 17523                              <1> 	; ...............................................................
 17524                              <1> 	;				
 17525                              <1> 	; Retro UNIX 8086 v1 modification:
 17526                              <1> 	;	 The user/application program puts address of the name
 17527                              <1> 	;        in BX register as 'sysunlink' system call argument.
 17528                              <1> 
 17529                              <1> 	; / name - remove link name
 17530 000045CA 891D[D0700000]      <1> 	mov	[u.namep], ebx
 17531                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
 17532 000045D0 E8CA050000          <1> 	call	namei
 17533                              <1> 		; jsr r0,namei / find the i-number associated 
 17534                              <1> 			     ; / with the path name
 17535                              <1> 	;jc	error
 17536                              <1> 		; br error9 / not found
 17537 000045D5 730F                <1> 	jnc	short sysunlink1
 17538                              <1> 	; 'file not found !' error
 17539 000045D7 C705[2C710000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 17540 000045DF 0000                <1>
 17541 000045E1 E9F0F6FFFF          <1> 	jmp	error
 17542                              <1> sysunlink1:
 17543 000045E6 6650                <1> 	push	ax
 17544                              <1> 		; mov r1,-(sp) / put its i-number on the stack
 17545 000045E8 E8A6FFFFFF          <1> 	call	isdir
 17546                              <1> 		; jsr r0,isdir / is it a directory
 17547 000045ED 6631C0              <1> 	xor 	ax, ax
 17548 000045F0 66A3[F0700000]      <1> 	mov	[u.dirbuf], ax ; 0
 17549                              <1> 		; clr u.dirbuf / no, clear the location that will
 17550                              <1> 			   ; / get written into the i-number portion
 17551                              <1> 			 ; / of the entry
 17552 000045F6 832D[D4700000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
 17553                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
 17554 000045FD E86E000000          <1> 	call	wdir
 17555                              <1> 		; jsr r0,wdir / free the directory entry
 17556 00004602 6658                <1> 	pop	ax
 17557                              <1> 		; mov (sp)+,r1 / get i-number back
 17558 00004604 E8620F0000          <1> 	call	iget
 17559                              <1> 		; jsr r0,iget / get i-node
 17560 00004609 E8F0100000          <1> 	call	setimod
 17561                              <1> 		; jsr r0,setimod / set modified flag
 17562 0000460E FE0D[526D0000]      <1> 	dec	byte [i.nlks]
 17563                              <1> 		; decb i.nlks / decrement the number of links
 17564 00004614 0F85DCF6FFFF        <1> 	jnz	sysret
 17565                              <1> 		; bgt sysret9 / if this was not the last link
 17566                              <1> 			    ; / to file return
 17567                              <1> 	; AX = r1 = i-number
 17568 0000461A E8C8090000          <1> 	call	anyi
 17569                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
 17570                              <1> 			 ; / Then free contents of file and destroy it.
 17571 0000461F E9D2F6FFFF          <1> 	jmp	sysret
 17572                              <1> 		; br sysret9
 17573                              <1> 
 17574                              <1> mkdir:
 17575                              <1> 	; 04/12/2015 (14 byte directory names)
 17576                              <1> 	; 12/10/2015
 17577                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
 17578                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 17579                              <1> 	;
 17580                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
 17581                              <1> 	; by u.namep into the current directory.
 17582                              <1> 	;
 17583                              <1> 	; INPUTS ->
 17584                              <1> 	;    u.namep - points to a file name 
 17585                              <1> 	;	           that is about to be a directory entry.
 17586                              <1> 	;    ii - current directory's i-number.	
 17587                              <1> 	; OUTPUTS ->
 17588                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
 17589                              <1> 	;    u.off - points to entry to be filled 
 17590                              <1> 	;	     in the current directory		
 17591                              <1> 	;    u.base - points to start of u.dirbuf.
 17592                              <1> 	;    r1 - contains i-number of current directory 
 17593                              <1> 	;	
 17594                              <1> 	; ((AX = R1)) output
 17595                              <1> 	;
 17596                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
 17597                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 17598                              <1> 	;
 17599                              <1> 
 17600                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 17601 00004624 31C0                <1> 	xor 	eax, eax
 17602 00004626 BF[F2700000]        <1> 	mov     edi, u.dirbuf+2
 17603 0000462B 89FE                <1> 	mov	esi, edi
 17604 0000462D AB                  <1> 	stosd
 17605 0000462E AB                  <1> 	stosd
 17606                              <1> 	; 04/12/2015 (14 byte directory names)
 17607 0000462F AB                  <1> 	stosd
 17608 00004630 66AB                <1> 	stosw
 17609                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
 17610 00004632 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
 17611                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 17612                              <1> 	;mov 	ebp, [u.namep]
 17613 00004634 E8B1060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 17614                              <1> 		; esi = physical address (page start + offset)
 17615                              <1> 		; ecx = byte count in the page (1 - 4096)
 17616                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 17617                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
 17618                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
 17619                              <1> mkdir_1: ; 1: 
 17620 00004639 45                  <1> 	inc	ebp ; 12/10/2015
 17621                              <1> 	;
 17622                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
 17623                              <1> 	 ; 01/08/2013
 17624 0000463A AC                  <1> 	lodsb
 17625                              <1> 		; movb (r2)+,r1 / move character in name to r1
 17626 0000463B 20C0                <1> 	and 	al, al
 17627 0000463D 7427                <1> 	jz 	short mkdir_3 	  
 17628                              <1> 		; beq 1f / if null, done
 17629 0000463F 3C2F                <1> 	cmp	al, '/'
 17630                              <1> 		; cmp r1,$'/ / is it a "/"?
 17631 00004641 7414                <1> 	je	short mkdir_err
 17632                              <1> 	;je	error
 17633                              <1> 		; beq error9 / yes, error
 17634                              <1> 	; 12/10/2015
 17635 00004643 6649                <1> 	dec	cx
 17636 00004645 7505                <1> 	jnz	short mkdir_2
 17637                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
 17638 00004647 E8A4060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 17639                              <1> 		; esi = physical address (page start + offset)
 17640                              <1> 		; ecx = byte count in the page
 17641                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
 17642                              <1> mkdir_2:
 17643 0000464C 81FF[00710000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
 17644                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
 17645                              <1> 				     ; / a char?
 17646 00004652 74E5                <1> 	je	short mkdir_1
 17647                              <1> 		; beq 1b / yes, go back
 17648 00004654 AA                  <1> 	stosb
 17649                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
 17650 00004655 EBE2                <1> 	jmp 	short mkdir_1
 17651                              <1> 		; br 1b / get next char
 17652                              <1> mkdir_err:
 17653                              <1> 	; 17/06/2015
 17654 00004657 C705[2C710000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 17655 0000465F 0000                <1>
 17656 00004661 E970F6FFFF          <1> 	jmp	error
 17657                              <1> 
 17658                              <1> mkdir_3: ; 1:
 17659 00004666 A1[CC700000]        <1> 	mov	eax, [u.dirp]
 17660 0000466B A3[D4700000]        <1> 	mov	[u.off], eax
 17661                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
 17662                              <1> 				 ; / slot to u.off
 17663                              <1> wdir: ; 29/04/2013
 17664 00004670 C705[DC700000]-     <1>         mov     dword [u.base], u.dirbuf
 17665 00004676 [F0700000]          <1>
 17666                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
 17667 0000467A C705[E0700000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
 17668 00004682 0000                <1>
 17669                              <1> 		; mov $10.,u.count / u.count = 10
 17670 00004684 66A1[90700000]      <1> 	mov	ax, [ii] 
 17671                              <1> 		; mov ii,r1 / r1 has i-number of current directory
 17672 0000468A B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
 17673 0000468C E8C10F0000          <1> 	call 	access
 17674                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
 17675                              <1> 				 ; / for writing
 17676                              <1> 	; AX = i-number of current directory
 17677                              <1> 	; 01/08/2013
 17678 00004691 FE05[2A710000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
 17679 00004697 E83D130000          <1> 	call	writei
 17680                              <1> 		; jsr r0,writei / write into directory
 17681 0000469C C3                  <1> 	retn	
 17682                              <1> 		; rts r0
 17683                              <1> 
 17684                              <1> 	; 11/12/2021
 17685                              <1> 	; 04/12/2021
 17686                              <1> 	; 30/11/2021
 17687                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 17688                              <1> sysexec:
 17689                              <1> 	; 02/05/2021
 17690                              <1> 	; 27/03/2021
 17691                              <1> 	; 26/03/2021
 17692                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 17693                              <1> 	; 23/10/2015
 17694                              <1> 	; 10/10/2015, 18/10/2015, 19/10/2015
 17695                              <1> 	; 29/07/2015, 05/08/2015, 05/08/2015
 17696                              <1> 	; 21/07/2015, 24/07/2015, 25/07/2015
 17697                              <1> 	; 01/07/2015, 02/07/2015, 20/07,2015
 17698                              <1> 	; 24/06/2015, 25/06/2021
 17699                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 17700                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 17701                              <1> 	;
 17702                              <1> 	; 'sysexec' initiates execution of a file whose path name if
 17703                              <1> 	; pointed to by 'name' in the sysexec call. 
 17704                              <1> 	; 'sysexec' performs the following operations:
 17705                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
 17706                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
 17707                              <1> 	;    3. sets trap vectors to system routines.
 17708                              <1> 	;    4. loads arguments to be passed to executing file into
 17709                              <1> 	;	highest locations of user's core
 17710                              <1> 	;    5. puts pointers to arguments in locations immediately
 17711                              <1> 	;	following arguments.
 17712                              <1> 	;    6.	saves number of arguments in next location.
 17713                              <1> 	;    7. intializes user's stack area so that all registers
 17714                              <1> 	;	will be zeroed and the PS is cleared and the PC set
 17715                              <1> 	;	to core when 'sysret' restores registers 
 17716                              <1> 	;	and does an rti.
 17717                              <1> 	;    8. inializes u.r0 and u.sp
 17718                              <1> 	;    9. zeros user's core down to u.r0
 17719                              <1> 	;   10.	reads executable file from storage device into core
 17720                              <1> 	;	starting at location 'core'.
 17721                              <1> 	;   11.	sets u.break to point to end of user's code with
 17722                              <1> 	;	data area appended.
 17723                              <1> 	;   12.	calls 'sysret' which returns control at location
 17724                              <1> 	;	'core' via 'rti' instruction.
 17725                              <1> 	;
 17726                              <1> 	; Calling sequence:
 17727                              <1> 	;	sysexec; namep; argp
 17728                              <1> 	; Arguments:
 17729                              <1> 	;	namep - points to pathname of file to be executed
 17730                              <1> 	;	argp  - address of table of argument pointers
 17731                              <1> 	;	argp1... argpn - table of argument pointers
 17732                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
 17733                              <1> 	; Inputs: (arguments)
 17734                              <1> 	; Outputs: -	
 17735                              <1> 	; ...............................................................
 17736                              <1> 	;
 17737                              <1> 	; Retro UNIX 386 v1 modification: 
 17738                              <1> 	;	User application runs in it's own virtual space 
 17739                              <1> 	;	which is izolated from kernel memory (and other
 17740                              <1> 	;	memory pages) via 80386	paging in ring 3 
 17741                              <1> 	;	privilige mode. Virtual start address is always 0.
 17742                              <1> 	;	User's core memory starts at linear address 400000h
 17743                              <1> 	;	(the end of the 1st 4MB).
 17744                              <1> 	;
 17745                              <1> 	; Retro UNIX 8086 v1 modification: 
 17746                              <1> 	;	user/application segment and system/kernel segment
 17747                              <1> 	;	are different and sysenter/sysret/sysrele routines
 17748                              <1> 	;	are different (user's registers are saved to 
 17749                              <1> 	;	and then restored from system's stack.)
 17750                              <1> 	;
 17751                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 17752                              <1> 	;	      arguments which were in these registers;
 17753                              <1> 	;	      but, it returns by putting the 1st argument
 17754                              <1> 	;	      in 'u.namep' and the 2nd argument
 17755                              <1> 	;	      on top of stack. (1st argument is offset of the
 17756                              <1> 	;	      file/path name in the user's program segment.)
 17757                              <1> 	
 17758                              <1> 	;call	arg2
 17759                              <1> 	; * name - 'u.namep' points to address of file/path name
 17760                              <1> 	;          in the user's program segment ('u.segmnt')
 17761                              <1> 	;          with offset in BX register (as sysopen argument 1).
 17762                              <1> 	; * argp - sysexec argument 2 is in CX register 
 17763                              <1> 	;          which is on top of stack.
 17764                              <1> 	;
 17765                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
 17766                              <1> 
 17767                              <1> 	; 23/06/2015 (32 bit modifications)
 17768                              <1> 
 17769 0000469D 891D[D0700000]      <1> 	mov	[u.namep], ebx ; argument 1
 17770                              <1>         ; 18/10/2015
 17771 000046A3 890D[F0710000]      <1> 	mov     [argv], ecx  ; * ; argument 2
 17772 000046A9 E8F1040000          <1> 	call	namei
 17773                              <1> 		; jsr r0,namei / namei returns i-number of file 
 17774                              <1> 			     ; / named in sysexec call in r1
 17775                              <1> 	;jc	error
 17776                              <1> 		; br error9
 17777 000046AE 7322                <1> 	jnc	short sysexec_0
 17778                              <1> 
 17779                              <1> ; temporary - 11/12/2021
 17780 000046B0 C70500800B00344E34- <1> mov	dword [0B8000h], 4E344E34h
 17781 000046B9 4E                  <1>
 17782 000046BA B9FFFF0F00          <1> mov	ecx, 0FFFFFh
 17783                              <1> abovez:
 17784 000046BF 4A                  <1> dec	edx
 17785 000046C0 42                  <1> inc	edx
 17786 000046C1 E2FC                <1> loop	abovez
 17787                              <1> 
 17788                              <1> 
 17789                              <1> 	;
 17790                              <1> 	; 'file not found !' error
 17791 000046C3 C705[2C710000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
 17792 000046CB 0000                <1>
 17793 000046CD E904F6FFFF          <1> 	jmp	error
 17794                              <1> 
 17795                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 17796                              <1> 	; (executable file flag is checked in 'access')
 17797                              <1> 	; (following error message is in 'access' subroutine)
 17798                              <1> ;sysexec_not_exf:
 17799                              <1> 	;; 'not executable file !' error
 17800                              <1> 	;mov	dword [u.error], ERR_NOT_EXECUTABLE
 17801                              <1> 	;jmp	error 
 17802                              <1> sysexec_0:
 17803                              <1> ; temporary - 28/11/2021
 17804 000046D2 C70500800B00314E31- <1> mov	dword [0B8000h], 4E314E31h
 17805 000046DB 4E                  <1>
 17806 000046DC B9FFFF0F00          <1> mov	ecx, 0FFFFFh
 17807                              <1> above1:
 17808 000046E1 4A                  <1> dec	edx
 17809 000046E2 42                  <1> inc	edx
 17810 000046E3 E2FC                <1> loop	above1
 17811                              <1> 
 17812                              <1> 	; 26/03/2021 ('iget' will be called in 'access')
 17813                              <1> 	;call	iget
 17814                              <1> 	;	; jsr r0,iget / get i-node for file to be executed
 17815                              <1> 	;
 17816                              <1> 	;test	word [i.flgs], 10h
 17817                              <1> 	;	; bit $20,i.flgs / is file executable
 17818                              <1> 	;jz	short sysexec_not_exf
 17819                              <1> 	;;jz	error
 17820                              <1> 	;	; beq error9
 17821                              <1> 	; 26/03/2021
 17822 000046E5 66BA4000            <1> 	mov	dx, 40h ; IEXEC - execute, owner
 17823 000046E9 E8640F0000          <1> 	call	access
 17824                              <1> 	; ! we are here because there is execute permission !
 17825                              <1> 	; ('iopen' is not needed for regular files, from now on)
 17826                              <1> 
 17827                              <1> 	; 26/03/2021
 17828                              <1> 	;; 25/03/2021
 17829                              <1> 	;; (ref: Retro UNIX 386 v2, 'ux.s')
 17830                              <1> 	;mov	dx, 40h ; IEXEC - execute, owner
 17831                              <1> 	;;
 17832                              <1> 	;call	iopen
 17833                              <1> 	;	; jsr r0,iopen / gets i-node for file with i-number
 17834                              <1> 	;		     ; / given in r1 (opens file)
 17835                              <1> 	
 17836                              <1> 	; 26/03/2021
 17837                              <1> 	; AX = i-number of the file
 17838                              <1> 	;test	word [i.flgs], 20h
 17839                              <1> 	;	; bit $40,i.flgs / test user id on execution bit
 17840                              <1> 	;jz	short sysexec_1
 17841                              <1> 	;	; beq 1f
 17842                              <1> 	;cmp 	byte [u.uid], 0 ; 02/08/2013
 17843                              <1> 	;	; tstb u.uid / test user id
 17844                              <1> 	;jna	short sysexec_1
 17845                              <1> 	;	; beq 1f / super user
 17846                              <1> 
 17847                              <1> 	;mov	cl, [i.uid]
 17848                              <1> 	;mov	[u.uid], cl ; 02/08/2013
 17849                              <1> 	;	; movb i.uid,u.uid / put user id of owner of file
 17850                              <1> 				 ; / as process user id
 17851                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 17852 000046EE A0[516D0000]        <1> 	mov	al, [i.flgs+1]
 17853 000046F3 66833D[0A710000]00  <1> 	cmp	word [u.uid], 0	; super user (root) ?
 17854                              <1> 	;jna	short sysexec_19 ; yes, super user
 17855                              <1> 	;; 02/05/2021
 17856 000046FB 7620                <1> 	jna	short sysexec_1	; don't set UID or GID
 17857                              <1> 
 17858                              <1> 	; test set user id on execution bit 
 17859 000046FD A808                <1> 	test	al, 08h ; ISUID flag (800h)
 17860                              <1> 	;jz	short sysexec_19
 17861                              <1> 	; 02/05/2021
 17862 000046FF 741C                <1> 	jz	short sysexec_1 ; do not set group ID
 17863                              <1> 				; (if user ID will not be set)
 17864                              <1> 				; (02/05/2021)	
 17865                              <1> 	; set user id on exec (800h)
 17866                              <1> 	; 26/03/2021
 17867                              <1> sysexec_setuid:
 17868                              <1> 	;; 27/03/2021
 17869                              <1> 	;cmp	word [u.uid], 0
 17870                              <1> 	;;jna	short sysexec_19 ; super user
 17871                              <1> 	;; 02/05/2021
 17872                              <1> 	;jna	short sysexec_1 ; do not set group ID
 17873                              <1> 	;			; (if user ID will not be set)
 17874                              <1> 	;			; (02/05/2021)
 17875 00004701 668B0D[546D0000]    <1> 	mov	cx, [i.uid]
 17876 00004708 66890D[0A710000]    <1> 	mov	[u.uid], cx
 17877                              <1> sysexec_19:
 17878                              <1> 	; test set group id on execution bit 
 17879 0000470F A804                <1> 	test	al, 04h ; ISGID flag (400h)
 17880 00004711 740A                <1> 	jz	short sysexec_1
 17881                              <1> sysexec_setgid:
 17882                              <1> 	; set group id on exec (400h)
 17883 00004713 A0[566D0000]        <1> 	mov	al, [i.gid]
 17884 00004718 A2[0E710000]        <1> 	mov	[u.gid], al
 17885                              <1> 	;
 17886                              <1> sysexec_1:
 17887                              <1> 	; 11/12/2021
 17888                              <1> 	; 04/12/2021
 17889                              <1> 	; 18/10/2015
 17890                              <1> 	; 10/10/2015
 17891                              <1> 	; 24/07/2015
 17892                              <1> 	; 21/07/2015
 17893                              <1> 	; 25/06/2015
 17894                              <1> 	; 24/06/2015
 17895                              <1>         ; Moving arguments to the end of [u.upage]
 17896                              <1> 	; (by regarding page borders in user's memory space)
 17897                              <1> 	;
 17898                              <1> 	; 10/10/2015
 17899                              <1> 	; 21/07/2015
 17900 0000471D 89E5                <1> 	mov	ebp, esp ; (**)
 17901                              <1> 	; 18/10/2015
 17902 0000471F 89EF                <1> 	mov 	edi, ebp
 17903 00004721 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
 17904                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
 17905 00004726 29CF                <1> 	sub	edi, ecx
 17906 00004728 89FC                <1> 	mov	esp, edi
 17907 0000472A 31C0                <1> 	xor	eax, eax
 17908 0000472C A3[E4700000]        <1> 	mov 	[u.nread], eax ; 0
 17909 00004731 49                  <1> 	dec	ecx ; 256 - 1
 17910 00004732 890D[E0700000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
 17911                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
 17912                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 17913 00004738 FE05[2A710000]      <1> 	inc	byte [u.kcall] ; the caller is kernel ('sysexec')
 17914                              <1> sysexec_2:
 17915 0000473E 8B35[F0710000]      <1> 	mov	esi, [argv] ; 18/10/2015
 17916 00004744 E873020000          <1> 	call	get_argp
 17917 00004749 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
 17918                              <1> sysexec_3:
 17919 0000474E 21C0                <1> 	and	eax, eax
 17920 00004750 7454                <1> 	jz	short sysexec_6
 17921                              <1> 	; 18/10/2015
 17922 00004752 010D[F0710000]      <1> 	add	[argv], ecx ; 4
 17923                              <1> 	;inc	word [argc]
 17924                              <1> 	; 11/12/2021
 17925 00004758 FF05[EC710000]      <1> 	inc	dword [argc]
 17926                              <1> 	;
 17927 0000475E A3[DC700000]        <1> 	mov	[u.base], eax
 17928                              <1>  	; 23/10/2015
 17929 00004763 66C705[24710000]00- <1> 	mov	word [u.pcount], 0
 17930 0000476B 00                  <1>
 17931                              <1> sysexec_4:
 17932 0000476C E822140000          <1> 	call	cpass ; get a character from user's core memory
 17933 00004771 750B                <1>         jnz	short sysexec_5
 17934                              <1> 		; (max. 255 chars + null)
 17935                              <1> 	; 18/10/2015
 17936 00004773 28C0                <1> 	sub 	al, al
 17937 00004775 AA                  <1> 	stosb
 17938 00004776 FF05[E4700000]      <1> 	inc	dword [u.nread]
 17939 0000477C EB28                <1> 	jmp	short sysexec_6
 17940                              <1> sysexec_5:
 17941 0000477E AA                  <1> 	stosb
 17942 0000477F 20C0                <1> 	and 	al, al
 17943 00004781 75E9                <1> 	jnz	short sysexec_4
 17944 00004783 B904000000          <1> 	mov	ecx, 4
 17945 00004788 390D[E8710000]      <1> 	cmp	[ncount], ecx ; 4
 17946 0000478E 72AE                <1> 	jb	short sysexec_2
 17947 00004790 8B35[E4710000]      <1> 	mov	esi, [nbase]
 17948 00004796 010D[E4710000]      <1> 	add	[nbase], ecx ; 4	
 17949                              <1> 	;sub	[ncount], cx 
 17950                              <1> 	; 11/12/2021
 17951 0000479C 290D[E8710000]      <1> 	sub	[ncount], ecx
 17952 000047A2 8B06                <1> 	mov	eax, [esi]
 17953 000047A4 EBA8                <1> 	jmp	short sysexec_3
 17954                              <1> sysexec_6:
 17955                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 17956 000047A6 FE0D[2A710000]      <1> 	dec	byte [u.kcall] ; 0
 17957                              <1> 	; 18/10/2015
 17958                              <1> 	; argument list transfer from user's core memory to
 17959                              <1> 	; kernel stack frame is OK here.
 17960                              <1> 	; [u.nread] = ; argument list length
 17961                              <1> 	;mov	[argv], esp ; start address of argument list
 17962                              <1> 	;
 17963                              <1> 	; 18/10/2015
 17964                              <1> 	; 24/07/2015
 17965                              <1>         ; 21/07/2015
 17966                              <1> 	; 02/07/2015
 17967                              <1> 	; 25/06/2015
 17968                              <1> 	; 24/06/2015
 17969                              <1> 	; 23/06/2015
 17970                              <1> 	;
 17971 000047AC 8B1D[1C710000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
 17972 000047B2 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
 17973 000047B4 740A                <1> 	jz	short sysexec_7
 17974 000047B6 A1[18710000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
 17975 000047BB E8E2E8FFFF          <1> 	call	deallocate_page_dir
 17976                              <1> sysexec_7:
 17977 000047C0 E812E8FFFF          <1> 	call	make_page_dir
 17978                              <1> 	;jc	short sysexec_14
 17979                              <1> 	;jc	panic  ; allocation error 
 17980                              <1> 	;	       ; after a deallocation would be nonsence !?
 17981                              <1> 	; 26/03/2021
 17982 000047C5 7243                <1> 	jc	short sysexec_panic
 17983                              <1> 	
 17984                              <1> 	; 24/07/2015
 17985                              <1> 	; map kernel pages (1st 4MB) to PDE 0
 17986                              <1> 	;     of the user's page directory
 17987                              <1> 	;     (It is needed for interrupts!)
 17988                              <1> 	; 18/10/2015
 17989 000047C7 8B15[B86F0000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
 17990 000047CD 8B02                <1> 	mov	eax, [edx] ; physical address of
 17991                              <1> 			   ; kernel's first page table (1st 4 MB)
 17992                              <1> 			   ; (PDE 0 of kernel's page directory)
 17993 000047CF 8B15[18710000]      <1> 	mov 	edx, [u.pgdir]
 17994 000047D5 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
 17995                              <1> 	;
 17996                              <1> 	; 20/07/2015
 17997 000047D7 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
 17998                              <1> 	; 18/10/2015
 17999 000047DC BE[DC710000]        <1> 	mov	esi, pcore ; physical start address
 18000                              <1> sysexec_8:	
 18001 000047E1 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
 18002 000047E6 E80AE8FFFF          <1> 	call	make_page_table
 18003                              <1> 	;jc	panic
 18004                              <1> 	; 26/03/2021
 18005 000047EB 721D                <1> 	jc	short sysexec_panic
 18006                              <1> 	;
 18007                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
 18008 000047ED E811E8FFFF          <1> 	call	make_page ; make new page, clear and set the pte
 18009                              <1> 	;jc	panic
 18010                              <1> 	; 26/03/2021
 18011 000047F2 7216                <1> 	jc	short sysexec_panic
 18012                              <1> 	;
 18013 000047F4 8906                <1> 	mov	[esi], eax ; 24/06/2015
 18014                              <1> 	; ebx = virtual address (24/07/2015)
 18015                              <1> 	; 30/11/2021
 18016                              <1> 	;call 	add_to_swap_queue
 18017                              <1> 	; 18/10/2015
 18018 000047F6 81FE[E0710000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
 18019 000047FC 7411                <1> 	je	short sysexec_9 ; yes
 18020 000047FE BE[E0710000]        <1> 	mov	esi, ecore  ; physical address of the last page
 18021                              <1> 	; 20/07/2015
 18022 00004803 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
 18023                              <1> 	; ebx = virtual end address + segment base address - 4K
 18024 00004808 EBD7                <1>         jmp     short sysexec_8
 18025                              <1> sysexec_panic:
 18026                              <1> 	; 26/03/2021
 18027 0000480A E949EDFFFF          <1> 	jmp	panic
 18028                              <1> 
 18029                              <1> sysexec_9:
 18030                              <1> 	; 11/12/2021
 18031                              <1> 	; 18/10/2015
 18032                              <1> 	; 26/08/2015
 18033                              <1> 	; 25/06/2015
 18034                              <1> 	; move arguments from kernel stack to [ecore]
 18035                              <1> 	; (argument list/line will be copied from kernel stack
 18036                              <1> 	; frame to the last (stack) page of user's core memory)
 18037                              <1> 	; 18/10/2015
 18038 0000480F 8B3D[E0710000]      <1> 	mov	edi, [ecore]
 18039 00004815 81C700100000        <1> 	add	edi, PAGE_SIZE
 18040                              <1> 	;movzx	eax, word [argc]
 18041                              <1> 	; 11/12/2021
 18042 0000481B A1[EC710000]        <1> 	mov	eax, [argc]
 18043 00004820 09C0                <1> 	or	eax, eax
 18044 00004822 7509                <1> 	jnz	short sysexec_10
 18045 00004824 89FB                <1> 	mov 	ebx, edi
 18046 00004826 83EB04              <1> 	sub	ebx, 4 
 18047 00004829 8903                <1> 	mov	[ebx], eax ; 0
 18048 0000482B EB40                <1> 	jmp 	short sysexec_13
 18049                              <1> sysexec_10:
 18050 0000482D 8B0D[E4700000]      <1> 	mov	ecx, [u.nread]
 18051                              <1> 	;mov 	esi, [argv]
 18052 00004833 89E6                <1> 	mov	esi, esp ; start address of argument list
 18053 00004835 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
 18054 00004837 89C2                <1> 	mov	edx, eax
 18055 00004839 FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
 18056 0000483B C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
 18057 0000483E 89FB                <1> 	mov	ebx, edi
 18058 00004840 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
 18059 00004843 29D3                <1> 	sub 	ebx, edx
 18060 00004845 89FA                <1> 	mov	edx, edi
 18061 00004847 F3A4                <1> 	rep	movsb
 18062 00004849 89D6                <1> 	mov 	esi, edx
 18063 0000484B 89DF                <1> 	mov 	edi, ebx
 18064 0000484D BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
 18065 00004852 2B15[E0710000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
 18066 00004858 AB                  <1> 	stosd	; eax = argument count
 18067                              <1> sysexec_11:
 18068 00004859 89F0                <1> 	mov	eax, esi
 18069 0000485B 01D0                <1> 	add	eax, edx
 18070 0000485D AB                  <1> 	stosd  ; eax = virtual address
 18071 0000485E FE0D[EC710000]      <1> 	dec	byte [argc]
 18072 00004864 7407                <1> 	jz	short sysexec_13
 18073                              <1> sysexec_12:
 18074 00004866 AC                  <1> 	lodsb
 18075 00004867 20C0                <1> 	and	al, al
 18076 00004869 75FB                <1> 	jnz	short sysexec_12
 18077 0000486B EBEC                <1> 	jmp	short sysexec_11
 18078                              <1> 	;
 18079                              <1> 	; 1:
 18080                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
 18081                              <1> 			     ; / pointers to arguments to be passed
 18082                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
 18083                              <1> 			      ; / u.quit = 1 take quit
 18084                              <1> 		; mov $1,u.intr / u.intr determines handling of 
 18085                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
 18086                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
 18087                              <1> 			       ; / system routine
 18088                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector
 18089                              <1> 			       ; / set to take system routine
 18090                              <1> 		; mov $sstack,sp / stack space used during swapping
 18091                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
 18092                              <1> 		; mov $ecore,r5 / r5 has end of core
 18093                              <1> 		; mov $core,r4 / r4 has start of users core
 18094                              <1> 		; mov r4,u.base / u.base has start of users core
 18095                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
 18096                              <1> 	; 1:
 18097                              <1> 		; tst (r2)+ / argument char = "nul"
 18098                              <1> 		; bne 1b
 18099                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of
 18100                              <1> 			  ; / end of argument pointer list
 18101                              <1> 	; 1:
 18102                              <1> 	     ; / move arguments to bottom of users core
 18103                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 18104                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
 18105                              <1> 			    ; / ptr list
 18106                              <1> 		; blo 1f / branch to 1f when all arguments
 18107                              <1> 		       ; / are moved
 18108                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
 18109                              <1> 	; 2:
 18110                              <1> 		; tstb (r3)+
 18111                              <1> 		; bne 2b / scan argument for \0 (nul)
 18112                              <1> 
 18113                              <1> 	; 2:
 18114                              <1> 		; movb -(r3),-(r5) / move argument char 
 18115                              <1> 				 ; / by char starting at "ecore"
 18116                              <1> 		; cmp r3,(r2) / moved all characters in 
 18117                              <1> 			    ; / this argument
 18118                              <1> 		; bhi 2b / branch 2b if not
 18119                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
 18120                              <1> 			     ; / r5 has pointer to nth arg
 18121                              <1> 		; br 1b / string
 18122                              <1> 	; 1:
 18123                              <1> 		; clrb -(r5)
 18124                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
 18125                              <1> 			; / last word of argument strings
 18126                              <1> 		; mov $core,r2
 18127                              <1> 	
 18128                              <1> 	; 1: / move argument pointers into core following 
 18129                              <1> 	      ; / argument strings
 18130                              <1> 		; cmp r2,r4
 18131                              <1> 		; bhis 1f / branch to 1f when all pointers
 18132                              <1> 			; / are moved
 18133                              <1> 		; mov (r2)+,-(r5)
 18134                              <1> 		; br 1b
 18135                              <1> 	; 1:
 18136                              <1> 		; sub $core,r4 / gives number of arguments *2
 18137                              <1> 		; asr r4 / divide r4 by 2 to calculate 
 18138                              <1> 		       ; / the number of args stored
 18139                              <1> 		; mov r4,-(r5) / save number of arguments ahead
 18140                              <1> 			     ; / of the argument pointers
 18141                              <1> sysexec_13:
 18142                              <1> 	; 30/11/2021
 18143                              <1> 	; 28/11/2021
 18144                              <1> 	; 19/10/2015
 18145                              <1> 	; 18/10/2015
 18146                              <1> 	; 29/07/2015
 18147                              <1> 	; 25/07/2015
 18148                              <1> 	; 24/07/2015
 18149                              <1> 	; 20/07/2015
 18150                              <1> 	; 25/06/2015
 18151                              <1> 	; 24/06/2015
 18152                              <1> 	; 23/06/2015
 18153                              <1> 	;
 18154                              <1> 	; moving arguments to [ecore] is OK here..
 18155                              <1> 	; 18/10/2015
 18156 0000486D 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
 18157                              <1> 	; ebx = beginning addres of argument list pointers
 18158                              <1> 	;	in user's stack
 18159                              <1> 	; 19/10/2015
 18160 0000486F 2B1D[E0710000]      <1> 	sub 	ebx, [ecore]
 18161 00004875 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
 18162                              <1> 			; end of core - 4096 (last page)
 18163                              <1> 			; (virtual address)
 18164 0000487B 891D[F0710000]      <1> 	mov	[argv], ebx
 18165 00004881 891D[E8700000]      <1> 	mov	[u.break], ebx ; available user memory
 18166                              <1> 	;
 18167 00004887 29C0                <1> 	sub	eax, eax
 18168 00004889 C705[E0700000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
 18169 00004891 0000                <1>
 18170                              <1> 		; mov $14,u.count
 18171 00004893 C705[C8700000]-     <1> 	mov	dword [u.fofp], u.off
 18172 00004899 [D4700000]          <1>
 18173                              <1> 		; mov $u.off,u.fofp
 18174 0000489D A3[D4700000]        <1> 	mov	[u.off], eax ; 0
 18175                              <1> 		; clr u.off / set offset in file to be read to zero
 18176                              <1> 	; 25/07/2015
 18177 000048A2 A3[DC700000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
 18178                              <1> 	; 25/06/2015 
 18179 000048A7 A1[90700000]        <1> 	mov	eax, [ii] ; 28/11/2021 (32 bit inode number)
 18180                              <1> 	; AX = i-number of the executable file
 18181 000048AC E81A0F0000          <1> 	call	readi
 18182                              <1> 		; jsr r0,readi / read in first six words of 
 18183                              <1> 			; / user's file, starting at $core
 18184                              <1> 		; mov sp,r5 / put users stack address in r5
 18185                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
 18186                              <1> 				; / from r5 (leaves number of words
 18187                              <1> 				; / less 26 available for
 18188                              <1> 			     	; / program in user core
 18189                              <1> 		; mov r5,u.count /
 18190                              <1> 	; 25/06/2015
 18191 000048B1 8B0D[E8700000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
 18192 000048B7 890D[E0700000]      <1> 	mov	[u.count], ecx ; save for overrun check
 18193                              <1> 	;
 18194 000048BD 8B0D[E4700000]      <1> 	mov	ecx, [u.nread]
 18195 000048C3 890D[E8700000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
 18196 000048C9 80F920              <1> 	cmp	cl, 32
 18197 000048CC 7540                <1>         jne     short sysexec_15
 18198                              <1> 	;:
 18199                              <1> 	; 25/06/2015
 18200                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
 18201                              <1> 	; 18/10/2015
 18202 000048CE 8B35[DC710000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
 18203                              <1> 		             ; (phys. start addr. of the exec. file)
 18204 000048D4 AD                  <1> 	lodsd
 18205 000048D5 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBh, 1Eh -> jump to +32
 18206 000048D9 7533                <1> 	jne	short sysexec_15
 18207                              <1> 		; cmp core,$405 / br .+14 is first instruction 
 18208                              <1> 			      ; / if file is standard a.out format
 18209                              <1> 		; bne 1f / branch, if not standard format
 18210 000048DB AD                  <1> 	lodsd
 18211 000048DC 89C1                <1> 	mov	ecx, eax ; text (code) section size
 18212 000048DE AD                  <1> 	lodsd
 18213 000048DF 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
 18214                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
 18215                              <1> 		              ; / number of bytes in program text
 18216                              <1> 		; sub $14,r5 / subtract 12
 18217 000048E1 89CB                <1> 	mov	ebx, ecx
 18218                              <1> 	;
 18219                              <1> 	; 25/06/2015
 18220                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
 18221                              <1> 	;	and SINGLIX operating systems (as code template).
 18222                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
 18223                              <1> 	;	due to RUFS (floppy disk file system) restriction...
 18224                              <1> 	;	Overrun is not possible for current version.
 18225                              <1> 	;
 18226 000048E3 AD                  <1> 	lodsd	
 18227 000048E4 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
 18228 000048E6 3B1D[E0700000]      <1> 	cmp	ebx, [u.count]
 18229 000048EC 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
 18230                              <1> 	;
 18231                              <1> 	; 24/07/2015
 18232                              <1> 	; add bss section size to [u.break]
 18233 000048EE 0105[E8700000]      <1> 	add 	[u.break], eax
 18234                              <1> 	;
 18235 000048F4 83E920              <1> 	sub	ecx, 32 ; header size (already loaded)
 18236                              <1> 	;cmp	ecx, [u.count]
 18237                              <1> 	;jnb	short sysexec_16
 18238                              <1> 		; cmp r5,u.count /
 18239                              <1> 		; bgt 1f / branch if r5 greater than u.count
 18240 000048F7 890D[E0700000]      <1> 	mov	[u.count], ecx ; required read count
 18241                              <1> 		; mov r5,u.count
 18242                              <1> 	;
 18243 000048FD EB29                <1> 	jmp	short sysexec_16
 18244                              <1> 	;
 18245                              <1> sysexec_14:
 18246                              <1> 	; 23/06/2015
 18247                              <1> 	; insufficient (out of) memory
 18248 000048FF C705[2C710000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
 18249 00004907 0000                <1>
 18250 00004909 E9C8F3FFFF          <1> 	jmp	error
 18251                              <1> 	;
 18252                              <1> sysexec_15:
 18253                              <1> 	; 25/06/2015
 18254                              <1>         ;movzx   edx, word [i.size] ; file size
 18255                              <1> 	; 30/11/2021
 18256 0000490E 8B15[586D0000]      <1> 	mov	edx, [i.size] ; file size
 18257 00004914 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
 18258 00004916 7626                <1> 	jna	short sysexec_17 ; no need to next read
 18259 00004918 01D1                <1> 	add	ecx, edx ; [i.size]
 18260 0000491A 3B0D[E0700000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
 18261 00004920 77DD                <1> 	ja	short sysexec_14
 18262 00004922 8915[E0700000]      <1> 	mov	[u.count], edx
 18263                              <1> sysexec_16:
 18264                              <1> 	;mov	ax, [ii] ; i-number
 18265                              <1> 	; 28/11/2021
 18266 00004928 A1[90700000]        <1> 	mov	eax, [ii] ; 32 bit inode number
 18267 0000492D E8990E0000          <1> 	call	readi
 18268                              <1> 		; add core+10,u.nread / add size of user data area
 18269                              <1> 		                    ; / to u.nread
 18270                              <1> 		; br 2f
 18271                              <1> 	; 1:
 18272                              <1> 		; jsr r0,readi / read in rest of file
 18273                              <1> 	; 2:
 18274 00004932 8B0D[E4700000]      <1> 	mov	ecx, [u.nread]
 18275 00004938 010D[E8700000]      <1> 	add	[u.break], ecx
 18276                              <1> 		; mov u.nread,u.break / set users program break to end of
 18277                              <1> 				    ; / user code
 18278                              <1> 		; add $core+14,u.break / plus data area
 18279                              <1> 	; 20/07/2015
 18280                              <1> sysexec_17:
 18281                              <1> 	; 26/03/2021 - Retro UNIX 386 v2
 18282                              <1> 	; ('iclose' is not needed for regular files, from now on)
 18283                              <1> 	;;mov	ax, [ii] ; i-number
 18284                              <1> 	;call	iclose
 18285                              <1> 	;	; jsr r0,iclose / does nothing
 18286 0000493E 31C0                <1>         xor     eax, eax
 18287 00004940 FEC0                <1> 	inc	al
 18288 00004942 66A3[04710000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
 18289 00004948 66A3[06710000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
 18290                              <1> 	; 30/11/2021
 18291 0000494E FEC8                <1> 	dec	al  ; eax = 0
 18292                              <1> 	; 02/07/2015
 18293                              <1>         ;cmp	dword [u.ppgdir], 0 ; is the caller sys_init (kernel) ?
 18294 00004950 3905[1C710000]      <1> 	cmp	[u.ppgdir], eax ; 0 ; is the caller sys_init (kernel) ?
 18295 00004956 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
 18296                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
 18297 00004958 8B15[B86F0000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
 18298 0000495E 8915[1C710000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here
 18299                              <1> sysexec_18:
 18300                              <1> 
 18301                              <1> ; temporary - 28/11/2021
 18302 00004964 C70504800B00394E39- <1> mov	dword [0B8004h], 4E394E39h
 18303 0000496D 4E                  <1>
 18304 0000496E B9FFFF0000          <1> mov	ecx, 0FFFFh
 18305                              <1> above7:
 18306 00004973 4A                  <1> dec	edx
 18307 00004974 42                  <1> inc	edx
 18308 00004975 E2FC                <1> loop	above7
 18309                              <1> 
 18310                              <1> ;; temporary - 04/12/2021
 18311                              <1> ;;push	eax
 18312                              <1> ;mov	esi, [pcore]
 18313                              <1> ;add	esi, 0AFh
 18314                              <1> ;call	print_msg
 18315                              <1> ;pop	eax
 18316                              <1> ;mov	ecx, 0FFFFh
 18317                              <1> ;above8:
 18318                              <1> ;dec	edx
 18319                              <1> ;inc	edx
 18320                              <1> ;loop	above8
 18321                              <1> 
 18322                              <1> 	; 18/10/2015
 18323                              <1> 	; 05/08/2015
 18324                              <1> 	; 29/07/2015
 18325 00004977 8B2D[F0710000]      <1> 	mov	ebp, [argv] ; user's stack pointer must points to argument
 18326                              <1> 			    ; list pointers (argument count)
 18327 0000497D FA                  <1> 	cli
 18328 0000497E 8B25[546F0000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
 18329                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
 18330                              <1> 			    ; for this process	 
 18331                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
 18332                              <1> 	;;xor	eax, eax ; 0
 18333                              <1> 	;dec	al ; eax = 0
 18334                              <1> 	; eax = 0 ; 30/11/2021 
 18335 00004984 66BA2300            <1> 	mov	dx, UDATA
 18336 00004988 6652                <1> 	push	dx  ; user's stack segment
 18337 0000498A 55                  <1> 	push	ebp ; user's stack pointer
 18338                              <1> 		    ; (points to number of arguments)
 18339 0000498B FB                  <1> 	sti
 18340 0000498C 9C                  <1> 	pushfd	; EFLAGS
 18341                              <1> 		; Set IF for enabling interrupts in user mode
 18342                              <1> 	;or	dword [esp], 200h 
 18343                              <1> 	;
 18344                              <1> 	;mov	bx, UCODE
 18345                              <1> 	;push	bx ; user's code segment
 18346 0000498D 6A1B                <1> 	push	UCODE
 18347                              <1> 	;push	0
 18348 0000498F 50                  <1> 	push	eax ; EIP (=0) - start address -
 18349                              <1> 		; clr -(r5) / popped into ps when rti in 
 18350                              <1> 			  ; / sysrele is executed
 18351                              <1> 		; mov $core,-(r5) / popped into pc when rti 
 18352                              <1> 		                ; / in sysrele is executed
 18353                              <1> 		;mov r5,0f / load second copyz argument
 18354                              <1> 		;tst -(r5) / decrement r5
 18355 00004990 8925[AC700000]      <1> 	mov	[u.sp], esp ; 29/07/2015
 18356                              <1> 	; 05/08/2015
 18357                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
 18358                              <1> 	; ('push dx' would cause to general protection fault, 
 18359                              <1> 	; after 'pop ds' etc.)
 18360                              <1> 	;
 18361                              <1> 	;; push dx ; ds (UDATA)
 18362                              <1> 	;; push dx ; es (UDATA)
 18363                              <1> 	;; push dx ; fs (UDATA)
 18364                              <1> 	;; push dx ; gs (UDATA)
 18365                              <1> 	;
 18366                              <1> 	; This is a trick to prevent general protection fault
 18367                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
 18368 00004996 8EC2                <1> 	mov 	es, dx ; UDATA
 18369 00004998 06                  <1> 	push 	es ; ds (UDATA)
 18370 00004999 06                  <1> 	push 	es ; es (UDATA)
 18371 0000499A 06                  <1> 	push 	es ; fs (UDATA)
 18372 0000499B 06                  <1> 	push	es ; gs (UDATA)
 18373 0000499C 66BA1000            <1> 	mov	dx, KDATA
 18374 000049A0 8EC2                <1> 	mov	es, dx
 18375                              <1> 	;
 18376                              <1> 	;; pushad simulation
 18377 000049A2 89E5                <1> 	mov	ebp, esp ; esp before pushad
 18378 000049A4 50                  <1> 	push	eax ; eax (0)
 18379 000049A5 50                  <1> 	push	eax ; ecx (0)
 18380 000049A6 50                  <1> 	push	eax ; edx (0)
 18381 000049A7 50                  <1> 	push	eax ; ebx (0)
 18382 000049A8 55                  <1> 	push	ebp ; esp before pushad
 18383 000049A9 50                  <1> 	push	eax ; ebp (0)
 18384 000049AA 50                  <1> 	push	eax ; esi (0)		
 18385 000049AB 50                  <1> 	push	eax ; edi (0)	
 18386                              <1> 	;
 18387 000049AC A3[B4700000]        <1> 	mov	[u.r0], eax ; eax = 0
 18388 000049B1 8925[B0700000]      <1> 	mov	[u.usp], esp
 18389                              <1> 		; mov r5,u.r0 /
 18390                              <1> 		; sub $16.,r5 / skip 8 words
 18391                              <1> 		; mov r5,u.sp / assign user stack pointer value,
 18392                              <1> 		;             / effectively zeroes all regs
 18393                              <1> 			    ; / when sysrele is executed
 18394                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
 18395                              <1> 		; clr u.break
 18396                              <1> 		; mov r5,sp / point sp to user's stack
 18397                              <1> 	;
 18398 000049B7 E93CF3FFFF          <1> 	jmp	sysret0
 18399                              <1> 	;jmp	sysret
 18400                              <1> 		; br sysret3 / return to core image at $core
 18401                              <1> 
 18402                              <1> get_argp:
 18403                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 18404                              <1> 	; 18/10/2015 (nbase, ncount)
 18405                              <1> 	; 21/07/2015
 18406                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
 18407                              <1> 	; Get (virtual) address of argument from user's core memory
 18408                              <1> 	;
 18409                              <1> 	; INPUT:
 18410                              <1> 	;	esi = virtual address of argument pointer
 18411                              <1> 	; OUTPUT:
 18412                              <1> 	;	eax = virtual address of argument
 18413                              <1> 	;
 18414                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
 18415                              <1> 	;
 18416 000049BC 833D[1C710000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
 18417                              <1> 				    ; (the caller is kernel)
 18418 000049C3 767C                <1>         jna     short get_argpk 
 18419                              <1> 	;
 18420 000049C5 89F3                <1>      	mov	ebx, esi
 18421 000049C7 E893E9FFFF          <1> 	call	get_physical_addr ; get physical address
 18422 000049CC 7254                <1>         jc	short get_argp_err ; 11/12/2021
 18423 000049CE A3[E4710000]        <1> 	mov 	[nbase], eax ; physical address	
 18424                              <1> 	;mov	[ncount], cx ; remain byte count in page (1-4096)
 18425                              <1> 	; 11/12/2021
 18426 000049D3 890D[E8710000]      <1> 	mov	[ncount], ecx
 18427 000049D9 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
 18428                              <1> 	;cmp	cx, ax ; 4
 18429                              <1> 	; 11/12/2021
 18430 000049DE 39C1                <1> 	cmp	ecx, eax ; 4
 18431 000049E0 734A                <1> 	jnb	short get_argp2
 18432 000049E2 89F3                <1> 	mov	ebx, esi
 18433 000049E4 01CB                <1> 	add	ebx, ecx
 18434 000049E6 E874E9FFFF          <1> 	call	get_physical_addr ; get physical address
 18435 000049EB 7235                <1> 	jc	short get_argp_err
 18436                              <1> 	;push	esi
 18437 000049ED 89C6                <1> 	mov	esi, eax
 18438                              <1> 	;xchg	cx, [ncount]
 18439                              <1> 	; 11/12/2021
 18440 000049EF 870D[E8710000]      <1> 	xchg	ecx, [ncount]
 18441 000049F5 8735[E4710000]      <1> 	xchg	esi, [nbase]
 18442 000049FB B504                <1> 	mov	ch, 4
 18443 000049FD 28CD                <1> 	sub	ch, cl
 18444                              <1> get_argp0:
 18445 000049FF AC                  <1> 	lodsb
 18446                              <1> 	;push	ax
 18447                              <1> 	; 11/12/2021
 18448 00004A00 50                  <1> 	push	eax
 18449 00004A01 FEC9                <1> 	dec	cl
 18450 00004A03 75FA                <1>         jnz     short get_argp0
 18451 00004A05 8B35[E4710000]      <1> 	mov	esi, [nbase]
 18452                              <1> 	; 21/07/2015
 18453 00004A0B 0FB6C5              <1> 	movzx	eax, ch
 18454 00004A0E 0105[E4710000]      <1> 	add	[nbase], eax
 18455                              <1> 	;sub	[ncount], ax
 18456                              <1> 	; 11/12/2021
 18457 00004A14 2905[E8710000]      <1> 	sub	[ncount], eax
 18458                              <1> get_argp1:
 18459 00004A1A AC                  <1> 	lodsb
 18460 00004A1B FECD                <1> 	dec	ch
 18461 00004A1D 743B                <1>         jz      short get_argp3
 18462                              <1>         ;push	ax
 18463                              <1> 	; 11/12/2021
 18464 00004A1F 50                  <1> 	push	eax
 18465 00004A20 EBF8                <1> 	jmp     short get_argp1
 18466                              <1> get_argp_err:
 18467 00004A22 A3[2C710000]        <1> 	mov	[u.error], eax
 18468 00004A27 E9AAF2FFFF          <1> 	jmp	error
 18469                              <1> get_argp2:
 18470                              <1> 	; 21/07/2015
 18471                              <1> 	;mov	eax, 4
 18472 00004A2C 8B15[E4710000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
 18473 00004A32 0105[E4710000]      <1> 	add	[nbase], eax
 18474                              <1> 	;sub	[ncount], ax
 18475                              <1> 	; 11/12/2021
 18476 00004A38 2905[E8710000]      <1> 	sub	[ncount], eax
 18477                              <1> 	;
 18478 00004A3E 8B02                <1> 	mov	eax, [edx]
 18479 00004A40 C3                  <1> 	retn
 18480                              <1> get_argpk:
 18481                              <1> 	; Argument is in kernel's memory space
 18482 00004A41 66C705[E8710000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
 18483 00004A49 10                  <1>
 18484 00004A4A 8935[E4710000]      <1> 	mov	[nbase], esi
 18485 00004A50 8305[E4710000]04    <1> 	add	dword [nbase], 4
 18486 00004A57 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physical addr.
 18487 00004A59 C3                  <1> 	retn
 18488                              <1> get_argp3:
 18489 00004A5A B103                <1> 	mov	cl, 3
 18490                              <1> get_argp4:
 18491 00004A5C C1E008              <1> 	shl	eax, 8
 18492                              <1> 	;pop	dx
 18493                              <1> 	; 11/12/2021
 18494 00004A5F 5A                  <1> 	pop	edx
 18495 00004A60 88D0                <1> 	mov 	al, dl
 18496 00004A62 E2F8                <1>         loop    get_argp4
 18497                              <1> 	;pop	esi
 18498 00004A64 C3                  <1> 	retn	
 18499                              <1> 
 18500                              <1> sysfstat: 
 18501                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18502                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18503                              <1> 	;
 18504                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
 18505                              <1> 	; on open files instead of files given by name. It puts the
 18506                              <1> 	; buffer address on the stack, gets the i-number and
 18507                              <1> 	; checks to see if the file is open for reading or writing.
 18508                              <1> 	; If the file is open for writing (i-number is negative)
 18509                              <1> 	; the i-number is set positive and a branch into 'sysstat'
 18510                              <1> 	; is made.	
 18511                              <1> 	;
 18512                              <1> 	; Calling sequence:
 18513                              <1> 	;	sysfstat; buf
 18514                              <1> 	; Arguments:
 18515                              <1> 	;	buf - buffer address
 18516                              <1> 	;
 18517                              <1> 	; Inputs: *u.r0 - file descriptor
 18518                              <1> 	; Outputs: buffer is loaded with file information
 18519                              <1> 	; ...............................................................
 18520                              <1> 	;				
 18521                              <1> 	; Retro UNIX 8086 v1 modification:
 18522                              <1> 	;       'sysfstat' system call has two arguments; so,
 18523                              <1> 	;	* 1st argument, file descriptor is in BX register
 18524                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 18525                              <1> 
 18526                              <1> 	; / set status of open file
 18527                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
 18528 00004A65 51                  <1> 	push	ecx
 18529                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
 18530                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
 18531                              <1> 		; jsr r0,getf / get the files i-number
 18532                              <1> 	; BX = file descriptor (file number)
 18533 00004A66 E800010000          <1> 	call	getf1
 18534 00004A6B 6621C0              <1> 	and	ax, ax ; i-number of the file
 18535                              <1> 		; tst	r1 / is it 0?
 18536                              <1> 	;jz	error
 18537                              <1> 		; beq error3 / yes, error
 18538 00004A6E 750F                <1> 	jnz	short sysfstat1
 18539 00004A70 C705[2C710000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 18540 00004A78 0000                <1>
 18541 00004A7A E957F2FFFF          <1> 	jmp	error
 18542                              <1> sysfstat1:
 18543 00004A7F 80FC80              <1> 	cmp	ah, 80h
 18544 00004A82 7223                <1>         jb      short sysstat1
 18545                              <1> 		; bgt 1f / if i-number is negative (open for writing)
 18546 00004A84 66F7D8              <1> 	neg	ax
 18547                              <1> 		; neg r1 / make it positive, then branch
 18548 00004A87 EB1E                <1> 	jmp	short sysstat1
 18549                              <1> 		; br 1f / to 1f
 18550                              <1> sysstat:
 18551                              <1> 	; 18/10/2015
 18552                              <1> 	; 07/10/2015
 18553                              <1> 	; 02/09/2015
 18554                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 18555                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 18556                              <1> 	;
 18557                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
 18558                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
 18559                              <1> 	; long and information about the file placed in it.	
 18560                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
 18561                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
 18562                              <1> 	; is then loaded and the results are given in the UNIX
 18563                              <1> 	; Programmers Manual sysstat (II).	
 18564                              <1> 	;
 18565                              <1> 	; Calling sequence:
 18566                              <1> 	;	sysstat; name; buf
 18567                              <1> 	; Arguments:
 18568                              <1> 	;	name - points to the name of the file
 18569                              <1> 	;	buf - address of a 34 bytes buffer
 18570                              <1> 	; Inputs: -
 18571                              <1> 	; Outputs: buffer is loaded with file information
 18572                              <1> 	; ...............................................................
 18573                              <1> 	;				
 18574                              <1> 	; Retro UNIX 8086 v1 modification: 
 18575                              <1> 	;       'sysstat' system call has two arguments; so,
 18576                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 18577                              <1> 	;	to get sysstat system call arguments from the user;
 18578                              <1> 	;	* 1st argument, name is pointed to by BX register
 18579                              <1> 	;	* 2nd argument, buf is pointed to by CX register
 18580                              <1> 	;
 18581                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
 18582                              <1> 	;	      arguments which were in these registers;
 18583                              <1> 	;	      but, it returns by putting the 1st argument
 18584                              <1> 	;	      in 'u.namep' and the 2nd argument
 18585                              <1> 	;	      on top of stack. (1st argument is offset of the
 18586                              <1> 	;	      file/path name in the user's program segment.)		 	
 18587                              <1> 	
 18588                              <1> 	; / ; name of file; buffer - get files status
 18589                              <1> 		; jsr r0,arg2 / get the 2 arguments
 18590 00004A89 891D[D0700000]      <1> 	mov	[u.namep], ebx
 18591 00004A8F 51                  <1> 	push	ecx
 18592 00004A90 E80A010000          <1> 	call	namei
 18593                              <1> 		; jsr r0,namei / get the i-number for the file
 18594                              <1> 	;jc	error
 18595                              <1> 		; br error3 / no such file, error
 18596 00004A95 7310                <1> 	jnc	short sysstat1
 18597                              <1> 	; pop 	ecx
 18598                              <1> sysstat_err0:
 18599                              <1> 	; 'file not found !' error
 18600 00004A97 C705[2C710000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 18601 00004A9F 0000                <1>
 18602 00004AA1 E930F2FFFF          <1> 	jmp	error
 18603                              <1> 
 18604 00004AA6 00                  <1> statx: db 0
 18605                              <1> 
 18606                              <1> sysstat1: ; 1:
 18607 00004AA7 E8BF0A0000          <1> 	call	iget
 18608                              <1> 		; jsr r0,iget / get the i-node into core
 18609                              <1> 	; 07/10/2015 (ax = [ii], inode number)
 18610                              <1> 	; 02/09/2015
 18611 00004AAC 8F05[DC700000]      <1> 	pop	dword [u.base]
 18612                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
 18613 00004AB2 E858000000          <1> 	call	sysstat_gpa ; get physical address
 18614 00004AB7 730A                <1> 	jnc 	short sysstat2
 18615                              <1> sysstat_err1:
 18616 00004AB9 A3[2C710000]        <1> 	mov	dword [u.error], eax ; error code
 18617 00004ABE E913F2FFFF          <1> 	jmp	error
 18618                              <1> sysstat2:
 18619 00004AC3 A0[90700000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
 18620 00004AC8 AA                  <1> 	stosb
 18621 00004AC9 FF05[DC700000]      <1> 	inc 	dword [u.base]
 18622 00004ACF 6649                <1> 	dec 	cx
 18623 00004AD1 7505                <1> 	jnz	short sysstat3
 18624 00004AD3 E837000000          <1> 	call	sysstat_gpa
 18625                              <1> 	;jc	short sysstat_err1
 18626                              <1> sysstat3:
 18627 00004AD8 A0[91700000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
 18628 00004ADD AA                  <1> 	stosb
 18629                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
 18630 00004ADE FF05[DC700000]      <1> 	inc 	dword [u.base]
 18631                              <1> 	;dec 	word [u.pcount]
 18632 00004AE4 6649                <1> 	dec	cx
 18633 00004AE6 7505                <1> 	jnz	short sysstat4
 18634 00004AE8 E822000000          <1> 	call	sysstat_gpa
 18635                              <1> 	;jc	short sysstat_err1	
 18636                              <1> sysstat4:
 18637 00004AED BE[506D0000]        <1> 	mov	esi, inode
 18638                              <1> 		; mov $inode,r2 / r2 points to i-node
 18639                              <1> sysstat5: ; 1:
 18640 00004AF2 A4                  <1> 	movsb
 18641                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
 18642 00004AF3 FF05[DC700000]      <1> 	inc 	dword [u.base]
 18643                              <1> 	;dec 	word [u.pcount]
 18644 00004AF9 6649                <1> 	dec	cx
 18645 00004AFB 7505                <1> 	jnz	short sysstat6
 18646 00004AFD E80D000000          <1> 	call	sysstat_gpa
 18647                              <1> 	;jc	short sysstat_err1
 18648                              <1> sysstat6:		
 18649 00004B02 81FE[706D0000]      <1> 	cmp	esi, inode + 32
 18650                              <1> 		; cmp r2,$inode+32 / done?
 18651 00004B08 75E8                <1> 	jne	short sysstat5
 18652                              <1> 		; bne 1b / no, go back
 18653 00004B0A E9E7F1FFFF          <1> 	jmp	sysret
 18654                              <1> 		; br sysret3 / return through sysret
 18655                              <1> 	;
 18656                              <1> sysstat_gpa: ; get physical address of file status buffer
 18657                              <1> 	; 02/09/2015
 18658 00004B0F 8B1D[DC700000]      <1> 	mov 	ebx, [u.base]
 18659                              <1> 	; 07/10/2015
 18660 00004B15 E845E8FFFF          <1> 	call	get_physical_addr ; get physical address
 18661                              <1> 	;jc	short sysstat_gpa1
 18662 00004B1A 729D                <1> 	jc	short sysstat_err1
 18663                              <1> 	; 18/10/2015
 18664 00004B1C 89C7                <1> 	mov	edi, eax ; physical address
 18665                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
 18666                              <1> ;sysstat_gpa1:
 18667 00004B1E C3                  <1> 	retn
 18668                              <1> 
 18669                              <1> fclose:
 18670                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 18671                              <1> 	; 08/04/2021
 18672                              <1> 	; 04/04/2021
 18673                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
 18674                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
 18675                              <1> 	;            (32 bit offset pointer modification)
 18676                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
 18677                              <1> 	;
 18678                              <1> 	; Given the file descriptor (index to the u.fp list)
 18679                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
 18680                              <1> 	; If i-node is active (i-number > 0) the entry in 
 18681                              <1> 	; u.fp list is cleared. If all the processes that opened
 18682                              <1> 	; that file close it, then fsp etry is freed and the file
 18683                              <1> 	; is closed. If not a return is taken. 
 18684                              <1> 	; If the file has been deleted while open, 'anyi' is called
 18685                              <1> 	; to see anyone else has it open, i.e., see if it is appears
 18686                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
 18687                              <1> 	; a check is made to see if the file is special.	
 18688                              <1> 	;
 18689                              <1> 	; INPUTS ->
 18690                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
 18691                              <1> 	;    u.fp - list of entries in the fsp table
 18692                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
 18693                              <1> 	; OUTPUTS ->
 18694                              <1> 	;    r1 - contains the same file descriptor
 18695                              <1> 	;    r2 - contains i-number
 18696                              <1> 	;
 18697                              <1> 	; ((AX = R1))
 18698                              <1> 	; ((Modified registers: edx, ebx, ecx, esi, edi, ebp))
 18699                              <1> 	;
 18700                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
 18701                              <1> 	;              if i-number of the file is 0. (error)
 18702                              <1> 
 18703                              <1> 	; 08/04/2021
 18704                              <1> 	; INPUT:
 18705                              <1> 	;	eax = file descriptor
 18706                              <1> 	; OUTPUT:
 18707                              <1> 	;	cf = 0 -> eax = file descriptor
 18708                              <1> 	;	cf = 1 -> eax = error code
 18709                              <1> 	;		  (al = 0 -> file not open)
 18710                              <1> 
 18711                              <1> 	; 18/08/2020
 18712                              <1> 	;movzx	edx, ax ; **
 18713 00004B1F 89C3                <1> 	mov	ebx, eax
 18714                              <1> 
 18715                              <1> 	; 18/08/2020
 18716                              <1> _fclose:
 18717 00004B21 53                  <1> 	push	ebx ; ***  ; file descriptor (index to u.fp)
 18718                              <1> 
 18719                              <1> 	;push	ax ; ***
 18720                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
 18721                              <1> 			     ; / the index to u.fp list)
 18722                              <1> 	; ebx = file descriptor/number
 18723 00004B22 E844000000          <1> 	call	getf
 18724                              <1> 		; jsr r0,getf / r1 contains i-number, 
 18725                              <1> 			    ; / cdev has device =, u.fofp 
 18726                              <1> 			    ; / points to 3rd word of fsp entry
 18727                              <1> 	;cmp	eax, 1 ; 18/08/2020
 18728 00004B27 6683F801            <1> 	cmp	ax, 1 ; r1
 18729                              <1> 		; tst r1 / is i-number 0?
 18730 00004B2B 723C                <1> 	jb	short fclose_2
 18731                              <1> 		; beq 1f / yes, i-node not active so return
 18732                              <1> 		; tst (r0)+ / no, jump over error return
 18733                              <1> 	
 18734                              <1> 	;mov	ebx, edx ; **
 18735                              <1>  	; 18/08/2020
 18736 00004B2D 8B1C24              <1> 	mov	ebx, [esp]
 18737                              <1> 	;mov	edx, eax 
 18738                              <1> 	;;mov 	dx, ax ; *
 18739                              <1> 		; mov r1,r2 / move i-number to r2 ;*
 18740                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
 18741                              <1> 			    ; / which is index to u.fp ; **
 18742 00004B30 C683[BE700000]00    <1> 	mov	byte [ebx+u.fp], 0
 18743                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
 18744 00004B37 8B1D[C8700000]      <1> 	mov	ebx, [u.fofp]
 18745                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
 18746                              <1> 
 18747                              <1> 	; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
 18748                              <1> 	; ebx = 5th word of fsp entry (64 bit file offset)
 18749                              <1> fclose_0:
 18750                              <1> 	;;dec	byte [ebx-2] ; 18/08/2020 - Retro UNIX 386 v2
 18751                              <1> 	; 04/04/2021
 18752 00004B3D FE4BFF              <1> 	dec	byte [ebx-1] ; 04/04/2021 - Retro UNIX 386 v2
 18753                              <1> 	;dec	byte [ebx+4] ; 18/06/2015
 18754                              <1> 		; decb 2(r1) / decrement the number of processes 
 18755                              <1> 			   ; / that have opened the file
 18756 00004B40 7927                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
 18757                              <1> 		; bge 1f / if all processes haven't closed the file, return
 18758                              <1> 	;
 18759                              <1> 	;push	dx ;*
 18760                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
 18761                              <1> 	;;xor	ax, ax ; 0
 18762                              <1> 	;xor	eax, eax ; 18/08/2020
 18763                              <1> 		; clear 1st word of fsp entry
 18764                              <1> 	;mov	[ebx-8], ax ; 0 ; 18/08/2020
 18765                              <1> 	; 18/08/2020 - Retro UNIX 386 v2
 18766 00004B42 66C743F80000        <1> 	mov	word [ebx-8], 0 ; clear 1st word of fsp entry ; i-number
 18767                              <1> 			; Note: 32 bit i-node number field is ready but
 18768                              <1> 			;	it is not used in current runix version.	
 18769                              <1> 
 18770                              <1> 	;;mov	[ebx-4], ax ; 0
 18771                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
 18772                              <1> 	;mov	al, [ebx+5] ; 18/06/2015
 18773                              <1> 	;	; tstb	3(r1) / has this file been deleted
 18774                              <1> 	;and	al, al
 18775                              <1> 	;jz	short fclose_1
 18776                              <1> 	;	; beq 2f / no, branch
 18777                              <1> 
 18778                              <1> 	;push	edx ; * ; 18/08/2020
 18779                              <1> 	;mov	eax, edx ; * ; 18/08/2020
 18780                              <1> 
 18781                              <1> 	;; 18/08/2020 - Retro UNIX 386 v2 (new fsp structure)
 18782                              <1> 	;;test	byte [ebx-3], 80h ; open mode & status flags
 18783                              <1> 	; 04/04/2021 - Retro UNIX 386 v2 (new fsp structure)
 18784                              <1> 	;test	byte [ebx-4], 80h ; open mode & status flags 
 18785                              <1> 	;jz	short fclose_1	; deleted file flag (bit 7)
 18786                              <1> 
 18787                              <1> 	; 04/04/2021
 18788 00004B48 31D2                <1> 	xor	edx, edx
 18789 00004B4A 8A53FC              <1> 	mov	dl, [ebx-4] ; open mode & status flags
 18790 00004B4D F6C280              <1> 	test	dl, 80h	    ; deleted file flag (bit 7)
 18791 00004B50 7409                <1> 	jz	short fclose_1 ; (not deleted -while open-)
 18792 00004B52 52                  <1> 	push	edx
 18793                              <1> 
 18794                              <1> 	; deleted file !
 18795                              <1> 
 18796                              <1> 	;mov	ax, dx ; *
 18797                              <1> 		; mov r2,r1 / yes, put i-number back into r1
 18798                              <1> 	; AX = inode number
 18799 00004B53 E88F040000          <1> 	call	anyi
 18800                              <1> 		; jsr r0,anyi / free all blocks related to i-number
 18801                              <1> 			    ; / check if file appears in fsp again
 18802                              <1> 	; 04/04/2021
 18803 00004B58 5A                  <1> 	pop	edx
 18804                              <1> 	; 08/04/2021
 18805 00004B59 720C                <1> 	jc	short fclose_3 ; error code in eax	
 18806                              <1> 	; 18/08/2020
 18807                              <1> 	; jmp short fclose_2
 18808                              <1> 
 18809                              <1> 	; ax = inode number
 18810                              <1> fclose_1: ; 2:
 18811                              <1> 	; 04/04/2021
 18812 00004B5B 80E201              <1> 	and	dl, 1
 18813 00004B5E FEC2                <1> 	inc	dl ; 0 -> 1 (open for read), 1 -> 2 (open for write)
 18814                              <1> 	
 18815                              <1> 	;pop	eax ; * ; 18/08/2020 
 18816                              <1> 	;;pop	ax ; *
 18817                              <1> 		; mov (sp)+,r1 / put i-number back into r1
 18818 00004B60 E894130000          <1> 	call	iclose ; close if it is special file 
 18819                              <1> 		; jsr r0,iclose / check to see if it is a special file
 18820                              <1> 	; 08/04/2021
 18821 00004B65 7302                <1> 	jnc	short fclose_2
 18822                              <1> fclose_3:
 18823 00004B67 5B                  <1> 	pop	ebx  ; ***  ; file descriptor
 18824                              <1> 	; eax = error code
 18825 00004B68 C3                  <1> 	retn
 18826                              <1> fclose_2: ; 1:
 18827 00004B69 58                  <1> 	pop	eax ; *** ; 18/08/2020
 18828                              <1> 	;pop	ax ; ***
 18829                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
 18830 00004B6A C3                  <1> 	retn
 18831                              <1> 		; rts r0
 18832                              <1> 
 18833                              <1> 	; 04/12/2021 - Retro UNIX 386 v2 fs compatibility code
 18834                              <1> getf:	; / get the device number and the i-number of an open file
 18835                              <1> 	; 13/05/2015
 18836                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 18837                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 18838                              <1> 
 18839                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 18840                              <1> 	;
 18841                              <1> 	; 16/05/2021
 18842                              <1> 	; 27/03/2020 - Retro UNIX 386 v2 
 18843                              <1> 	;	(new open files -fsp- structure)
 18844                              <1> 	; 13/05/2015
 18845                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
 18846                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
 18847                              <1> 	
 18848                              <1> 	; INPUT: 
 18849                              <1> 	;    ;eax = file descriptor/number
 18850                              <1> 	;     ebx = file descriptor/number ; 18/08/2020 	
 18851                              <1> 	; OUTPUT:
 18852                              <1> 	;     bl = open mode & status flag ; 27/03/2020
 18853                              <1> 	;        (bit 0 open mode flag, 0 = read, 1 = write)  
 18854                              <1> 	;    eax = inode number (in AX)
 18855                              <1> 	;          If eax = 0 -> file not open
 18856                              <1> 	;   byte [cdev] = logical drive number (of inode in eax)
 18857                              <1> 	;	
 18858                              <1> 	; Modified registers: eax, ebx
 18859                              <1> 
 18860                              <1> 	; 16/05/2021 ('getf' procedure, unix v7 x86 'fio.c')
 18861                              <1> 	; /*
 18862                              <1> 	;  * Convert a user supplied
 18863                              <1> 	;  * file descriptor into a pointer
 18864                              <1> 	;  * to a file structure.
 18865                              <1> 	;  * Only task is to check range
 18866                              <1> 	;  * of the descriptor.
 18867                              <1> 	;  */
 18868                              <1> 	; struct file *
 18869                              <1> 	; getf(f)
 18870                              <1> 	;
 18871                              <1> 	; 18/08/2020
 18872                              <1> 	; 	ebx = file descriptor/number
 18873                              <1> 
 18874                              <1> 	; 16/05/2021
 18875                              <1> 	NOFILE	equ 10
 18876                              <1> 
 18877                              <1> 	; 18/08/2020
 18878                              <1> 	;mov	ebx, eax
 18879                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
 18880                              <1> 
 18881                              <1> 	; ebx = file descriptor/number
 18882                              <1> 
 18883                              <1> 	; 18/08/2020
 18884 00004B6B 29C0                <1> 	sub	eax, eax ; eax = 0
 18885                              <1>  
 18886 00004B6D 83FB0A              <1> 	cmp	ebx, 10 ; cmp ebx, NOFILE ; 16/05/2021
 18887                              <1> 		; cmp r1,$10. / user limited to 10 open files
 18888 00004B70 732C                <1>         jnb	short getf2 ; 13/05/2015
 18889                              <1> 	;jnb	error
 18890                              <1> 		; bhis error3 / u.fp is table of users open files,
 18891                              <1> 			    ; / index in fsp table
 18892 00004B72 8A9B[BE700000]      <1> 	mov	bl, [ebx+u.fp]
 18893                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
 18894                              <1> 		                  ; / in fsp table
 18895 00004B78 08DB                <1> 	or	bl, bl
 18896                              <1> 	;jnz	short getf3
 18897 00004B7A 7422                <1> 	jz	short getf2 ; 18/08/2020
 18898                              <1> 	;;jz	short getf4
 18899                              <1> 		; beq 1f / if its zero return
 18900                              <1> ;getf2:
 18901                              <1> ;	; 'File not open !' error (ax=0)
 18902                              <1> ;	;sub	eax, eax ; 18/08/2020
 18903                              <1> ;	retn
 18904                              <1> ;getf3:	
 18905                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
 18906                              <1> 	;
 18907                              <1> 	; 'fsp' table (10 bytes/entry)
 18908                              <1> 	; bit 15				   bit 0
 18909                              <1> 	; ---|-------------------------------------------
 18910                              <1> 	; r/w|		i-number of open file
 18911                              <1> 	; ---|-------------------------------------------
 18912                              <1> 	;		   device number
 18913                              <1> 	; -----------------------------------------------
 18914                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
 18915                              <1> 	; -----------------------------------------------
 18916                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
 18917                              <1> 	; ----------------------|------------------------
 18918                              <1> 	;  flag that says file 	| number of processes
 18919                              <1> 	;   has been deleted	| that have file open 
 18920                              <1> 	; ----------------------|------------------------
 18921                              <1> 
 18922                              <1> 	; Retro UNIX 386 v2 modification ! (27/03/2020)
 18923                              <1> 
 18924                              <1> 	; bit 15 				    bit 0
 18925                              <1> 	; ----------------------------------------------- byte 0
 18926                              <1> 	;    	       i-number of open file           
 18927                              <1> 	; ----------------------------------------------- byte 2
 18928                              <1> 	;          high word of 32 bit i-number       
 18929                              <1> 	; ----------------------------------------------- byte 4
 18930                              <1> 	;    open mode & status  |   device number     
 18931                              <1> 	; ----------------------------------------------- byte 6
 18932                              <1> 	;       reserved byte    |    open count  
 18933                              <1> 	; ----------------------------------------------- byte 8
 18934                              <1> 	;   offset pointer, i.e., r/w pointer to file 
 18935                              <1> 	; ----------------------------------------------- byte 10
 18936                              <1> 	;     64 bit file offset pointer (bit 16-31)  
 18937                              <1> 	; ----------------------------------------------- byte 12
 18938                              <1> 	;     64 bit file offset pointer (bit 32-47)   
 18939                              <1> 	; ----------------------------------------------- byte 14
 18940                              <1> 	;     64 bit file offset pointer (bit 48-63)  
 18941                              <1> 	; ----------------------------------------------- byte 16
 18942                              <1> 	
 18943                              <1> 	; 11/05/2015 - Retro UNIX 386 v1
 18944                              <1> 	;mov	eax, 10
 18945                              <1> 
 18946                              <1> 	; 27/03/2020 - Retro UNIX 386 v2	
 18947                              <1> 	;mov	eax, opfls.size ; mov eax, 16
 18948                              <1> 	
 18949                              <1> 	;sub	eax, eax ; 18/08/2020 ; eax = 0
 18950                              <1> 
 18951                              <1> 	;mov	al, opfls.size  ; mov al, 16
 18952                              <1> 	;
 18953                              <1> 	;mul	bl
 18954                              <1> 	;;mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
 18955                              <1> 	;; 27/03/2020
 18956                              <1> 	;mov	ebx, fsp - (opfls.size - opfls.offset) ; fsp - 8
 18957                              <1> 	
 18958                              <1> 	;add	ebx, eax
 18959                              <1> 		; asl r1
 18960                              <1> 		; asl r1 / multiply by 8 to get index into 
 18961                              <1> 		       ; / fsp table entry
 18962                              <1> 		; asl r1
 18963                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
 18964                              <1> 			      ; / in the fsp entry
 18965                              <1> 	; 18/08/2020
 18966 00004B7C FECB                <1> 	dec	bl ; zero based fsp table entry number
 18967 00004B7E C0E304              <1> 	shl	bl, 4 ; * 16 ; opfls.size
 18968 00004B81 81C3[586D0000]      <1> 	add	ebx, fsp + 8 ; opfls.offset	
 18969                              <1> 	; ebx = address of the file offset pointer 
 18970                              <1> 	;	(not file offset! not fsp entry address !)
 18971                              <1> 
 18972 00004B87 891D[C8700000]      <1> 	mov	[u.fofp], ebx
 18973                              <1> 		; mov r1,u.fofp / save address of 3rd word 
 18974                              <1> 			     ; / in fsp entry in u.fofp
 18975                              <1> 	; 18/08/2020
 18976 00004B8D 8A43FD              <1> 	mov	al, [ebx-3]  ; open mode & status flags
 18977                              <1> 
 18978 00004B90 50                  <1> 	push	eax
 18979                              <1> 
 18980                              <1> 	;mov	ax, [ebx]
 18981                              <1> 	;;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
 18982                              <1> 	;mov	[cdev], ax ; ;;in fact (!) 
 18983                              <1> 			     ;;dev number is in 1 byte
 18984                              <1> 		; mov -(r1),cdev / remove the device number cdev
 18985                              <1> 	
 18986                              <1> 	; 18/08/2020
 18987 00004B91 8A43FC              <1> 	mov	al, [ebx-4]  ; logical drive number
 18988                              <1> 
 18989 00004B94 A2[95700000]        <1> 	mov	[cdev], al
 18990                              <1> 
 18991                              <1> 	;dec	ebx
 18992                              <1> 	;dec	ebx
 18993                              <1> 	; 18/08/2020
 18994 00004B99 668B43F8            <1> 	mov	ax, [ebx-8]
 18995                              <1> 		; mov -(r1),r1 / and the i-number  r1
 18996                              <1> 
 18997 00004B9D 5B                  <1> 	pop	ebx ; ebx = bl = open mode and status flag
 18998                              <1> 		; (bit 0 is open mode flag, 0 = read, 1 = write)
 18999                              <1> 	; eax = inode number (in ax)	
 19000                              <1> 
 19001                              <1> getf2:	; 18/08/2020
 19002                              <1> ;getf4:	; 1:
 19003 00004B9E C3                  <1> 	retn
 19004                              <1> 		; rts r0
 19005                              <1> 
 19006                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 19007                              <1> namei:
 19008                              <1> 	; 18/10/2021
 19009                              <1> 	; 12/06/2021
 19010                              <1> 	; 01/05/2021
 19011                              <1> 	; 26/03/2021
 19012                              <1> 	; 25/03/2021 (Retro UNIX 386 v2 - Beginning)
 19013                              <1> 	; 04/12/2015 (14 byte file names)
 19014                              <1> 	; 18/10/2015 (nbase, ncount)
 19015                              <1> 	; 12/10/2015
 19016                              <1> 	; 21/08/2015
 19017                              <1> 	; 18/07/2015
 19018                              <1> 	; 02/07/2015
 19019                              <1> 	; 17/06/2015
 19020                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
 19021                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 19022                              <1> 	;
 19023                              <1> 	; 'namei' takes a file path name and returns i-number of
 19024                              <1> 	; the file in the current directory or the root directory
 19025                              <1> 	; (if the first character of the pathname is '/').	
 19026                              <1> 	;
 19027                              <1> 	; INPUTS ->
 19028                              <1> 	;    u.namep - points to a file path name
 19029                              <1> 	;    u.cdir - i-number of users directory
 19030                              <1> 	;    u.cdev - device number on which user directory resides	
 19031                              <1> 	; OUTPUTS ->
 19032                              <1> 	;    r1 - i-number of file
 19033                              <1> 	;    cdev
 19034                              <1> 	;    u.dirbuf - points to directory entry where a match 
 19035                              <1> 	;               occurs in the search for file path name.
 19036                              <1> 	;	        If no match u.dirb points to the end of 
 19037                              <1> 	;               the directory and r1 = i-number of the current
 19038                              <1> 	;	        directory.	
 19039                              <1> 	; ((AX = R1))
 19040                              <1> 	;
 19041                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
 19042                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
 19043                              <1> 	;
 19044                              <1> 
 19045                              <1> 	;mov	ax, [u.cdir]
 19046                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
 19047                              <1> 			      ; / in r1
 19048                              <1> 	; 01/05/2021
 19049 00004B9F A1[B8700000]        <1> 	mov	eax, [u.cdir]	
 19050 00004BA4 8A15[BC700000]      <1> 	mov	dl, [u.cdrv]
 19051 00004BAA 8815[95700000]      <1> 	mov	[cdev], dl
 19052                              <1> 	;mov	dx, [u.cdrv]
 19053                              <1> 	;mov	[cdev], dx	; NOTE: Retro UNIX 8086 v1 
 19054                              <1> 				; device/drive number is in 1 byte, 
 19055                              <1> 				; not in 1 word!
 19056                              <1> 		; mov u.cdev,cdev / device number for users directory 
 19057                              <1> 				; / into cdev
 19058                              <1> 	; 12/10/2015
 19059                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 19060                              <1>       	; convert virtual (pathname) addr to physical address
 19061 00004BB0 E835010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
 19062                              <1> 		; esi = physical address of [u.namep]
 19063                              <1> 		; ecx = byte count in the page
 19064 00004BB5 803E2F              <1> 	cmp	byte [esi], '/'
 19065                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
 19066 00004BB8 751C                <1> 	jne	short namei_1
 19067                              <1> 		; bne 1f
 19068 00004BBA FF05[D0700000]      <1> 	inc	dword [u.namep]
 19069                              <1> 		; inc u.namep / go to next char
 19070                              <1> 	;dec	cx ; remain byte count in the page
 19071 00004BC0 49                  <1> 	dec	ecx ; 18/10/2021
 19072 00004BC1 7506                <1> 	jnz	short namei_0
 19073                              <1> 	; 12/10/2015
 19074 00004BC3 E822010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
 19075                              <1> 		; esi = physical address (page start + offset)
 19076                              <1> 		; ecx = byte count in the page
 19077 00004BC8 4E                  <1> 	dec	esi
 19078                              <1> namei_0:
 19079 00004BC9 46                  <1> 	inc 	esi  ; go to next char
 19080                              <1> 	;mov	ax, [rootdir] ; 09/07/2013
 19081                              <1> 	; 18/10/2021
 19082 00004BCA A1[9C700000]        <1> 	mov	eax, [rootdir]
 19083                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
 19084 00004BCF C605[95700000]00    <1> 	mov	byte [cdev], 0
 19085                              <1> 		; clr cdev / clear device number
 19086                              <1> namei_1: ; 1:
 19087 00004BD6 F606FF              <1> 	test	byte [esi], 0FFh
 19088                              <1> 	;jz	short getf4
 19089                              <1> 	; 26/03/2021
 19090                              <1> 	;jz	short getf2 ; retn
 19091                              <1> 	;;jz	nig
 19092                              <1> 		; tstb *u.namep / is the character in file name a nul
 19093                              <1> 		; beq nig / yes, end of file name reached; 
 19094                              <1> 			; / branch to "nig"
 19095                              <1> 	; 12/06/2021
 19096 00004BD9 7501                <1> 	jnz	short namei_2
 19097 00004BDB C3                  <1> 	retn
 19098                              <1> namei_2: ; 1:
 19099                              <1> 	; 18/10/2015
 19100 00004BDC 8935[E4710000]      <1> 	mov 	[nbase], esi
 19101                              <1> 	;mov 	[ncount], cx
 19102                              <1> 	; 18/10/2021
 19103 00004BE2 890D[E8710000]      <1> 	mov	[ncount], ecx
 19104                              <1> 	;
 19105                              <1> 	;;mov	dx, 2
 19106                              <1> 	;mov	dl, 2 ; user flag (read, non-owner)
 19107                              <1> 	; 25/03/2021
 19108                              <1> 	;mov	dx, 100h ; IREAD - read, owner 
 19109                              <1> 	; 18/10/2021
 19110 00004BE8 29D2                <1> 	sub	edx, edx
 19111 00004BEA FEC6                <1> 	inc	dh ; dx = 100h ; IREAD - read, owner 
 19112 00004BEC E8610A0000          <1> 	call	access
 19113                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
 19114                              <1> 	; 'access' will not return here if user has not "r" permission !
 19115                              <1> 
 19116                              <1> ; temporary - 11/12/2021
 19117 00004BF1 C70500800B00334E33- <1> mov	dword [0B8000h], 4E334E33h
 19118 00004BFA 4E                  <1>
 19119 00004BFB B9FFFF0000          <1> mov	ecx, 0FFFFh
 19120                              <1> abovec:
 19121 00004C00 4A                  <1> dec	edx
 19122 00004C01 42                  <1> inc	edx
 19123 00004C02 E2FC                <1> loop	abovec
 19124                              <1> 
 19125                              <1> 	;test 	word [i.flgs], 4000h
 19126                              <1> 	;	; bit $40000,i.flgs / directory i-node?
 19127                              <1>         ;jz	short namei_err
 19128                              <1> 		; beq error3 / no, got an error
 19129                              <1> 	; 26/03/2021 
 19130                              <1> ;	mov	al, [i.flgs+1]
 19131                              <1> ;	;test	al, 80h ; IFREG ; 80h
 19132                              <1> ;	;jz	short namei_err ; not a regular file ! (device!?)
 19133                              <1> ;	;and	al, 40h ; IFDIR ; 40h
 19134                              <1> ;	;jz	short namei_err ; not a sub directory !
 19135                              <1> ;	shl	al, 1 ; 80h (IFREG flag) -> cf = 1
 19136                              <1> ;	jnc	short namei_err ; not a regular file ! (device!?)
 19137                              <1> ;	shl	al, 1 ; 80h (IFDIR flag) -> cf = 1
 19138                              <1> ;	jnc	short namei_err ; not a sub directory !
 19139                              <1> 
 19140                              <1> 	; 27/03/2021
 19141 00004C04 E812010000          <1> 	call	chk_dir ; check for directory, jump to 'error' if not
 19142                              <1> 	; CPU will be here if the inode is a (valid) directory inode
 19143                              <1> 
 19144                              <1> ; temporary - 11/12/2021
 19145 00004C09 C70504800B00384E38- <1> mov	dword [0B8004h], 4E384E38h
 19146 00004C12 4E                  <1>
 19147 00004C13 B9FFFF0F00          <1> mov	ecx, 0FFFFFh
 19148                              <1> aboved:
 19149 00004C18 4A                  <1> dec	edx
 19150 00004C19 42                  <1> inc	edx
 19151 00004C1A E2FC                <1> loop	aboved
 19152                              <1> 
 19153                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
 19154                              <1> 	;xor	eax, eax
 19155                              <1> 	;mov	[u.off], eax ; 0
 19156                              <1> 	; 01/05/2021 - Retro UNIX 386 v2 inode structure
 19157 00004C1C A1[586D0000]        <1> 	mov	eax, [i.size]
 19158                              <1> 	;mov	ax, [i.size]
 19159 00004C21 A3[CC700000]        <1> 	mov	[u.dirp], eax
 19160                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
 19161                              <1> 		; clr u.off / u.off is file offset used by user
 19162                              <1> 	; 18/10/2021
 19163 00004C26 31C0                <1> 	xor	eax, eax
 19164                              <1> 	;mov	[u.off], eax ; 0
 19165 00004C28 BB[D4700000]        <1> 	mov	ebx, u.off
 19166 00004C2D 8903                <1> 	mov	[ebx], eax ; mov dword [u.off], 0
 19167                              <1> 	;
 19168 00004C2F 891D[C8700000]      <1> 	mov	[u.fofp], ebx ; u.off ; 18/10/2021
 19169                              <1> 	;mov	dword [u.fofp], u.off
 19170                              <1> 			; mov $u.off,u.fofp / u.fofp is a pointer to 
 19171                              <1> 				  ; / the offset portion of fsp entry
 19172                              <1> namei_3: ; 2:
 19173 00004C35 C705[DC700000]-     <1> 	mov	dword [u.base], u.dirbuf
 19174 00004C3B [F0700000]          <1>
 19175                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
 19176                              <1> 				    ; / copied from a directory
 19177 00004C3F C705[E0700000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
 19178 00004C47 0000                <1>
 19179                              <1>  		; mov $10.,u.count / u.count is byte count 
 19180                              <1> 				 ; / for reads and writes
 19181                              <1> 	;mov 	ax, [ii]
 19182                              <1> 	; 18/10/2021
 19183 00004C49 A1[90700000]        <1> 	mov	eax, [ii] ; (32 bit inode number)
 19184                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
 19185 00004C4E FE05[2A710000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
 19186 00004C54 E8720B0000          <1>     	call	readi
 19187                              <1> 		; jsr r0,readi / read 10. bytes of file 
 19188                              <1> 		      ; with i-number (r1); i.e. read a directory entry
 19189                              <1> 
 19190 00004C59 8B0D[E4700000]      <1> 	mov 	ecx, [u.nread]
 19191 00004C5F 09C9                <1> 	or 	ecx, ecx
 19192                              <1> 		; tst u.nread
 19193 00004C61 741A                <1> 	jz	short nib
 19194                              <1> 		; ble nib / gives error return
 19195                              <1> 	;
 19196                              <1> 	;mov 	bx, [u.dirbuf]
 19197                              <1> 	;and 	bx, bx       
 19198                              <1> 	; 18/10/2021
 19199 00004C63 66F705[F0700000]FF- <1> 	test	word [u.dirbuf], 0FFFFh
 19200 00004C6B FF                  <1>
 19201                              <1> 		; tst u.dirbuf /
 19202 00004C6C 7513                <1> 	jnz	short namei_4
 19203                              <1> 		; bne 3f / branch when active directory entry 
 19204                              <1> 		       ; / (i-node word in entry non zero)
 19205 00004C6E A1[D4700000]        <1> 	mov	eax, [u.off]
 19206 00004C73 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
 19207 00004C76 A3[CC700000]        <1> 	mov	[u.dirp], eax
 19208                              <1> 		; mov u.off,u.dirp
 19209                              <1> 		; sub $10.,u.dirp
 19210 00004C7B EBB8                <1> 	jmp	short namei_3
 19211                              <1> 		; br 2b
 19212                              <1> 
 19213                              <1> 	; 18/07/2013
 19214                              <1> nib: 
 19215 00004C7D 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
 19216 00004C7F F9                  <1> 	stc
 19217                              <1> nig:
 19218 00004C80 C3                  <1> 	retn
 19219                              <1> 
 19220                              <1> 	; 27/03/2021
 19221                              <1> ;namei_err:
 19222                              <1> 	; 16/06/2015
 19223                              <1> ;	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
 19224                              <1> ;	jmp	error
 19225                              <1> 
 19226                              <1> namei_4: ; 3:
 19227                              <1> 	; 18/10/2015
 19228                              <1> 	; 12/10/2015
 19229                              <1> 	; 21/08/2015
 19230                              <1> 	; 18/07/2015
 19231 00004C81 8B2D[D0700000]      <1> 	mov	ebp, [u.namep]
 19232                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
 19233 00004C87 BF[F2700000]        <1> 	mov 	edi, u.dirbuf + 2
 19234                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
 19235                              <1> 	; 18/10/2015
 19236 00004C8C 8B35[E4710000]      <1> 	mov	esi, [nbase]
 19237                              <1> 	;mov	cx, [ncount]
 19238                              <1> 	;and	cx, cx
 19239                              <1> 	; 18/10/2021
 19240 00004C92 8B0D[E8710000]      <1> 	mov	ecx, [ncount]
 19241 00004C98 21C9                <1> 	and	ecx, ecx
 19242 00004C9A 7505                <1> 	jnz	short namei_5	
 19243                              <1> 	;
 19244 00004C9C E84F000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 19245                              <1> 		; esi = physical address (page start + offset)
 19246                              <1> 		; ecx = byte count in the page
 19247                              <1> namei_5: ; 3:
 19248 00004CA1 45                  <1> 	inc	ebp ; 18/07/2015
 19249 00004CA2 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
 19250                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
 19251 00004CA3 08C0                <1> 	or 	al, al
 19252 00004CA5 741C                <1> 	jz 	short namei_7
 19253                              <1> 		; beq 3f / if char is nul, then the last char in string
 19254                              <1> 			; / has been moved
 19255 00004CA7 3C2F                <1> 	cmp	al, '/'
 19256                              <1> 		; cmp r4,$'/ / is char a </>
 19257 00004CA9 7418                <1> 	je 	short namei_7
 19258                              <1> 		; beq 3f	
 19259                              <1> 	; 12/10/2015
 19260                              <1> 	;dec	cx ; remain byte count in the page
 19261 00004CAB 49                  <1> 	dec	ecx ; 18/10/2021
 19262 00004CAC 7505                <1> 	jnz	short namei_6
 19263 00004CAE E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
 19264                              <1> 		; esi = physical address (page start + offset)
 19265                              <1> 		; ecx = byte count in the page
 19266                              <1> namei_6:
 19267 00004CB3 81FF[00710000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 19268                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
 19269                              <1> 				     ; / all 8 bytes of file name
 19270 00004CB9 74E6                <1> 	je	short namei_5
 19271                              <1> 		; beq 3b
 19272 00004CBB AE                  <1> 	scasb	
 19273                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
 19274                              <1> 			      ; / char read from directory
 19275 00004CBC 74E3                <1> 	je 	short namei_5
 19276                              <1> 		; beq 3b / branch if chars match
 19277                              <1> 
 19278 00004CBE E972FFFFFF          <1>         jmp	namei_3 ; 2b
 19279                              <1> 		; br 2b / file names do not match go to next directory entry
 19280                              <1> namei_7: ; 3:
 19281 00004CC3 81FF[00710000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
 19282                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
 19283 00004CC9 7409                <1> 	je	short namei_8
 19284                              <1> 		; beq 3f
 19285                              <1> 	;mov 	ah, [edi]
 19286                              <1> 	;;inc 	edi 
 19287                              <1> 	;and 	ah, ah
 19288                              <1> 	;	; tstb (r3)+ /
 19289                              <1>         ; 18/10/2021
 19290 00004CCB F607FF              <1> 	test	byte [edi], 0FFh
 19291 00004CCE 0F8561FFFFFF        <1> 	jnz	namei_3
 19292                              <1> 		; bne 2b
 19293                              <1> namei_8: ; 3
 19294 00004CD4 892D[D0700000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
 19295                              <1> 		; mov r2,u.namep / u.namep points to char 
 19296                              <1> 			       ; / following a / or nul
 19297                              <1> 	;mov	bx, [u.dirbuf]
 19298                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
 19299                              <1> 				; / entry to r1
 19300 00004CDA 20C0                <1> 	and 	al, al
 19301                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
 19302                              <1> 		      ;  / if r4 = </> then go to next directory
 19303                              <1> 	;mov	ax, bx
 19304                              <1> 	;mov 	ax, [u.dirbuf] ; 17/06/2015
 19305                              <1>         ; 18/10/2021 (16 bit inode number in 32 bit register)
 19306 00004CDC 0FB705[F0700000]    <1> 	movzx	eax, word [u.dirbuf] 
 19307 00004CE3 0F85F3FEFFFF        <1> 	jnz	namei_2 
 19308                              <1> 		; bne 1b
 19309                              <1> 	; AX = i-number of the file
 19310                              <1> ;;nig:
 19311 00004CE9 C3                  <1> 	retn
 19312                              <1> 		; tst (r0)+ / gives non-error return
 19313                              <1> ;;nib:
 19314                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
 19315                              <1> 		       ; ax = 0 -> file not found 
 19316                              <1> ;;	stc	; 27/05/2013
 19317                              <1> ;;	retn
 19318                              <1> 		; rts r0
 19319                              <1> 
 19320                              <1> trans_addr_nmbp:
 19321                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 19322                              <1> 	; 18/10/2015
 19323                              <1> 	; 12/10/2015
 19324 00004CEA 8B2D[D0700000]      <1> 	mov 	ebp, [u.namep]
 19325                              <1> trans_addr_nm: 
 19326                              <1> 	; 18/10/2021 - Retro UNIX 386 v2
 19327                              <1> 	; Convert virtual (pathname) address to physical address
 19328                              <1> 	; (Retro UNIX 386 v1 feature only !)
 19329                              <1> 	; 18/10/2015
 19330                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
 19331                              <1> 	; 02/07/2015
 19332                              <1> 	; 17/06/2015
 19333                              <1> 	; 16/06/2015
 19334                              <1> 	;
 19335                              <1> 	; INPUTS: 
 19336                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
 19337                              <1> 	;	[u.pgdir] = user's page directory
 19338                              <1> 	; OUTPUT:
 19339                              <1> 	;       esi = physical address of the pathname
 19340                              <1> 	;	ecx = remain byte count in the page
 19341                              <1> 	;
 19342                              <1> 	; (Modified registers: EBX, ECX, EDX, ESI) ; 18/10/2021
 19343                              <1> 	;
 19344                              <1> 
 19345                              <1> 	; 18/10/2021
 19346 00004CF0 29C9                <1> 	sub	ecx, ecx
 19347                              <1> 	;
 19348                              <1>         ;cmp	dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
 19349 00004CF2 390D[1C710000]      <1> 	cmp	[u.ppgdir], ecx ; 0 ; 18/10/2021
 19350 00004CF8 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
 19351                              <1> 				     ; it is already physical address
 19352 00004CFA 50                  <1>    	push	eax	
 19353 00004CFB 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
 19354 00004CFD E85DE6FFFF          <1>        	call	get_physical_addr ; get physical address
 19355 00004D02 7204                <1> 	jc	short tr_addr_nm_err
 19356                              <1> 	; 18/10/2015
 19357                              <1> 	; eax = physical address 
 19358                              <1> 	; ecx = remain byte count in page (1-4096) ; 18/10/2021
 19359                              <1> 		; 12/10/2015 (cx = [u.pncount])
 19360 00004D04 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
 19361 00004D06 58                  <1> 	pop	eax 
 19362 00004D07 C3                  <1> 	retn
 19363                              <1> 
 19364                              <1> tr_addr_nm_err:
 19365 00004D08 A3[2C710000]        <1> 	mov	[u.error], eax
 19366                              <1> 	;pop 	eax
 19367 00004D0D E9C4EFFFFF          <1> 	jmp	error
 19368                              <1> 
 19369                              <1> trans_addr_nmk:
 19370                              <1> 	; 12/10/2015
 19371                              <1> 	; 02/07/2015
 19372 00004D12 8B35[D0700000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
 19373                              <1> 	;mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
 19374                              <1> 	; 18/10/2021
 19375 00004D18 B510                <1> 	mov	ch, PAGE_SIZE/256
 19376 00004D1A C3                  <1> 	retn
 19377                              <1> 
 19378                              <1> 
 19379                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 19380                              <1> chk_dir:
 19381                              <1> 	; 12/06/2021
 19382                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
 19383                              <1> 	; Check for directory inode
 19384                              <1> 
 19385 00004D1B 8A0D[516D0000]      <1> 	mov	cl, [i.flgs+1]
 19386                              <1> 	;test	cl, 80h ; IFREG ; 80h
 19387                              <1> 	;jz	short chk_dir_err ; not a regular file ! (device!?)
 19388                              <1> 	;and	cl, 40h ; IFDIR ; 40h
 19389                              <1> 	;jz	short chk_dir_err ; not a sub directory !
 19390 00004D21 D0E1                <1> 	shl	cl, 1 ; 80h (IFREG flag) -> cf = 1
 19391 00004D23 7305                <1> 	jnc	short chk_dir_err ; not a regular file ! (device!?)
 19392 00004D25 D0E1                <1> 	shl	cl, 1 ; 80h (IFDIR flag) -> cf = 1
 19393 00004D27 7301                <1> 	jnc	short chk_dir_err ; not a sub directory !
 19394                              <1> 	; 12/06/2021
 19395 00004D29 C3                  <1> 	retn
 19396                              <1> chk_dir_err:
 19397 00004D2A C705[2C710000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 19398 00004D32 0000                <1>
 19399 00004D34 E99DEFFFFF          <1> 	jmp	error
 19400                              <1> 
 19401                              <1> syschdir:
 19402                              <1> 	; / makes the directory specified in the argument
 19403                              <1> 	; / the current directory
 19404                              <1> 	;
 19405                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19406                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
 19407                              <1> 	;
 19408                              <1> 	; 'syschdir' makes the directory specified in its argument
 19409                              <1> 	; the current working directory.
 19410                              <1> 	;
 19411                              <1> 	; Calling sequence:
 19412                              <1> 	;	syschdir; name
 19413                              <1> 	; Arguments:
 19414                              <1> 	;	name - address of the path name of a directory
 19415                              <1> 	;	       terminated by nul byte.	
 19416                              <1> 	; Inputs: -
 19417                              <1> 	; Outputs: -
 19418                              <1> 	; ...............................................................
 19419                              <1> 	;				
 19420                              <1> 	; Retro UNIX 8086 v1 modification:
 19421                              <1> 	;	 The user/application program puts address of 
 19422                              <1> 	;	 the path name in BX register as 'syschdir' 
 19423                              <1> 	; 	 system call argument.
 19424                              <1> 
 19425 00004D39 891D[D0700000]      <1> 	mov	[u.namep], ebx
 19426                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
 19427 00004D3F E85BFEFFFF          <1> 	call	namei
 19428                              <1> 		; jsr r0,namei / find its i-number
 19429                              <1> 	;jc	error
 19430                              <1> 		; br error3
 19431 00004D44 730F                <1> 	jnc	short syschdir0
 19432                              <1> 	; 'directory not found !' error
 19433 00004D46 C705[2C710000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
 19434 00004D4E 0000                <1>
 19435 00004D50 E981EFFFFF          <1> 	jmp	error
 19436                              <1> syschdir0:
 19437 00004D55 E8F8080000          <1> 	call	access
 19438                              <1> 		; jsr r0,access; 2 / get i-node into core
 19439 00004D5A 66F705[506D0000]00- <1> 	test	word [i.flgs], 4000h
 19440 00004D62 40                  <1>
 19441                              <1> 		; bit $40000,i.flgs / is it a directory?
 19442                              <1> 	;jz	error 
 19443                              <1> 		; beq error3 / no error
 19444 00004D63 750F                <1> 	jnz	short syschdir1
 19445 00004D65 C705[2C710000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
 19446 00004D6D 0000                <1>
 19447 00004D6F E962EFFFFF          <1> 	jmp	error
 19448                              <1> syschdir1:
 19449 00004D74 66A3[B8700000]      <1> 	mov	[u.cdir], ax
 19450                              <1> 		; mov r1,u.cdir / move i-number to users 
 19451                              <1> 			      ; / current directory
 19452 00004D7A 66A1[95700000]      <1> 	mov	ax, [cdev]
 19453 00004D80 66A3[BC700000]      <1> 	mov	[u.cdrv], ax
 19454                              <1> 		; mov cdev,u.cdev / move its device to users 
 19455                              <1> 			        ; / current device
 19456 00004D86 E96BEFFFFF          <1> 	jmp	sysret
 19457                              <1> 		; br sysret3
 19458                              <1> 	
 19459                              <1> syschmod: ; < change mode of file >
 19460                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19461                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 19462                              <1> 	;
 19463                              <1> 	; 'syschmod' changes mode of the file whose name is given as
 19464                              <1> 	; null terminated string pointed to by 'name' has it's mode 
 19465                              <1> 	; changed to 'mode'.
 19466                              <1> 	;
 19467                              <1> 	; Calling sequence:
 19468                              <1> 	;	syschmod; name; mode
 19469                              <1> 	; Arguments:
 19470                              <1> 	;	name - address of the file name
 19471                              <1> 	;	       terminated by null byte.
 19472                              <1> 	;	mode - (new) mode/flags < attributes >
 19473                              <1> 	;	
 19474                              <1> 	; Inputs: -
 19475                              <1> 	; Outputs: -
 19476                              <1> 	; ...............................................................
 19477                              <1> 	;				
 19478                              <1> 	; Retro UNIX 8086 v1 modification: 
 19479                              <1> 	;       'syschmod' system call has two arguments; so,
 19480                              <1> 	;	* 1st argument, name is pointed to by BX register
 19481                              <1> 	;	* 2nd argument, mode is in CX register
 19482                              <1> 	;
 19483                              <1> 	; Mode bits (Flags):
 19484                              <1> 	;	bit 0 - write permission for non-owner (1)
 19485                              <1> 	;	bit 1 - read permission for non-owner (2)
 19486                              <1> 	;	bit 2 - write permission for owner (4)
 19487                              <1> 	;	bit 3 - read permission for owner (8)
 19488                              <1> 	;	bit 4 - executable flag (16) 	
 19489                              <1> 	;	bit 5 - set user ID on execution flag (32) 
 19490                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
 19491                              <1> 	;	bit 12 - large file flag (4096)
 19492                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
 19493                              <1> 	;	bit 14 - directory flag (16384)
 19494                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
 19495                              <1> 
 19496                              <1> 	; / name; mode
 19497 00004D8B E814000000          <1> 	call	isown
 19498                              <1> 		;jsr r0,isown / get the i-node and check user status
 19499 00004D90 66F705[506D0000]00- <1> 	test	word [i.flgs], 4000h
 19500 00004D98 40                  <1>
 19501                              <1> 		; bit	$40000,i.flgs / directory?
 19502 00004D99 7402                <1> 	jz	short syschmod1
 19503                              <1> 		; beq 2f / no
 19504                              <1> 	; AL = (new) mode
 19505 00004D9B 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
 19506                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
 19507                              <1> 			   ; / executable modes
 19508                              <1> syschmod1: ; 2:
 19509 00004D9D A2[506D0000]        <1> 	mov	[i.flgs], al	
 19510                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
 19511 00004DA2 EB42                <1> 	jmp	short isown1
 19512                              <1> 		; br 1f
 19513                              <1> 
 19514                              <1> isown:
 19515                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19516                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
 19517                              <1> 	;
 19518                              <1> 	; 'isown' is given a file name (the 1st argument).
 19519                              <1> 	;  It find the i-number of that file via 'namei' 
 19520                              <1> 	;  then gets the i-node into core via 'iget'.
 19521                              <1> 	;  It then tests to see if the user is super user. 
 19522                              <1> 	;  If not, it cheks to see if the user is owner of 
 19523                              <1> 	;  the file. If he is not an error occurs.
 19524                              <1> 	;  If user is the owner 'setimod' is called to indicate
 19525                              <1> 	;  the inode has been modificed and the 2nd argument of
 19526                              <1> 	;  the call is put in r2.
 19527                              <1> 	;
 19528                              <1> 	; INPUTS ->
 19529                              <1> 	;    arguments of syschmod and syschown calls
 19530                              <1> 	; OUTPUTS ->
 19531                              <1> 	;    u.uid - id of user
 19532                              <1> 	;    imod - set to a 1
 19533                              <1> 	;    r2 - contains second argument of the system call				 	
 19534                              <1> 	;
 19535                              <1> 	;   ((AX=R2) output as 2nd argument)
 19536                              <1> 	;
 19537                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 19538                              <1> 	;
 19539                              <1> 		; jsr r0,arg2 / u.namep points to file name
 19540                              <1> 	;; ! 2nd argument on top of stack !
 19541                              <1> 	;; 22/06/2015 - 32 bit modifications
 19542                              <1> 	;; 07/07/2013
 19543 00004DA4 891D[D0700000]      <1> 	mov	[u.namep], ebx ;; 1st argument
 19544 00004DAA 51                  <1> 	push 	ecx ;; 2nd argument
 19545                              <1> 	;;
 19546 00004DAB E8EFFDFFFF          <1> 	call	namei
 19547                              <1> 		; jsr r0,namei / get its i-number
 19548                              <1>        ; Retro UNIX 8086 v1 modification !
 19549                              <1>        ; ax = 0 -> file not found 
 19550                              <1> 	;and	ax, ax
 19551                              <1> 	;jz	error
 19552                              <1> 	;jc	error ; 27/05/2013
 19553                              <1> 		; br error3
 19554 00004DB0 730F                <1> 	jnc	short isown0
 19555                              <1> 	; 'file not found !' error
 19556 00004DB2 C705[2C710000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
 19557 00004DBA 0000                <1>
 19558 00004DBC E915EFFFFF          <1> 	jmp	error
 19559                              <1> isown0:
 19560 00004DC1 E8A5070000          <1> 	call	iget
 19561                              <1> 		; jsr r0,iget / get i-node into core
 19562 00004DC6 A0[0A710000]        <1> 	mov	al, [u.uid] ; 02/08/2013
 19563 00004DCB 08C0                <1> 	or	al, al
 19564                              <1> 		; tstb u.uid / super user?
 19565 00004DCD 7417                <1> 	jz	short isown1
 19566                              <1> 		; beq 1f / yes, branch
 19567 00004DCF 3A05[546D0000]      <1> 	cmp	al, [i.uid]
 19568                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
 19569                              <1> 				 ; / the file
 19570                              <1> 	;jne	error
 19571                              <1> 		; beq 1f / yes
 19572                              <1> 		; jmp error3 / no, error
 19573 00004DD5 740F                <1> 	je	short isown1
 19574                              <1> 
 19575 00004DD7 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
 19576 00004DDF 0000                <1>
 19577                              <1> 			;  'permission denied !' error
 19578 00004DE1 E9F0EEFFFF          <1> 	jmp	error
 19579                              <1> isown1: ; 1:
 19580 00004DE6 E813090000          <1> 	call	setimod
 19581                              <1> 		; jsr r0,setimod / indicates 
 19582                              <1> 		;	       ; / i-node has been modified
 19583 00004DEB 58                  <1> 	pop	eax ; 2nd argument
 19584                              <1> 		; mov (sp)+,r2 / mode is put in r2 
 19585                              <1> 		       ; / (u.off put on stack with 2nd arg)
 19586 00004DEC C3                  <1> 	retn
 19587                              <1> 		; rts r0
 19588                              <1> 
 19589                              <1> ;;arg:  ; < get system call arguments >
 19590                              <1> 	; 'arg' extracts an argument for a routine whose call is 
 19591                              <1> 	; of form:
 19592                              <1> 	;	sys 'routine' ; arg1
 19593                              <1> 	;		or
 19594                              <1> 	;	sys 'routine' ; arg1 ; arg2
 19595                              <1> 	;		or
 19596                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
 19597                              <1> 	;	
 19598                              <1> 	; INPUTS ->
 19599                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
 19600                              <1> 	;	This pointers's value is actually the value of
 19601                              <1> 	;	update pc at the the trap to sysent (unkni) is
 19602                              <1> 	;	made to process the sys instruction
 19603                              <1> 	;    r0 - contains the return address for the routine
 19604                              <1> 	;	that called arg. The data in the word pointer 
 19605                              <1> 	;	to by the return address is used as address
 19606                              <1> 	;	in which the extracted argument is stored   		
 19607                              <1> 	;    	
 19608                              <1> 	; OUTPUTS ->
 19609                              <1> 	;    'address' - contains the extracted argument 
 19610                              <1> 	;    u.sp+18 - is incremented by 2 
 19611                              <1> 	;    r1 - contains the extracted argument
 19612                              <1> 	;    r0 - points to the next instruction to be
 19613                              <1> 	;	 executed in the calling routine.
 19614                              <1> 	;
 19615                              <1>   
 19616                              <1> 	; mov u.sp,r1
 19617                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
 19618                              <1> 			; / into argument of arg2
 19619                              <1> 	; add $2,18.(r1) / point pc on stack 
 19620                              <1> 			      ; / to next system argument
 19621                              <1> 	; rts r0
 19622                              <1> 
 19623                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
 19624                              <1> 	; 'arg2' takes first argument in system call
 19625                              <1> 	;  (pointer to name of the file) and puts it in location
 19626                              <1> 	;  u.namep; takes second argument and puts it in u.off
 19627                              <1> 	;  and on top of the stack
 19628                              <1> 	;	
 19629                              <1> 	; INPUTS ->
 19630                              <1> 	;    u.sp, r0
 19631                              <1> 	;    	
 19632                              <1> 	; OUTPUTS ->
 19633                              <1> 	;    u.namep
 19634                              <1> 	;    u.off 
 19635                              <1> 	;    u.off pushed on stack
 19636                              <1> 	;    r1
 19637                              <1> 	;
 19638                              <1> 
 19639                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
 19640                              <1> 				; / first arg in sys call
 19641                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
 19642                              <1> 				; / second arg in sys call
 19643                              <1> 	; mov r0,r1 / r0 points to calling routine
 19644                              <1> 	; mov (sp),r0 / put operation code back in r0
 19645                              <1> 	; mov u.off,(sp) / put pointer to second argument 
 19646                              <1> 			; / on stack
 19647                              <1> 	; jmp (r1) / return to calling routine
 19648                              <1> 
 19649                              <1> syschown: ; < change owner of file >
 19650                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19651                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 19652                              <1> 	;
 19653                              <1> 	; 'syschown' changes the owner of the file whose name is given
 19654                              <1> 	; as null terminated string pointed to by 'name' has it's owner
 19655                              <1> 	; changed to 'owner'
 19656                              <1> 	;
 19657                              <1> 	; Calling sequence:
 19658                              <1> 	;	syschown; name; owner
 19659                              <1> 	; Arguments:
 19660                              <1> 	;	name - address of the file name
 19661                              <1> 	;	       terminated by null byte.
 19662                              <1> 	;	owner - (new) owner (number/ID)
 19663                              <1> 	;	
 19664                              <1> 	; Inputs: -
 19665                              <1> 	; Outputs: -
 19666                              <1> 	; ...............................................................
 19667                              <1> 	;				
 19668                              <1> 	; Retro UNIX 8086 v1 modification: 
 19669                              <1> 	;       'syschown' system call has two arguments; so,
 19670                              <1> 	;	* 1st argument, name is pointed to by BX register
 19671                              <1> 	;	* 2nd argument, owner number is in CX register
 19672                              <1> 	;
 19673                              <1> 	; / name; owner
 19674 00004DED E8B2FFFFFF          <1> 	call	isown
 19675                              <1> 		; jsr r0,isown / get the i-node and check user status
 19676 00004DF2 803D[0A710000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
 19677                              <1> 		; tstb u.uid / super user
 19678 00004DF9 7418                <1> 	jz	short syschown1
 19679                              <1> 		; beq 2f / yes, 2f
 19680 00004DFB F605[506D0000]20    <1>         test    byte [i.flgs], 20h ; 32
 19681                              <1> 		; bit $40,i.flgs / no, set userid on execution?
 19682                              <1> 	;jnz	error
 19683                              <1> 		; bne 3f / yes error, could create Trojan Horses
 19684 00004E02 740F                <1> 	jz	short syschown1
 19685                              <1> 	; 'permission denied !'
 19686 00004E04 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
 19687 00004E0C 0000                <1>
 19688 00004E0E E9C3EEFFFF          <1> 	jmp	error
 19689                              <1> syschown1: ; 2:
 19690                              <1> 	; AL = owner (number/ID)
 19691 00004E13 A2[546D0000]        <1> 	mov	[i.uid], al ; 23/06/2015
 19692                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
 19693                              <1> 			       ; / in the i-node
 19694 00004E18 E9D9EEFFFF          <1> 	jmp	sysret
 19695                              <1> 	; 1: 
 19696                              <1> 		; jmp sysret4
 19697                              <1> 	; 3:
 19698                              <1> 		; jmp	error
 19699                              <1> 
 19700                              <1> systime: ; / get time of year
 19701                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19702                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
 19703                              <1> 	;
 19704                              <1> 	; 20/06/2013
 19705                              <1> 	; 'systime' gets the time of the year.
 19706                              <1> 	; The present time is put on the stack.
 19707                              <1> 	;
 19708                              <1> 	; Calling sequence:
 19709                              <1> 	;	systime
 19710                              <1> 	; Arguments: -
 19711                              <1> 	;	
 19712                              <1> 	; Inputs: -
 19713                              <1> 	; Outputs: sp+2, sp+4 - present time
 19714                              <1> 	; ...............................................................
 19715                              <1> 	;	
 19716                              <1> 	; Retro UNIX 8086 v1 modification: 
 19717                              <1> 	;       'systime' system call will return to the user
 19718                              <1> 	;	with unix time (epoch) in DX:AX register pair
 19719                              <1> 	;
 19720                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
 19721                              <1> 	;	system call for PC compatibility !!		 	
 19722                              <1> 
 19723 00004E1D E8D7E9FFFF          <1> 	call 	epoch
 19724 00004E22 A3[B4700000]        <1> 	mov 	[u.r0], eax
 19725                              <1> 		; mov s.time,4(sp)
 19726                              <1> 		; mov s.time+2,2(sp) / put the present time 
 19727                              <1> 				   ; / on the stack
 19728                              <1> 		; br sysret4
 19729 00004E27 E9CAEEFFFF          <1> 	jmp	sysret 
 19730                              <1> 
 19731                              <1> sysstime: ; / set time
 19732                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19733                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 19734                              <1> 	;
 19735                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
 19736                              <1> 	;
 19737                              <1> 	; Calling sequence:
 19738                              <1> 	;	sysstime
 19739                              <1> 	; Arguments: -
 19740                              <1> 	;	
 19741                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
 19742                              <1> 	; Outputs: -
 19743                              <1> 	; ...............................................................
 19744                              <1> 	;	
 19745                              <1> 	; Retro UNIX 8086 v1 modification: 
 19746                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
 19747                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
 19748                              <1> 	; 
 19749                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
 19750                              <1> 	;	to get sysstime system call arguments from the user;
 19751                              <1> 	;	* 1st argument, lowword of unix time is in BX register
 19752                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
 19753                              <1> 	;
 19754                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
 19755                              <1> 	;	system call for PC compatibility !!	
 19756                              <1> 
 19757 00004E2C 803D[0A710000]00    <1> 	cmp	byte [u.uid], 0
 19758                              <1> 		; tstb u.uid / is user the super user
 19759                              <1> 	;ja	error
 19760                              <1> 		; bne error4 / no, error
 19761 00004E33 760F                <1> 	jna	short systime1
 19762                              <1> 	; 'permission denied !'
 19763 00004E35 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
 19764 00004E3D 0000                <1>
 19765 00004E3F E992EEFFFF          <1> 	jmp	error
 19766                              <1> systime1:
 19767                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
 19768                              <1> 	; EBX = unix (epoch) time (from user)
 19769 00004E44 89D8                <1> 	mov	eax, ebx
 19770 00004E46 E82EEBFFFF          <1> 	call 	set_date_time
 19771                              <1> 		; mov 4(sp),s.time
 19772                              <1> 		; mov 2(sp),s.time+2 / set the system time
 19773 00004E4B E9A6EEFFFF          <1> 	jmp	sysret
 19774                              <1> 		; br sysret4
 19775                              <1> 
 19776                              <1> sysbreak:
 19777                              <1> 	; 18/10/2015
 19778                              <1> 	; 07/10/2015
 19779                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
 19780                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
 19781                              <1> 	;
 19782                              <1> 	; 'sysbreak' sets the programs break points. 
 19783                              <1> 	; It checks the current break point (u.break) to see if it is
 19784                              <1> 	; between "core" and the stack (sp). If it is, it is made an
 19785                              <1> 	; even address (if it was odd) and the area between u.break
 19786                              <1> 	; and the stack is cleared. The new breakpoint is then put
 19787                              <1> 	; in u.break and control is passed to 'sysret'.
 19788                              <1> 	;
 19789                              <1> 	; Calling sequence:
 19790                              <1> 	;	sysbreak; addr
 19791                              <1> 	; Arguments: -
 19792                              <1> 	;	
 19793                              <1> 	; Inputs: u.break - current breakpoint
 19794                              <1> 	; Outputs: u.break - new breakpoint 
 19795                              <1> 	;	area between old u.break and the stack (sp) is cleared.
 19796                              <1> 	; ...............................................................
 19797                              <1> 	;	
 19798                              <1> 	; Retro UNIX 8086 v1 modification:
 19799                              <1> 	;	The user/application program puts breakpoint address
 19800                              <1> 	;       in BX register as 'sysbreak' system call argument.
 19801                              <1> 	; 	(argument transfer method 1)
 19802                              <1> 	;
 19803                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
 19804                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
 19805                              <1> 	;  NOTE:
 19806                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
 19807                              <1> 	;	'u.break' address) of user's memory for original unix's
 19808                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
 19809                              <1> 
 19810                              <1> 		; mov u.break,r1 / move users break point to r1
 19811                              <1> 		; cmp r1,$core / is it the same or lower than core?
 19812                              <1> 		; blos 1f / yes, 1f
 19813                              <1> 	; 23/06/2015
 19814 00004E50 8B2D[E8700000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
 19815                              <1> 	;and	ebp, ebp
 19816                              <1> 	;jz	short sysbreak_3 
 19817                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
 19818                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
 19819 00004E56 8B15[AC700000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
 19820 00004E5C 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
 19821                              <1> 	; 07/10/2015
 19822 00004E5F 891D[E8700000]      <1> 	mov	[u.break], ebx ; virtual address !!!
 19823                              <1> 	;
 19824 00004E65 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
 19825                              <1> 			   ; with top of user's stack (virtual!)
 19826 00004E67 7327                <1> 	jnb	short sysbreak_3
 19827                              <1> 		; cmp r1,sp / is it the same or higher 
 19828                              <1> 			  ; / than the stack?
 19829                              <1> 		; bhis 1f / yes, 1f
 19830 00004E69 89DE                <1> 	mov	esi, ebx
 19831 00004E6B 29EE                <1> 	sub	esi, ebp ; new break point - old break point
 19832 00004E6D 7621                <1> 	jna	short sysbreak_3 
 19833                              <1> 	;push	ebx
 19834                              <1> sysbreak_1:
 19835 00004E6F 89EB                <1> 	mov	ebx, ebp  
 19836 00004E71 E8E9E4FFFF          <1> 	call	get_physical_addr ; get physical address
 19837 00004E76 0F828CFEFFFF        <1> 	jc	tr_addr_nm_err
 19838                              <1> 	; 18/10/2015
 19839 00004E7C 89C7                <1> 	mov	edi, eax 
 19840 00004E7E 29C0                <1> 	sub	eax, eax ; 0
 19841                              <1> 		 ; ECX = remain byte count in page (1-4096)
 19842 00004E80 39CE                <1> 	cmp	esi, ecx
 19843 00004E82 7302                <1> 	jnb	short sysbreak_2
 19844 00004E84 89F1                <1> 	mov	ecx, esi
 19845                              <1> sysbreak_2:
 19846 00004E86 29CE                <1> 	sub	esi, ecx
 19847 00004E88 01CD                <1> 	add	ebp, ecx
 19848 00004E8A F3AA                <1> 	rep 	stosb
 19849 00004E8C 09F6                <1> 	or	esi, esi
 19850 00004E8E 75DF                <1> 	jnz	short sysbreak_1
 19851                              <1> 	;
 19852                              <1> 		; bit $1,r1 / is it an odd address
 19853                              <1> 		; beq 2f / no, its even
 19854                              <1> 		; clrb (r1)+ / yes, make it even
 19855                              <1> 	; 2: / clear area between the break point and the stack
 19856                              <1> 		; cmp r1,sp / is it higher or same than the stack
 19857                              <1> 		; bhis 1f / yes, quit
 19858                              <1> 		; clr (r1)+ / clear word
 19859                              <1> 		; br 2b / go back
 19860                              <1> 	;pop	ebx
 19861                              <1> sysbreak_3: ; 1:
 19862                              <1> 	;mov	[u.break], ebx ; virtual address !!!
 19863                              <1> 		; jsr r0,arg; u.break / put the "address" 
 19864                              <1> 			; / in u.break (set new break point)
 19865                              <1> 		; br sysret4 / br sysret
 19866 00004E90 E961EEFFFF          <1> 	jmp	sysret
 19867                              <1> 
 19868                              <1> 
 19869                              <1> maknod: 
 19870                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19871                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 19872                              <1> 	;
 19873                              <1> 	; 'maknod' creates an i-node and makes a directory entry
 19874                              <1> 	; for this i-node in the current directory.
 19875                              <1> 	;
 19876                              <1> 	; INPUTS ->
 19877                              <1> 	;    r1 - contains mode
 19878                              <1> 	;    ii - current directory's i-number	
 19879                              <1> 	;    	
 19880                              <1> 	; OUTPUTS ->
 19881                              <1> 	;    u.dirbuf - contains i-number of free i-node 
 19882                              <1> 	;    i.flgs - flags in new i-node 
 19883                              <1> 	;    i.uid - filled with u.uid
 19884                              <1> 	;    i.nlks - 1 is put in the number of links
 19885                              <1> 	;    i.ctim - creation time				
 19886                              <1> 	;    i.ctim+2 - modification time
 19887                              <1> 	;    imod - set via call to setimod
 19888                              <1> 	;	
 19889                              <1> 	; ((AX = R1)) input
 19890                              <1> 	;
 19891                              <1> 	; (Retro UNIX Prototype : 
 19892                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
 19893                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
 19894                              <1> 
 19895                              <1> 	; / r1 contains the mode
 19896 00004E95 80CC80              <1> 	or 	ah, 80h  ; 10000000b
 19897                              <1> 		; bis	$100000,r1 / allocate flag set
 19898 00004E98 6650                <1> 	push	ax
 19899                              <1> 		; mov r1,-(sp) / put mode on stack
 19900                              <1> 	; 31/07/2013
 19901 00004E9A 66A1[90700000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
 19902                              <1> 		; mov ii,r1 / move current i-number to r1
 19903 00004EA0 B201                <1> 	mov	dl, 1 ; owner flag mask
 19904 00004EA2 E8AB070000          <1> 	call	access	
 19905                              <1> 		; jsr r0,access; 1 / get its i-node into core
 19906 00004EA7 6650                <1> 	push	ax
 19907                              <1> 		; mov r1,-(sp) / put i-number on stack
 19908 00004EA9 66B82800            <1> 	mov	ax, 40
 19909                              <1> 		; mov $40.,r1 / r1 = 40
 19910                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
 19911 00004EAD 6640                <1> 	inc	ax
 19912                              <1> 		; inc r1 / r1 = r1 + 1
 19913 00004EAF E8E3080000          <1> 	call	imap
 19914                              <1> 		; jsr r0,imap / get byte address and bit position in 
 19915                              <1> 			    ; /	inode map in r2 & m
 19916                              <1>           ; DX (MQ) has a 1 in the calculated bit position
 19917                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
 19918                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
 19919                              <1> 	;	       Inode count must be checked here
 19920                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
 19921 00004EB4 8413                <1> 	test	[ebx], dl
 19922                              <1> 		; bitb mq,(r2) / is the i-node active
 19923 00004EB6 75F5                <1> 	jnz	short maknod1
 19924                              <1> 		; bne 1b / yes, try the next one
 19925 00004EB8 0813                <1> 	or	[ebx], dl
 19926                              <1> 		; bisb mq,(r2) / no, make it active 
 19927                              <1> 			     ; / (put a 1 in the bit map)
 19928 00004EBA E8AC060000          <1> 	call	iget
 19929                              <1> 		; jsr r0,iget / get i-node into core
 19930 00004EBF 66F705[506D0000]00- <1> 	test	word [i.flgs], 8000h 
 19931 00004EC7 80                  <1>
 19932                              <1> 		; tst i.flgs / is i-node already allocated
 19933 00004EC8 75E3                <1> 	jnz	short maknod1	
 19934                              <1> 		; blt 1b / yes, look for another one
 19935 00004ECA 66A3[F0700000]      <1> 	mov	[u.dirbuf], ax
 19936                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
 19937 00004ED0 6658                <1> 	pop	ax
 19938                              <1> 		; mov (sp)+,r1 / get current i-number back
 19939 00004ED2 E894060000          <1> 	call	iget
 19940                              <1> 		; jsr r0,iget / get i-node in core
 19941 00004ED7 E848F7FFFF          <1> 	call	mkdir
 19942                              <1> 		; jsr r0,mkdir / make a directory entry 
 19943                              <1> 			     ; / in current directory
 19944 00004EDC 66A1[F0700000]      <1> 	mov	ax, [u.dirbuf]
 19945                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
 19946 00004EE2 E884060000          <1> 	call	iget
 19947                              <1> 		; jsr r0,iget / get it into core
 19948                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
 19949 00004EE7 B908000000          <1> 	mov	ecx, 8 
 19950 00004EEC 31C0                <1> 	xor	eax, eax ; 0
 19951 00004EEE BF[506D0000]        <1> 	mov	edi, inode 
 19952 00004EF3 F3AB                <1> 	rep	stosd
 19953                              <1> 	;
 19954 00004EF5 668F05[506D0000]    <1> 	pop	word [i.flgs]
 19955                              <1> 		; mov (sp)+,i.flgs / fill flags
 19956 00004EFC 8A0D[0A710000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
 19957 00004F02 880D[546D0000]      <1> 	mov 	[i.uid], cl
 19958                              <1> 		; movb u.uid,i.uid / user id	
 19959 00004F08 C605[526D0000]01    <1> 	mov     byte [i.nlks], 1
 19960                              <1> 		; movb $1,i.nlks / 1 link
 19961                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
 19962                              <1> 	;mov	eax, [s.time]
 19963                              <1> 	;mov 	[i.ctim], eax
 19964                              <1> 	 	; mov s.time,i.ctim / time created
 19965                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
 19966                              <1> 	; Retro UNIX 8086 v1 modification !
 19967                              <1> 	; i.ctime=0, i.ctime+2=0 and
 19968                              <1>         ; 'setimod' will set ctime of file via 'epoch'
 19969 00004F0F E8EA070000          <1> 	call setimod
 19970                              <1> 		; jsr r0,setimod / set modified flag
 19971 00004F14 C3                  <1> 	retn
 19972                              <1> 		; rts r0 / return
 19973                              <1> 
 19974                              <1> sysseek: ; / moves read write pointer in an fsp entry
 19975                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 19976                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 19977                              <1> 	;
 19978                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
 19979                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
 19980                              <1> 	; The file descriptor refers to a file open for reading or
 19981                              <1> 	; writing. The read (or write) pointer is set as follows:
 19982                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
 19983                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
 19984                              <1> 	;	  current location plus offset.
 19985                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
 19986                              <1> 	;	  size of file plus offset.
 19987                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
 19988                              <1> 	;
 19989                              <1> 	; Calling sequence:
 19990                              <1> 	;	sysseek; offset; ptrname
 19991                              <1> 	; Arguments:
 19992                              <1> 	;	offset - number of bytes desired to move 
 19993                              <1> 	;		 the r/w pointer
 19994                              <1> 	;	ptrname - a switch indicated above
 19995                              <1> 	;
 19996                              <1> 	; Inputs: r0 - file descriptor 
 19997                              <1> 	; Outputs: -
 19998                              <1> 	; ...............................................................
 19999                              <1> 	;	
 20000                              <1> 	; Retro UNIX 8086 v1 modification: 
 20001                              <1> 	;       'sysseek' system call has three arguments; so,
 20002                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
 20003                              <1> 	;	* 2nd argument, offset is in CX register
 20004                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
 20005                              <1> 	;	
 20006                              <1> 
 20007 00004F15 E823000000          <1> 	call	seektell
 20008                              <1> 	; AX = u.count
 20009                              <1> 	; BX = *u.fofp
 20010                              <1> 		; jsr r0,seektell / get proper value in u.count
 20011                              <1> 		; add u.base,u.count / add u.base to it
 20012 00004F1A 0305[DC700000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
 20013 00004F20 8903                <1> 	mov	[ebx], eax
 20014                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
 20015 00004F22 E9CFEDFFFF          <1> 	jmp	sysret
 20016                              <1> 		; br sysret4
 20017                              <1> 
 20018                              <1> systell: ; / get the r/w pointer
 20019                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20020                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 20021                              <1> 	;
 20022                              <1> 	; Retro UNIX 8086 v1 modification:
 20023                              <1> 	; ! 'systell' does not work in original UNIX v1,
 20024                              <1> 	; 	    it returns with error !
 20025                              <1> 	; Inputs: r0 - file descriptor 
 20026                              <1> 	; Outputs: r0 - file r/w pointer
 20027                              <1> 
 20028                              <1> 	;xor	ecx, ecx ; 0
 20029 00004F27 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
 20030                              <1> 	;call 	seektell
 20031 00004F2C E812000000          <1> 	call 	seektell0 ; 05/08/2013
 20032                              <1> 	;mov	ebx, [u.fofp]
 20033 00004F31 8B03                <1> 	mov	eax, [ebx]
 20034 00004F33 A3[B4700000]        <1> 	mov	[u.r0], eax
 20035 00004F38 E9B9EDFFFF          <1> 	jmp	sysret
 20036                              <1> 
 20037                              <1> ; Original unix v1 'systell' system call:
 20038                              <1> 		; jsr r0,seektell
 20039                              <1> 		; br error4
 20040                              <1> 
 20041                              <1> seektell:
 20042                              <1> 	; 03/01/2016
 20043                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20044                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
 20045                              <1> 	;
 20046                              <1> 	; 'seektell' puts the arguments from sysseek and systell
 20047                              <1> 	; call in u.base and u.count. It then gets the i-number of
 20048                              <1> 	; the file from the file descriptor in u.r0 and by calling
 20049                              <1> 	; getf. The i-node is brought into core and then u.count
 20050                              <1> 	; is checked to see it is a 0, 1, or 2.
 20051                              <1> 	; If it is 0 - u.count stays the same
 20052                              <1> 	;          1 - u.count = offset (u.fofp)
 20053                              <1> 	;	   2 - u.count = i.size (size of file)
 20054                              <1> 	; 	 		
 20055                              <1> 	; !! Retro UNIX 8086 v1 modification:
 20056                              <1> 	;	Argument 1, file descriptor is in BX;
 20057                              <1> 	;	Argument 2, offset is in CX;
 20058                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
 20059                              <1> 	;
 20060                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
 20061                              <1> 	; call 	arg
 20062                              <1> 	;
 20063                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
 20064                              <1> 	;
 20065 00004F3D 890D[DC700000]      <1> 	mov 	[u.base], ecx ; offset
 20066                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
 20067                              <1> seektell0:
 20068 00004F43 8915[E0700000]      <1> 	mov 	[u.count], edx
 20069                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
 20070                              <1> 	; mov	ax, bx
 20071                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
 20072                              <1> 			     ; / (index in u.fp list)
 20073                              <1> 	; call	getf
 20074                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
 20075                              <1> 	; BX = file descriptor (file number)
 20076 00004F49 E81DFCFFFF          <1> 	call	getf1
 20077 00004F4E 6609C0              <1> 	or	ax, ax ; i-number of the file
 20078                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
 20079                              <1> 		             ; / put it on the stack
 20080                              <1> 	;jz	error
 20081                              <1> 		; beq error4 / if i-number is 0, not active so error
 20082 00004F51 750F                <1> 	jnz	short seektell1
 20083 00004F53 C705[2C710000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
 20084 00004F5B 0000                <1>
 20085 00004F5D E974EDFFFF          <1> 	jmp	error
 20086                              <1> seektell1:
 20087                              <1> 	;push	eax
 20088 00004F62 80FC80              <1> 	cmp	ah, 80h
 20089 00004F65 7203                <1> 	jb	short seektell2
 20090                              <1> 		; bgt .+4 / if its positive jump
 20091 00004F67 66F7D8              <1> 	neg	ax
 20092                              <1> 		; neg r1 / if not make it positive
 20093                              <1> seektell2:
 20094 00004F6A E8FC050000          <1> 	call	iget
 20095                              <1> 		; jsr r0,iget / get its i-node into core
 20096 00004F6F 8B1D[C8700000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
 20097 00004F75 803D[E0700000]01    <1> 	cmp	byte [u.count], 1
 20098                              <1> 		; cmp u.count,$1 / is ptr name =1
 20099 00004F7C 7705                <1> 	ja	short seektell3
 20100                              <1> 		; blt 2f / no its zero
 20101 00004F7E 740A                <1> 	je	short seektell_4
 20102                              <1> 		; beq 1f / yes its 1
 20103 00004F80 31C0                <1> 	xor	eax, eax
 20104                              <1> 	;jmp	short seektell_5
 20105 00004F82 C3                  <1> 	retn
 20106                              <1> seektell3:
 20107                              <1> 	; 03/01/2016
 20108                              <1> 	;movzx	eax, word [i.size]
 20109 00004F83 66A1[586D0000]      <1>         mov   	ax, [i.size]
 20110                              <1>                 ; mov i.size,u.count /  put number of bytes 
 20111                              <1>                                    ; / in file in u.count
 20112                              <1> 	;jmp	short seektell_5
 20113                              <1> 		; br 2f
 20114 00004F89 C3                  <1> 	retn
 20115                              <1> seektell_4: ; 1: / ptrname =1
 20116                              <1> 	;mov	ebx, [u.fofp]
 20117 00004F8A 8B03                <1> 	mov	eax, [ebx]
 20118                              <1> 		; mov *u.fofp,u.count / put offset in u.count
 20119                              <1> ;seektell_5: ; 2: / ptrname =0
 20120                              <1> 	;mov	[u.count], eax
 20121                              <1> 	;pop	eax 
 20122                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
 20123 00004F8C C3                  <1> 	retn
 20124                              <1> 		; rts r0
 20125                              <1> 
 20126                              <1> sysintr: ; / set interrupt handling
 20127                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20128                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 20129                              <1> 	;
 20130                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
 20131                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
 20132                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
 20133                              <1> 	; If one does the interrupt character in the tty buffer is
 20134                              <1> 	; cleared and 'sysret'is called. If one does not exits
 20135                              <1> 	; 'sysret' is just called.	
 20136                              <1> 	;
 20137                              <1> 	; Calling sequence:
 20138                              <1> 	;	sysintr; arg
 20139                              <1> 	; Argument:
 20140                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
 20141                              <1> 	;	    - if 1, intterupts cause their normal result
 20142                              <1> 	;		 i.e force an exit.
 20143                              <1> 	;	    - if arg is a location within the program,
 20144                              <1> 	;		control is passed to that location when
 20145                              <1> 	;		an interrupt occurs.	
 20146                              <1> 	; Inputs: -
 20147                              <1> 	; Outputs: -
 20148                              <1> 	; ...............................................................
 20149                              <1> 	;	
 20150                              <1> 	; Retro UNIX 8086 v1 modification: 
 20151                              <1> 	;       'sysintr' system call sets u.intr to value of BX
 20152                              <1> 	;	then branches into sysquit.
 20153                              <1> 	;
 20154 00004F8D 66891D[04710000]    <1> 	mov	[u.intr], bx
 20155                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
 20156                              <1> 		; br 1f / go into quit routine
 20157 00004F94 E95DEDFFFF          <1> 	jmp	sysret
 20158                              <1> 
 20159                              <1> sysquit:
 20160                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20161                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 20162                              <1> 	;
 20163                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
 20164                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
 20165                              <1> 	; tty exists. If one does the interrupt character in the tty
 20166                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
 20167                              <1> 	; 'sysret' is just called.	
 20168                              <1> 	;
 20169                              <1> 	; Calling sequence:
 20170                              <1> 	;	sysquit; arg
 20171                              <1> 	; Argument:
 20172                              <1> 	;	arg - if 0, this call diables quit signals from the
 20173                              <1> 	;		typewriter (ASCII FS)
 20174                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
 20175                              <1> 	;		cease and a core image to be produced.
 20176                              <1> 	;		 i.e force an exit.
 20177                              <1> 	;	    - if arg is an addres in the program,
 20178                              <1> 	;		a quit causes control to sent to that
 20179                              <1> 	;		location.	
 20180                              <1> 	; Inputs: -
 20181                              <1> 	; Outputs: -
 20182                              <1> 	; ...............................................................
 20183                              <1> 	;	
 20184                              <1> 	; Retro UNIX 8086 v1 modification: 
 20185                              <1> 	;       'sysquit' system call sets u.quit to value of BX
 20186                              <1> 	;	then branches into 'sysret'.
 20187                              <1> 	;
 20188 00004F99 66891D[06710000]    <1> 	mov	[u.quit], bx
 20189 00004FA0 E951EDFFFF          <1> 	jmp	sysret
 20190                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
 20191                              <1> 	;1:
 20192                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
 20193                              <1> 			      ; / to r1
 20194                              <1> 		; beq sysret4 / return to user
 20195                              <1> 		; clrb 6(r1) / clear the interrupt character 
 20196                              <1> 			   ; / in the tty buffer
 20197                              <1> 		; br sysret4 / return to user
 20198                              <1> 
 20199                              <1> syssetuid: ; / set process id
 20200                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20201                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
 20202                              <1> 	;
 20203                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
 20204                              <1> 	; to the process id in (u.r0). Both the effective user and 
 20205                              <1> 	; u.uid and the real user u.ruid are set to this. 
 20206                              <1> 	; Only the super user can make this call.	
 20207                              <1> 	;
 20208                              <1> 	; Calling sequence:
 20209                              <1> 	;	syssetuid
 20210                              <1> 	; Arguments: -
 20211                              <1> 	;
 20212                              <1> 	; Inputs: (u.r0) - contains the process id.
 20213                              <1> 	; Outputs: -
 20214                              <1> 	; ...............................................................
 20215                              <1> 	;	
 20216                              <1> 	; Retro UNIX 8086 v1 modification: 
 20217                              <1> 	;       BL contains the (new) user ID of the current process
 20218                              <1> 
 20219                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
 20220 00004FA5 3A1D[0C710000]      <1> 	cmp	bl, [u.ruid] 
 20221                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
 20222                              <1> 			       ; / id number
 20223 00004FAB 741E                <1> 	je	short setuid1
 20224                              <1> 		; beq 1f / yes
 20225 00004FAD 803D[0A710000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
 20226                              <1> 		; tstb u.uid / no, is current user the super user?
 20227                              <1> 	;ja	error
 20228                              <1> 		; bne error4 / no, error
 20229 00004FB4 760F                <1> 	jna	short setuid0
 20230 00004FB6 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
 20231 00004FBE 0000                <1>
 20232                              <1> 				;  'permission denied !' error
 20233 00004FC0 E911EDFFFF          <1> 	jmp	error
 20234                              <1> setuid0:
 20235 00004FC5 881D[0C710000]      <1> 	mov	[u.ruid], bl
 20236                              <1> setuid1: ; 1:
 20237 00004FCB 881D[0A710000]      <1> 	mov	[u.uid], bl ; 02/08/2013
 20238                              <1> 		; movb r1,u.uid / put process id in u.uid
 20239                              <1> 		; movb r1,u.ruid / put process id in u.ruid
 20240 00004FD1 E920EDFFFF          <1> 	jmp	sysret
 20241                              <1> 		; br sysret4 / system return
 20242                              <1> 
 20243                              <1> sysgetuid: ; < get user id >
 20244                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20245                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
 20246                              <1> 	;
 20247                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
 20248                              <1> 	; The real user ID identifies the person who is logged in,
 20249                              <1> 	; in contradistinction to the effective user ID, which
 20250                              <1> 	; determines his access permission at each moment. It is thus
 20251                              <1> 	; useful to programs which operate using the 'set user ID'
 20252                              <1> 	; mode, to find out who invoked them.	
 20253                              <1> 	;
 20254                              <1> 	; Calling sequence:
 20255                              <1> 	;	syssetuid
 20256                              <1> 	; Arguments: -
 20257                              <1> 	;
 20258                              <1> 	; Inputs: -
 20259                              <1> 	; Outputs: (u.r0) - contains the real user's id.
 20260                              <1> 	; ...............................................................
 20261                              <1> 	;	
 20262                              <1> 	; Retro UNIX 8086 v1 modification: 
 20263                              <1> 	;       AL contains the real user ID at return.
 20264                              <1> 	;
 20265 00004FD6 0FB605[0C710000]    <1> 	movzx 	eax, byte [u.ruid]
 20266 00004FDD A3[B4700000]        <1> 	mov	[u.r0], eax
 20267                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
 20268 00004FE2 E90FEDFFFF          <1> 	jmp	sysret
 20269                              <1> 		; br sysret4 / systerm return, sysret
 20270                              <1> 
 20271                              <1> anyi: 
 20272                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 20273                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
 20274                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
 20275                              <1> 	;
 20276                              <1> 	; 'anyi' is called if a file deleted while open.
 20277                              <1> 	; "anyi" checks to see if someone else has opened this file.
 20278                              <1> 	;
 20279                              <1> 	; INPUTS ->
 20280                              <1> 	;    r1 - contains an i-number
 20281                              <1> 	;    fsp - start of table containing open files
 20282                              <1> 	;
 20283                              <1> 	; OUTPUTS ->
 20284                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
 20285                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
 20286                              <1> 	;    if file not found - bit in i-node map is cleared
 20287                              <1> 	;    			 (i-node is freed)
 20288                              <1> 	;               all blocks related to i-node are freed
 20289                              <1> 	;	        all flags in i-node are cleared
 20290                              <1> 	; ((AX = R1)) input
 20291                              <1> 	;
 20292                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 20293                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 20294                              <1> 	;
 20295                              <1> 		; / r1 contains an i-number
 20296 00004FE7 BB[506D0000]        <1> 	mov	ebx, fsp
 20297                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
 20298                              <1> anyi_1: ; 1:
 20299 00004FEC 663B03              <1> 	cmp	ax, [ebx]
 20300                              <1> 		; cmp r1,(r2) / do i-numbers match?
 20301 00004FEF 7433                <1> 	je	short anyi_3
 20302                              <1> 		; beq 1f / yes, 1f
 20303 00004FF1 66F7D8              <1> 	neg	ax
 20304                              <1> 		; neg r1 / no complement r1
 20305 00004FF4 663B03              <1> 	cmp	ax, [ebx]
 20306                              <1> 		; cmp r1,(r2) / do they match now?
 20307 00004FF7 742B                <1> 	je	short anyi_3
 20308                              <1> 		; beq 1f / yes, transfer
 20309                              <1> 		; / i-numbers do not match
 20310 00004FF9 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
 20311                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
 20312                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
 20313                              <1> 	; 22/11/2021
 20314 00004FFC 81FB[70700000]      <1> 	cmp	ebx, fsp + (NFILES*fp.size) ; fsp+(NFILES*16)
 20315                              <1> 	;cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
 20316                              <1> 		; cmp r2,$fsp+[nfiles*8] 
 20317                              <1> 				; / are we at last entry in the table
 20318 00005002 72E8                <1> 	jb	short anyi_1
 20319                              <1> 		; blt 1b / no, check next entries i-number
 20320                              <1> 	;cmp	ax, 32768
 20321 00005004 80FC80              <1> 	cmp	ah, 80h ; negative number check
 20322                              <1> 		; tst r1 / yes, no match
 20323                              <1> 		; bge .+4
 20324 00005007 7203                <1> 	jb	short anyi_2
 20325 00005009 66F7D8              <1> 	neg	ax
 20326                              <1> 		; neg r1 / make i-number positive
 20327                              <1> anyi_2:	
 20328 0000500C E886070000          <1> 	call	imap
 20329                              <1> 		; jsr r0,imap / get address of allocation bit 
 20330                              <1> 			    ; / in the i-map in r2
 20331                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
 20332                              <1>         ;; eBX (R2) has address of the byte with allocation bit
 20333                              <1>  	; not	dx
 20334 00005011 F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
 20335                              <1>         ;and	[ebx], dx
 20336 00005013 2013                <1> 	and 	[ebx], dl 
 20337                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
 20338 00005015 E806070000          <1> 	call	itrunc
 20339                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
 20340 0000501A 66C705[506D0000]00- <1>  	mov 	word [i.flgs], 0
 20341 00005022 00                  <1>
 20342                              <1> 		; clr i.flgs / clear all flags in the i-node
 20343 00005023 C3                  <1> 	retn
 20344                              <1> 		;rts	r0 / return
 20345                              <1> anyi_3: ; 1: / i-numbers match
 20346 00005024 FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
 20347                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
 20348                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
 20349 00005027 C3                  <1> 	retn
 20350                              <1> 		; rts r0
 20351                                  %include 'u3.s'      ; 10/05/2015
 20352                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS3.INC
 20353                              <1> ; Last Modification: 15/09/2015
 20354                              <1> ; ----------------------------------------------------------------------------
 20355                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 20356                              <1> ; (v0.1 - Beginning: 11/07/2012)
 20357                              <1> ;
 20358                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 20359                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 20360                              <1> ; <Bell Laboratories (17/3/1972)>
 20361                              <1> ; <Preliminary Release of UNIX Implementation Document>
 20362                              <1> ;
 20363                              <1> ; Retro UNIX 8086 v1 - U3.ASM (08/03/2014) //// UNIX v1 -> u3.s
 20364                              <1> ;
 20365                              <1> ; ****************************************************************************
 20366                              <1> 
 20367                              <1> tswitch: ; Retro UNIX 386 v1
 20368                              <1> tswap:
 20369                              <1> 	; 01/09/2015
 20370                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 20371                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 20372                              <1> 	; time out swap, called when a user times out.
 20373                              <1> 	; the user is put on the low priority queue.
 20374                              <1> 	; This is done by making a link from the last user
 20375                              <1> 	; on the low priority queue to him via a call to 'putlu'.
 20376                              <1> 	; then he is swapped out.
 20377                              <1> 	;
 20378                              <1> 	; Retro UNIX 386 v1 modification ->
 20379                              <1> 	;       swap (software task switch) is performed by changing
 20380                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 20381                              <1> 	;	as in Retro UNIX 8086 v1.
 20382                              <1> 	;
 20383                              <1> 	; RETRO UNIX 8086 v1 modification ->
 20384                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 20385                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 20386                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 20387                              <1> 	;	compatibles was using 1MB segmented memory 
 20388                              <1> 	;	in 8086/8088 times.
 20389                              <1> 	;
 20390                              <1> 	; INPUTS ->
 20391                              <1> 	;    u.uno - users process number
 20392                              <1> 	;    runq+4 - lowest priority queue
 20393                              <1> 	; OUTPUTS ->
 20394                              <1> 	;    r0 - users process number
 20395                              <1> 	;    r2 - lowest priority queue address
 20396                              <1> 	;
 20397                              <1> 	; ((AX = R0, BX = R2)) output
 20398                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
 20399                              <1> 	;
 20400 00005028 A0[09710000]        <1> 	mov 	al, [u.uno]
 20401                              <1> 	       	; movb u.uno,r1 / move users process number to r1
 20402                              <1> 		; mov  $runq+4,r2 
 20403                              <1> 			; / move lowest priority queue address to r2
 20404 0000502D E8CE000000          <1>         call 	putlu
 20405                              <1> 		; jsr r0,putlu / create link from last user on Q to 
 20406                              <1> 		             ; / u.uno's user
 20407                              <1> 
 20408                              <1> switch: ; Retro UNIX 386 v1
 20409                              <1> swap:
 20410                              <1> 	; 02/09/2015
 20411                              <1> 	; 01/09/2015
 20412                              <1> 	; 31/08/2015
 20413                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 20414                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 20415                              <1> 	; 'swap' is routine that controls the swapping of processes
 20416                              <1> 	; in and out of core.
 20417                              <1> 	;
 20418                              <1> 	; Retro UNIX 386 v1 modification ->
 20419                              <1> 	;       swap (software task switch) is performed by changing
 20420                              <1> 	;	user's page directory (u.pgdir) instead of segment change
 20421                              <1> 	;	as in Retro UNIX 8086 v1.
 20422                              <1> 	;
 20423                              <1> 	; RETRO UNIX 8086 v1 modification ->
 20424                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 20425                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 20426                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 20427                              <1> 	;	compatibles was using 1MB segmented memory 
 20428                              <1> 	;	in 8086/8088 times.
 20429                              <1> 	;
 20430                              <1> 	; INPUTS ->
 20431                              <1> 	;    runq table - contains processes to run.
 20432                              <1> 	;    p.link - contains next process in line to be run.
 20433                              <1> 	;    u.uno - process number of process in core	
 20434                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
 20435                              <1> 	; OUTPUTS ->
 20436                              <1> 	;    (original unix v1 -> present process to its disk block)
 20437                              <1> 	;    (original unix v1 -> new process into core -> 
 20438                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
 20439                              <1> 	;	   for new process)
 20440                              <1> 	;    u.quant = 3 (Time quantum for a process)
 20441                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
 20442                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
 20443                              <1> 	;	 for now, it will swap the process if there is not
 20444                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
 20445                              <1> 	;	 or will count down from 3 to 0 even if there is a
 20446                              <1> 	;        keyboard event locking due to repetitive key strokes.
 20447                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
 20448                              <1> 	;
 20449                              <1> 	;    u.pri -points to highest priority run Q.
 20450                              <1> 	;    r2 - points to the run queue.
 20451                              <1> 	;    r1 - contains new process number
 20452                              <1> 	;    r0 - points to place in routine or process that called
 20453                              <1> 	;	  swap all user parameters
 20454                              <1> 	;				
 20455                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
 20456                              <1> 	;
 20457                              <1> swap_0:
 20458                              <1> 		;mov $300,*$ps / processor priority = 6
 20459 00005032 BE[A4700000]        <1> 	mov	esi, runq
 20460                              <1> 		; mov $runq,r2 / r2 points to runq table
 20461                              <1> swap_1: ; 1: / search runq table for highest priority process
 20462 00005037 668B06              <1> 	mov	ax, [esi]
 20463 0000503A 6621C0              <1> 	and 	ax, ax
 20464                              <1>        		; tst (r2)+ / are there any processes to run 
 20465                              <1> 			  ; / in this Q entry
 20466 0000503D 7507                <1> 	jnz	short swap_2
 20467                              <1>        		; bne 1f / yes, process 1f
 20468                              <1> 		; cmp r2,$runq+6 / if zero compare address 
 20469                              <1> 			       ; / to end of table
 20470                              <1> 		; bne 1b / if not at end, go back
 20471 0000503F E8E1000000          <1> 	call	idle
 20472                              <1> 		; jsr r0,idle; s.idlet+2 / wait for interrupt; 
 20473                              <1> 				       ; / all queues are empty
 20474 00005044 EBF1                <1> 	jmp	short swap_1
 20475                              <1> 		; br swap
 20476                              <1> swap_2: ; 1:
 20477 00005046 0FB6D8              <1> 	movzx	ebx, al ; 02/09/2015
 20478                              <1> 		; tst -(r2) / restore pointer to right Q entry
 20479                              <1>  		; mov r2,u.pri / set present user to this run queue
 20480                              <1> 	        ; movb (r2)+,r1 / move 1st process in queue to r1
 20481 00005049 38E0                <1> 	cmp	al, ah
 20482                              <1> 		; cmpb r1,(r2)+ / is there only 1 process 
 20483                              <1> 			      ; / in this Q to be run
 20484 0000504B 740A                <1> 	je	short swap_3
 20485                              <1>        		; beq 1f / yes
 20486                              <1> 		; tst -(r2) / no, pt r2 back to this Q entry
 20487                              <1> 	;movzx	ebx, al
 20488 0000504D 8AA3[0F6E0000]      <1> 	mov	ah, [ebx+p.link-1] 
 20489 00005053 8826                <1>        	mov	[esi], ah
 20490                              <1> 		; movb p.link-1(r1),(r2) / move next process 
 20491                              <1> 				       ; / in line into run queue
 20492 00005055 EB06                <1> 	jmp	short swap_4
 20493                              <1>        		; br 2f
 20494                              <1> swap_3: ; 1:
 20495 00005057 6631D2              <1> 	xor	dx, dx
 20496 0000505A 668916              <1> 	mov	[esi], dx
 20497                              <1> 		; clr -(r2) / zero the entry; no processes on the Q
 20498                              <1> swap_4: ; / write out core to appropriate disk area and read 
 20499                              <1>       ; / in new process if required
 20500                              <1>        		; clr *$ps / clear processor status
 20501 0000505D 8A25[09710000]      <1> 	mov 	ah, [u.uno]
 20502 00005063 38C4                <1> 	cmp	ah, al
 20503                              <1> 		; cmpb r1,u.uno / is this process the same as 
 20504                              <1> 			      ; / the process in core?
 20505 00005065 743B                <1>        	je	short swap_8
 20506                              <1>        		; beq 2f / yes, don't have to swap
 20507                              <1>        		; mov r0,-(sp) / no, write out core; save r0 
 20508                              <1> 			   ; / (address in routine that called swap)
 20509                              <1> 		; mov r1,-(sp) / put r1 (new process #) on the stack
 20510                              <1> 	; 01/09/2015
 20511                              <1> 	;mov	[u.usp], esp
 20512                              <1>        		; mov sp,u.usp / save stack pointer
 20513                              <1> 		; mov $sstack,sp / move swap stack pointer 
 20514                              <1> 			       ; / to the stack pointer
 20515 00005067 08E4                <1> 	or	ah, ah
 20516                              <1>        		; tstb u.uno / is the process # = 0
 20517 00005069 740D                <1>        	jz	short swap_6 ; 'sysexit'
 20518                              <1> 		; beq  1f / yes, kill process by overwriting
 20519                              <1> 	; 02/09/2015
 20520 0000506B 8925[B0700000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
 20521                              <1> 	;
 20522 00005071 E834000000          <1> 	call	wswap
 20523                              <1> 		;jsr r0,wswap / write out core to disk
 20524                              <1> 	 ; 31/08/2015
 20525                              <1> 	;movzx	ebx, al ; New (running) process number
 20526 00005076 EB1C                <1> 	jmp 	short swap_7
 20527                              <1> swap_6:
 20528                              <1> 	; 31/08/2015
 20529                              <1> 	; Deallocate memory pages belong to the process
 20530                              <1> 	; which is being terminated
 20531                              <1> 	; 14/05/2015 ('sysexit')
 20532                              <1>  	; Deallocate memory pages of the process
 20533                              <1> 	; (Retro UNIX 386 v1 modification !)
 20534                              <1> 	;
 20535                              <1> 	; movzx ebx, al
 20536 00005078 53                  <1> 	push	ebx
 20537 00005079 A1[18710000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
 20538 0000507E 8B1D[1C710000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
 20539 00005084 E819E0FFFF          <1> 	call	deallocate_page_dir
 20540 00005089 A1[14710000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
 20541 0000508E E8A7E0FFFF          <1> 	call	deallocate_page
 20542 00005093 5B                  <1> 	pop	ebx
 20543                              <1> swap_7: ;1: 
 20544                              <1> 	; 02/09/2015
 20545                              <1> 	; 31/08/2015
 20546                              <1> 	; 14/05/2015
 20547 00005094 C0E302              <1> 	shl	bl, 2 ; * 4 
 20548 00005097 8B83[2C6E0000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
 20549                              <1> 	;cli
 20550 0000509D E831000000          <1> 	call	rswap
 20551                              <1>  		; mov (sp)+,r1 / restore r1 to new process number
 20552                              <1> 		; jsr r0,rswap / read new process into core
 20553                              <1>        		; jsr r0,unpack / unpack the users stack from next
 20554                              <1> 			      ; / to his program to its normal
 20555                              <1> 	; 01/09/2015
 20556                              <1> 	;mov	esp, [u.usp]	
 20557                              <1> 		; mov u.usp,sp / location; restore stack pointer to
 20558                              <1> 			     ; / new process stack
 20559                              <1> 		; mov (sp)+,r0 / put address of where the process 
 20560                              <1> 			     ; / that just got swapped in, left off.,
 20561                              <1> 			     ; / i.e., transfer control to new process
 20562                              <1> 	;sti
 20563                              <1> swap_8: ;2:
 20564                              <1> 	; RETRO UNIX 8086 v1 modification !
 20565 000050A2 C605[00710000]04    <1> 	mov	byte [u.quant], time_count 
 20566                              <1> 		; movb $30.,uquant / initialize process time quantum
 20567 000050A9 C3                  <1> 	retn
 20568                              <1> 		; rts r0 / return
 20569                              <1> 
 20570                              <1> wswap:  ; < swap out, swap to disk >
 20571                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 20572                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 20573                              <1> 	; 'wswap' writes out the process that is in core onto its 
 20574                              <1> 	; appropriate disk area.
 20575                              <1> 	;
 20576                              <1> 	; Retro UNIX 386 v1 modification ->
 20577                              <1> 	;       User (u) structure content and the user's register content
 20578                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
 20579                              <1> 	;	saving 'u' structure and user registers for task switching).
 20580                              <1> 	;	u.usp - points to kernel stack address which contains
 20581                              <1> 	;		user's registers while entering system call.  
 20582                              <1> 	;	u.sp  - points to kernel stack address 
 20583                              <1> 	;		to return from system call -for IRET-.
 20584                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 20585                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 20586                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 20587                              <1> 	;
 20588                              <1> 	; Retro UNIX 8086 v1 modification ->
 20589                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 20590                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 20591                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 20592                              <1> 	;	compatibles was using 1MB segmented memory 
 20593                              <1> 	;	in 8086/8088 times.
 20594                              <1> 	;
 20595                              <1> 	; INPUTS ->
 20596                              <1> 	;    u.break - points to end of program
 20597                              <1> 	;    u.usp - stack pointer at the moment of swap
 20598                              <1> 	;    core - beginning of process program		
 20599                              <1> 	;    ecore - end of core 	
 20600                              <1> 	;    user - start of user parameter area		
 20601                              <1> 	;    u.uno - user process number	
 20602                              <1> 	;    p.dska - holds block number of process	
 20603                              <1> 	; OUTPUTS ->
 20604                              <1> 	;    swp I/O queue
 20605                              <1> 	;    p.break - negative word count of process 
 20606                              <1> 	;    r1 - process disk address	
 20607                              <1> 	;    r2 - negative word count
 20608                              <1> 	;
 20609                              <1> 	; RETRO UNIX 8086 v1 input/output:
 20610                              <1> 	;
 20611                              <1> 	; INPUTS ->
 20612                              <1> 	;    u.uno - process number (to be swapped out)
 20613                              <1> 	; OUTPUTS ->
 20614                              <1> 	;    none
 20615                              <1> 	;
 20616                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
 20617                              <1> 	;
 20618 000050AA 8B3D[14710000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
 20619 000050B0 B94C000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 20620 000050B5 BE[AC700000]        <1> 	mov	esi, user ; active user (u) structure	
 20621 000050BA F3A5                <1> 	rep	movsd
 20622                              <1> 	;
 20623 000050BC 8B35[B0700000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
 20624                              <1> 			     ;      points to user registers)
 20625 000050C2 8B0D[AC700000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 20626                              <1> 			     ; (for IRET)
 20627                              <1> 			     ; [u.sp] -> EIP (user)
 20628                              <1> 			     ; [u.sp+4]-> CS (user)
 20629                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 20630                              <1> 			     ; [u.sp+12] -> ESP (user)
 20631                              <1> 			     ; [u.sp+16] -> SS (user)	
 20632 000050C8 29F1                <1> 	sub	ecx, esi     ; required space for user registers
 20633 000050CA 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 20634                              <1> 			     ; (for IRET) 	
 20635 000050CD C1E902              <1> 	shr	ecx, 2	     		
 20636 000050D0 F3A5                <1> 	rep	movsd
 20637 000050D2 C3                  <1> 	retn
 20638                              <1> 
 20639                              <1> 	; Original UNIX v1 'wswap' routine:
 20640                              <1> 	; wswap:
 20641                              <1> 		; mov *$30,u.emt / determines handling of emts
 20642                              <1>         	; mov *$10,u.ilgins / determines handling of 
 20643                              <1> 				; / illegal instructions
 20644                              <1> 		; mov u.break,r2 / put process program break address in r2
 20645                              <1> 		; inc r2 / add 1 to it 
 20646                              <1> 		; bic $1,r2 / make it even
 20647                              <1> 		; mov r2,u.break / set break to an even location
 20648                              <1> 		; mov u.usp,r3 / put users stack pointer 
 20649                              <1> 			     ; / at moment of swap in r3
 20650                              <1> 		; cmp r2,$core / is u.break less than $core
 20651                              <1> 		; blos 2f / yes
 20652                              <1> 		; cmp r2,r3 / no, is (u.break) greater than stack ptr.
 20653                              <1>        		; bhis 2f / yes
 20654                              <1> 	; 1:
 20655                              <1>        		; mov (r3)+,(r2)+ / no, pack stack next to users program
 20656                              <1> 		; cmp r3,$ecore / has stack reached end of core
 20657                              <1> 		; bne 1b / no, keep packing
 20658                              <1> 	 	; br 1f / yes
 20659                              <1> 	; 2:
 20660                              <1>        		; mov $ecore,r2 / put end of core in r2 
 20661                              <1> 	; 1:
 20662                              <1>        		; sub  $user,r2 / get number of bytes to write out 
 20663                              <1> 			   ; / (user up to end of stack gets written out)
 20664                              <1> 		; neg r2 / make it negative
 20665                              <1> 		; asr r2 / change bytes to words (divide by 2)
 20666                              <1> 		; mov r2,swp+4 / word count
 20667                              <1> 		; movb u.uno,r1 / move user process number to r1
 20668                              <1> 		; asl r1 / x2 for index
 20669                              <1>       		; mov r2,p.break-2(r1) / put negative of word count 
 20670                              <1> 				     ; / into the p.break table
 20671                              <1>        		; mov p.dska-2(r1),r1 / move disk address of swap area 
 20672                              <1> 				    ; /	for process to r1
 20673                              <1>        		; mov r1,swp+2 / put processes dska address in swp+2 
 20674                              <1> 			     ; / (block number)
 20675                              <1> 		; bis $1000,swp / set it up to write (set bit 9)
 20676                              <1>        		; jsr r0,ppoke / write process out on swap area of disk
 20677                              <1> 	; 1:
 20678                              <1>        		; tstb swp+1 / is lt done writing?
 20679                              <1>        		; bne 1b / no, wait
 20680                              <1> 		; rts r0 / yes, return to swap
 20681                              <1> 
 20682                              <1> rswap:  ; < swap in, swap from disk >
 20683                              <1> 	; 15/09/2015
 20684                              <1> 	; 28/08/2015
 20685                              <1> 	; 14/05/2015
 20686                              <1> 	; 09/05/2015 (Retro UNIX 386 v1 - Beginning)
 20687                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
 20688                              <1> 	; 'rswap' reads a process whose number is in r1, 
 20689                              <1> 	; from disk into core.
 20690                              <1> 	;
 20691                              <1> 	; Retro UNIX 386 v1 modification ->
 20692                              <1> 	;       User (u) structure content and the user's register content
 20693                              <1> 	;	will be restored from process's/user's UPAGE (a page for
 20694                              <1> 	;	saving 'u' structure and user registers for task switching).
 20695                              <1> 	;	u.usp - points to kernel stack address which contains
 20696                              <1> 	;		user's registers while entering system call.  
 20697                              <1> 	;	u.sp  - points to kernel stack address 
 20698                              <1> 	;		to return from system call -for IRET-.
 20699                              <1> 	;	[u.usp]+32+16 = [u.sp] 
 20700                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
 20701                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
 20702                              <1> 	;
 20703                              <1> 	; RETRO UNIX 8086 v1 modification ->
 20704                              <1> 	;       'swap to disk' is replaced with 'change running segment'
 20705                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
 20706                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
 20707                              <1> 	;	compatibles was using 1MB segmented memory 
 20708                              <1> 	;	in 8086/8088 times.
 20709                              <1> 	;
 20710                              <1> 	; INPUTS ->
 20711                              <1> 	;    r1 - process number of process to be read in
 20712                              <1> 	;    p.break - negative of word count of process 
 20713                              <1> 	;    p.dska - disk address of the process		
 20714                              <1> 	;    u.emt - determines handling of emt's 	
 20715                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 20716                              <1> 	; OUTPUTS ->
 20717                              <1> 	;    8 = (u.ilgins)
 20718                              <1> 	;    24 = (u.emt)
 20719                              <1> 	;    swp - bit 10 is set to indicate read 
 20720                              <1> 	;		(bit 15=0 when reading is done)	
 20721                              <1> 	;    swp+2 - disk block address
 20722                              <1> 	;    swp+4 - negative word count 	
 20723                              <1> 	;      ((swp+6 - address of user structure)) 
 20724                              <1> 	;
 20725                              <1> 	; RETRO UNIX 8086 v1 input/output:
 20726                              <1> 	;
 20727                              <1> 	; INPUTS ->
 20728                              <1> 	;    AL	- new process number (to be swapped in)	 
 20729                              <1> 	; OUTPUTS ->
 20730                              <1> 	;    none
 20731                              <1> 	;
 20732                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
 20733                              <1> 	;
 20734                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
 20735 000050D3 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
 20736 000050D5 B94C000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
 20737 000050DA BF[AC700000]        <1> 	mov	edi, user ; active user (u) structure	
 20738 000050DF F3A5                <1> 	rep	movsd
 20739 000050E1 58                  <1> 	pop	eax ; 15/09/2015, 'rswap' return address 
 20740 000050E2 8B3D[B0700000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
 20741                              <1> 			     ;      points to user registers)
 20742 000050E8 8B0D[AC700000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
 20743                              <1> 			     ; (for IRET)
 20744                              <1> 			     ; [u.sp] -> EIP (user)
 20745                              <1> 			     ; [u.sp+4]-> CS (user)
 20746                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
 20747                              <1> 			     ; [u.sp+12] -> ESP (user)
 20748                              <1> 			     ; [u.sp+16] -> SS (user)		
 20749                              <1> 	; 28/08/2015
 20750 000050EE 29F9                <1> 	sub	ecx, edi     ; required space for user registers
 20751 000050F0 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
 20752                              <1> 			     ; (for IRET) 	
 20753 000050F3 C1E902              <1> 	shr	ecx, 2	       		
 20754 000050F6 F3A5                <1> 	rep	movsd
 20755 000050F8 8B25[B0700000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
 20756 000050FE 50                  <1> 	push	eax ; 15/09/2015 'rswap' return address
 20757 000050FF C3                  <1> 	retn
 20758                              <1> 
 20759                              <1> 	; Original UNIX v1 'rswap'  and 'unpack' routines:
 20760                              <1> 	;rswap:
 20761                              <1>        		; asl r1 / process number x2 for index
 20762                              <1>        		; mov p.break-2(r1), swp+4 / word count
 20763                              <1>        		; mov p.dska-2(r1),swp+2 / disk address
 20764                              <1>        		; bis $2000,swp / read
 20765                              <1>        		; jsr r0,ppoke / read it in 
 20766                              <1> 	; 1:
 20767                              <1>        		; tstb swp+1 / done
 20768                              <1>        		; bne 1b / no, wait for bit 15 to clear (inhibit bit)
 20769                              <1>        		; mov u.emt,*$30 / yes move these
 20770                              <1>        		; mov u.ilgins,*$10 / back
 20771                              <1>        		; rts r0 / return
 20772                              <1> 
 20773                              <1> 	;unpack: ; / move stack back to its normal place
 20774                              <1> 		; mov u.break,r2 / r2 points to end of user program
 20775                              <1>        		; cmp r2,$core / at beginning of user program yet?
 20776                              <1> 		; blos 2f / yes, return
 20777                              <1> 		; cmp r2,u.usp / is break_above the stack pointer 
 20778                              <1> 			     ; / before swapping
 20779                              <1> 		; bhis 2f / yes, return
 20780                              <1> 		; mov $ecore,r3 / r3 points to end of core
 20781                              <1> 		; add r3,r2
 20782                              <1> 		; sub u.usp,r2 / end of users stack is in r2
 20783                              <1> 	; 1:
 20784                              <1> 		; mov -(r2),-(r3) / move stack back to its normal place
 20785                              <1> 		; cmp r2,u.break / in core
 20786                              <1> 		; bne 1b
 20787                              <1> 	; 2:
 20788                              <1>        		; rts r0
 20789                              <1> 
 20790                              <1> putlu: 
 20791                              <1> 	; 12/09/2015
 20792                              <1> 	; 02/09/2015
 20793                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 20794                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
 20795                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
 20796                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
 20797                              <1> 	; the last process on the queue to process in r1 by putting
 20798                              <1> 	; the process number in r1 into the last process's link.
 20799                              <1> 	;
 20800                              <1> 	; INPUTS ->
 20801                              <1> 	;    r1 - user process number
 20802                              <1> 	;    r2 - points to lowest priority queue 
 20803                              <1> 	;    p.dska - disk address of the process		
 20804                              <1> 	;    u.emt - determines handling of emt's 	
 20805                              <1> 	;    u.ilgins - determines handling of illegal instructions		
 20806                              <1> 	; OUTPUTS ->
 20807                              <1> 	;    r3 - process number of last process on the queue upon
 20808                              <1> 	;	  entering putlu
 20809                              <1> 	;    p.link-1 + r3 - process number in r1
 20810                              <1> 	;    r2 - points to lowest priority queue
 20811                              <1> 	;
 20812                              <1> 	; ((Modified registers: EDX, EBX)) 
 20813                              <1> 	;
 20814                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
 20815                              <1> 
 20816                              <1> 	; eBX = r2
 20817                              <1> 	; eAX = r1 (AL=r1b)
 20818                              <1> 
 20819 00005100 BB[A4700000]        <1> 	mov	ebx, runq
 20820 00005105 0FB613              <1> 	movzx  	edx, byte [ebx]
 20821 00005108 43                  <1> 	inc	ebx
 20822 00005109 20D2                <1> 	and	dl, dl
 20823                              <1> 		; tstb (r2)+ / is queue empty?
 20824 0000510B 740A                <1>        	jz	short putlu_1
 20825                              <1> 		; beq 1f / yes, branch
 20826 0000510D 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
 20827                              <1> 		; movb (r2),r3 / no, save the "last user" process number
 20828                              <1> 			     ; / in r3
 20829 0000510F 8882[0F6E0000]      <1>        	mov	[edx+p.link-1], al
 20830                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
 20831                              <1> 			     ; / "last users" link
 20832 00005115 EB03                <1> 	jmp	short putlu_2
 20833                              <1> 		; br 2f /
 20834                              <1> putlu_1: ; 1:
 20835 00005117 8843FF              <1> 	mov	[ebx-1], al
 20836                              <1>        		; movb r1,-1(r2) / user is only user; 
 20837                              <1> 			    ; / put process no. at beginning and at end
 20838                              <1> putlu_2: ; 2: 
 20839 0000511A 8803                <1> 	mov	[ebx], al
 20840                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
 20841                              <1> 			     ; / on the queue
 20842 0000511C 88C2                <1> 	mov	dl, al
 20843 0000511E 88B2[0F6E0000]      <1>         mov     [edx+p.link-1], dh ; 0
 20844                              <1> 		; dec r2 / restore r2
 20845 00005124 C3                  <1>         retn
 20846                              <1> 		; rts r0
 20847                              <1> 
 20848                              <1> ;copyz:
 20849                              <1> ;       mov     r1,-(sp) / put r1 on stack
 20850                              <1> ;       mov     r2,-(sp) / put r2 on stack
 20851                              <1> ;       mov     (r0)+,r1
 20852                              <1> ;       mov     (r0)+,r2
 20853                              <1> ;1:
 20854                              <1> ;       clr     (r1)+ / clear all locations between r1 and r2
 20855                              <1> ;       cmp     r1,r2 
 20856                              <1> ;       blo     1b
 20857                              <1> ;       mov     (sp)+,r2 / restore r2
 20858                              <1> ;       mov     (sp)+,r1 / restore r1
 20859                              <1> ;       rts     r0 
 20860                              <1> 
 20861                              <1> idle:
 20862                              <1> 	; 01/09/2015
 20863                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 20864                              <1> 	; 10/04/2013 - 23/10/2013 (Retro UNIX 8086 v1)
 20865                              <1> 	; (idle & wait loop)
 20866                              <1> 	; Retro Unix 8086 v1 modification on original UNIX v1
 20867                              <1> 	; idle procedure!
 20868                              <1>       	;
 20869                              <1>   	; 01/09/2015
 20870 00005125 FB                  <1> 	sti
 20871                              <1>       	; 29/07/2013
 20872 00005126 F4                  <1>       	hlt
 20873 00005127 90                  <1>       	nop ; 10/10/2013
 20874 00005128 90                  <1>       	nop
 20875 00005129 90                  <1>       	nop
 20876                              <1>       	; 23/10/2013
 20877 0000512A 90                  <1>       	nop
 20878 0000512B 90                  <1>       	nop
 20879 0000512C 90                  <1>       	nop
 20880 0000512D 90                  <1>       	nop
 20881 0000512E C3                  <1>       	retn      
 20882                              <1> 
 20883                              <1> 	;mov *$ps,-(sp) / save ps on stack
 20884                              <1> 	;clr *$ps / clear ps
 20885                              <1> 	;mov clockp,-(sp) / save clockp on stack
 20886                              <1> 	;mov (r0)+,clockp / arg to idle in clockp
 20887                              <1> 	;1 / wait for interrupt
 20888                              <1> 	;mov (sp)+,clockp / restore clockp, ps
 20889                              <1> 	;mov (sp)+,*$ps
 20890                              <1> 	;rts r0
 20891                              <1> 
 20892                              <1> clear:
 20893                              <1> 	; 10/05/2015 (Retro UNIX 386 v1 - Beginning)
 20894                              <1> 	; 09/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 20895                              <1> 	; 'clear' zero's out of a block (whose block number is in r1)
 20896                              <1> 	; on the current device (cdev)
 20897                              <1> 	;	
 20898                              <1> 	; INPUTS ->
 20899                              <1> 	;    r1 - block number of block to be zeroed
 20900                              <1> 	;    cdev - current device number 
 20901                              <1> 	; OUTPUTS ->
 20902                              <1> 	;    a zeroed I/O buffer onto the current device
 20903                              <1> 	;    r1 - points to last entry in the I/O buffer
 20904                              <1> 	;
 20905                              <1> 	; ((AX = R1)) input/output
 20906                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 14/11/2012, UNIXCOPY.ASM)
 20907                              <1>         ;    ((Modified registers: EDX, ECX, EBX, ESI, EDI, EBP))  
 20908                              <1> 
 20909 0000512F E853100000          <1> 	call 	wslot
 20910                              <1> 		; jsr r0,wslot / get an I/O buffer set bits 9 and 15 in first
 20911                              <1>                    ; / word of I/O queue r5 points to first data word in buffer
 20912 00005134 89DF                <1> 	mov	edi, ebx ; r5
 20913 00005136 89C2                <1> 	mov	edx, eax
 20914 00005138 B980000000          <1> 	mov	ecx, 128
 20915                              <1> 		; mov $256.,r3
 20916 0000513D 31C0                <1> 	xor	eax, eax
 20917 0000513F F3AB                <1> 	rep	stosd
 20918 00005141 89D0                <1> 	mov	eax, edx
 20919                              <1> ; 1: 
 20920                              <1>        		; clr (r5)+ / zero data word in buffer
 20921                              <1>        		; dec r3
 20922                              <1>        		; bgt 1b / branch until all data words in buffer are zero
 20923 00005143 E85B100000          <1> 	call	dskwr
 20924                              <1> 		; jsr r0,dskwr / write zeroed buffer area out onto physical
 20925                              <1>                              ; / block specified in r1
 20926                              <1> 	; eAX (r1) = block number
 20927 00005148 C3                  <1> 	retn
 20928                              <1> 		; rts r0
 20929                                  %include 'u4.s'      ; 15/04/2015
 20930                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 20931                              <1> ; (re-write kernel for test by using previous version without a major defect)
 20932                              <1> ; ****************************************************************************
 20933                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS4.INC
 20934                              <1> ; Last Modification: 05/12/2021
 20935                              <1> ; ----------------------------------------------------------------------------
 20936                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 20937                              <1> ; (v0.1 - Beginning: 11/07/2012)
 20938                              <1> ;
 20939                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 20940                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 20941                              <1> ; <Bell Laboratories (17/3/1972)>
 20942                              <1> ; <Preliminary Release of UNIX Implementation Document>
 20943                              <1> ;
 20944                              <1> ; Retro UNIX 8086 v1 - U4.ASM (04/07/2014) //// UNIX v1 -> u4.s
 20945                              <1> ;
 20946                              <1> ; ****************************************************************************
 20947                              <1> 
 20948                              <1> ;setisp:
 20949                              <1>        ;mov     r1,-(sp)
 20950                              <1>        ;mov     r2,-(sp)
 20951                              <1>        ;mov     r3,-(sp)
 20952                              <1>        ;mov     clockp,-(sp)
 20953                              <1>        ;mov     $s.syst+2,clockp
 20954                              <1>        ;jmp     (r0)
 20955                              <1> 
 20956                              <1> clock: ; / interrupt from 60 cycle clock
 20957                              <1> 	
 20958                              <1> 	; 14/10/2015
 20959                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
 20960                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
 20961                              <1> 
 20962                              <1>        ;mov     r0,-(sp) / save r0
 20963                              <1>        ;tst     *$lks / restart clock?
 20964                              <1>        ;mov     $s.time+2,r0 / increment the time of day
 20965                              <1>        ;inc     (r0)
 20966                              <1>        ;bne     1f
 20967                              <1>        ;inc     -(r0)
 20968                              <1> ;1:
 20969                              <1>        ;mov     clockp,r0 / increment appropriate time category
 20970                              <1>        ;inc     (r0)
 20971                              <1>        ;bne     1f
 20972                              <1>        ;inc     -(r0)
 20973                              <1> ;1:
 20974                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 20975                              <1> 
 20976 00005149 803D[00710000]00    <1> 	cmp	byte [u.quant], 0
 20977 00005150 772C                <1> 	ja	short clk_1
 20978                              <1> 	;
 20979 00005152 803D[A9700000]FF    <1>         cmp     byte [sysflg], 0FFh ; user or system space ?
 20980 00005159 7529                <1> 	jne	short clk_2 ; system space (sysflg <> 0FFh)
 20981 0000515B 803D[09710000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ?
 20982 00005162 761A                <1> 	jna	short clk_1 ; yes, do not swap out
 20983 00005164 66833D[04710000]00  <1> 	cmp	word [u.intr], 0
 20984 0000516C 7616                <1> 	jna	short clk_2
 20985                              <1> clk_0:
 20986                              <1> 	; 14/10/2015
 20987 0000516E FE05[A9700000]      <1> 	inc	byte [sysflg] ; Now, we are in system space
 20988 00005174 58                  <1> 	pop	eax ; return address to the timer interrupt
 20989                              <1> 	;
 20990 00005175 B020                <1> 	MOV	AL,EOI			; GET END OF INTERRUPT MASK
 20991                              <1> 	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
 20992 00005177 E620                <1> 	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
 20993                              <1> 	;
 20994 00005179 E9DDEBFFFF          <1> 	jmp     sysrelease ; 'sys release' by clock/timer
 20995                              <1> clk_1:
 20996 0000517E FE0D[00710000]      <1> 	dec	byte [u.quant]
 20997                              <1> clk_2:
 20998 00005184 C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
 20999                              <1> 
 21000                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
 21001                              <1> 
 21002                              <1>        ;mov     $uquant,r0 / decrement user time quantum
 21003                              <1>        ;decb    (r0)
 21004                              <1>        ;bge     1f / if less than 0
 21005                              <1>        ;clrb    (r0) / make it 0
 21006                              <1> ;1: / decrement time out counts return now if priority was not 0
 21007                              <1>        ;cmp     4(sp),$200 / ps greater than or equal to 200
 21008                              <1>        ;bge     2f / yes, check time outs
 21009                              <1>        ;tstb    (r0) / no, user timed out?
 21010                              <1>        ;bne     1f / no
 21011                              <1>        ;cmpb    sysflg,$-1 / yes, are we outside the system?
 21012                              <1>        ;bne     1f / no, 1f
 21013                              <1>        ;mov     (sp)+,r0 / yes, put users r0 in r0
 21014                              <1>        ;sys     0 / sysrele
 21015                              <1>        ;rti
 21016                              <1> ;2: / priority is high so just decrement time out counts
 21017                              <1>        ;mov     $toutt,r0 / r0 points to beginning of time out table
 21018                              <1> ;2:
 21019                              <1>        ;tstb    (r0) / is the time out?
 21020                              <1>        ;beq     3f / yes, 3f (get next entry)
 21021                              <1>        ;decb    (r0) / no, decrement the time
 21022                              <1>        ;bne     3f / isit zero now?
 21023                              <1>        ;incb    (r0) / yes, increment the time
 21024                              <1> ;3:
 21025                              <1>        ;inc     r0 / next entry
 21026                              <1>        ;cmp     r0,$touts / end of toutt table?
 21027                              <1>        ;blo     2b / no, check this entry
 21028                              <1>        ;mov     (sp)+,r0 / yes, restore r0
 21029                              <1>        ;rti / return from interrupt
 21030                              <1> ;1: / decrement time out counts; if 0 call subroutine
 21031                              <1>        ;mov     (sp)+,r0 / restore r0
 21032                              <1>        ;mov     $240,*$ps / set processor priority to 5
 21033                              <1>        ;jsr     r0,setisp / save registers
 21034                              <1>        ;mov     $touts-toutt-1,r0 / set up r0 as index to decrement thru
 21035                              <1>                                ;  / the table
 21036                              <1> ;1:
 21037                              <1>        ;tstb    toutt(r0) / is the time out for this entry
 21038                              <1>        ;beq     2f / yes
 21039                              <1>        ;decb    toutt(r0) / no, decrement the time
 21040                              <1>        ;bne     2f / is the time 0, now
 21041                              <1>        ;asl     r0 / yes, 2 x r0 to get word index for tout entry
 21042                              <1>        ;jsr     r0,*touts(r0) / go to appropriate routine specified in this
 21043                              <1>        ;asr     r0 / touts entry; set r0 back to toutt index
 21044                              <1> ;2:
 21045                              <1>        ;dec     r0 / set up r0 for next entry
 21046                              <1>        ;bge     1b / finished? , no, go back
 21047                              <1>        ;br      retisp / yes, restore registers and do a rti
 21048                              <1> 
 21049                              <1> ;retisp:
 21050                              <1>        ;mov     (sp)+,clockp / pop values before interrupt off the stack
 21051                              <1>        ;mov     (sp)+,r3
 21052                              <1>        ;mov     (sp)+,r2
 21053                              <1>        ;mov     (sp)+,r1
 21054                              <1>        ;mov     (sp)+,r0
 21055                              <1>        ;rti     / return from interrupt
 21056                              <1> 
 21057                              <1> 
 21058                              <1> wakeup: ; / wakeup processes waiting for an event 
 21059                              <1> 	; / by linking them to the queue
 21060                              <1> 	;
 21061                              <1> 	; 15/09/2015
 21062                              <1> 	; 29/06/2015
 21063                              <1> 	; 15/04/2015 (Retro UNIX 386 v1 - Beginning)
 21064                              <1> 	;
 21065                              <1> 	; 15/05/2013 - 02/06/2014
 21066                              <1> 	; Retro UNIX 8086 v1 modification !
 21067                              <1> 	; (Process/task switching routine by using
 21068                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.)
 21069                              <1> 	;
 21070                              <1> 	; In original UNIX v1, 'wakeup' is called to wake the process
 21071                              <1> 	; sleeping in the specified wait channel by creating a link 
 21072                              <1> 	; to it from the last user process on the run queue.
 21073                              <1> 	; If there is no process to wake up, nothing happens.
 21074                              <1> 	;
 21075                              <1> 	; In Retro UNIX 8086 v1, Int 09h keyboard interrupt will set
 21076                              <1> 	; 'switching' status of the current process (owns current tty)
 21077                              <1> 	; (via alt + function keys) to a process which has highest
 21078                              <1> 	; priority (on run queue) on the requested tty (0 to 7, except
 21079                              <1> 	; 8 and 9 which are tty identifiers of COM1, COM2 serial ports)
 21080                              <1> 	; as it's console tty. (NOTE: 'p.ttyc' is used to set console
 21081                              <1> 	; tty for tty switching by keyboard.)	 
 21082                              <1> 	; 
 21083                              <1> 	; INPUT -> 
 21084                              <1> 	;	   AL = wait channel (r3) ('tty number' for now)
 21085                              <1> 	;	   ;;EBX = Run queue (r2) offset
 21086                              <1> 	;
 21087                              <1> 	; ((modified registers: EAX, EBX))
 21088                              <1> 	;
 21089 00005185 0FB6D8              <1> 	movzx	ebx, al ; 29/06/2015
 21090 00005188 81C3[18700000]      <1> 	add	ebx, wlist
 21091 0000518E 8A03                <1> 	mov	al, [ebx] ; waiting list (waiting process number)
 21092 00005190 20C0                <1> 	and	al, al
 21093 00005192 7424                <1> 	jz	short wa0 ; nothing to wakeup
 21094                              <1> 	;
 21095 00005194 30E4                <1> 	xor	ah, ah
 21096 00005196 8825[00710000]      <1> 	mov 	[u.quant], ah ; 0 ; time quantum = 0	
 21097 0000519C 8823                <1> 	mov	[ebx], ah ; 0 ; zero wait channel entry
 21098                              <1> 	; 15/09/2015
 21099 0000519E 0FB6D8              <1> 	movzx	ebx, al
 21100 000051A1 88A3[FF6D0000]      <1> 	mov	[ebx+p.waitc-1], ah ; 0
 21101 000051A7 FEC4                <1> 	inc	ah
 21102 000051A9 88A3[1F6E0000]      <1> 	mov	byte [ebx+p.stat-1], ah ; 1 ; SRUN
 21103                              <1> 	;
 21104 000051AF 57                  <1> 	push	edi
 21105 000051B0 52                  <1> 	push	edx
 21106 000051B1 E84AFFFFFF          <1> 	call	putlu
 21107 000051B6 5A                  <1> 	pop	edx
 21108 000051B7 5F                  <1> 	pop	edi
 21109                              <1> wa0:
 21110 000051B8 C3                  <1> 	retn
 21111                              <1> 
 21112                              <1> 	; 05/12/2021
 21113                              <1> 	; 30/11/2021 - Retro UNIX 386 v1.2
 21114                              <1> sleep: 
 21115                              <1> 	; 15/09/2015
 21116                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 21117                              <1> 	;
 21118                              <1> 	; 09/05/2013 - 20/03/2014
 21119                              <1> 	;
 21120                              <1> 	; Retro UNIX 8086 v1 modification !
 21121                              <1> 	; (Process/task switching and quit routine by using
 21122                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 21123                              <1> 	;
 21124                              <1> 	; In original UNIX v1, 'sleep' is called to wait for
 21125                              <1> 	; tty and tape output or input becomes available
 21126                              <1> 	; and process is put on waiting channel and swapped out,
 21127                              <1> 	; then -when the tty or tape is ready to write or read-
 21128                              <1> 	; 'wakeup' gets process back to active swapped-in status.)
 21129                              <1> 	;
 21130                              <1> 	; In Retro UNIX 8086 v1, Int 1Bh ctrl+brk interrupt and
 21131                              <1> 	; Int 09h keyboard interrupt will set 'quit' or 'switching'		
 21132                              <1> 	; status of the current process also INT 1Ch will count down
 21133                              <1> 	; 'uquant' value and INT 09h will redirect scancode of keystroke
 21134                              <1> 	; to tty buffer of the current process and kernel will get
 21135                              <1> 	; user input by using tty buffer of the current process
 21136                              <1> 	; (instead of standard INT 16h interrupt).
 21137                              <1> 	; TTY output will be redirected to related video page of text mode
 21138                              <1> 	; (INT 10h will be called with different video page depending
 21139                              <1> 	; on tty assignment of the active process: 0 to 7 for
 21140                              <1> 	; pseudo screens.)
 21141                              <1> 	;
 21142                              <1> 	; In Retro UNIX 8086 v1, 'sleep' will be called to wait for
 21143                              <1> 	; a keystroke from keyboard or wait for reading or writing
 21144                              <1> 	; characters/data on serial port(s).
 21145                              <1> 	;
 21146                              <1> 	; Character/Terminal input/output through COM1 and COM2 will be
 21147                              <1> 	; performed by related routines in addition to pseudo TTY routines.
 21148                              <1> 	; 
 21149                              <1> 	; R1 = AH = wait channel (0-9 for TTYs) ; 05/10/2013 (22/09/2013)
 21150                              <1> 	;
 21151                              <1> 	;; 05/10/2013
 21152                              <1>         ;10/12/2013
 21153                              <1> 	;cmp   byte [u.uno], 1
 21154                              <1>         ;ja    short sleep0
 21155                              <1> 	;retn
 21156                              <1> 
 21157                              <1> 	; 20/03/2014
 21158                              <1> 	;mov	bx, [runq]
 21159                              <1> 	;cmp	bl, bh
 21160                              <1> 	;jne	short sleep0	
 21161                              <1> 	; 25/02/2014
 21162                              <1> 	;cmp	word ptr [runq], 0
 21163                              <1> 	;ja	short sleep0	
 21164                              <1> 	;retn
 21165                              <1> sleep0:
 21166                              <1> 	;
 21167 000051B9 E851000000          <1> 	call	isintr
 21168                              <1> 	;jnz	sysret
 21169                              <1> 		; / wait for event
 21170                              <1>        		; jsr r0,isintr / check to see if interrupt 
 21171                              <1> 			      ; / or quit from user
 21172                              <1>                		; br 2f / something happened
 21173                              <1> 			      ; / yes, his interrupt so return
 21174                              <1>                      	      ;	/ to user
 21175                              <1> 	; 05/12/2021
 21176 000051BE 7405                <1> 	jz	short sleep_2
 21177                              <1> sleep_3:
 21178 000051C0 E931EBFFFF          <1> 	jmp	sysret
 21179                              <1> sleep_2:
 21180                              <1> 	; 30/06/2015
 21181 000051C5 0FB6DC              <1>     	movzx	ebx, ah ; 30/06/2015
 21182 000051C8 81C3[18700000]      <1> 	add	ebx, wlist
 21183 000051CE 8A03                <1> 	mov	al, [ebx]
 21184 000051D0 20C0                <1> 	and	al, al
 21185 000051D2 7407                <1> 	jz	short sleep1
 21186 000051D4 53                  <1> 	push	ebx
 21187 000051D5 E826FFFFFF          <1> 	call	putlu
 21188 000051DA 5B                  <1> 	pop	ebx
 21189                              <1> sleep1:
 21190 000051DB A0[09710000]        <1> 	mov	al, [u.uno]    
 21191 000051E0 8803                <1>   	mov	[ebx], al 	; put the process number
 21192                              <1> 				; in the wait channel
 21193                              <1> 		; mov (r0)+,r1 / put number of wait channel in r1
 21194                              <1> 		; movb wlist(r1),-(sp) / put old process number in there,
 21195                              <1> 				     ; / on the stack
 21196                              <1>        		; movb u.uno,wlist(r1) / put process number of process
 21197                              <1> 				     ; / to put to sleep in there
 21198                              <1> 	; 30/11/2021
 21199 000051E2 31DB                <1> 	xor	ebx, ebx
 21200 000051E4 8A1D[95700000]      <1> 	mov	bl, [cdev]
 21201 000051EA 53                  <1> 	push	ebx
 21202                              <1>         ; 15/09/2015
 21203                              <1> 	;movzx	ebx, al
 21204 000051EB 88C3                <1> 	mov	bl, al
 21205 000051ED C683[1F6E0000]04    <1>         mov     byte [ebx+p.stat-1], 4 ; SSLEEP
 21206 000051F4 FEC4                <1> 	inc	ah
 21207 000051F6 88A3[FF6D0000]      <1> 	mov	[ebx+p.waitc-1], ah ; wait channel + 1
 21208                              <1> 	;
 21209                              <1> 	;push	word [cdev]
 21210                              <1> 	;	; mov cdev,-(sp) / nothing happened in isintr so
 21211 000051FC E831FEFFFF          <1> 	call	swap
 21212                              <1>        		; jsr r0,swap / swap out process that needs to sleep
 21213                              <1>         ;pop	word [cdev]
 21214                              <1> 	;	; mov (sp)+,cdev / restore device
 21215                              <1> 	; 30/11/2021
 21216 00005201 58                  <1> 	pop	eax
 21217 00005202 A2[95700000]        <1> 	mov	[cdev], al
 21218 00005207 E803000000          <1> 	call	isintr
 21219                              <1> 	; 22/09/2013
 21220                              <1> 	;jnz	sysret         
 21221                              <1> 		; jsr r0,isintr / check for interrupt of new process
 21222                              <1>                		; br 2f / yes, return to new user
 21223                              <1> 		; movb (sp)+,r1 / no, r1 = old process number that was 
 21224                              <1> 				; / originally on the wait channel
 21225                              <1>        		; beq 1f / if 0 branch
 21226                              <1>   		; mov $runq+4,r2 / r2 points to lowest priority queue
 21227                              <1>        		; mov $300,*$ps / processor priority = 6
 21228                              <1> 		; jsr r0,putlu / create link to old process number
 21229                              <1>        		; clr *$ps / clear the status; process priority = 0
 21230                              <1> 	; 05/12/2021
 21231 0000520C 75B2                <1> 	jnz	short sleep_3 ; jump to sysret
 21232                              <1>      ;1:
 21233 0000520E C3                  <1> 	retn
 21234                              <1> 		; rts r0 / return
 21235                              <1>      ;2:
 21236                              <1>         ;;jmp	sysret
 21237                              <1> 		; jmp sysret / return to user
 21238                              <1> 
 21239                              <1> isintr:
 21240                              <1> 	; 30/11/2021	
 21241                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 21242                              <1> 	;
 21243                              <1> 	; 09/05/2013 - 30/05/2014
 21244                              <1> 	;
 21245                              <1> 	; Retro UNIX 8086 v1 modification !
 21246                              <1> 	; (Process/task switching and quit routine by using
 21247                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
 21248                              <1> 	;
 21249                              <1> 	; Retro UNIX 8086 v1 modification:
 21250                              <1> 	; 'isintr' checks if user interrupt request is enabled
 21251                              <1> 	;  and there is a 'quit' request by user;
 21252                              <1> 	;  otherwise, 'isintr' will return with zf=1 that means
 21253                              <1> 	;  "nothing to do". (20/10/2013)
 21254                              <1> 	;
 21255                              <1> 	; 20/10/2013
 21256 0000520F 66833D[EE700000]00  <1> 	cmp 	word [u.ttyp], 0 ; has process got a tty ?
 21257 00005217 761F                <1> 	jna	short isintr2 ; retn
 21258                              <1> 	; 03/09/2013
 21259                              <1> 	; (nothing to do)
 21260                              <1> 	;retn
 21261                              <1> 	; 22/09/2013
 21262 00005219 66833D[04710000]00  <1> 	cmp	word [u.intr], 0
 21263 00005221 7615                <1> 	jna	short isintr2 ; retn
 21264                              <1> 	; 30/05/2014
 21265                              <1> 	;push	ax
 21266 00005223 50                  <1> 	push	eax ; 30/11/2021 
 21267 00005224 66A1[06710000]      <1> 	mov	ax, [u.quit]
 21268 0000522A 6609C0              <1> 	or	ax, ax ; 0 ?
 21269 0000522D 7408                <1> 	jz	short isintr1 ; zf = 1
 21270 0000522F 6683F8FE            <1> 	cmp	ax, 0FFFEh  ; 'ctrl + brk' check
 21271 00005233 7702                <1> 	ja	short isintr1 ; 0FFFFh, zf = 0
 21272                              <1> 	;xor	ax, ax ; zf = 1
 21273                              <1> 	; 30/11/2021
 21274 00005235 31C0                <1> 	xor	eax, eax
 21275                              <1> isintr1:
 21276                              <1> 	;pop	ax
 21277                              <1> 	; 30/11/2021
 21278 00005237 58                  <1> 	pop	eax
 21279                              <1> isintr2: ; 22/09/2013
 21280                              <1> 	; zf=1 -> nothing to do
 21281 00005238 C3                  <1> 	retn
 21282                              <1> 
 21283                              <1> 	; UNIX v1 original 'isintr' routine... 
 21284                              <1>        	;mov     r1,-(sp) / put number of wait channel on the stack
 21285                              <1>        	;mov     r2,-(sp) / save r2
 21286                              <1>        	;mov     u.ttyp,r1 / r1 = pointer to buffer of process control
 21287                              <1>         ;                 / typewriter
 21288                              <1>        	;beq     1f / if 0, do nothing except skip return
 21289                              <1>        	;movb    6(r1),r1 / put interrupt char in the tty buffer in r1
 21290                              <1>        	;beq     1f / if its 0 do nothing except skip return
 21291                              <1>        	;cmp     r1,$177 / is interrupt char = delete?
 21292                              <1>        	;bne     3f / no, so it must be a quit (fs)
 21293                              <1>        	;tst     u.intr / yes, value of u.intr determines handling
 21294                              <1>         ;              / of interrupts
 21295                              <1>        	;bne     2f / if not 0, 2f. If zero do nothing.
 21296                              <1>      ;1:
 21297                              <1>        	;tst     (r0)+ / bump r0 past system return (skip)
 21298                              <1>      ;4:
 21299                              <1>        	;mov     (sp)+,r2 / restore r1 and r2
 21300                              <1>        	;mov     (sp)+,r1
 21301                              <1>        	;rts     r0
 21302                              <1>      ;3: / interrupt char = quit (fs)
 21303                              <1>        	;tst     u.quit / value of u.quit determines handling of quits
 21304                              <1>        	;beq     1b / u.quit = 0 means do nothing
 21305                              <1>      ;2: / get here because either u.intr <> 0 or u.qult <> O
 21306                              <1>        	;mov     $tty+6,r1 / move pointer to tty block into r1
 21307                              <1>      ;1: / find process control tty entry in tty block
 21308                              <1>        	;cmp     (r1),u.ttyp / is this the process control tty buffer?
 21309                              <1>        	;beq     1f / block found go to 1f
 21310                              <1>        	;add     $8,r1 / look at next tty block
 21311                              <1>        	;cmp     r1,$tty+[ntty*8]+6 / are we at end of tty blocks
 21312                              <1>        	;blo     1b / no
 21313                              <1>        	;br      4b / no process control tty found so go to 4b
 21314                              <1>      ;1:
 21315                              <1>        	;mov     $240,*$ps / set processor priority to 5
 21316                              <1>        	;movb    -3(r1),0f / load getc call argument; character llst
 21317                              <1>         ;                  / identifier
 21318                              <1>        	;inc     0f / increment
 21319                              <1>      ;1:
 21320                              <1>        	;jsr     r0,getc; 0:.. / erase output char list for control
 21321                              <1>         ;        br 4b / process tty. This prevents a line of stuff
 21322                              <1>         ;             / being typed out after you hit the interrupt
 21323                              <1>         ;             / key
 21324                              <1>        	;br      1b
 21325                                  %include 'u5.s'      ; 03/06/2015
 21326                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 21327                              <1> ; (re-write kernel for test by using previous version without a major defect)
 21328                              <1> ; ****************************************************************************
 21329                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS5.INC
 21330                              <1> ; Last Modification: 30/11/2021
 21331                              <1> ; ----------------------------------------------------------------------------
 21332                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 21333                              <1> ; (v0.1 - Beginning: 11/07/2012)
 21334                              <1> ;
 21335                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 21336                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 21337                              <1> ; <Bell Laboratories (17/3/1972)>
 21338                              <1> ; <Preliminary Release of UNIX Implementation Document>
 21339                              <1> ;
 21340                              <1> ; Retro UNIX 8086 v1 - U5.AS M (07/08/2013) //// UNIX v1 -> u5.s
 21341                              <1> ;
 21342                              <1> ; ****************************************************************************
 21343                              <1> 
 21344                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 21345                              <1> mget_w:
 21346                              <1> 	; 28/10/2021
 21347                              <1> 	; 22/08/2021
 21348                              <1> 	; 20/08/2021
 21349                              <1> 	; 25/05/2020
 21350                              <1> 	; 24/05/2020 - Retro UNIX 386 v2	
 21351 00005239 C605[F6710000]01    <1> 	mov	byte [mget_rw], 1 ; write access
 21352 00005240 EB07                <1> 	jmp	short mget
 21353                              <1> mget_r:
 21354                              <1> 	; 28/10/2021
 21355                              <1> 	; 22/08/2021
 21356                              <1> 	; 25/05/2020
 21357                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 21358 00005242 C605[F6710000]00    <1> 	mov	byte [mget_rw], 0 ; read access	
 21359                              <1> mget:
 21360                              <1> 	; 28/11/2021
 21361                              <1> 	; 22/11/2021
 21362                              <1> 	; 28/10/2021 - temporary (simplified code)
 21363                              <1> 	; 22/08/2021
 21364                              <1> 	; 20/08/2021
 21365                              <1> 	; 25/05/2020
 21366                              <1> 	; 24/05/2020
 21367                              <1> 	; 05/05/2020
 21368                              <1> 	; 02/05/2020, 03/05/2020
 21369                              <1> 	; 29/04/2020 - Retro UNIX 386 v2
 21370                              <1> 	; New inode model/format (Modified UNIX v7 inode model)
 21371                              <1> 	;	
 21372                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21373                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 21374                              <1> 	;
 21375                              <1> 	; Get existing or (allocate) a new disk block for file
 21376                              <1> 	; 
 21377                              <1> 	; INPUTS ->
 21378                              <1> 	;    u.fofp (file offset pointer)
 21379                              <1> 	;    inode 
 21380                              <1> 	;    u.off (file offset)
 21381                              <1> 	; OUTPUTS ->
 21382                              <1> 	;    r1 (physical block number)
 21383                              <1> 	;    r2, r3, r5 (internal)
 21384                              <1> 	;
 21385                              <1> 	; ((AX = R1)) output
 21386                              <1> 	;    (Retro UNIX Prototype : 05/03/2013 - 14/11/2012, UNIXCOPY.ASM)
 21387                              <1> 	;
 21388                              <1> 	; Modified registers: eax, edx, ebx, ecx, esi, edi, ebp
 21389                              <1> 
 21390                              <1> 	; Retro UNIX 386 v2 'mget' procedure
 21391                              <1> 	; source code reference:
 21392                              <1> 	; 'mget' procedure in UNIXHDCP.ASM (25/01/2020) by Erdogan Tan
 21393                              <1> 
 21394                              <1> 	; Get sector/block address for current file pointer
 21395                              <1> 	; (If file pointer points to a number greater than current file
 21396                              <1> 	; size, a new -empty- sector/block will be created/written.)
 21397                              <1> 
 21398                              <1> 	; Note: 'mget' procedure will be used for only RUNIX v2 FS.
 21399                              <1> 	;	(installable file system drivers will not use 'mget')
 21400                              <1> 	;	 !!! 512 bytes per sector !!!  ; 02/05/2020
 21401                              <1> 
 21402                              <1> 	; ! 64 bit fofp ! but Retro UNIX 386 v2 kernel will use 32 bit
 21403                              <1> 	; file offset for regular files and directories.
 21404                              <1> 	; ('mget' procedure will be called for regular files & directories)
 21405                              <1> 
 21406                              <1> 	; 28/10/2021
 21407                              <1> 	; Note: 'mget' uses only current inode ([ii], 'inode:')
 21408                              <1> 	; (inode must be loaded at 'inode:' addr by 'iget' before 'mget')  
 21409                              <1> 
 21410                              <1> 		; mov *u.fofp,mq / file offset in mq
 21411                              <1> 		; clr ac / later to be high sig
 21412                              <1> 		; mov $-8,lsh   / divide ac/mq by 256.
 21413                              <1> 		; mov mq,r2
 21414                              <1> 		; bit $10000,i.flgs / lg/sm is this a large or small file
 21415                              <1> 		; bne 4f / branch for large file
 21416                              <1> mget_0:	
 21417 00005249 8B35[C8700000]      <1>         mov     esi, [u.fofp]
 21418 0000524F 8B1E                <1> 	mov	ebx, [esi]
 21419                              <1>         ; ebx = file offset
 21420                              <1> 
 21421                              <1> 	; 20/08/2021
 21422 00005251 C1EB09              <1> 	shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 21423                              <1> 
 21424 00005254 F605[516D0000]10    <1> 	test	byte [i.flgs+1], 10h ; is this a large or small file addr?
 21425                              <1> 	;jz	short mget_1 ; small file addressing
 21426                              <1> 	;jmp	mget_5	; large file addressing
 21427 0000525B 7566                <1> 	jnz	short mget_5 ; 03/05/2020
 21428                              <1> mget_1:
 21429                              <1> 	; If large file flag is clear -not set- RUNIX v2 FS inode
 21430                              <1> 	; will contain 10 direct disk block/sector dword pointers.
 21431                              <1> 
 21432                              <1> 	; 05/05/2020
 21433                              <1> 	;shr	ebx, 9 ; / 512 (to convert byte offset to sector offset)
 21434                              <1> 
 21435 0000525D 83FB0A              <1> 	cmp	ebx, 10	; block 10
 21436 00005260 7324                <1> 	jnb	short mget_3 ; file offset >= 5120
 21437                              <1> 
 21438                              <1> 	; 05/05/2020
 21439                              <1> 	;cmp	ebx, 5120
 21440                              <1> 	;jnb	short mget_3 ; file offset >= 5120
 21441                              <1> 
 21442                              <1> 	;mov	bl, bh
 21443                              <1> 	;and	bl, 1Eh ; clear all bits but bits 1,2,3,4 ; 0,2,..,18
 21444                              <1> 	;	; max. value = 12h = 10010b = 18 (because ebx <= 5119) 
 21445                              <1> 	;shl	bl, 1	; * 2 ; max. value = 24h = 100100b = 36
 21446                              <1> 	;xor	bh, bh  ; clear bh
 21447                              <1> 		; RUNIX v2 (RUFS 2) file system bytes per sector value
 21448                              <1> 		; is always 512.
 21449                              <1> 		; ebx = 4*(ebx/512)  = 0 to 36
 21450                              <1> 
 21451                              <1> 	; 05/05/2020
 21452 00005262 C0E302              <1> 	shl	bl, 2 ; * 4
 21453                              <1> 		 ; ebx = 0 to 36
 21454                              <1> 
 21455 00005265 8B83[5C6D0000]      <1> 	mov	eax, [ebx+i.dskp] ; disk sector addr ptr 0 to 9 for file
 21456                              <1> 	; 22/08/2021
 21457 0000526B 89DE                <1> 	mov	esi, ebx
 21458 0000526D 31DB                <1> 	xor	ebx, ebx ; 0
 21459                              <1> 
 21460 0000526F 09C0                <1> 	or	eax, eax
 21461 00005271 7512                <1> 	jnz	short mget_2 ; existing block/sector
 21462                              <1> 
 21463 00005273 56                  <1> 	push	esi ; * ; 22/08/2021
 21464 00005274 E846010000          <1> 	call	alloc_m ; 24/05/2020	
 21465                              <1> 	;call	alloc	; allocate a new sector/block for this file	
 21466                              <1> 			; eax = sector/block number
 21467                              <1> 			; ebx = buffer header address
 21468 00005279 5E                  <1> 	pop	esi ; * ; 22/08/2021
 21469                              <1> 	; 28/11/2021
 21470                              <1> 	;jc	short mget_2 
 21471                              <1> 			; cf = 1 -> eax = 'no free block' error
 21472                              <1> 	; 22/08/2021
 21473 0000527A 8986[5C6D0000]      <1> 	mov	[esi+i.dskp], eax  ; logical sector/block address
 21474                              <1> 
 21475                              <1> 	;call	setimod	; set inode modification flag
 21476                              <1> 			; and set modification time
 21477                              <1> 	; 24/05/2020
 21478                              <1> 	;retn
 21479 00005280 E979040000          <1> 	jmp	setimod
 21480                              <1> 
 21481                              <1> 	; eax = logical sector/block number
 21482                              <1> 	; ([idev] = logical drive number)
 21483                              <1> 	; 28/10/2021
 21484                              <1> 	; [cdev] = logical drive number (0 or 1)
 21485                              <1> 	;	(0 = root fs, 1 = mounted fs)
 21486                              <1> mget_2:
 21487 00005285 C3                  <1> 	retn
 21488                              <1> 		; rts r0
 21489                              <1> mget_3: ; 3: / adding on block which changes small file to a large file
 21490                              <1> 	; 22/11/2021
 21491 00005286 E834010000          <1> 	call	alloc_m ; 24/05/2020
 21492                              <1> 	;call	alloc	; allocate a new sector/block for this file
 21493                              <1> 			; eax = sector/block number
 21494                              <1> 			; ebx = buffer header  ; 24/05/2020
 21495                              <1> 	; 28/11/2021
 21496                              <1> 	;jc	short mget_2 ; error code in eax
 21497                              <1>         ; EAX (r1) = Physical block number
 21498 0000528B E8F70E0000          <1> 	call 	wslot
 21499                              <1> 		; jsr r0,wslot / set up I/O buffer for write, r5 points to 
 21500                              <1> 			     ; / first data word in buffer
 21501                              <1>         ; EAX (r1) = Physical block number
 21502                              <1> 	; 28/11/2021
 21503                              <1> 	; ebx = buffer (data) address
 21504                              <1> 	; 22/11/2021
 21505 00005290 31C9                <1> 	xor	ecx, ecx
 21506 00005292 B10A                <1> 	mov 	cl, 10	; r3, transfer old physical block pointers
 21507                              <1> 			; into new indirect block area for the new
 21508                              <1> 			; large file		
 21509 00005294 89DF                <1> 	mov 	edi, ebx ; r5
 21510 00005296 BE[5C6D0000]        <1> 	mov	esi, i.dskp  ; current inode's direct disk addr ptrs
 21511 0000529B 89C2                <1> 	mov	edx, eax
 21512 0000529D 31C0                <1> 	xor	eax, eax
 21513                              <1> mget_4:
 21514 0000529F A5                  <1> 	movsd 	
 21515 000052A0 8946FC              <1> 	mov	[esi-4], eax ; 0
 21516 000052A3 E2FA                <1> 	loop	mget_4
 21517                              <1> 
 21518                              <1> 	; 22/11/2021
 21519 000052A5 B176                <1> 	mov 	cl, 128-10 ; clear rest of data buffer
 21520                              <1> ;mget_4: ; 1
 21521 000052A7 F3AB                <1> 	rep 	stosd
 21522                              <1> 		; clr (r5)+
 21523                              <1> 		; dec r3
 21524                              <1> 		; bgt 1b
 21525 000052A9 89D0                <1> 	mov	eax, edx
 21526                              <1>         ; EAX (r1) = Physical block number
 21527 000052AB E8F30E0000          <1> 	call	dskwr
 21528                              <1> 		; jsr r0,dskwr / write new indirect block on disk
 21529                              <1>         ; EAX (r1) = Physical block number
 21530 000052B0 A3[5C6D0000]        <1> 	mov 	[i.dskp], eax ; 22/11/2021 
 21531                              <1> 		; mov r1,i.dskp / put pointer to indirect block in i-node
 21532 000052B5 800D[516D0000]10    <1> 	or	byte [i.flgs+1], 10000b ; 10h ; 16  ; large file flag
 21533                              <1> 		; bis $10000,i.flgs / set large file bit 
 21534                              <1> 				  ; / in i.flgs word of i-node
 21535 000052BC E83D040000          <1> 	call	setimod
 21536                              <1> 		; jsr r0,setimod / set i-node modified flag
 21537                              <1> 
 21538 000052C1 EB86                <1> 	jmp	short mget_0 
 21539                              <1> 		; br mget
 21540                              <1> 
 21541                              <1> mget_5:  ; 4 ; large file
 21542                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 21543                              <1> 	;
 21544                              <1> 	; Retro UNIX 386 v2 disk inode contains..
 21545                              <1> 	; (if large file flag is set)
 21546                              <1> 	; 8 indirect disk block/sector dword pointers
 21547                              <1> 	; +1 double indirect disk block/sector dword pointers
 21548                              <1> 	; +1 triple indirect disk block/sector dword pointers
 21549                              <1> 
 21550                              <1> 	; check indirect pointers limit (as file offset)
 21551                              <1> 	; 8*128 = 1024 blocks (or sectors) or 512 KB
 21552                              <1> 	; check dx (file offset hw) value
 21553                              <1> 	
 21554                              <1> 	; 03/05/2020
 21555                              <1> 	;cmp	ebx, 524288  ; is file offset >= 524288 ?
 21556                              <1> 	;jnb	short mget_6 ; yes, check double indirect limit
 21557                              <1> 
 21558                              <1> 	; 05/05/2020
 21559 000052C3 81FB00040000        <1> 	cmp	ebx, 1024    ; block 1024 (byte 524288)	
 21560 000052C9 7321                <1> 	jnb	short mget_6 ; check double indirect limit
 21561                              <1> 
 21562 000052CB C605[F8710000]01    <1> 	mov	byte [level], 1 ; levels, 1 = indirect blocks
 21563                              <1> 
 21564                              <1> 	; 05/05/2020
 21565                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 21566                              <1> 
 21567 000052D2 88D9                <1> 	mov	cl, bl
 21568 000052D4 80E17F              <1> 	and	cl, 127
 21569 000052D7 880D[F9710000]      <1> 	mov	[level+1], cl ; level 1, direct block ptr index (0 to 127)
 21570 000052DD 66C1EB07            <1> 	shr	bx, 7 ; bl = level 0, indirect block pointer index (0 to 7)
 21571                              <1> 	;mov	[level+2], bl
 21572                              <1> 
 21573 000052E1 C0E302              <1> 	shl	bl, 2 ; * 4 to convert index number to offset
 21574                              <1> 
 21575                              <1> 	;mov	esi, i.dskp
 21576                              <1> 	;add	esi, ebx
 21577                              <1> 
 21578 000052E4 8DB3[5C6D0000]      <1> 	lea	esi, [ebx+i.dskp]
 21579                              <1> 
 21580 000052EA EB66                <1> 	jmp	short mget_8
 21581                              <1> 
 21582                              <1> mget_6:
 21583                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 21584                              <1> 	; 03/05/2020
 21585                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 21586                              <1> 	; check double indirect pointer limit (as file offset)
 21587                              <1> 	; (128*128)+1024 = 16384+1024 blocks or 8 MB + 512 KB
 21588                              <1> 	; check dx (file offset hw) value
 21589                              <1> 	
 21590                              <1> 	;cmp	ebx, 8912896 ; >= 17408 sectors (16384+1024) ?	
 21591                              <1> 	;jnb	short mget_7 ; yes, use triple indirect pointer (block)
 21592                              <1> 
 21593                              <1> 	; 05/05/2020
 21594 000052EC 81FB00440000        <1> 	cmp	ebx, 17408   ; block 17408 (byte 8912896)	
 21595 000052F2 7329                <1> 	jnb	short mget_7 ; use triple indirect pointer (block)
 21596                              <1> 
 21597 000052F4 C605[F8710000]02    <1> 	mov	byte [level], 2  ; levels, 2 = double indirect blocks
 21598                              <1> 	
 21599                              <1> 	;sub	ebx, 524288 ; 1024 sectors
 21600                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 21601                              <1> 			; (from sector 1024)
 21602                              <1> 	; 05/05/2020
 21603 000052FB 81EB00040000        <1> 	sub	ebx, 1024 ; offset from sector 1024
 21604                              <1> 	
 21605 00005301 88D9                <1> 	mov	cl, bl
 21606 00005303 80E17F              <1> 	and	cl, 127
 21607 00005306 880D[F9710000]      <1> 	mov	[level+1], cl
 21608                              <1> 			; level 2, direct block ptr index (0 to 127)	
 21609 0000530C 66C1EB07            <1> 	shr	bx, 7
 21610 00005310 881D[FA710000]      <1> 	mov	[level+2], bl
 21611                              <1> 			; level 1, indirect block ptr index (0 to 127)
 21612                              <1> 
 21613 00005316 BE[7C6D0000]        <1> 	mov	esi, i.dskp + 32 ; 8*4
 21614                              <1> 			; level 0, double indirect block pointer
 21615 0000531B EB35                <1> 	jmp	short mget_8
 21616                              <1> 
 21617                              <1> mget_7:
 21618                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 21619                              <1> 	; 03/05/2020
 21620                              <1> 	; 13/11/2019 (UNIXHDCP.ASM)
 21621                              <1> 	; triple indirect pointer ; 8912896 to 1082654720 bytes
 21622                              <1> 	;mov	esi, i.dskp + 36 ; 9*4
 21623                              <1> 
 21624 0000531D C605[F8710000]03    <1> 	mov	byte [level], 3  ; levels, 3 = triple indirect blocks
 21625                              <1> 
 21626                              <1> 	;sub	ebx, 8912896 ; 17408 sectors (16384+1024)
 21627                              <1> 	;shr	ebx, 9	; ebx = sector offset (flat)
 21628                              <1> 			; (from sector 17408)
 21629                              <1> 	; 05/05/2020
 21630 00005324 81EB00440000        <1> 	sub	ebx, 17408 ; offset from sector 17408	
 21631                              <1> 
 21632 0000532A 88D9                <1> 	mov	cl, bl
 21633 0000532C 80E17F              <1> 	and	cl, 127
 21634 0000532F 880D[F9710000]      <1> 	mov	[level+1], cl  
 21635                              <1> 			; level 3, direct block ptr index (0 to 127)	
 21636 00005335 C1EB07              <1> 	shr	ebx, 7	
 21637 00005338 88D9                <1> 	mov	cl, bl
 21638 0000533A 80E17F              <1> 	and	cl, 127
 21639 0000533D 880D[FA710000]      <1> 	mov	[level+2], cl
 21640                              <1> 			; level 2, indirect block ptr index (0 to 127)
 21641 00005343 66C1EB07            <1> 	shr	bx, 7
 21642 00005347 881D[FB710000]      <1> 	mov	[level+3], bl
 21643                              <1> 			; level 1, double indir blk ptr index (0 to 127)
 21644                              <1> 
 21645 0000534D BE[806D0000]        <1> 	mov	esi, i.dskp + 36 ; 9*4
 21646                              <1> 			; level 0, triple indirect block pointer
 21647                              <1> mget_8:
 21648                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibiliy modification
 21649 00005352 8B06                <1> 	mov	eax, [esi]
 21650 00005354 09C0                <1> 	or 	eax, eax ; R1
 21651 00005356 7515                <1> 	jnz 	short mget_10 ; 2f
 21652                              <1> 		; bne 2f / if no indirect block exists
 21653 00005358 56                  <1> 	push	esi	; * ; 24/05/2020
 21654                              <1> 
 21655 00005359 E861000000          <1> 	call	alloc_m ; 24/05/2020
 21656                              <1> 	;call	alloc	; allocate a new block for this file	
 21657                              <1> 			; eax = block number
 21658                              <1> 			; ebx = buffer header address
 21659                              <1> 			; [pdn] = physical drive number ; 25/05/2020
 21660                              <1> 	;jc	mget_2	; cf -> 1 & eax = 0 -> no free block
 21661                              <1> 
 21662 0000535E 5E                  <1> 	pop	esi	; * ; 24/05/2020
 21663                              <1> 	;jc	short mget_9
 21664                              <1> 
 21665 0000535F 8906                <1> 	mov	[esi], eax ; record sector/block address on i.dskp area
 21666                              <1> 
 21667 00005361 E898030000          <1> 	call 	setimod
 21668                              <1> 		; jsr r0,setimod / set i-node modified byte
 21669                              <1> 	; EAX = new block number
 21670 00005366 E8C4FDFFFF          <1> 	call 	clear
 21671                              <1> 		; jsr r0,clear / clear new block
 21672                              <1> 	; 22/11/2021
 21673 0000536B EB05                <1> 	jmp	short mget_11
 21674                              <1> ;mget_9:
 21675                              <1> ;	retn
 21676                              <1> mget_10: ;2
 21677                              <1> 	; 05/03/2013
 21678                              <1> 	; EAX = r1, physical block number (of indirect block)
 21679 0000536D E8B50D0000          <1> 	call 	dskrd ; read indirect block
 21680                              <1> 		; jsr r0,dskrd / read in indirect block
 21681                              <1> 	;jc	short mget_9
 21682                              <1> mget_11:
 21683                              <1> 	; 22/11/2021
 21684                              <1> 	; eax = physical block/sector address
 21685                              <1> 	; ebx = buffer address
 21686                              <1> 
 21687 00005372 89C2                <1> 	mov	edx, eax ; *  ; save sector number in edx
 21688                              <1> 
 21689 00005374 0FB605[F8710000]    <1> 	movzx	eax, byte [level]
 21690 0000537B 8A80[F8710000]      <1> 	mov	al, [eax+level] ; get sector pointer offset
 21691 00005381 66C1E002            <1> 	shl	ax, 2 ; * 4
 21692                              <1> 
 21693 00005385 01C3                <1> 	add	ebx, eax
 21694                              <1> 
 21695 00005387 8B03                <1> 	mov 	eax, [ebx] ; put physical block no of block
 21696                              <1> 			   ; in file sought in R1 (EAX)
 21697                              <1> 		; mov (r2),r1 / put physical block no of block in file
 21698                              <1> 	               	    ; / sought in r1
 21699                              <1> 
 21700 00005389 21C0                <1> 	and	eax, eax  ; if logical sector/block number is zero
 21701                              <1> 			  ; then we need a new block for file
 21702 0000538B 740B                <1> 	jz	short mget_12
 21703                              <1> 
 21704 0000538D FE0D[F8710000]      <1> 	dec	byte [level]
 21705 00005393 75D8                <1> 	jnz	short mget_10
 21706                              <1> 
 21707 00005395 29DB                <1> 	sub	ebx, ebx ; ebx = 0 ; existing sector
 21708                              <1> 
 21709 00005397 C3                  <1> 	retn
 21710                              <1> 
 21711                              <1> mget_12:
 21712                              <1> 	; 22/11/2021
 21713 00005398 52                  <1> 	push	edx ; *
 21714 00005399 53                  <1> 	push	ebx ; **	 ; buffer data position
 21715 0000539A E820000000          <1> 	call	alloc_m
 21716                              <1> 	;call	alloc	 ; allocate a new block for this file	
 21717                              <1> 			 ; eax = block number (logical)
 21718                              <1> 			 ; ebx = buffer header address
 21719 0000539F 5E                  <1> 	pop	esi ; **
 21720 000053A0 5A                  <1> 	pop	edx ; *
 21721                              <1> 	;jc	short mget_9 ; cf -> 1 & eax = 0 -> no free block
 21722                              <1> 
 21723 000053A1 8906                <1> 	mov	[esi], eax ; record/save block number (logical)
 21724                              <1> 
 21725                              <1> 	; 22/11/2021
 21726 000053A3 870424              <1> 	xchg	eax, [esp] ; *
 21727                              <1> 
 21728                              <1> 	; eax (r1) = physical block number (of indirect block)
 21729 000053A6 E8DC0D0000          <1> 	call 	wslot
 21730                              <1> 		; jsr r0,wslot
 21731                              <1>         ; eax (r1) = physical block number
 21732                              <1> 	; ebx (r5) = pointer to buffer (indirect block)
 21733 000053AB E8F30D0000          <1> 	call 	dskwr
 21734                              <1> 	; eax = r1 = physical block number (of indirect block)
 21735                              <1> 		; jsr r0,dskwr / write newly modified indirect block 
 21736                              <1> 			     ; / back out on disk
 21737 000053B0 58                  <1> 	pop	eax ; *  ; 31/07/2013
 21738                              <1> 		; mov (sp),r1 / restore block number of new block	
 21739                              <1> 	; eax (r1) = physical block number of new block
 21740 000053B1 E879FDFFFF          <1> 	call 	clear
 21741                              <1> 		; jsr r0,clear / clear new block
 21742                              <1> 
 21743 000053B6 FE0D[F8710000]      <1> 	dec	byte [level]
 21744 000053BC 75B4                <1> 	jnz	short mget_11
 21745                              <1> 	
 21746                              <1> 	; 22/11/2021
 21747                              <1> 	; ebx = buffer address
 21748                              <1> mget_13: ; 2
 21749                              <1> 	; eax (r1) = Block number of new block
 21750 000053BE C3                  <1> 	retn
 21751                              <1> 		; rts r0
 21752                              <1> 
 21753                              <1> 	; 26/11/2021
 21754                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 21755                              <1> alloc_m:
 21756                              <1> 	; 27/11/2021
 21757                              <1> 	; 28/10/2021
 21758                              <1> 	; 07/05/2021
 21759                              <1> 	; 26/05/2020
 21760                              <1> 	; 25/05/2020
 21761                              <1> 	; 24/05/2020 - Retro UNIX 386 v2
 21762                              <1> 	; 'alloc' call in 'mget'
 21763                              <1> 	;
 21764                              <1> 	; (('mget_r' will be returned with error))
 21765                              <1> 	; (('mget_w' will continue to 'alloc'))
 21766                              <1> 
 21767                              <1> 	; Note: 'sysread' will return with cf = 0, eax = 0
 21768                              <1> 	; if [fofp] >= file size (eax = 0 --> EOF)
 21769                              <1> 	; So, if we are here, that means [fofp] < file size
 21770                              <1> 	;     but disk address is 0. 
 21771                              <1> 	
 21772 000053BF 803D[F6710000]01    <1> 	cmp	byte [mget_rw], 1 ; write access ? (mget_w) 
 21773 000053C6 730F                <1> 	jnb	short alloc ; yes (this is a call from 'mget_w')
 21774                              <1> 	; ((cf = 1))	
 21775                              <1> 	; no (this is a call from 'mget_r') !
 21776                              <1> 	;mov	eax, ERR_FILE_SIZE ; file size error (inode error!)
 21777                              <1> 		; [User may change this empty/invalid inode (disk) sector
 21778                              <1> 		; pointer with a new valid inode (disk) sector pointer 
 21779                              <1> 		; by writing new clear (zero) sector to same file position
 21780                              <1> 		; in order to correct file size -inode parm/content- error.
 21781                              <1> 		; It may be useful for recovering lost data if other sector
 21782                              <1> 		; pointers are not empty.]	
 21783                              <1> 	;retn
 21784                              <1> 	; 27/11/2021
 21785 000053C8 C705[2C710000]1400- <1> 	mov	dword [u.error], ERR_FILE_SIZE 
 21786 000053D0 0000                <1>
 21787                              <1> 			; file size error (inode error!)
 21788 000053D2 E9FFE8FFFF          <1> 	jmp	error
 21789                              <1> alloc:
 21790                              <1> 	; 27/11/2021
 21791                              <1> 	; 26/11/2021 - Major modification for Runix v2 file system
 21792                              <1> 	;	(I have called this kernel version as v1.2, it is a
 21793                              <1> 	;	 debug/test version just before Retro UNIX 386 v2 kernel)
 21794                              <1> 	;	((there were running problems on new version, 
 21795                              <1> 	;	  so i am developing an intermediate version with minimum
 21796                              <1> 	;	  modification on v1.1 code which is successfuly running))
 21797                              <1> 	;	 ; /// Erdogan Tan - Istanbul, 26/11/2021 /// 
 21798                              <1> 	;	 
 21799                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 21800                              <1> 	; 01/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 21801                              <1> 	;
 21802                              <1> 	; get a free block and 
 21803                              <1> 	; set the corresponding bit in the free storage map
 21804                              <1> 	; 
 21805                              <1> 	; INPUTS ->
 21806                              <1> 	;    cdev (current device)
 21807                              <1> 	;    r2 
 21808                              <1> 	;    r3
 21809                              <1> 	; OUTPUTS ->
 21810                              <1> 	;    r1 (physical block number of block assigned)
 21811                              <1> 	;    smod, mmod, systm (super block), mount (mountable super block)	
 21812                              <1> 	;
 21813                              <1> 	; ((AX = R1)) output
 21814                              <1> 	;    (Retro UNIX Prototype : 14/11/2012 - 21/07/2012, UNIXCOPY.ASM)
 21815                              <1>         ;    ((Modified registers: edx, ecx)) 
 21816                              <1> 
 21817                              <1> 	; 26/11/2021
 21818                              <1> 	; INPUT:
 21819                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 21820                              <1> 	; OUTPUT:
 21821                              <1> 	;	eax = disk block/sector number/address (physical)
 21822                              <1> 	;	(ebx = disk buffer address for sector/block in eax)
 21823                              <1> 	;
 21824                              <1> 	;    Note:	
 21825                              <1> 	;	Free blocks map will be modified and written to it's disk.
 21826                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 21827                              <1> 	;	modification flag will be set; but the superblock 
 21828                              <1> 	;	will not be written to it's disk in this 'alloc' procedure)
 21829                              <1> 	;
 21830                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi, ebp 
 21831                              <1> 
 21832                              <1> 	; 26/11/2021
 21833 000053D7 BB[307E0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 21834                              <1> 		; mov $systm,r2 / start of inode and free storage map for drum
 21835 000053DC F605[95700000]01    <1> 	test	byte [cdev], 1
 21836                              <1> 		; tst cdev
 21837 000053E3 7405                <1> 	jz	short alloc_1
 21838                              <1> 		; beq 1f / drum is device
 21839 000053E5 BB[38800000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 21840                              <1> 		; mov $mount,r2 / disk or tape is device, start of inode and
 21841                              <1> 			      ; / free storage map
 21842                              <1> alloc_1: ; 1
 21843                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 21844                              <1> 	;test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 21845                              <1> 	;jnz	short alloc_2  ; 'read only file system' error
 21846                              <1> 	;
 21847 000053EA 8B4B38              <1> 	mov	ecx, [ebx+SB.FreeBlocks] ; count of free blocks/sectors
 21848 000053ED 21C9                <1> 	and	ecx, ecx
 21849 000053EF 750F                <1> 	jnz	short alloc_3
 21850                              <1> alloc_2:
 21851                              <1> 	; 'no free blocks on disk !' error
 21852 000053F1 C705[2C710000]2100- <1> 	mov	dword [u.error], ERR_ALLOC
 21853 000053F9 0000                <1>
 21854 000053FB E9D6E8FFFF          <1> 	jmp	error
 21855                              <1> alloc_3:
 21856                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 21857 00005400 31C0                <1> 	xor	eax, eax
 21858                              <1> 	; 23/07/2021
 21859 00005402 8B4B3C              <1> 	mov	ecx, [ebx+SB.FirstFreeBlk] ; 1st free sector number
 21860                              <1> 					 ; (as logical sector number)
 21861 00005405 09C9                <1> 	or	ecx, ecx
 21862 00005407 7415                <1> 	jz	short alloc_5 ; 0 = initial/reset value or 'not valid'
 21863 00005409 41                  <1> 	inc	ecx ; 0FFFFFFFFh -> 0
 21864 0000540A 7412                <1> 	jz	short alloc_5 ; 'not valid' or 'not calculated'
 21865 0000540C 49                  <1> 	dec	ecx ; restore first free block value
 21866 0000540D 89C8                <1> 	mov	eax, ecx
 21867                              <1> 	; 1 allocation byte (in fbm) is for 8 sectors
 21868 0000540F C1E903              <1> 	shr	ecx, 3 ; first free block number / 8
 21869 00005412 80E1FC              <1> 	and	cl, ~3  ; dword alignment (to backward)
 21870                              <1> 	; 27/11/2021
 21871 00005415 890D[38820000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm
 21872                              <1> alloc_4:
 21873 0000541B C1E80C              <1> 	shr	eax, 12 ; 1 fbm sector for 4096 sectors
 21874                              <1> alloc_5:
 21875                              <1> 	; 26/11/2021
 21876 0000541E 53                  <1> 	push	ebx ; ** ; superblock buffer address 
 21877                              <1> 	; eax = fbm sector index
 21878 0000541F A3[3C820000]        <1> 	mov	[free_map_index], eax
 21879 00005424 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 21880                              <1> 			; free blocks map start sector addr
 21881                              <1> 	;add	eax, [ebx+SB.BootSectAddr] 
 21882                              <1> 	;		; + Hidden Sectors
 21883                              <1> 	; eax = physical sector number
 21884 00005427 E8FB0C0000          <1> 	call	dskrd
 21885                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 21886                              <1> 	; eax = physical sector number
 21887                              <1> 	; ebx = buffer data address
 21888                              <1> 	; 27/11/2021
 21889 0000542C 8B15[38820000]      <1> 	mov	edx, [free_map_offset] ; byte position on fbm
 21890 00005432 A3[40820000]        <1> 	mov	[free_map_sector], eax ; physical sector number
 21891 00005437 B9FF010000          <1> 	mov	ecx, 511
 21892                              <1> 	;and	edx, 511
 21893 0000543C 21CA                <1> 	and 	edx, ecx ; fbm byte offset in fbm buffer
 21894 0000543E 41                  <1> 	inc	ecx ; 512
 21895 0000543F 01D9                <1> 	add	ecx, ebx
 21896 00005441 01DA                <1> 	add	edx, ebx ; + buffer address
 21897 00005443 5B                  <1> 	pop	ebx ; ** ; superblock buffer address 
 21898                              <1> 	;
 21899                              <1> 	; ebx = superblock buffer address
 21900                              <1> 	; edx = superblock buffer address + byte offset (dword aligned)
 21901                              <1> 	; ecx = superblock buffer address + 512
 21902                              <1> alloc_6:
 21903                              <1> 	; 26/11/2021 - Retro UNIX 386 v2 file system compatibility code
 21904                              <1> 	;		for Retro UNIX 386 v1.2
 21905                              <1> 	; 25/05/2020 - Retro UNIX 386 v2 code
 21906                              <1> 	; (dword scan) ((1 dword = 32 sectors, 1 byte = 8 sectors))
 21907                              <1> 	; ((Note: Logical drive size must be multiplies of 32 sectors))
 21908                              <1> 	; 19/05/2020
 21909                              <1> 	; edx = free blocks map byte address 
 21910 00005444 0FBC02              <1> 	bsf	eax, [edx] ; Scans source operand for first bit set (1).
 21911                              <1> 			  ; Clear ZF if a bit is found set (1) and 
 21912                              <1> 			  ; loads the destination with an index to
 21913                              <1> 			  ; first set bit. (0 -> 31) 
 21914                              <1> 			  ; Sets ZF to 1 if no bits are found set.
 21915 00005447 752A                <1> 	jnz	short alloc_8 ; ZF = 0 -> a free block has been found
 21916                              <1> 
 21917 00005449 A1[38820000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 21918 0000544E 83C004              <1> 	add	eax, 4 ; next dword
 21919 00005451 3B431C              <1> 	cmp	eax, [ebx+SB.FreeMapSize] ; fbm size in bytes
 21920 00005454 7209                <1> 	jb	short alloc_7
 21921                              <1> 	; invalidate superblock's first free block field
 21922 00005456 C7433CFFFFFFFF      <1> 	mov	dword [ebx+SB.FirstFreeBlk], 0FFFFFFFFh
 21923                              <1> 	; 'no free blocks on disk !' error
 21924 0000545D EB92                <1> 	jmp	alloc_2
 21925                              <1> alloc_7:
 21926                              <1> 		; 26/05/2020
 21927                              <1> 		; NOTE: If ldrv size is not multiplies of 32 sectors,
 21928                              <1> 		; mod (ldrv size / 32) sectors (at the end of ldrv)
 21929                              <1> 		; can not be allocated (for regular files or dirs)! 
 21930                              <1> 		; (Kernel or runix fs installation program can use
 21931                              <1> 		;  this fact to save/duplicate critical sectors/data 
 21932                              <1> 		;  onto end sectors of that logical drive's runix fs.)
 21933                              <1> 
 21934                              <1> 	; 26/11/2021
 21935 0000545F A3[38820000]        <1> 	mov	[free_map_offset], eax
 21936                              <1> 	; 28/07/2021
 21937                              <1> 	; set next first free block value for search
 21938 00005464 C1E003              <1> 	shl	eax, 3 ; * 8 ; first free block
 21939                              <1>  	; 26/11/2021
 21940 00005467 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 21941                              <1> 	; search (scan) for next free block map dword (in buffer)
 21942 0000546A 83C204              <1> 	add	edx, 4 ; next dword
 21943 0000546D 39CA                <1> 	cmp	edx, ecx
 21944 0000546F 72D3                <1> 	jb	short alloc_6
 21945                              <1> 	; 27/11/2021
 21946 00005471 EBA8                <1> 	jmp	short alloc_4
 21947                              <1> 
 21948                              <1> alloc_8:
 21949                              <1> 	; 26/11/2021
 21950                              <1> 	; convert bit index to xor value
 21951                              <1> 	; and then set allocated flag for corresponding fbm bit 
 21952 00005473 89C1                <1> 	mov	ecx, eax
 21953                              <1> 	;mov	cl, al 
 21954                              <1> 	;sub	eax, eax
 21955                              <1> 	;inc	al ; eax = 1
 21956 00005475 B001                <1> 	mov	al, 1
 21957 00005477 D3E0                <1> 	shl	eax, cl
 21958 00005479 3102                <1> 	xor	[edx], eax  ; clear allocated block's bit in the fbm
 21959                              <1> 	; zero bit means allocated disk block (1 means free disk block) 
 21960                              <1> 
 21961 0000547B A1[38820000]        <1> 	mov	eax, [free_map_offset] ; byte offset from start of fbm
 21962                              <1> 		; note: eax is dword aligned (0,4,8,12..) !
 21963 00005480 C1E003              <1> 	shl	eax, 3 ; * 8 ; free block number base
 21964 00005483 01C8                <1> 	add	eax, ecx ; add allocation bit index (0 to 31)	
 21965 00005485 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax ; current free block
 21966                              <1> 				; (which is being allocated here)
 21967                              <1> 
 21968                              <1> 	;mov	eax, [ebx+SB.FreeMapAddr] 
 21969                              <1> 	;		; free blocks map start sector addr
 21970                              <1> 	;add	eax, [free_map_index]
 21971                              <1> 	
 21972                              <1> 	;;add	eax, [ebx+SB.BootSectAddr] 
 21973                              <1> 	;		; + Hidden Sectors
 21974                              <1> 	; eax = physical sector number
 21975                              <1> 	
 21976                              <1> 	; 27/11/2021
 21977 00005488 A1[40820000]        <1> 	mov	eax, [free_map_sector] ; physical sector number
 21978                              <1> 	
 21979 0000548D E8F50C0000          <1> 	call	wslot
 21980                              <1> 	; ebx = buffer data address (write operation bit is set)
 21981                              <1> 	; eax = physical sector number
 21982                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 21983                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 21984                              <1> 
 21985                              <1> 	; 27/11/2021
 21986                              <1> 	;mov	[free_map_buffer], ebx ; save free map buffer address
 21987                              <1> 
 21988 00005492 E80C0D0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 21989                              <1> 		      ; (at the beginning/head of the buffer chain)
 21990                              <1> 
 21991                              <1> 	; if we are here, buffer has been written to disk successfully 
 21992                              <1> 	; (otherwise cpu would jump to 'error' address)
 21993                              <1> 
 21994                              <1> 	; set superblock modified flag
 21995 00005497 BA[A7700000]        <1> 	mov	edx, smod
 21996 0000549C BB[307E0000]        <1> 	mov	ebx, systm
 21997 000054A1 F605[95700000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 21998 000054A8 7406                <1> 	jz	short alloc_9  ; no, root device
 21999                              <1> 	; yes, mounted device
 22000 000054AA BB[38800000]        <1> 	mov	ebx, mount
 22001                              <1> 	;mov	edx, mmod
 22002 000054AF 42                  <1> 	inc	edx ; edx = offset mmod
 22003                              <1> alloc_9: 
 22004 000054B0 FE02                <1> 	inc	byte [edx] ; superblock modified !
 22005                              <1> 	
 22006                              <1> 	; Allocating a new sector/block (for file) has been completed here.
 22007 000054B2 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 22008 000054B5 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0 
 22009 000054B6 7405                <1> 	jz	short alloc_10 ; not valid (not set)
 22010 000054B8 48                  <1> 	dec	eax ; Free Blocks
 22011 000054B9 48                  <1> 	dec	eax ; Free Blocks = Free Blocks - 1
 22012 000054BA 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax
 22013                              <1> alloc_10:
 22014 000054BD E8980D0000          <1> 	call	get_system_time
 22015                              <1> 		; eax = current time (as unix epoch time)
 22016                              <1> 	; 30/07/2021
 22017 000054C2 89435C              <1> 	mov	[ebx+SB.ModifTime], eax
 22018                              <1> 
 22019 000054C5 8B433C              <1> 	mov	eax, [ebx+SB.FirstFreeBlk] ; allocated block address
 22020 000054C8 FF433C              <1> 	inc	dword [ebx+SB.FirstFreeBlk] 
 22021                              <1> 				; +1, new value of first free block
 22022                              <1> 				; (new search will be started from here)
 22023                              <1> 				; ((it may not be free, no problem))
 22024                              <1> 
 22025                              <1> 	; put free map buffer address in ebx
 22026                              <1> 	; 27/11/2021
 22027                              <1> 	;mov	ebx, [free_map_buffer]
 22028                              <1> 
 22029 000054CB C3                  <1> 	retn	
 22030                              <1> 
 22031                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22032                              <1> free:
 22033                              <1> 	; 05/11/2021
 22034                              <1> 	; 29/10/2021 - temporary (simplified code)
 22035                              <1> 	; 14/08/2021
 22036                              <1> 	; 12/06/2021
 22037                              <1> 	; 07/06/2020
 22038                              <1> 	; 25/05/2020 (Retro UNIX 386 v2 - Beginning)
 22039                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22040                              <1> 	; 07/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 22041                              <1> 	;
 22042                              <1> 	; calculates byte address and bit position for given block number
 22043                              <1> 	; then sets the corresponding bit in the free storage map
 22044                              <1> 	; 
 22045                              <1> 	; INPUTS ->
 22046                              <1> 	;    r1 - block number for a block structured device
 22047                              <1> 	;    cdev - current device 
 22048                              <1> 	; OUTPUTS ->
 22049                              <1> 	;    free storage map is updated
 22050                              <1> 	;    smod is incremented if cdev is root device (fixed disk)
 22051                              <1> 	;    mmod is incremented if cdev is a removable disk 	
 22052                              <1> 	;
 22053                              <1> 	;  (Retro UNIX Prototype : 01/12/2012, UNIXCOPY.ASM)
 22054                              <1>         ;  ((Modified registers: DX, CX))  
 22055                              <1> 
 22056                              <1> 	; 27/11/2021
 22057                              <1> 	; INPUT:
 22058                              <1> 	;	[cdev] = current device (root = 0, mounted = 1) 
 22059                              <1> 	;	eax = disk block/sector number/address (logical)
 22060                              <1> 	; OUTPUT:
 22061                              <1> 	;	ebx = superblock buffer address
 22062                              <1> 	;
 22063                              <1> 	;    Note:	
 22064                              <1> 	;	Free blocks map will be modified and written to it's disk.
 22065                              <1> 	;	Superblock (buffer) of [cdev] will be modified and it's 
 22066                              <1> 	;	modification flag will be set; but the superblock 
 22067                              <1> 	;	will not be written to it's disk in this 'free' procedure)
 22068                              <1> 	;
 22069                              <1> 	; Modified registers: ebx, ecx, edx, esi, edi, ebp 
 22070                              <1> 
 22071                              <1> 	; 27/11/2021
 22072 000054CC BB[307E0000]        <1> 	mov 	ebx, systm ; (SuperBlock of root file system)
 22073 000054D1 F605[95700000]01    <1> 	test	byte [cdev], 1
 22074 000054D8 7405                <1> 	jz	short free_1
 22075 000054DA BB[38800000]        <1> 	mov	ebx, mount ; (SuperBlock of mounted file system)
 22076                              <1> free_1: ; 1
 22077                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 file system compatibility code
 22078                              <1> 	;test	byte [ebx+SB.ReadOnly], 1 ; if bit 0 is 1, it is RO fs	
 22079                              <1> 	;jz	short free_2 
 22080                              <1> 	; 'read only file system' error
 22081 000054DF C705[2C710000]1E00- <1> 	mov	dword [u.error], ERR_READ_ONLY_FS
 22082 000054E7 0000                <1>
 22083 000054E9 E9E8E7FFFF          <1> 	jmp	error
 22084                              <1> free_2:
 22085 000054EE 89C1                <1> 	mov	ecx, eax ; logical sector/block number
 22086 000054F0 A3[40820000]        <1> 	mov	[free_map_sector], eax
 22087 000054F5 C1E903              <1> 	shr	ecx, 3	; convert to fbmap byte offset
 22088 000054F8 C1E80C              <1> 	shr	eax, 12 ; convert to fbmap sector index 
 22089                              <1> 			; (1 fb sector for 4096 sectors)
 22090                              <1> 	;and	cl, ~3	; dword alignment (to backward)
 22091 000054FB 890D[38820000]      <1> 	mov	[free_map_offset], ecx ; byte position on fbm
 22092                              <1> 	; 27/11/2021
 22093                              <1> 	; eax = fbm sector index
 22094 00005501 034318              <1> 	add	eax, [ebx+SB.FreeMapAddr] 
 22095                              <1> 			; free blocks map start sector address
 22096                              <1> 	;add	eax, [ebx+SB.BootSectAddr]
 22097                              <1> 	;		; + Hidden Sectors
 22098                              <1> 	; ebx = superblock address
 22099                              <1> 	; eax = physical sector number
 22100 00005504 E81E0C0000          <1> 	call	dskrd
 22101                              <1> 	; cpu returns here if there is/was not an error in 'dskrd'
 22102                              <1> 	; eax = physical sector number
 22103                              <1> 	; ebx = buffer data address
 22104                              <1> 	; 27/11/2021
 22105 00005509 A3[3C820000]        <1> 	mov	[free_map_index], eax  ; save physical sector address
 22106 0000550E 8B15[38820000]      <1> 	mov	edx, [free_map_offset] ; byte position on fbm
 22107                              <1> 	;
 22108 00005514 29C0                <1> 	sub	eax, eax
 22109 00005516 A0[40820000]        <1> 	mov	al, [free_map_sector] ; logical sector number
 22110 0000551B 2407                <1> 	and	al, 7
 22111                              <1> 
 22112                              <1> 	; al = bit offset in fbm allocation byte
 22113                              <1> 	; edx = buffer address (start+offset)
 22114                              <1> 	; [free_map_offset] = byte position on fbm
 22115                              <1> 	; 27/11/2021
 22116 0000551D 0FAB02              <1> 	bts	[edx], eax  ; copy value of bit position in eax to cf
 22117                              <1> 			    ; then set same bit position at [edx]
 22118 00005520 7305                <1> 	jnc	short free_3 ; it was allocated sector
 22119                              <1> 
 22120                              <1> 	; already free sector !? 
 22121                              <1> 	; (nonsence or defective fs)
 22122                              <1> 
 22123 00005522 30C0                <1> 	xor	al, al ; 0  ; eax = 0
 22124 00005524 48                  <1> 	dec	eax ; 0FFFFFFFFh
 22125                              <1> 	;mov	[ebx+SB.FreeBlocks], eax 
 22126                              <1> 		; invalidate free blocks count
 22127 00005525 EB18                <1> 	jmp	short free_5
 22128                              <1> free_3:
 22129                              <1> 	; 27/11/2021
 22130 00005527 8B4338              <1> 	mov	eax, [ebx+SB.FreeBlocks]
 22131 0000552A 40                  <1> 	inc	eax
 22132 0000552B 7401                <1> 	jz	short free_4 ; 0FFFFFFFFh -> 0 (invalid!)
 22133 0000552D 48                  <1> 	dec	eax  ; 0 -> 0FFFFFFFFh (invalid!)
 22134                              <1> free_4: 
 22135 0000552E 50                  <1> 	push	eax ; * ; number of free blocks 
 22136                              <1> 	;mov	eax, [free_map_index] ; fbm sector index
 22137                              <1> 	;add	eax, [ebx+SB.FreeMapAddr] 
 22138                              <1> 			; free blocks map start sector address
 22139                              <1> 	;add	eax, [ebx+SB.BootSectAddr]
 22140                              <1> 	;		; + Hidden Sectors
 22141 0000552F A1[3C820000]        <1> 	mov	eax, [free_map_index] ; restore physical sector address
 22142                              <1> 	; eax = physical sector number
 22143 00005534 E84E0C0000          <1> 	call	wslot
 22144                              <1> 	; ebx = buffer data address (write operation bit is set)
 22145                              <1> 	; eax = physical sector number
 22146                              <1> 	; Note: ebx contains addr of the 1st buffer in the buffer
 22147                              <1> 	; (the last allocated buffer becomes the 1st in buffer chain)
 22148                              <1> 
 22149 00005539 E8650C0000          <1> 	call	dskwr ; writes the 1st buffer to sector
 22150                              <1> 		      ; (at the beginning/head of the buffer chain)
 22151                              <1> 
 22152                              <1> 	; if we are here, buffer has been written to disk successfully 
 22153                              <1> 	; (otherwise cpu would jump to 'error' address)
 22154 0000553E 58                  <1> 	pop	eax ; *  ; number of free blocks 
 22155                              <1> free_5:
 22156                              <1> 	; eax = number of free blocks 
 22157                              <1> 	;
 22158                              <1> 	; set superblock modified flag
 22159 0000553F BA[A7700000]        <1> 	mov	edx, smod
 22160 00005544 BB[307E0000]        <1> 	mov	ebx, systm
 22161 00005549 F605[95700000]01    <1> 	test	byte [cdev], 1 ; mounted device ?
 22162 00005550 7406                <1> 	jz	short free_6 ; no, root device
 22163                              <1> 	; yes, mounted device
 22164 00005552 BB[38800000]        <1> 	mov	ebx, mount
 22165                              <1> 	;mov	edx, mmod
 22166 00005557 42                  <1> 	inc	edx ; edx = offset mmod
 22167                              <1> free_6: 
 22168 00005558 894338              <1> 	mov	[ebx+SB.FreeBlocks], eax 
 22169                              <1> 
 22170 0000555B A1[40820000]        <1> 	mov	eax, [free_map_sector] ; logical sector number
 22171 00005560 3B433C              <1> 	cmp	eax, [ebx+SB.FirstFreeBlk]
 22172 00005563 7303                <1> 	jnb	short free_7
 22173 00005565 89433C              <1> 	mov	[ebx+SB.FirstFreeBlk], eax
 22174                              <1> free_7:
 22175 00005568 FE02                <1> 	inc	byte [edx] ; superblock modified !
 22176 0000556A C3                  <1> 	retn
 22177                              <1> 	
 22178                              <1> iget:
 22179                              <1> 	; 30/11/2021
 22180                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22181                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22182                              <1> 	; 07/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
 22183                              <1> 	;
 22184                              <1> 	; get a new i-node whose i-number in r1 and whose device is in cdev
 22185                              <1> 	;
 22186                              <1> 	; ('iget' returns current i-number in r1, if input value of r1 is 0)
 22187                              <1> 	; 
 22188                              <1> 	; INPUTS ->
 22189                              <1> 	;    ii - current i-number, rootdir
 22190                              <1> 	;    cdev - new i-node device
 22191                              <1> 	;    idev - current i-node device
 22192                              <1> 	;    imod - current i-node modified flag
 22193                              <1> 	;    mnti - cross device file i-number
 22194                              <1> 	;    r1 - i-numbe rof new i-node
 22195                              <1> 	;    mntd - mountable device number		
 22196                              <1> 	; 	 
 22197                              <1> 	; OUTPUTS ->
 22198                              <1> 	;    cdev, idev, imod, ii, r1
 22199                              <1> 	;
 22200                              <1> 	; ((AX = R1)) input/output
 22201                              <1> 	;
 22202                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 22203                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 22204                              <1> 
 22205                              <1> 	; 22/11/2021
 22206                              <1> 	;;mov	dl, [cdev] ; 18/07/2013
 22207                              <1> 	;;mov	dh, [idev] ; 07/08/2013
 22208                              <1> 	; 26/05/2020 - Retro UNIX 386 v2
 22209                              <1> 	;mov	dh, [cdev]
 22210                              <1> 	;mov	dl, [idev]
 22211 0000556B 668B15[94700000]    <1> 	mov	dx, [idev] ; [idev] in dl, [cdev] in dh
 22212                              <1> 	;
 22213                              <1> 	; 22/11/2021
 22214 00005572 25FFFF0000          <1> 	and	eax, 0FFFFh
 22215 00005577 3B05[90700000]      <1> 	cmp 	eax, [ii]
 22216                              <1> 		; cmp r1,ii / r1 = i-number of current file
 22217 0000557D 7504                <1> 	jne 	short iget_1
 22218                              <1> 		; bne 1f
 22219 0000557F 38F2                <1> 	cmp	dl, dh
 22220                              <1> 		; cmp idev,cdev
 22221                              <1> 			  ; / is device number of i-node = current device
 22222 00005581 746C                <1>         je	short iget_5
 22223                              <1> 	;	; beq 2f
 22224                              <1> 	; 14/08/2021
 22225                              <1> iget_1: ; 1:
 22226 00005583 30DB                <1> 	xor	bl, bl
 22227 00005585 381D[A6700000]      <1> 	cmp	[imod], bl ; 0	
 22228                              <1> 		; tstb imod / has i-node of current file
 22229                              <1> 			  ; / been modified i.e., imod set
 22230 0000558B 7628                <1> 	jna	short iget_2
 22231                              <1> 		; beq 1f
 22232 0000558D 881D[A6700000]      <1> 	mov	[imod], bl ; 0
 22233                              <1> 		;  clrb	imod / if it has, 
 22234                              <1> 			   ; / we must write the new i-node out on disk
 22235                              <1> 	; 22/11/2021 (32 bit push-pop)
 22236 00005593 50                  <1> 	push	eax ; *
 22237                              <1> 		; mov r1,-(sp)
 22238 00005594 52                  <1> 	push	edx ; **
 22239                              <1> 		; mov cdev,-(sp)
 22240 00005595 A1[90700000]        <1> 	mov	eax, [ii]
 22241                              <1> 		; mov ii,r1
 22242                              <1> 	;mov	dh, [idev]
 22243 0000559A 8835[95700000]      <1> 	mov	[cdev], dh
 22244                              <1> 		; mov idev,cdev
 22245 000055A0 FEC3                <1> 	inc	bl ; 1
 22246                              <1> 	; 31/07/2013
 22247 000055A2 881D[F4710000]      <1> 	mov     [rw], bl ; 1 == write 
 22248                              <1> 	;;28/07/2013 rw -> u.rw
 22249                              <1>         ;;mov   [u.rw], bl ; 1 == write
 22250 000055A8 E843000000          <1> 	call	icalc
 22251                              <1> 		; jsr r0,icalc; 1
 22252 000055AD 5A                  <1> 	pop	edx ; **
 22253 000055AE 8835[95700000]      <1> 	mov	[cdev], dh ; 22/11/2021
 22254                              <1> 		; mov (sp)+,cdev
 22255 000055B4 58                  <1> 	pop	eax ; *
 22256                              <1> 		; mov (sp)+,r1
 22257                              <1> iget_2: ; 1:
 22258                              <1> 	;and	ax, ax
 22259 000055B5 21C0                <1> 	and	eax, eax ; 22/11/2021 (32 bit inode number)
 22260                              <1> 		; tst r1 / is new i-number non zero
 22261 000055B7 7431                <1> 	jz	short iget_4 ; 2f
 22262                              <1> 		; beq 2f / branch if r1=0
 22263                              <1> 
 22264                              <1> 	;mov 	dh, [cdev]
 22265 000055B9 08F6                <1> 	or	dh, dh ; 22/11/2021
 22266                              <1> 		; tst cdev / is the current device number non zero
 22267                              <1> 			 ; / (i.e., device =/ drum)
 22268 000055BB 7515                <1> 	jnz	short iget_3 ;  1f
 22269                              <1> 		; bne 1f / branch 1f cdev =/ 0  ;; (cdev != 0)
 22270                              <1> 	; 22/11/2021
 22271 000055BD 3B05[A0700000]      <1> 	cmp	eax, [mnti]
 22272                              <1> 	;cmp	ax, [mnti]			
 22273                              <1> 		; cmp r1,mnti / mnti is the i-number of the cross device
 22274                              <1> 			    ; / file (root directory of mounted device)
 22275 000055C3 750D                <1> 	jne	short iget_3 ; 1f
 22276                              <1> 		; bne 1f
 22277                              <1>         ;mov    bl, [mntd]
 22278 000055C5 FEC6                <1> 	inc	dh ; mov dh, 1 ; 22/11/2021
 22279 000055C7 8835[95700000]      <1>         mov	[cdev], dh ; 22/11/2021
 22280                              <1> 		; mov mntd,cdev / make mounted device the current device
 22281                              <1> 	; 22/11/2021
 22282 000055CD A1[9C700000]        <1> 	mov	eax, [rootdir] ; rootdir = 1 (for runix v2 file system)
 22283                              <1> 	;mov	ax, [rootdir]
 22284                              <1> 		; mov rootdir,r1
 22285                              <1> iget_3: ; 1:
 22286                              <1> 	; 22/11/2021
 22287 000055D2 A3[90700000]        <1> 	mov	[ii], eax ; 32 bit inode number
 22288                              <1> 	;mov	[ii], ax
 22289                              <1> 		; mov r1,ii
 22290                              <1> 	; 30/11/2021
 22291 000055D7 8835[94700000]      <1> 	mov	[idev], dh ; cdev 
 22292                              <1> 	;mov	[idev], dl ; cdev
 22293                              <1> 		; mov cdev,idev
 22294 000055DD 30DB                <1> 	xor	bl, bl
 22295                              <1>         ; 31/07/2013
 22296 000055DF 881D[F4710000]      <1> 	mov     [rw], bl ; 0 == read 
 22297                              <1> 	;;28/07/2013 rw -> u.rw       
 22298                              <1>         ;;mov   [u.rw], bl ; 0 = read
 22299 000055E5 E806000000          <1> 	call	icalc
 22300                              <1> 		; jsr r0,icalc; 0 / read in i-node ii
 22301                              <1> iget_4: ; 2:
 22302                              <1> 	; 22/11/2021
 22303 000055EA A1[90700000]        <1> 	mov	eax, [ii]
 22304                              <1> 	;mov	ax, [ii]
 22305                              <1> 		; mov ii,r1
 22306                              <1> iget_5:
 22307 000055EF C3                  <1> 	retn
 22308                              <1> 		; rts r0
 22309                              <1> 
 22310                              <1> icalc:
 22311                              <1> 	; 28/11/2021
 22312                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification 
 22313                              <1> 	; 02/07/2015
 22314                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22315                              <1> 	; 07/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 22316                              <1> 	;
 22317                              <1> 	; calculate physical block number from i-number then
 22318                              <1> 	; read or write that block
 22319                              <1> 	;
 22320                              <1> 	; 'icalc' is called from 'iget'
 22321                              <1> 	;
 22322                              <1> 	; for original unix v1:
 22323                              <1> 	; / i-node i is located in block (i+31.)/16. and begins 32.*
 22324                              <1>        	; / (i+31.) mod 16. bytes from its start
 22325                              <1> 	;
 22326                              <1> 	; for retro unix 8086 v1:
 22327                              <1> 	;  i-node is located in block (i+47)/16 and
 22328                              <1> 	;  begins 32*(i+47) mod 16 bytes from its start
 22329                              <1> 	;
 22330                              <1> 	; INPUTS ->
 22331                              <1> 	;    r1 - i-number of i-node
 22332                              <1> 	; 	 
 22333                              <1> 	; OUTPUTS ->
 22334                              <1> 	;    inode r/w
 22335                              <1> 	;
 22336                              <1> 	; ((AX = R1)) input
 22337                              <1> 	;
 22338                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 18/11/2012, UNIXCOPY.ASM)
 22339                              <1>         ;  ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))  
 22340                              <1> 	;
 22341                              <1> 
 22342                              <1> 	; 28/11/2021
 22343                              <1> 	;cmp	byte [idev], 0 ; [cdev] = [idev]
 22344 000055F0 803D[95700000]00    <1> 	cmp	byte [cdev], 0
 22345 000055F7 7607                <1> 	jna	short icalc_0r
 22346 000055F9 BD[38800000]        <1> 	mov	ebp, mount  ; mounted file system's superblock 
 22347 000055FE EB05                <1> 	jmp	short icalc_0m
 22348                              <1> icalc_0r:
 22349                              <1> 	; 28/11/2021
 22350 00005600 BD[307E0000]        <1> 	mov	ebp, systm  ; root file system's superblock 
 22351                              <1> icalc_0m:
 22352                              <1> 	; 22/11/2021
 22353                              <1> 	;mov	edx, eax
 22354 00005605 8B15[90700000]      <1> 	mov	edx, [ii] ; 32 bit inode number
 22355 0000560B 8B4528              <1> 	mov	eax, [ebp+SB.InodeTblAddr] ; inode table base address
 22356                              <1> 	;
 22357 0000560E 4A                  <1> 	dec	edx ; 0 based inode number 
 22358                              <1> 		    ; (inode index in inode table)
 22359 0000560F 52                  <1> 	push	edx ; *
 22360 00005610 C1EA03              <1> 	shr	edx, 3
 22361 00005613 7402                <1> 	jz	short icalc_0t ; 0 for inodes 1 to 8
 22362 00005615 01D0                <1> 	add	eax, edx
 22363                              <1> icalc_0t:
 22364                              <1> 	;add	eax, [ebp+SB.BootSectAddr]
 22365 00005617 E80B0B0000          <1> 	call	dskrd
 22366                              <1> 		; jsr r0,dskrd / read in block containing i-node i.
 22367                              <1> 	; 31/07/2013
 22368 0000561C 803D[F4710000]00    <1>         cmp     byte [rw], 0 ; Retro Unix 8086 v1 feature !
 22369                              <1> 	;; 28/07/2013 rw -> u.rw
 22370                              <1>         ;;cmp	byte [u.rw], 0 ; Retro Unix 8086 v1 feature !
 22371                              <1> 		; tst (r0)
 22372 00005623 7605                <1> 	jna	short icalc_1
 22373                              <1> 		; beq 1f / branch to wslot when argument
 22374                              <1> 		       ; / in icalc call = 1
 22375                              <1> 	; eAX = r1  = block number
 22376 00005625 E85D0B0000          <1> 	call	wslot
 22377                              <1> 		; jsr r0,wslot / set up data buffer for write
 22378                              <1> 			     ; / (will be same buffer as dskrd got)
 22379                              <1> 	; EBX = r5 points to first word in data area for this block
 22380                              <1> icalc_1: ; 1:
 22381 0000562A 5A                  <1> 	pop	edx ; *
 22382                              <1> 	; 22/11/2021
 22383 0000562B 83E207              <1> 	and 	edx, 07h ; 8 inodes per inode table sector
 22384 0000562E C1E206              <1> 	shl 	edx, 6 ; * 64 (inode size)
 22385                              <1> 	; edx = 64 * (mod(inodenumber-1)/8)
 22386 00005631 89DE                <1> 	mov	esi, ebx  ; ebx points 1st word of the buffer
 22387 00005633 01D6                <1> 	add	esi, edx  ; edx is inode offset in the buffer
 22388                              <1>           	; eSI (r5) points to first word in i-node i.	
 22389                              <1> 		; mov (sp)+,mq / calculate offset in data buffer; 
 22390                              <1> 			     ; / 32.*(i+31.)mod16
 22391                              <1> 		; mov $5,lsh / for i-node i.
 22392                              <1> 		; add mq,r5 / r5 points to first word in i-node i.
 22393 00005635 BF[506D0000]        <1> 	mov	edi, inode
 22394                              <1> 		; mov $inode,r1 / inode is address of first word 
 22395                              <1> 			      ; / of current i-node
 22396                              <1> 	;mov 	ecx, 8 ; 02/07/2015 (32 bit modification)
 22397                              <1> 	;	; mov $16.,r3
 22398                              <1> 	; 28/11/2021
 22399 0000563A 29C9                <1> 	sub	ecx, ecx
 22400 0000563C B110                <1> 	mov	cl, 16 ; Retro UNIX 386 v2 inode size = 64 bytes
 22401                              <1> 	; 31/07/2013
 22402 0000563E 382D[F4710000]      <1>   	cmp     [rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 22403                              <1>        ;;28/07/2013 rw -> u.rw                 
 22404                              <1>        ;;cmp    [u.rw], ch ; 0  ;; Retro Unix 8086 v1 feature !
 22405                              <1> 		; tst (r0)+ / branch to 2f when argument in icalc call = 0
 22406 00005644 7609                <1> 	jna	short icalc_3
 22407                              <1> 		; beq 2f / r0 now contains proper return address 
 22408                              <1> 		       ; / for rts r0
 22409                              <1> icalc_2: ; 1:
 22410 00005646 87F7                <1> 	xchg 	esi, edi
 22411                              <1> 	; overwrite old i-node (in buffer to be written)
 22412 00005648 F3A5                <1> 	rep 	movsd
 22413                              <1> 		; mov (r1)+,(r5)+ / over write old i-node
 22414                              <1> 		; dec r3
 22415                              <1> 		; bgt 1b
 22416                              <1> 	;call	dskwr
 22417                              <1> 	;	; jsr r0,dskwr / write inode out on device
 22418                              <1> 	;retn
 22419                              <1> 	;	; rts r0
 22420                              <1> 	; 28/11/2021
 22421 0000564A E9540B0000          <1> 	jmp	dskwr
 22422                              <1> icalc_3: ; 2:
 22423                              <1> 	; copy new i-node into inode area of (core) memory
 22424 0000564F F3A5                <1> 	rep 	movsd
 22425                              <1> 		; mov (r5)+,(r1)+ / read new i-node into 
 22426                              <1> 		                ; / "inode" area of core
 22427                              <1> 		; dec r3
 22428                              <1> 		; bgt 2b
 22429 00005651 C3                  <1> 	retn
 22430                              <1> 		; rts r0
 22431                              <1> 
 22432                              <1> access:
 22433                              <1> 	; 28/11/2021
 22434                              <1> 	; 22/11/2021 - Retro UNIX 386 v2 compatibility modification
 22435                              <1> 	; 31/10/2021 - temporary (simplified code)
 22436                              <1> 	; 14/06/2021
 22437                              <1> 	; 02/05/2021
 22438                              <1> 	; 27/03/2021
 22439                              <1> 	; 26/03/2021
 22440                              <1> 	; 25/03/2021
 22441                              <1> 	; 23/03/2021 (Retro UNIX 386 v2 - Beginning)
 22442                              <1> 	;	((ref: unix v7 source - fio.c))
 22443                              <1> 	; ref: INODE STRUCTURE of Retro UNIX v2 file system
 22444                              <1> 	;	07/02/2020, 'RETRO UNIX v2 Inodes.pdf'
 22445                              <1> 	;	 
 22446                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22447                              <1> 	; 24/04/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 22448                              <1> 	;
 22449                              <1> 	; check whether user is owner of file or user has read or write
 22450                              <1> 	; permission (based on i.flgs).
 22451                              <1> 	;
 22452                              <1> 	; INPUTS ->
 22453                              <1> 	;    r1 - i-number of file
 22454                              <1> 	;    u.uid
 22455                              <1> 	; arg0 -> (owner flag mask)	 		
 22456                              <1> 	;     Retro UNIX 8086 v1 feature -> owner flag mask in DL (DX) 	 
 22457                              <1> 	; OUTPUTS ->
 22458                              <1> 	;    inode (or jump to error)
 22459                              <1> 	;
 22460                              <1> 	; ((AX = R1)) input/output
 22461                              <1> 	;
 22462                              <1> 	;  ((Modified registers: eCX, eBX, eDX, eSI, eDI, eBP))
 22463                              <1> 
 22464                              <1> 	; 26/03/2021
 22465                              <1> 	; INPUT:
 22466                              <1> 	;	eax = inode number (ax)
 22467                              <1> 	;	 dx = mode (IEXEC, IREAD or IWRITE) 
 22468                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 22469                              <1> 	;	
 22470                              <1> 	; OUTPUT:
 22471                              <1> 	;	inode (or jump to error)
 22472                              <1> 	;	eax (ax) = [ii] = inode number
 22473                              <1> 	;	[cdev] = logical drive number ; 31/10/2021 
 22474                              <1> 	;
 22475                              <1> 	; Modified registers: (eax), ebx, ecx, edx, esi, edi, ebp
 22476                              <1> 	;
 22477                              <1> 	; IREAD	 equ 100h ; read permission flag, owner
 22478                              <1> 	; IWRITE equ 80h  ; write permission flag, owner
 22479                              <1> 	; IEXEC	 equ 40h  ; execute permission flag, owner	 
 22480                              <1> 		
 22481                              <1> 	; 23/03/2021
 22482 00005652 52                  <1> 	push	edx ; save flag (DX)
 22483                              <1> 	;push	dx  ; save flag (DL)
 22484 00005653 E813FFFFFF          <1> 	call	iget
 22485                              <1> 		; jsr r0,iget / read in i-node for current directory
 22486                              <1> 			    ; / (i-number passed in r1)
 22487                              <1> 	;;mov	cl, [i.flgs]
 22488                              <1> 	;;	; mov i.flgs,r2
 22489                              <1> 	; 23/03/2021
 22490                              <1> 	;mov	cx, [i.iflgs]	
 22491                              <1> 
 22492                              <1> 	;;pop	dx  ; restore flag (DL)
 22493                              <1> 	; 23/03/2021
 22494 00005658 5A                  <1> 	pop	edx ; restore flag (DX)
 22495                              <1> 
 22496                              <1> 	; 28/11/2021 (iget will not return here if there is an error)
 22497                              <1> 	; 31/10/2021
 22498                              <1> 	;jc	short access_5
 22499                              <1> 
 22500                              <1> 	; 31/10/2021
 22501                              <1> 	; Note: If eax input is same with [mnti], 'iget' will change
 22502                              <1> 	; [cdev] to 1 and eax will be 1 (root dir of mounted fs) 
 22503                              <1> 
 22504                              <1> 	; 27/03/2021
 22505                              <1> 	; 23/03/2021
 22506                              <1> 	; (check if it is write permission flag)
 22507 00005659 6681FA8000          <1> 	cmp	dx, 80h ; IWRITE
 22508 0000565E 7755                <1> 	ja	short access_r	; IREAD = 100h (owner)
 22509 00005660 7222                <1> 	jb	short access_x	; IEXEC = 40h (owner)
 22510                              <1> 	; IWRITE (80h)
 22511                              <1> access_w:
 22512                              <1> 	; 23/03/2021
 22513                              <1> 	; ((ref: Retro UNIX 386 v2, 'ux.s', 'ldrv' structure))
 22514                              <1> 	;mov	bl, [idev]
 22515                              <1> 	;call	getfs
 22516                              <1>  	;movzx	ebx, byte [idev]  ; logical drive number
 22517                              <1> 	;shl	bx, 6 ; * 64	  ; of current inode	
 22518                              <1> 	;add	ebx, ldrvtable	
 22519                              <1> 	;;test	byte [ebx+ldrv.pflags], 01h ; read only fs flag
 22520                              <1> 	;;jz	short access_0
 22521                              <1> 	;; 14/06/2021
 22522                              <1> 	; 14/06/2021
 22523                              <1> 	; check block device (fs) if it is read only fs or not ? 
 22524                              <1> 	;mov	edi, [ebx+ldrv.superblk]
 22525                              <1> 	;test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 22526                              <1> 	;jz	short access_0
 22527                              <1> 	; 31/10/2021
 22528 00005662 803D[95700000]01    <1> 	cmp	byte [cdev], 1
 22529 00005669 7207                <1> 	jb	short access_7 ; [cdev] = 0
 22530                              <1> 	; [cdev] = 1
 22531                              <1> 	; 28/11/2021
 22532 0000566B BF[38800000]        <1> 	mov	edi, mount ; mounted file system's superblock buffer
 22533 00005670 EB05                <1> 	jmp	short access_8
 22534                              <1> access_7:
 22535                              <1> 	; 28/11/2021
 22536 00005672 BF[307E0000]        <1> 	mov	edi, systm ; root file system's superblock buffer
 22537                              <1> access_8:
 22538 00005677 F6476A01            <1> 	test	byte [edi+SB.ReadOnly], 1 ; bit 0 = 1 ?
 22539 0000567B 7438                <1> 	jz	short access_0
 22540                              <1> 
 22541                              <1> 	; 23/03/2021
 22542                              <1> 	;mov	dword [u.error], ERR_READ_ONLY_FS
 22543                              <1> 	;		; 'read only file system !' error
 22544                              <1> 	;jmp	error
 22545                              <1> 
 22546                              <1> 	; 31/10/2021
 22547 0000567D B81E000000          <1> 	mov	eax, ERR_READ_ONLY_FS
 22548                              <1> 			; 'read only file system !' error
 22549                              <1> 	; 27/03/2021
 22550 00005682 EB27                <1> 	jmp	short access_5
 22551                              <1> 
 22552                              <1> 	; check block device (fs) if it is read only fs or not ? 
 22553                              <1> 
 22554                              <1> 	;mov	dh, [u.uid]
 22555                              <1> 	;cmp	dh, [i.uid]
 22556                              <1> 	;	; cmpb i.uid,u.uid / is user same as owner of file
 22557                              <1> 	;jne	short access_1
 22558                              <1> 		; bne 1f / no, then branch
 22559                              <1> access_x:
 22560                              <1> 	; IEXEC (40h)
 22561                              <1> 	; 27/03/2021
 22562 00005684 668B1D[506D0000]    <1> 	mov	bx, [i.flgs]
 22563 0000568B F6C780              <1> 	test	bh, 80h ; regular file ?
 22564 0000568E 7416                <1> 	jz	short access_4 ; not executable file !
 22565 00005690 F6C740              <1> 	test	bh, 40h	; directory ?
 22566 00005693 7511                <1> 	jnz	short access_4 ; not executable file !
 22567 00005695 668B0D[0A710000]    <1> 	mov	cx, [u.uid]
 22568 0000569C 6609C9              <1> 	or	cx, cx
 22569 0000569F 7520                <1> 	jnz	short access_3 ; (restricted user)
 22570                              <1> 	; (super user)
 22571                              <1> 	;test	[i.flgs], dl ; execute permission for owner
 22572                              <1> 	;test	byte [i.flgs], 49h ; for owner, group, others
 22573 000056A1 F6C349              <1> 	test	bl, 49h ; exec perm for owner, group, others
 22574 000056A4 7557                <1> 	jnz	short access_2
 22575                              <1> access_4:
 22576                              <1> 	; 31/10/2021
 22577 000056A6 B816000000          <1> 	mov	eax, ERR_NOT_EXECUTABLE
 22578                              <1> 			; 'not executable file !' error
 22579                              <1> 	; 26/03/2021
 22580                              <1> ;;sysexec_not_exf:
 22581                              <1> ;	mov	dword [u.error], ERR_NOT_EXECUTABLE
 22582                              <1> ;			; 'not executable file !' error
 22583                              <1> ;access_5:
 22584                              <1> ;	jmp	error
 22585                              <1> 	
 22586                              <1> 	; 31/10/2021
 22587                              <1> access_5:
 22588 000056AB A3[2C710000]        <1> 	mov	[u.error], eax
 22589 000056B0 E921E6FFFF          <1> 	jmp	error
 22590                              <1> 
 22591                              <1> access_r:
 22592                              <1> 	; 27/03/2021
 22593                              <1> access_0:
 22594                              <1> 	; 23/03/2021
 22595 000056B5 668B0D[0A710000]    <1> 	mov	cx, [u.uid]
 22596 000056BC 6609C9              <1> 	or	cx, cx ; 0 ; root ?
 22597 000056BF 743C                <1> 	jz	short access_2 ; yes
 22598                              <1> access_3:
 22599                              <1> 	; owner ?
 22600 000056C1 8A1D[566D0000]      <1> 	mov	bl, [i.gid]
 22601 000056C7 663B0D[546D0000]    <1> 	cmp	cx, [i.uid]
 22602                              <1> 	;je	short access_1
 22603                              <1> 	; 02/05/2021
 22604 000056CE 750E                <1> 	jne	short access_6
 22605                              <1> 	; check owner's group number/ID
 22606 000056D0 3A1D[0E710000]      <1> 	cmp	bl, [u.gid] ; same group number/ID ?
 22607 000056D6 7415                <1> 	je	short access_1 ; yes, owner
 22608                              <1> 	; one of others
 22609 000056D8 66C1EA06            <1> 	shr	dx, 6
 22610 000056DC EB0F                <1> 	jmp	short access_1 ; others
 22611                              <1> access_6:
 22612                              <1> 	;shr	cl, 2
 22613                              <1> 	;	; asrb r2 / shift owner read write bits into non owner
 22614                              <1> 	;	;       ; / read/write bits
 22615                              <1> 	;	; asrb r2
 22616                              <1> 
 22617                              <1> 	; 23/03/2021
 22618                              <1> 	; same group ?
 22619 000056DE 66C1EA03            <1> 	shr	dx, 3
 22620                              <1> 	;mov	cl, [u.gid]
 22621                              <1> 	;cmp	cl, [i.gid]
 22622                              <1> 	;je	short access_1
 22623                              <1> 	; 02/05/2021
 22624 000056E2 3A1D[0E710000]      <1> 	cmp	bl, [u.gid]
 22625 000056E8 7403                <1> 	je	short access_1 ; same group, different owner
 22626                              <1> 
 22627                              <1> 	; others
 22628                              <1> 	;shr	dx, 3
 22629 000056EA C0EA03              <1> 	shr	dl, 3
 22630                              <1> 	;jmp	short access_1	
 22631                              <1> 
 22632                              <1> ;access_1: ; 1:
 22633                              <1> 	;and	cl, dl
 22634                              <1> 	;	; bit r2,(r0)+ / test read-write flags against argument
 22635                              <1> 	;		     ; / in access call
 22636                              <1> 	;jnz	short access_2
 22637                              <1> 	;	; bne 1f
 22638                              <1> 	
 22639                              <1> 	;or	dh, dh	; super user (root) ?
 22640                              <1> 	;	; tstb u.uid
 22641                              <1> 	;jz	short access_2 ; yes, super user
 22642                              <1> 	;;jnz	error
 22643                              <1> 	;	; beq 1f
 22644                              <1> 	;	; jmp error
 22645                              <1> 	
 22646                              <1> 	;mov	dword [u.error], ERR_FILE_ACCESS 
 22647                              <1> 	;		; 'permission denied !' error
 22648                              <1> 	;jmp	error
 22649                              <1> 
 22650                              <1> access_1:
 22651                              <1> 	; 23/03/2021
 22652 000056ED 668515[506D0000]    <1> 	test	dx, [i.flgs]
 22653 000056F4 7507                <1> 	jnz	short access_2
 22654                              <1> 
 22655                              <1> 	;; r/w permission error
 22656                              <1> 	;mov	dword [u.error], ERR_FILE_ACCESS 
 22657                              <1> 	;		; 'permission denied !' error
 22658                              <1> 	;;jmp	error
 22659                              <1> 
 22660                              <1> 	; 31/10/2021
 22661 000056F6 B80B000000          <1> 	mov	eax, ERR_FILE_ACCESS 
 22662                              <1> 			; 'permission denied !' error
 22663                              <1> 	; 27/03/2021
 22664 000056FB EBAE                <1> 	jmp	short access_5
 22665                              <1> 
 22666                              <1> access_2: ; 1:
 22667                              <1> 	;; DL = flags
 22668                              <1> 	;retn
 22669                              <1> 	;	; rts r0
 22670                              <1> 	; 27/03/2021
 22671                              <1> 	; DX = flag (100h-20h-04h or 80h-10h-02h or 40h-08h-01h)
 22672 000056FD C3                  <1> 	retn
 22673                              <1> 
 22674                              <1> setimod:
 22675                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22676                              <1> 	; 09/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 22677                              <1> 	;
 22678                              <1> 	; 'setimod' sets byte at location 'imod' to 1; thus indicating that 
 22679                              <1> 	; the inode has been modified. Also puts the time of modification
 22680                              <1> 	; into the inode.
 22681                              <1> 	;
 22682                              <1> 	;  (Retro UNIX Prototype : 14/07/2012 - 23/02/2013, UNIXCOPY.ASM)
 22683                              <1>         ;  ((Modified registers: eDX, eCX, eBX)) 
 22684                              <1> 	;
 22685                              <1> 	
 22686                              <1> 	; push 	edx
 22687 000056FE 50                  <1> 	push	eax
 22688                              <1> 
 22689 000056FF C605[A6700000]01    <1> 	mov 	byte [imod], 1
 22690                              <1> 		; movb $1,imod / set current i-node modified bytes
 22691                              <1> 	; Erdogan Tan 14-7-2012
 22692 00005706 E8EEE0FFFF          <1> 	call 	epoch
 22693                              <1> 		 ; mov s.time,i.mtim 
 22694                              <1> 			    ; / put present time into file modified time
 22695                              <1> 		 ; mov s.time+2,i.mtim+2
 22696                              <1> 
 22697 0000570B A3[886D0000]        <1> 	mov 	[i.mtim], eax
 22698                              <1> 	
 22699                              <1> 	; Retro UNIX 386 v1 modification ! (cmp)
 22700                              <1> 	; Retro UNIX 8086 v1 modification ! (test)
 22701 00005710 833D[8C6D0000]00    <1> 	cmp	dword [i.ctim], 0
 22702 00005717 7505                <1> 	jnz	short setimod_ok
 22703                              <1> 
 22704 00005719 A3[8C6D0000]        <1> 	mov 	[i.ctim], eax
 22705                              <1> 
 22706                              <1> setimod_ok: ; 31/07/2013
 22707 0000571E 58                  <1> 	pop	eax
 22708                              <1> 	;pop	edx
 22709                              <1> 	
 22710 0000571F C3                  <1> 	retn
 22711                              <1> 		; rts r0
 22712                              <1> 
 22713                              <1> itrunc:
 22714                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22715                              <1> 	; 23/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
 22716                              <1> 	;
 22717                              <1> 	; 'itrunc' truncates a file whose i-number is given in r1
 22718                              <1> 	;  to zero length.
 22719                              <1> 	;
 22720                              <1> 	; INPUTS ->
 22721                              <1> 	;    r1 - i-number of i-node
 22722                              <1> 	;    i.dskp - pointer to contents or indirect block in an i-node
 22723                              <1> 	;    i.flgs - large file flag		
 22724                              <1> 	;    i.size - size of file	
 22725                              <1> 	; 	 
 22726                              <1> 	; OUTPUTS ->
 22727                              <1> 	;    i.flgs - large file flag is cleared
 22728                              <1> 	;    i.size - set to 0	
 22729                              <1> 	;    i.dskp .. i.dskp+16 - entire list is cleared
 22730                              <1> 	;    setimod - set to indicate i-node has been modified
 22731                              <1> 	;    r1 - i-number of i-node  					
 22732                              <1> 	;
 22733                              <1> 	; ((AX = R1)) input/output
 22734                              <1> 	;
 22735                              <1> 	;  (Retro UNIX Prototype : 01/12/2012 - 10/03/2013, UNIXCOPY.ASM)
 22736                              <1>         ;  ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 22737                              <1> 
 22738 00005720 E846FEFFFF          <1> 	call	iget
 22739                              <1> 		; jsr r0,iget
 22740 00005725 BE[5C6D0000]        <1> 	mov	esi, i.dskp
 22741                              <1> 		; mov $i.dskp,r2 / address of block pointers in r2
 22742 0000572A 31C0                <1> 	xor	eax, eax
 22743                              <1> itrunc_1: ; 1:
 22744 0000572C 66AD                <1> 	lodsw
 22745                              <1> 		; mov (r2)+,r1 / move physical block number into r1
 22746 0000572E 6609C0              <1> 	or 	ax, ax
 22747 00005731 743B                <1> 	jz	short itrunc_5
 22748                              <1> 		; beq 5f
 22749 00005733 56                  <1> 	push	esi
 22750                              <1> 		; mov r2,-(sp)
 22751 00005734 66F705[506D0000]00- <1> 	test    word [i.flgs], 1000h    
 22752 0000573C 10                  <1>
 22753                              <1> 		; bit $10000,i.flgs / test large file bit?
 22754 0000573D 7429                <1> 	jz	short itrunc_4
 22755                              <1> 		; beq 4f / if clear, branch
 22756 0000573F 50                  <1> 	push	eax
 22757                              <1> 		; mov r1,-(sp) / save block number of indirect block
 22758 00005740 E8E2090000          <1> 	call	dskrd
 22759                              <1> 		; jsr r0,dskrd / read in block, 1st data word 
 22760                              <1> 			     ; / pointed to by r5
 22761                              <1> 	; eBX = r5 = Buffer data address (the 1st word)
 22762 00005745 B900010000          <1> 	mov	ecx, 256
 22763                              <1> 		; mov $256.,r3 / move word count into r3
 22764 0000574A 89DE                <1> 	mov	esi, ebx
 22765                              <1> itrunc_2: ; 2:
 22766 0000574C 66AD                <1> 	lodsw
 22767                              <1> 		; mov (r5)+,r1 / put 1st data word in r1; 
 22768                              <1> 			     ; / physical block number
 22769 0000574E 6621C0              <1> 	and	ax, ax
 22770 00005751 7409                <1> 	jz	short itrunc_3
 22771                              <1> 		; beq 3f / branch if zero
 22772                              <1> 	;push	ecx
 22773 00005753 6651                <1> 	push	cx
 22774                              <1> 		; mov r3,-(sp) / save r3, r5 on stack
 22775                              <1> 	;push	esi
 22776                              <1> 		; mov r5,-(sp)
 22777 00005755 E872FDFFFF          <1> 	call	free
 22778                              <1> 		; jsr r0,free / free block in free storage map
 22779                              <1> 	;pop	esi
 22780                              <1> 		; mov(sp)+,r5
 22781 0000575A 6659                <1> 	pop	cx
 22782                              <1> 	;pop	ecx
 22783                              <1> 		; mov (sp)+,r3
 22784                              <1> itrunc_3: ; 3:
 22785 0000575C E2EE                <1> 	loop	itrunc_2
 22786                              <1> 		; dec r3 / decrement word count
 22787                              <1> 		; bgt 2b / branch if positive
 22788 0000575E 58                  <1> 	pop	eax
 22789                              <1> 		; mov (sp)+,r1 / put physical block number of 
 22790                              <1> 			     ; / indirect block
 22791                              <1> 	; 01/08/2013
 22792 0000575F 668125[506D0000]FF- <1>         and     word [i.flgs], 0EFFFh ; 1110111111111111b
 22793 00005767 EF                  <1>
 22794                              <1> itrunc_4: ; 4:
 22795 00005768 E85FFDFFFF          <1> 	call	free
 22796                              <1> 		; jsr r0,free / free indirect block
 22797 0000576D 5E                  <1> 	pop	esi
 22798                              <1> 		; mov (sp)+,r2
 22799                              <1> itrunc_5: ; 5:
 22800 0000576E 81FE[6C6D0000]      <1> 	cmp	esi, i.dskp+16
 22801                              <1> 		; cmp r2,$i.dskp+16.
 22802 00005774 72B6                <1> 	jb	short itrunc_1	
 22803                              <1> 		; bne 1b / branch until all i.dskp entries check
 22804                              <1> 	; 01/08/2013
 22805                              <1> 	;and     word [i.flgs], 0EFFFh ; 1110111111111111b
 22806                              <1> 		; bic $10000,i.flgs / clear large file bit
 22807 00005776 BF[5C6D0000]        <1> 	mov	edi, i.dskp
 22808 0000577B 66B90800            <1> 	mov	cx, 8
 22809 0000577F 6631C0              <1> 	xor 	ax, ax
 22810 00005782 66A3[586D0000]      <1> 	mov	[i.size], ax ; 0
 22811                              <1> 		; clr i.size / zero file size
 22812 00005788 F366AB              <1> 	rep	stosw
 22813                              <1> 		; jsr r0,copyz; i.dskp; i.dskp+16. 
 22814                              <1> 			   ; / zero block pointers
 22815 0000578B E86EFFFFFF          <1> 	call	setimod
 22816                              <1> 		; jsr r0,setimod / set i-node modified flag
 22817 00005790 66A1[90700000]      <1> 	mov	ax, [ii]
 22818                              <1> 		; mov ii,r1
 22819 00005796 C3                  <1> 	retn
 22820                              <1> 		; rts r0
 22821                              <1> 
 22822                              <1> imap:
 22823                              <1> 	; 03/06/2015 (Retro UNIX 386 v1 - Beginning)
 22824                              <1> 	; 26/04/2013 (Retro UNIX 8086 v1)
 22825                              <1> 	;
 22826                              <1> 	; 'imap' finds the byte in core (superblock) containing
 22827                              <1> 	; allocation bit for an i-node whose number in r1.
 22828                              <1> 	;
 22829                              <1> 	; INPUTS ->
 22830                              <1> 	;    r1 - contains an i-number
 22831                              <1> 	;    fsp - start of table containing open files
 22832                              <1> 	;
 22833                              <1> 	; OUTPUTS ->
 22834                              <1> 	;    r2 - byte address of byte with the allocation bit
 22835                              <1> 	;    mq - a mask to locate the bit position.	
 22836                              <1> 	;	  (a 1 is in calculated bit posisiton)
 22837                              <1> 	;
 22838                              <1> 	; ((AX = R1)) input/output
 22839                              <1> 	; ((DL/DX = MQ)) output
 22840                              <1> 	; ((BX = R2)) output
 22841                              <1> 	;
 22842                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
 22843                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI))  
 22844                              <1> 	;
 22845                              <1> 		; / get the byte that has the allocation bit for 
 22846                              <1> 		; / the i-number contained in r1
 22847                              <1> 	;mov	dx, 1
 22848 00005797 B201                <1> 	mov	dl, 1
 22849                              <1> 		; mov $1,mq / put 1 in the mq
 22850 00005799 0FB7D8              <1> 	movzx	ebx, ax
 22851                              <1> 		; mov r1,r2 / r2 now has i-number whose byte
 22852                              <1>  		          ; / in the map we must find
 22853 0000579C 6683EB29            <1> 	sub	bx, 41
 22854                              <1> 		; sub $41.,r2 / r2 has i-41
 22855 000057A0 88D9                <1> 	mov	cl, bl
 22856                              <1> 		; mov r2,r3 / r3 has i-41
 22857 000057A2 80E107              <1> 	and	cl, 7
 22858                              <1> 		; bic $!7,r3 / r3 has (i-41) mod 8 to get 
 22859                              <1> 			   ; / the bit position
 22860 000057A5 7402                <1> 	jz	short imap1
 22861                              <1> 	;shl	dx, cl
 22862 000057A7 D2E2                <1> 	shl	dl, cl
 22863                              <1> 		; mov r3,lsh / move the 1 over (i-41) mod 8 positions
 22864                              <1> imap1:			   ; / to the left to mask the correct bit
 22865 000057A9 66C1EB03            <1> 	shr	bx, 3
 22866                              <1> 		; asr r2
 22867                              <1> 		; asr r2
 22868                              <1> 		; asr r2 / r2 has (i-41) base 8 of the byte number
 22869                              <1> 		       ; / from the start of the map
 22870                              <1> 		; mov r2,-(sp) / put (i-41) base 8 on the stack
 22871 000057AD BE[307E0000]        <1> 	mov	esi, systm
 22872                              <1> 		; mov $systm,r2 / r2 points to the in-core image of
 22873                              <1> 				; / the super block for drum
 22874                              <1> 	;cmp	word [cdev], 0
 22875 000057B2 803D[95700000]00    <1> 	cmp	byte [cdev], 0
 22876                              <1> 		; tst cdev / is the device the disk
 22877 000057B9 7606                <1> 	jna	short imap2
 22878                              <1> 		; beq 1f / yes
 22879 000057BB 81C608020000        <1> 	add	esi, mount - systm
 22880                              <1> 		; add $mount-systm,r2 / for mounted device,
 22881                              <1> 			; / r2 points to 1st word of its super block
 22882                              <1> imap2: ; 1:
 22883 000057C1 66031E              <1> 	add	bx, [esi] ;; add free map size to si
 22884                              <1> 		; add (r2)+,(sp) / get byte address of allocation bit
 22885 000057C4 6683C304            <1> 	add	bx, 4
 22886 000057C8 01F3                <1> 	add	ebx, esi
 22887                              <1>         	; add (sp)+,r2 / ?
 22888                              <1> 	;add	ebx, 4 ;; inode map offset in superblock
 22889                              <1> 		      ;; (2 + free map size + 2)
 22890                              <1> 		; add $2,r2 / ?
 22891                              <1>  	; DL/DX (MQ) has a 1 in the calculated bit position
 22892                              <1>         ; BX (R2) has byte address of the byte with allocation bit
 22893 000057CA C3                  <1> 	retn
 22894                              <1> 		; rts r0
 22895                                  %include 'u6.s'      ; 31/05/2015
 22896                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 22897                              <1> ; (re-write kernel for test by using previous version without a major defect)
 22898                              <1> ; ****************************************************************************
 22899                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS6.INC
 22900                              <1> ; Last Modification: 11/12/2021
 22901                              <1> ; ----------------------------------------------------------------------------
 22902                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 22903                              <1> ; (v0.1 - Beginning: 11/07/2012)
 22904                              <1> ;
 22905                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 22906                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 22907                              <1> ; <Bell Laboratories (17/3/1972)>
 22908                              <1> ; <Preliminary Release of UNIX Implementation Document>
 22909                              <1> ;
 22910                              <1> ; Retro UNIX 8086 v1 - U6.ASM (23/07/2014) //// UNIX v1 -> u6.s
 22911                              <1> ;
 22912                              <1> ; ****************************************************************************
 22913                              <1> 
 22914                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 22915                              <1> readi:
 22916                              <1> 	; 20/05/2015
 22917                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 22918                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 22919                              <1> 	;
 22920                              <1> 	; Reads from an inode whose number in R1
 22921                              <1> 	; 
 22922                              <1> 	; INPUTS ->
 22923                              <1> 	;    r1 - inode number
 22924                              <1> 	;    u.count - byte count user desires
 22925                              <1> 	;    u.base - points to user buffer
 22926                              <1> 	;    u.fofp - points to word with current file offset
 22927                              <1> 	; OUTPUTS ->
 22928                              <1> 	;    u.count - cleared
 22929                              <1> 	;    u.nread - accumulates total bytes passed back
 22930                              <1> 	;
 22931                              <1> 	; ((AX = R1)) input/output
 22932                              <1> 	;    (Retro UNIX Prototype : 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
 22933                              <1>         ;    ((Modified registers: edx, ebx, ecx, esi, esi, ebp))  
 22934                              <1> 
 22935 000057CB 31D2                <1> 	xor	edx, edx ; 0
 22936 000057CD 8915[E4700000]      <1> 	mov 	[u.nread], edx ; 0
 22937                              <1> 		; clr u.nread / accumulates number of bytes transmitted
 22938 000057D3 668915[24710000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
 22939 000057DA 3915[E0700000]      <1> 	cmp 	[u.count], edx ; 0
 22940                              <1> 		; tst u.count / is number of bytes to be read greater than 0
 22941 000057E0 7701                <1> 	ja 	short readi_1 ; 1f
 22942                              <1> 		; bgt 1f / yes, branch
 22943 000057E2 C3                  <1> 	retn
 22944                              <1> 		; rts r0 / no, nothing to read; return to caller
 22945                              <1> readi_1: ; 1:
 22946                              <1> 	;	; mov r1,-(sp) / save i-number on stack
 22947                              <1> 	;cmp	ax, 40
 22948                              <1> 	;	; cmp r1,$40. / want to read a special file 
 22949                              <1> 	;	;             / (i-nodes 1,...,40 are for special files)
 22950                              <1>         ;ja	dskr 
 22951                              <1> 	;	; ble 1f / yes, branch
 22952                              <1> 	;	; jmp dskr / no, jmp to dskr; 
 22953                              <1> 	;	;         / read file with i-node number (r1)
 22954                              <1> 	;	;    / starting at byte ((u.fofp)), read in u.count bytes
 22955                              <1> 	
 22956                              <1> 	; 28/11/2021
 22957 000057E3 F605[2A710000]FF    <1> 	test	byte [u.kcall], 0FFh
 22958 000057EA 7505                <1> 	jnz	short readi_2  ; 'readi' called by 'namei'
 22959                              <1> 
 22960                              <1> 	; eax = inode number
 22961                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 22962 000057EC E87AFDFFFF          <1> 	call	iget
 22963                              <1> readi_2:
 22964                              <1> 	; 28/11/2021
 22965                              <1> 	; eax = inode number
 22966                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 22967 000057F1 E87E040000          <1> 	call	is_regular_file
 22968 000057F6 0F84E4000000        <1> 	jz	dskr ; regular file 
 22969                              <1> 
 22970                              <1> 	; (20/05/2015)
 22971 000057FC 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 22972                              <1> 
 22973                              <1> 	; 28/11/2021	
 22974                              <1> 	; device file
 22975 000057FD BB[17580000]        <1> 	mov	ebx, readi_4
 22976 00005802 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 22977 00005805 720E                <1> 	jb	short readi_3
 22978 00005807 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 22979 0000580A 7709                <1> 	ja	short readi_3	
 22980                              <1> 	
 22981                              <1> 	; convert v2 inode number to v1 device inode number
 22982 0000580C 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 22983 0000580E 89C1                <1> 	mov	ecx, eax
 22984 00005810 C0E102              <1> 	shl	cl, 2 ; * 4
 22985 00005813 01CB                <1> 	add	ebx, ecx
 22986                              <1> readi_3:
 22987 00005815 FF23                <1> 	jmp	dword [ebx]	
 22988                              <1> 		 ; jmp *1f-2(r1)
 22989                              <1> readi_4: ; 1:
 22990 00005817 [67580000]          <1> 	dd	null ; 28/11/2021
 22991 0000581B [6B580000]          <1> 	dd	rtty ; tty, AX = 1 (runix)
 22992                              <1> 		 ;rtty / tty; r1=2
 22993                              <1> 		 ;rppt / ppt; r1=4
 22994 0000581F [BC580000]          <1> 	dd	rmem ; mem, AX = 2 (runix)
 22995                              <1> 		 ;rmem / mem; r1=6
 22996                              <1> 		 ;rrf0 / rf0
 22997                              <1> 		 ;rrk0 / rk0
 22998                              <1> 		 ;rtap / tap0
 22999                              <1> 		 ;rtap / tap1
 23000                              <1> 		 ;rtap / tap2
 23001                              <1> 		 ;rtap / tap3
 23002                              <1> 		 ;rtap / tap4
 23003                              <1> 		 ;rtap / tap5
 23004                              <1> 		 ;rtap / tap6
 23005                              <1> 		 ;rtap / tap7
 23006 00005823 [CD5F0000]          <1> 	dd	rfd ; fd0, AX = 3 (runix only)
 23007 00005827 [CD5F0000]          <1> 	dd	rfd ; fd1, AX = 4 (runix only)
 23008 0000582B [CD5F0000]          <1> 	dd	rhd ; hd0, AX = 5 (runix only)
 23009 0000582F [CD5F0000]          <1> 	dd	rhd ; hd1, AX = 6 (runix only)	
 23010 00005833 [CD5F0000]          <1> 	dd	rhd ; hd2, AX = 7 (runix only)
 23011 00005837 [CD5F0000]          <1> 	dd	rhd ; hd3, AX = 8 (runix only)	
 23012 0000583B [D1580000]          <1> 	dd	rlpr ; lpr, AX = 9 (invalid, write only device !?)
 23013 0000583F [B8580000]          <1> 	dd	rcvt ; tty0, AX = 10 (runix)	  
 23014                              <1> 		 ;rcvt / tty0
 23015 00005843 [B8580000]          <1> 	dd	rcvt ; tty1, AX = 11 (runix)	  
 23016                              <1> 		 ;rcvt / tty1
 23017 00005847 [B8580000]          <1> 	dd	rcvt ; tty2, AX = 12 (runix)	  
 23018                              <1> 		 ;rcvt / tty2
 23019 0000584B [B8580000]          <1> 	dd	rcvt ; tty3, AX = 13 (runix)	  
 23020                              <1> 		 ;rcvt / tty3
 23021 0000584F [B8580000]          <1> 	dd	rcvt ; tty4, AX = 14 (runix)	  
 23022                              <1> 		 ;rcvt / tty4
 23023 00005853 [B8580000]          <1> 	dd	rcvt ; tty5, AX = 15 (runix)	  
 23024                              <1> 		 ;rcvt / tty5
 23025 00005857 [B8580000]          <1> 	dd	rcvt ; tty6, AX = 16 (runix)	  
 23026                              <1> 		 ;rcvt / tty6
 23027 0000585B [B8580000]          <1> 	dd	rcvt ; tty7, AX = 17 (runix)	  
 23028                              <1> 		 ;rcvt / tty7
 23029 0000585F [B8580000]          <1> 	dd	rcvt ; COM1, AX = 18 (runix only)	  
 23030                              <1> 		 ;rcrd / crd
 23031 00005863 [B8580000]          <1> 	dd	rcvt ; COM2, AX = 19 (runix only)
 23032                              <1> 
 23033                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23034                              <1> null:
 23035 00005867 31C0                <1> 	xor	eax, eax
 23036 00005869 58                  <1> 	pop	eax
 23037 0000586A C3                  <1> 	retn
 23038                              <1> 
 23039                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 23040                              <1> rtty: ; / read from console tty
 23041                              <1> 	; 17/10/2015 - 16/07/2015 (Retro UNIX 8086 v1)
 23042                              <1> 	; 	     (Only 1 byte is read, by ignoring byte count!)
 23043                              <1> 	;  	     WHAT FOR: Every character from Keyboard input 
 23044                              <1> 	;	     must be written immediate on video page (screen)
 23045                              <1> 	;	     when it is required.	
 23046                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23047                              <1> 	; 11/03/2013 - 19/06/2014 (Retro UNIX 8086 v1)
 23048                              <1> 	;
 23049                              <1> 	; Console tty buffer is PC keyboard buffer
 23050                              <1> 	; and keyboard-keystroke handling is different than original
 23051                              <1> 	; unix (PDP-11) here. TTY/Keyboard procedures here are changed
 23052                              <1> 	; according to IBM PC compatible ROM BIOS keyboard functions. 
 23053                              <1> 	;
 23054                              <1> 	; 06/12/2013
 23055 0000586B 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 23056 00005872 8A83[EF6D0000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 23057                              <1> rttys:
 23058                              <1> 		; mov tty+[8*ntty]-8+6,r5 / r5 is the address of the 4th word of
 23059                              <1> 	               ; / of the control and status block
 23060                              <1> 		; tst 2(r5) / for the console tty; this word points to the console
 23061                              <1> 		       ; / tty buffer
 23062                              <1> 	; 28/07/2013
 23063 00005878 A2[ED700000]        <1> 	mov 	[u.ttyn], al
 23064                              <1> 	; 13/01/2014
 23065 0000587D FEC0                <1> 	inc	al
 23066 0000587F A2[EE700000]        <1> 	mov	[u.ttyp], al ; tty number + 1
 23067                              <1> rtty_nc: ; 01/02/2014
 23068                              <1> 	; 29/09/2013
 23069 00005884 B90A000000          <1> 	mov	ecx, 10
 23070                              <1> rtty_1: 	; 01/02/2014
 23071                              <1> 	;push 	cx ; 29/09/2013
 23072                              <1> 	; 11/12/2021
 23073 00005889 51                  <1> 	push	ecx
 23074                              <1> 	; byte [u.ttyn] = tty number (0 to 9) 
 23075 0000588A B001                <1> 	mov 	al, 1
 23076 0000588C E89E0B0000          <1> 	call 	getc
 23077                              <1> 	;pop 	cx ; 29/09/2013	
 23078                              <1> 	; 11/12/2021
 23079 00005891 59                  <1> 	pop	ecx
 23080 00005892 7516                <1> 	jnz	short rtty_2
 23081                              <1> 		; bne 1f / 2nd word of console tty buffer contains number
 23082                              <1> 	               ; / of chars. Is this number non-zero?
 23083 00005894 E20D                <1> 	loop	rtty_idle ; 01/02/2014
 23084                              <1> 	; 05/10/2013
 23085 00005896 8A25[ED700000]      <1> 	mov	ah, [u.ttyn]
 23086                              <1> 	; 29/09/2013
 23087 0000589C E818F9FFFF          <1> 	call	sleep
 23088                              <1> 		; jsr r0,canon; ttych / if 0, call 'canon' to get a line
 23089                              <1>                 ;           / (120 chars.)
 23090                              <1> 	;byte [u.ttyn] = tty number (0 to 9) 
 23091 000058A1 EBE1                <1> 	jmp	short rtty_nc ; 01/02/2014
 23092                              <1> 
 23093                              <1> rtty_idle:
 23094                              <1> 	; 29/07/2013
 23095 000058A3 E87DF8FFFF          <1> 	call 	idle
 23096 000058A8 EBDF                <1> 	jmp	short rtty_1 ; 01/02/2014
 23097                              <1> 	;1:
 23098                              <1> 		; tst 2(r5) / is the number of characters zero
 23099                              <1> 		; beq ret1 / yes, return to caller via 'ret1'
 23100                              <1> 		; movb *4(r5),r1 / no, put character in r1
 23101                              <1> 		; inc 4(r5) / 3rd word of console tty buffer points to byte which
 23102                              <1> 		          ; / contains the next char.
 23103                              <1> 		; dec 2(r5) / decrement the character count
 23104                              <1> rtty_2:
 23105 000058AA 30C0                <1> 	xor 	al, al
 23106 000058AC E87E0B0000          <1> 	call 	getc
 23107 000058B1 E891000000          <1> 	call	passc
 23108                              <1> 		; jsr r0,passc / move the character to core (user)
 23109                              <1> 	;; 17/10/2015 - 16/07/2015
 23110                              <1> 	; 19/06/2014
 23111                              <1> 	;;jnz	short rtty_nc
 23112 000058B6 58                  <1> 	pop	eax  ; (20/05/2015)
 23113 000058B7 C3                  <1> 	retn 
 23114                              <1> ;ret1:
 23115                              <1> 		; jmp ret / return to caller via 'ret'
 23116                              <1> 
 23117                              <1> rcvt:   ; < receive/read character from tty >
 23118                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23119                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 23120                              <1> 	;
 23121                              <1> 	; Retro UNIX 8086 v1 modification !
 23122                              <1> 	; 
 23123                              <1> 	; In original UNIX v1, 'rcvt' routine 
 23124                              <1> 	;		(exactly different than this one)
 23125                              <1> 	;	was in 'u9.s' file.
 23126                              <1> 	;
 23127 000058B8 2C0A                <1> 	sub 	al, 10
 23128                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 23129                              <1> 	; 16/07/2013
 23130                              <1> 	; 21/05/2013
 23131 000058BA EBBC                <1>         jmp     short rttys
 23132                              <1>       
 23133                              <1> ;rppt: / read paper tape
 23134                              <1> ;	jsr	r0,pptic / gets next character in clist for ppt input and
 23135                              <1> ;			 / places
 23136                              <1> ;		br ret / it in r1; if there 1s no problem with reader, it
 23137                              <1> ;		       / also enables read bit in prs
 23138                              <1> ;	jsr	r0,passc / place character in users buffer area
 23139                              <1> ;	br	rppt
 23140                              <1> 
 23141                              <1> rmem: ; / transfer characters from memory to a user area of core
 23142                              <1> 	; 17/10/2015
 23143                              <1> 	; 11/06/2015
 23144                              <1> 	; 24/05/2015
 23145                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23146                              <1> 	;
 23147 000058BC 8B35[C8700000]      <1> 	mov     esi, [u.fofp]
 23148                              <1> rmem_1:
 23149 000058C2 8B1E                <1>         mov     ebx, [esi]        
 23150                              <1> 	        ; mov *u.fofp,r1 / save file offset which points to the char
 23151                              <1> 		               ; / to be transferred to user
 23152 000058C4 FF06                <1>         inc     dword [esi] ; 17/10/2015
 23153                              <1> 		; inc *u.fofp / increment file offset to point to 'next' 
 23154                              <1> 			    ; / char in memory file
 23155 000058C6 8A03                <1> 	mov	al, [ebx]
 23156                              <1> 		; movb (r1),r1 / get character from memory file, 
 23157                              <1> 		             ; / put it in r1
 23158 000058C8 E87A000000          <1> 	call	passc        ; jsr r0,passc / move this character to 
 23159                              <1> 			     ;  / the next byte of the users core area
 23160                              <1> 		; br rmem / continue
 23161 000058CD 75F3                <1> 	jnz	short rmem_1
 23162                              <1> ret_:
 23163 000058CF 58                  <1> 	pop	eax ; 09/06/2015
 23164 000058D0 C3                  <1> 	retn
 23165                              <1> 
 23166                              <1> rlpr:
 23167                              <1> ;1:
 23168                              <1> ;rcrd:
 23169 000058D1 C705[2C710000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 23170 000058D9 0000                <1>
 23171 000058DB E9F6E3FFFF          <1> 	jmp	error
 23172                              <1> 		;jmp	error / see 'error' routine
 23173                              <1> 
 23174                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23175                              <1> dskr:
 23176                              <1> 	; 12/10/2015
 23177                              <1> 	; 21/08/2015
 23178                              <1> 	; 25/07/2015
 23179                              <1> 	; 10/07/2015
 23180                              <1> 	; 16/06/2015
 23181                              <1> 	; 31/05/2015
 23182                              <1> 	; 24/05/2015 (Retro UNIX 386 v1 - Beginning)
 23183                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 23184                              <1> dskr_0:
 23185 000058E0 50                  <1> 	push	eax
 23186                              <1> 		; mov (sp),r1 / i-number in r1
 23187                              <1> 	; AX = i-number
 23188 000058E1 E885FCFFFF          <1> 	call	iget
 23189                              <1> 		; jsr r0,iget / get i-node (r1) into i-node section of core
 23190                              <1>         ;movzx	edx, word [i.size] ; 16/06/2015
 23191                              <1> 	;	; mov i.size,r2 / file size in bytes in r2
 23192                              <1> 	; 28/11/2021
 23193 000058E6 8B15[586D0000]      <1> 	mov	edx, [i.size] ; 32 bit file size (runix v2 inode)
 23194                              <1> 	;
 23195 000058EC 8B1D[C8700000]      <1> 	mov	ebx, [u.fofp]
 23196 000058F2 2B13                <1> 	sub	edx, [ebx]
 23197                              <1> 		; sub *u.fofp,r2 / subtract file offset
 23198                              <1>         ; 12/10/2015
 23199                              <1> 	; jna	short ret_ 
 23200                              <1> 		; blos ret
 23201 000058F4 7709                <1> 	ja	short dskr_1
 23202                              <1> 	;
 23203                              <1> dskr_retn: ; 12/10/2015
 23204 000058F6 58                  <1> 	pop	eax
 23205 000058F7 C605[2A710000]00    <1> 	mov	byte [u.kcall], 0
 23206 000058FE C3                  <1> 	retn	
 23207                              <1> dskr_1: 
 23208 000058FF 3B15[E0700000]      <1> 	cmp     edx, [u.count] 
 23209                              <1> 		; cmp r2,u.count / are enough bytes left in file 
 23210                              <1> 			       ; / to carry out read
 23211 00005905 7306                <1> 	jnb	short dskr_2
 23212                              <1> 		; bhis 1f
 23213 00005907 8915[E0700000]      <1> 	mov	[u.count], edx
 23214                              <1> 		; mov r2,u.count / no, just read to end of file
 23215                              <1> dskr_2: ; 1:
 23216                              <1> 	; (E)AX = i-number ; 28/11/2021 (32 bit inode number)
 23217                              <1> 	;call	mget
 23218                              <1> 		; jsr r0,mget / returns physical block number of block 
 23219                              <1> 		    ; / in file where offset points
 23220                              <1> 	; 28/11/2021
 23221 0000590D E830F9FFFF          <1> 	call	mget_r
 23222                              <1> 
 23223                              <1> 	; eax = physical block number
 23224                              <1> 	; [cdev] = current device number 
 23225 00005912 E810080000          <1> 	call	dskrd
 23226                              <1> 		; jsr r0,dskrd / read in block, r5 points to 
 23227                              <1> 			     ; / 1st word of data in buffer
 23228                              <1> 	; 09/06/2015
 23229 00005917 803D[2A710000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
 23230 0000591E 770F                <1> 	ja	short dskr_4	  ; zf=0 -> the caller is 'namei'
 23231 00005920 66833D[24710000]00  <1> 	cmp	word [u.pcount], 0
 23232 00005928 7705                <1> 	ja	short dskr_4
 23233                              <1> dskr_3:
 23234                              <1> 	; [u.base] = virtual address to transfer (as destination address)
 23235 0000592A E853000000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 23236                              <1> dskr_4:
 23237                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
 23238 0000592F E8BF020000          <1> 	call	sioreg
 23239                              <1> 		; jsr r0,sioreg
 23240 00005934 87F7                <1> 	xchg	esi, edi
 23241                              <1> 	; edi = file (user data) offset
 23242                              <1> 	; edi = sector (I/O) buffer offset
 23243                              <1> 	; ecx = byte count
 23244 00005936 F3A4                <1> 	rep	movsb
 23245                              <1> 		; movb (r2)+,(r1)+ / move data from buffer into working core
 23246                              <1> 		                 ; / starting at u.base
 23247                              <1> 		; dec r3
 23248                              <1> 		; bne 2b / branch until proper number of bytes are transferred
 23249                              <1> 	; 25/07/2015
 23250                              <1> 	; eax = remain bytes in buffer
 23251                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 23252 00005938 09C0                <1> 	or	eax, eax
 23253 0000593A 75EE                <1> 	jnz	short dskr_3 ; (page end before system buffer end!)		
 23254                              <1> 	; 03/08/2013
 23255                              <1> 	;pop	eax
 23256 0000593C 390D[E0700000]      <1> 	cmp	[u.count], ecx ; 0
 23257                              <1> 		; tst u.count / all bytes read off disk
 23258                              <1> 		; bne dskr
 23259                              <1> 		; br ret
 23260                              <1>         ;ja	short dskr_0
 23261                              <1> 	;mov	[u.kcall], cl ; 0 ; 09/06/2015
 23262                              <1> 	;retn
 23263                              <1> 	; 12/10/2015
 23264 00005942 76B2                <1> 	jna	short dskr_retn
 23265 00005944 58                  <1> 	pop	eax  ; (i-node number)
 23266 00005945 EB99                <1> 	jmp	short dskr_0
 23267                              <1> 	
 23268                              <1> passc:
 23269                              <1> 	; 18/10/2015
 23270                              <1> 	; 10/07/2015
 23271                              <1> 	; 01/07/2015
 23272                              <1> 	; 08/06/2015
 23273                              <1> 	; 04/06/2015
 23274                              <1> 	; 20/05/2015
 23275                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23276                              <1> 	;
 23277                              <1>    	;(Retro UNIX 386 v1 - translation from user's virtual address
 23278                              <1> 	;		      to physical address
 23279 00005947 66833D[24710000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 23280                              <1> 			     ; 1-4095 --> use previous physical base address
 23281                              <1> 			     ; in [u.pbase]
 23282 0000594F 7705                <1> 	ja	short passc_3
 23283                              <1> 	; 08/06/2015 - 10/07/2015
 23284 00005951 E82C000000          <1> 	call	trans_addr_w
 23285                              <1> passc_3:
 23286                              <1> 	; 19/05/2015
 23287 00005956 66FF0D[24710000]    <1> 	dec	word [u.pcount]
 23288                              <1> 	;
 23289 0000595D 8B1D[20710000]      <1> 	mov	ebx, [u.pbase]
 23290 00005963 8803                <1> 	mov	[ebx], al
 23291                              <1> 		; movb r1,*u.base / move a character to the next byte of the
 23292                              <1> 		               ; / users buffer
 23293 00005965 FF05[DC700000]      <1> 	inc	dword [u.base]
 23294                              <1> 		; inc u.base / increment the pointer to point to 
 23295                              <1> 			  ; / the next byte in users buffer
 23296 0000596B FF05[20710000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 23297 00005971 FF05[E4700000]      <1> 	inc	dword [u.nread]
 23298                              <1> 		; inc u.nread / increment the number of bytes read
 23299 00005977 FF0D[E0700000]      <1> 	dec	dword [u.count]
 23300                              <1> 		; dec u.count / decrement the number of bytes to be read
 23301                              <1> 		; bne 1f / any more bytes to read? ; yes, branch
 23302 0000597D C3                  <1> 	retn
 23303                              <1> 		; mov (sp)+,r0 / no, do a non-local return to the caller of
 23304                              <1> 		             ; / 'readi' by:
 23305                              <1> 		;/ (1) pop the return address off the stack into r0
 23306                              <1> 		; mov (sp)+,r1 / (2) pop the i-number off the stack into r1
 23307                              <1> 	;1:
 23308                              <1> 		; clr	*$ps / clear processor status
 23309                              <1> 		; rts r0 / return to address currently on top of stack
 23310                              <1> 
 23311                              <1> trans_addr_r:
 23312                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 23313                              <1> 	;	-'add_to_swap_queue' call is diasbled as temporary-
 23314                              <1> 	; Translate virtual address to physical address 
 23315                              <1> 	; for reading from user's memory space
 23316                              <1> 	; (Retro UNIX 386 v1 feature only !)
 23317                              <1> 	; 18/10/2015
 23318                              <1> 	; 10/07/2015
 23319                              <1> 	; 09/06/2015
 23320                              <1> 	; 08/06/2015 
 23321                              <1> 	; 04/06/2015
 23322                              <1> 	;
 23323                              <1> 	; 18/10/2015
 23324 0000597E 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
 23325 00005980 EB04                <1> 	jmp 	short trans_addr_rw
 23326                              <1> 
 23327                              <1> 	;push	eax
 23328                              <1> 	;push	ebx
 23329                              <1> 	;mov	ebx, [u.base]
 23330                              <1> 	;call	get_physical_addr ; get physical address
 23331                              <1> 	;;jnc	short cpass_0
 23332                              <1> 	;jnc	short passc_1
 23333                              <1> 	;mov	[u.error], eax
 23334                              <1> 	;;pop	ebx
 23335                              <1> 	;;pop	eax
 23336                              <1> 	;jmp	error
 23337                              <1> ;cpass_0:
 23338                              <1> 	; 18/10/2015
 23339                              <1> 	; 20/05/2015
 23340                              <1> 	;mov 	[u.pbase], eax ; physical address	
 23341                              <1> 	;mov	[u.pcount], cx ; remain byte count in page (1-4096)
 23342                              <1> 	;pop	ebx
 23343                              <1> 	;pop	eax
 23344                              <1> 	;retn	; 08/06/2015
 23345                              <1> 
 23346                              <1> trans_addr_w:
 23347                              <1> 	; 30/11/2021 (Retro UNIX 386 v2, Retro UNIX 386 v1.2)
 23348                              <1> 	;	-'add_to_swap_queue' call is disabled as temporary-
 23349                              <1> 	; Translate virtual address to physical address
 23350                              <1> 	; for writing to user's memory space
 23351                              <1> 	; (Retro UNIX 386 v1 feature only !)
 23352                              <1> 	; 18/10/2015
 23353                              <1> 	; 29/07/2015
 23354                              <1> 	; 10/07/2015
 23355                              <1> 	; 09/06/2015
 23356                              <1> 	; 08/06/2015
 23357                              <1> 	; 04/06/2015 (passc)
 23358                              <1> 	;
 23359                              <1> 	; 18/10/2015
 23360 00005982 29D2                <1> 	sub	edx, edx
 23361 00005984 FEC2                <1> 	inc	dl ; 1 (write access sign)
 23362                              <1> trans_addr_rw:
 23363 00005986 50                  <1> 	push	eax
 23364 00005987 53                  <1> 	push	ebx
 23365                              <1> 	; 18/10/2015
 23366 00005988 52                  <1> 	push 	edx ; r/w sign (in DL)
 23367                              <1> 	;
 23368 00005989 8B1D[DC700000]      <1> 	mov	ebx, [u.base]
 23369 0000598F E8CBD9FFFF          <1> 	call	get_physical_addr ; get physical address
 23370 00005994 730A                <1> 	jnc	short passc_0
 23371 00005996 A3[2C710000]        <1> 	mov	[u.error], eax
 23372                              <1> 	;pop	edx
 23373                              <1> 	;pop 	ebx
 23374                              <1> 	;pop	eax
 23375 0000599B E936E3FFFF          <1> 	jmp	error
 23376                              <1> passc_0:
 23377 000059A0 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page ; 18/10/2015
 23378 000059A3 5A                  <1> 	pop	edx ; 18/10/2015
 23379 000059A4 7515                <1> 	jnz	short passc_1
 23380                              <1> 	; 18/10/2015
 23381 000059A6 20D2                <1> 	and 	dl, dl
 23382 000059A8 7411                <1> 	jz	short passc_1
 23383                              <1> 	; 20/05/2015
 23384                              <1> 	; read only (duplicated) page -must be copied to a new page-
 23385                              <1> 	; EBX = linear address
 23386 000059AA 51                  <1> 	push 	ecx
 23387 000059AB E81ED9FFFF          <1> 	call 	copy_page
 23388 000059B0 59                  <1> 	pop	ecx
 23389 000059B1 7217                <1> 	jc	short passc_2
 23390                              <1> 	; 30/11/2021
 23391                              <1> 	;push	eax ; physical address of the new/allocated page
 23392                              <1> 	;call	add_to_swap_queue
 23393                              <1> 	;pop	eax
 23394                              <1> 	; 18/10/2015
 23395 000059B3 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
 23396                              <1> 	;mov 	ecx, PAGE_SIZE
 23397                              <1> 	;sub	ecx, ebx 
 23398 000059B9 01D8                <1> 	add	eax, ebx  
 23399                              <1> passc_1: 
 23400                              <1> 	; 18/10/2015
 23401                              <1> 	; 20/05/2015
 23402 000059BB A3[20710000]        <1> 	mov 	[u.pbase], eax ; physical address	
 23403 000059C0 66890D[24710000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
 23404 000059C7 5B                  <1> 	pop	ebx
 23405 000059C8 58                  <1> 	pop	eax
 23406 000059C9 C3                  <1> 	retn	; 08/06/2015
 23407                              <1> passc_2:
 23408 000059CA C705[2C710000]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
 23409 000059D2 0000                <1>
 23410                              <1> 	;pop 	ebx
 23411                              <1> 	;pop	eax
 23412 000059D4 E9FDE2FFFF          <1> 	jmp	error
 23413                              <1> 
 23414                              <1> 	; 11/12/2021
 23415                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23416                              <1> writei:
 23417                              <1> 	; 20/05/2015
 23418                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23419                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
 23420                              <1> 	;
 23421                              <1> 	; Write data to file with inode number in R1
 23422                              <1> 	; 
 23423                              <1> 	; INPUTS ->
 23424                              <1> 	;    r1 - inode number
 23425                              <1> 	;    u.count - byte count to be written
 23426                              <1> 	;    u.base - points to user buffer
 23427                              <1> 	;    u.fofp - points to word with current file offset
 23428                              <1> 	; OUTPUTS ->
 23429                              <1> 	;    u.count - cleared
 23430                              <1> 	;    u.nread - accumulates total bytes passed back	
 23431                              <1> 	; ((AX = R1))
 23432                              <1> 	;    (Retro UNIX Prototype : 18/11/2012 - 11/11/2012, UNIXCOPY.ASM)
 23433                              <1> 	;    ((Modified registers: DX, BX, CX, SI, DI, BP)) 	
 23434                              <1> 
 23435 000059D9 31C9                <1> 	xor	ecx, ecx
 23436 000059DB 890D[E4700000]      <1> 	mov 	[u.nread], ecx  ; 0
 23437                              <1> 		; clr u.nread / clear the number of bytes transmitted during
 23438                              <1> 		            ; / read or write calls
 23439 000059E1 66890D[24710000]    <1> 	mov	[u.pcount], cx ; 19/05/2015
 23440 000059E8 390D[E0700000]      <1> 	cmp 	[u.count], ecx
 23441                              <1> 	;	; tst u.count / test the byte count specified by the user
 23442 000059EE 7701                <1> 	ja 	short writei_1 ; 1f
 23443                              <1> 		; bgt 1f / any bytes to output; yes, branch
 23444 000059F0 C3                  <1> 	retn
 23445                              <1> 	;	; rts r0 / no, return - no writing to do
 23446                              <1> writei_1: ;1:
 23447                              <1> 	;	; mov r1 ,-(sp) / save the i-node number on the stack
 23448                              <1> 	;cmp 	ax, 40
 23449                              <1> 	;	; cmp r1,$40.
 23450                              <1> 	;	; / does the i-node number indicate a special file?
 23451                              <1>         ;ja	dskw 
 23452                              <1> 	;	; bgt dskw / no, branch to standard file output
 23453                              <1> 
 23454                              <1> 	; 28/11/2021
 23455 000059F1 F605[2A710000]FF    <1> 	test	byte [u.kcall], 0FFh
 23456 000059F8 7505                <1> 	jnz	short writei_2  ; 'writei' called by 'mkdir'
 23457                              <1> 
 23458                              <1> 	; eax = inode number
 23459                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 23460 000059FA E86CFBFFFF          <1> 	call	iget
 23461                              <1> writei_2:
 23462                              <1> 	; 28/11/2021
 23463                              <1> 	; eax = inode number
 23464                              <1> 	; [cdev] = device number (0 = root fs, 1 = mounted fs)
 23465 000059FF E870020000          <1> 	call	is_regular_file
 23466 00005A04 0F84FD000000        <1> 	jz	dskw ; regular file 
 23467                              <1> 
 23468                              <1> 	; (20/05/2015)
 23469 00005A0A 50                  <1> 	push	eax ; because subroutines will jump to 'ret_'
 23470                              <1> 	
 23471                              <1> 	; 28/11/2021	
 23472                              <1> 	; device file
 23473 00005A0B BB[255A0000]        <1> 	mov	ebx, writei_4
 23474 00005A10 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 23475 00005A13 720E                <1> 	jb	short writei_3
 23476 00005A15 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 23477 00005A18 7709                <1> 	ja	short writei_3 ; 11/12/2021	
 23478                              <1> 	
 23479                              <1> 	; convert v2 inode number to v1 device inode number
 23480 00005A1A 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 23481 00005A1C 89C1                <1> 	mov	ecx, eax
 23482 00005A1E C0E102              <1> 	shl	cl, 2 ; * 4
 23483 00005A21 01CB                <1> 	add	ebx, ecx
 23484                              <1> writei_3:
 23485 00005A23 FF23                <1> 	jmp	dword [ebx]	
 23486                              <1> 		; jmp *1f-2(r1)
 23487                              <1> 		; / jump table and jump to the appropriate routine
 23488                              <1> writei_4: ;1:
 23489 00005A25 [67580000]          <1> 	dd	null ; 28/11/2021
 23490 00005A29 [755A0000]          <1> 	dd	wtty ; tty, AX = 1 (runix)
 23491                              <1> 		 ;wtty / tty; r1=2
 23492                              <1> 		 ;wppt / ppt; r1=4
 23493 00005A2D [D75A0000]          <1> 	dd	wmem ; mem, AX = 2 (runix)
 23494                              <1> 		 ;wmem / mem; r1=6
 23495                              <1> 		 ;wrf0 / rf0
 23496                              <1> 		 ;wrk0 / rk0
 23497                              <1> 		 ;wtap / tap0
 23498                              <1> 		 ;wtap / tap1
 23499                              <1> 		 ;wtap / tap2
 23500                              <1> 		 ;wtap / tap3
 23501                              <1> 		 ;wtap / tap4
 23502                              <1> 		 ;wtap / tap5
 23503                              <1> 		 ;wtap / tap6
 23504                              <1> 		 ;wtap / tap7
 23505 00005A31 [4F600000]          <1> 	dd	wfd ; fd0, AX = 3 (runix only)
 23506 00005A35 [4F600000]          <1> 	dd	wfd ; fd1, AX = 4 (runix only)
 23507 00005A39 [4F600000]          <1> 	dd	whd ; hd0, AX = 5 (runix only)
 23508 00005A3D [4F600000]          <1> 	dd	whd ; hd1, AX = 6 (runix only)	
 23509 00005A41 [4F600000]          <1> 	dd	whd ; hd2, AX = 7 (runix only)
 23510 00005A45 [4F600000]          <1> 	dd	whd ; hd3, AX = 8 (runix only)	
 23511 00005A49 [C85A0000]          <1> 	dd	wlpr ; lpr, AX = 9   (runix)
 23512 00005A4D [C25A0000]          <1> 	dd	xmtt ; tty0, AX = 10 (runix)	  
 23513                              <1> 		 ;xmtt / tty0
 23514 00005A51 [C25A0000]          <1> 	dd	xmtt ; tty1, AX = 11 (runix)	  
 23515                              <1> 		 ;xmtt / tty1
 23516 00005A55 [C25A0000]          <1> 	dd	xmtt ; tty2, AX = 12 (runix)	  
 23517                              <1> 		 ;xmtt / tty2
 23518 00005A59 [C25A0000]          <1> 	dd	xmtt ; tty3, AX = 13 (runix)	  
 23519                              <1> 		 ;xmtt / tty3
 23520 00005A5D [C25A0000]          <1> 	dd	xmtt ; tty4, AX = 14 (runix)	  
 23521                              <1> 		 ;xmtt / tty4
 23522 00005A61 [C25A0000]          <1> 	dd	xmtt ; tty5, AX = 15 (runix)	  
 23523                              <1> 		 ;xmtt / tty5
 23524 00005A65 [C25A0000]          <1> 	dd	xmtt ; tty6, AX = 16 (runix)	  
 23525                              <1> 		 ;xmtt / tty6
 23526 00005A69 [C25A0000]          <1> 	dd	xmtt ; tty7, AX = 17 (runix)	  
 23527                              <1> 		 ;xmtt / tty7
 23528 00005A6D [C25A0000]          <1> 	dd	xmtt ; COM1, AX = 18 (runix only)	  
 23529                              <1> 		; / wlpr / lpr
 23530 00005A71 [C25A0000]          <1> 	dd	xmtt ; COM2, AX = 19 (runix only)
 23531                              <1> 
 23532                              <1> ;	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23533                              <1> ;null:
 23534                              <1> ;	xor	eax, eax
 23535                              <1> ;	pop	eax
 23536                              <1> ;	retn	
 23537                              <1> 
 23538                              <1> 	; 11/12/2021 - Retro UNIX 386 v1.2
 23539                              <1> wtty: ; write to console tty (write to screen)
 23540                              <1> 	; 18/11/2015
 23541                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23542                              <1> 	; 12/03/2013 - 07/07/2014 (Retro UNIX 8086 v1)
 23543                              <1> 	;
 23544                              <1> 	; Console tty output is on current video page
 23545                              <1> 	; Console tty character output procedure is changed here
 23546                              <1> 	; acconding to IBM PC compatible ROM BIOS video (text mode) functions.
 23547                              <1> 	;
 23548 00005A75 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 23549 00005A7C 8AA3[EF6D0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 23550 00005A82 88E0                <1> 	mov	al, ah ; 07/07/2014
 23551                              <1> wttys:	
 23552                              <1> 	; 10/10/2013
 23553 00005A84 8825[ED700000]      <1> 	mov 	[u.ttyn], ah
 23554                              <1> 	; 13/01/2014
 23555 00005A8A FEC0                <1> 	inc	al
 23556 00005A8C A2[EF700000]        <1> 	mov	[u.ttyp+1], al ; tty number + 1
 23557                              <1> wtty_nc: ; 15/05/2013
 23558                              <1> 	; AH = [u.ttyn] = tty number ; 28/07/2013
 23559 00005A91 E8FD000000          <1> 	call	cpass
 23560                              <1> 		; jsr r0,cpass / get next character from user buffer area; if
 23561                              <1> 		             ; / none go to return address in syswrite
 23562                              <1> 		; tst r1 / is character = null
 23563                              <1> 		; beq wtty / yes, get next character
 23564                              <1> 	; 10/10/2013
 23565 00005A96 7428                <1> 	jz	short wret
 23566                              <1> 	;1 :
 23567                              <1> 		;mov 	$240,*$ps / no, set processor priority to five
 23568                              <1> 		;cmpb	cc+1,$20. / is character count for console tty greater
 23569                              <1> 		;	          / than 20
 23570                              <1> 		;bhis	2f / yes; branch to put process to sleep
 23571                              <1> 	; 27/06/2014
 23572                              <1> wtty_1:
 23573                              <1> 	; AH = tty number
 23574                              <1> 	; AL = ASCII code of the character
 23575                              <1> 	; 15/04/2014
 23576                              <1> 	;push	ax
 23577                              <1> 	; 11/12/2021
 23578 00005A98 50                  <1> 	push	eax
 23579 00005A99 E8FF090000          <1> 	call	putc ; 14/05/2013
 23580 00005A9E 731D                <1> 	jnc	short wtty_2
 23581                              <1> 	; 18/11/2015
 23582 00005AA0 E880F6FFFF          <1> 	call	idle
 23583                              <1> 	;mov	ax, [esp]
 23584                              <1> 	; 11/12/2021
 23585 00005AA5 8B0424              <1> 	mov	eax, [esp]
 23586 00005AA8 E8F0090000          <1> 	call	putc
 23587 00005AAD 730E                <1> 	jnc	short wtty_2 
 23588                              <1> 	; 02/06/2014
 23589 00005AAF 8A25[ED700000]      <1> 	mov	ah, [u.ttyn]
 23590 00005AB5 E8FFF6FFFF          <1> 	call	sleep
 23591                              <1> 	;pop	ax
 23592                              <1> 	; 11/12/2021
 23593 00005ABA 58                  <1> 	pop	eax
 23594 00005ABB EBDB                <1> 	jmp 	short wtty_1
 23595                              <1> 		; jc 	error ; 15/05/2013 (COM1 or COM2 serial port error)
 23596                              <1> 		; jsr 	r0,putc; 1 / find place in freelist to assign to 
 23597                              <1> 			      ; / console tty and
 23598                              <1> 		; br 	2f / place character in list; if none available
 23599                              <1> 		   	  ; / branch to put process to sleep
 23600                              <1> 		; jsr	r0,startty / attempt to output character on tty
 23601                              <1> wtty_2:
 23602                              <1> 	; 15/04/2014
 23603                              <1> 	;pop	ax
 23604                              <1> 	; 11/12/2021
 23605 00005ABD 58                  <1> 	pop	eax
 23606 00005ABE EBD1                <1> 	jmp	short wtty_nc
 23607                              <1> 		; br wtty
 23608                              <1> wret:	; 10/10/2013 (20/05/2015)
 23609 00005AC0 58                  <1> 	pop	eax
 23610 00005AC1 C3                  <1> 	retn
 23611                              <1> 	;2:
 23612                              <1> 		;mov	r1,-(sp) / place character on stack
 23613                              <1> 		;jsr	r0,sleep; 1 / put process to sleep
 23614                              <1> 		;mov	(sp)+,r1 / remove character from stack
 23615                              <1> 		;br	1b / try again to place character in clist and output
 23616                              <1> 
 23617                              <1> xmtt:   ; < send/write character to tty >
 23618                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23619                              <1> 	; 15/05/2013 - 06/12/2013 (Retro UNIX 8086 v1)
 23620                              <1> 	;
 23621                              <1> 	; Retro UNIX 8086 v1 modification !
 23622                              <1> 	; 
 23623                              <1> 	; In original UNIX v1, 'xmtt' routine 
 23624                              <1> 	;		(exactly different than this one)
 23625                              <1> 	;	was in 'u9.s' file.
 23626                              <1> 	;
 23627 00005AC2 2C0A                <1> 	sub 	al, 10
 23628                              <1> 	; AL = tty number (0 to 9), (COM1=8, COM2=9)
 23629                              <1> 	; 10/10/2013
 23630 00005AC4 88C4                <1> 	mov	ah, al
 23631                              <1> 	; 28/07/2013
 23632 00005AC6 EBBC                <1> 	jmp	short wttys
 23633                              <1> 
 23634                              <1> ;wppt:
 23635                              <1> ;	jsr	r0,cpass / get next character from user buffer area,
 23636                              <1> ;		         / if none return to writei's calling routine
 23637                              <1> ;	jsr	r0,pptoc / output character on ppt
 23638                              <1> ;	br	wppt
 23639                              <1> wlpr:
 23640 00005AC8 C705[2C710000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY ; 19/05/2015
 23641 00005AD0 0000                <1>
 23642 00005AD2 E9FFE1FFFF          <1> 	jmp 	error   ; ... Printing procedure will be located here ...
 23643                              <1> 		;/	jsr	r0,cpass
 23644                              <1> 		;/	cmp	r0,$'a
 23645                              <1> 		;/	blo	1f
 23646                              <1> 		;/	cmp	r1,$'z
 23647                              <1> 		;/	bhi	1f
 23648                              <1> 		;/	sub	$40,r1
 23649                              <1> 		;/1:
 23650                              <1> 		;/	jsr	r0,lptoc
 23651                              <1> 		;/	br	wlpr
 23652                              <1> 		; br rmem / continue
 23653                              <1> 
 23654                              <1> wmem: ; / transfer characters from a user area of core to memory file
 23655                              <1> 	; 17/10/2015
 23656                              <1> 	; 11/06/2015
 23657                              <1> 	; 24/05/2015
 23658                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23659                              <1> 	;
 23660 00005AD7 813D[11080000]-     <1> 	cmp	dword [x_timer], clock ; multi tasking clock/timer
 23661 00005ADD [49510000]          <1>
 23662 00005AE1 7415                <1>         je      short wmem_acc_err
 23663                              <1> 	;
 23664 00005AE3 8B35[C8700000]      <1>         mov     esi, [u.fofp] 
 23665                              <1> wmem_1:
 23666 00005AE9 E8A5000000          <1> 	call	cpass
 23667                              <1> 		; jsr r0,cpass / get next character from users area of
 23668                              <1> 			     ; / core and put it in r1
 23669                              <1>         	; mov r1,-(sp) / put character on the stack
 23670                              <1> 	; 20/09/2013
 23671 00005AEE 74D0                <1> 	jz	short wret ; wmem_2  
 23672 00005AF0 8B1E                <1>         mov     ebx, [esi]
 23673                              <1> 		; mov *u.fofp,r1 / save file offset in r1
 23674 00005AF2 FF06                <1>         inc     dword [esi] ; 17/10/2015
 23675                              <1> 		; inc *u.fofp / increment file offset to point to next
 23676                              <1> 			    ; / available location in file
 23677 00005AF4 8803                <1> 	mov	[ebx], al	
 23678                              <1> 		; movb (sp)+,(r1) / pop char off stack, put in memory loc 
 23679                              <1> 			        ; / assigned to it
 23680 00005AF6 EBF1                <1> 	jmp	short wmem_1
 23681                              <1> 		; br wmem / continue
 23682                              <1> 	;1:
 23683                              <1> 	;jmp	error / ?
 23684                              <1> ;wmem_2:	
 23685                              <1> ;	; 20/09/2013
 23686                              <1> ;	pop	ax
 23687                              <1> ;	retn
 23688                              <1> 
 23689                              <1> wmem_acc_err:
 23690 00005AF8 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 23691 00005B00 0000                <1>
 23692 00005B02 E9CFE1FFFF          <1> 	jmp	error
 23693                              <1> 
 23694                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 23695                              <1> 
 23696                              <1> dskw: ; / write routine for non-special files
 23697                              <1> 	;
 23698                              <1> 	; 28/11/2021
 23699                              <1> 	; 25/07/2015
 23700                              <1> 	; 16/06/2015
 23701                              <1> 	; 09/06/2015
 23702                              <1> 	; 31/05/2015 (Retro UNIX 386 v1 - Beginning)
 23703                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
 23704                              <1> 
 23705                              <1> 	; 01/08/2013 (mkdir_w check)
 23706                              <1> 	;push	ax ; 26/04/2013
 23707                              <1> 	;	; mov (sp),r1 / get an i-node number from the stack into r1
 23708                              <1> 	; 28/11/2021
 23709 00005B07 50                  <1> 	push	eax
 23710                              <1> 	; AX = inode number
 23711 00005B08 E85EFAFFFF          <1> 	call	iget
 23712                              <1> 		; jsr r0,iget / write i-node out (if modified), 
 23713                              <1> 		            ; / read i-node 'r1' into i-node area of core
 23714 00005B0D 8B1D[C8700000]      <1>         mov     ebx, [u.fofp] 
 23715 00005B13 8B13                <1> 	mov 	edx, [ebx]
 23716                              <1> 		; mov *u.fofp,r2 / put the file offset [(u.off) or the offset
 23717                              <1> 			       ; / in the fsp entry for this file] in r2
 23718 00005B15 0315[E0700000]      <1> 	add 	edx, [u.count]	
 23719                              <1> 		; add u.count,r2 / no. of bytes to be written
 23720                              <1> 			       ; / + file offset is put in r2
 23721                              <1> 	;; 16/06/2015        
 23722                              <1> 	;cmp	edx, 65535 ; file size limit (for UNIX v1 file system)
 23723                              <1> 	;jna	short dskw_0
 23724                              <1> 	;mov	dword [u.error], ERR_FILE_SIZE ; 'file size error !'
 23725                              <1> 	;jmp	error
 23726                              <1> dskw_0:	
 23727                              <1> 	; 28/11/2021
 23728 00005B1B 3B15[586D0000]      <1> 	cmp	edx, [i.size] ; 32 bit file size (runix v2 inode)
 23729                              <1> 	;cmp	dx, [i.size]
 23730                              <1> 	;	; cmp r2,i.size / is this greater than the present size of
 23731                              <1> 		              ; / the file?
 23732 00005B21 760B                <1> 	jna	short dskw_1
 23733                              <1> 		; blos 1f / no, branch
 23734 00005B23 8915[586D0000]      <1> 	mov	[i.size], edx ; 32 bit file size (runix v2 inode)
 23735                              <1> 	;mov	[i.size], dx
 23736                              <1> 	 	; mov r2,i.size / yes, increase the file size to 
 23737                              <1> 			      ; / file offset + no. of data bytes
 23738 00005B29 E8D0FBFFFF          <1> 	call	setimod
 23739                              <1> 	 	; jsr r0,setimod / set imod=1 (i.e., core inode has been
 23740                              <1> 		          ; / modified), stuff time of modification into
 23741                              <1> 	          	  ; / core image of i-node
 23742                              <1> dskw_1: ; 1:
 23743                              <1> 	; 28/11/2021
 23744                              <1> 	;call	mget
 23745 00005B2E E806F7FFFF          <1> 	call	mget_w
 23746                              <1> 	; EAX = Block number
 23747                              <1> 		; jsr r0,mget / get the block no. in which to write 
 23748                              <1> 			    ; /	the next data byte
 23749                              <1> 	; eax = block number
 23750 00005B33 8B1D[C8700000]      <1> 	mov     ebx, [u.fofp]
 23751 00005B39 8B13                <1> 	mov	edx, [ebx]
 23752 00005B3B 81E2FF010000        <1> 	and	edx, 1FFh  
 23753                              <1> 		; bit *u.fofp,$777 / test the lower 9 bits of the file offset
 23754 00005B41 750C                <1> 	jnz	short dskw_2
 23755                              <1> 		; bne 2f / if its non-zero, branch; if zero, file offset = 0,
 23756                              <1> 		       ; / 512, 1024,...(i.e., start of new block)
 23757 00005B43 813D[E0700000]0002- <1> 	cmp	dword [u.count], 512
 23758 00005B4B 0000                <1>
 23759                              <1> 		; cmp u.count,$512. / if zero, is there enough data to fill
 23760                              <1> 				  ; / an entire block? (i.e., no. of
 23761 00005B4D 7305                <1> 	jnb	short dskw_3
 23762                              <1> 		; bhis 3f / bytes to be written greater than 512.? 
 23763                              <1> 			; / Yes, branch. Don't have to read block
 23764                              <1> dskw_2: ; 2: / in as no past info. is to be saved (the entire block will be
 23765                              <1>    		; / overwritten).
 23766 00005B4F E8D3050000          <1> 	call	dskrd
 23767                              <1> 		; jsr r0,dskrd / no, must retain old info.. 
 23768                              <1> 			     ; / Hence, read block 'r1' into an I/O buffer
 23769                              <1> dskw_3: ; 3:
 23770                              <1> 	; EAX (r1) = block/sector number
 23771 00005B54 E82E060000          <1> 	call	wslot
 23772                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
 23773                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
 23774 00005B59 803D[2A710000]00    <1> 	cmp	byte [u.kcall], 0
 23775 00005B60 770F                <1> 	ja	short dskw_5 ; zf=0 -> the caller is 'mkdir'
 23776                              <1> 	;
 23777 00005B62 66833D[24710000]00  <1> 	cmp	word [u.pcount], 0
 23778 00005B6A 7705                <1> 	ja	short dskw_5
 23779                              <1> dskw_4:
 23780                              <1> 	; [u.base] = virtual address to transfer (as source address)
 23781 00005B6C E80DFEFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 23782                              <1> dskw_5:
 23783                              <1> 	; eBX (r5) = system (I/O) buffer address
 23784 00005B71 E87D000000          <1> 	call	sioreg
 23785                              <1> 		; jsr r0,sioreg / r3 = no. of bytes of data, 
 23786                              <1> 			     ; / r1 = address of data, r2 points to location
 23787                              <1> 			     ; / in buffer in which to start writing data
 23788                              <1> 	; eSI = file (user data) offset
 23789                              <1> 	; eDI = sector (I/O) buffer offset
 23790                              <1> 	; eCX = byte count
 23791                              <1> 	;
 23792 00005B76 F3A4                <1>   	rep	movsb
 23793                              <1> 		; movb (r1 )+,(r2)+ 
 23794                              <1> 		         ; / transfer a byte of data to the I/O buffer
 23795                              <1> 		; dec r3 / decrement no. of bytes to be written
 23796                              <1> 		; bne 2b / have all bytes been transferred? No, branch
 23797                              <1> 	; 25/07/2015
 23798                              <1> 	; eax = remain bytes in buffer
 23799                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
 23800 00005B78 09C0                <1> 	or	eax, eax
 23801 00005B7A 75F0                <1> 	jnz	short dskw_4 ; (page end before system buffer end!)	
 23802                              <1> dskw_6:
 23803 00005B7C E822060000          <1> 	call	dskwr
 23804                              <1> 		; jsr r0,dskwr / yes, write the block and the i-node
 23805 00005B81 833D[E0700000]00    <1>         cmp     dword [u.count], 0
 23806                              <1> 		; tst u.count / any more data to write?
 23807 00005B88 77A4                <1> 	ja	short dskw_1
 23808                              <1> 		; bne 1b / yes, branch
 23809                              <1> 	; 03/08/2013
 23810 00005B8A C605[2A710000]00    <1> 	mov	byte [u.kcall], 0
 23811                              <1> 	; 20/09/2013 (;;)
 23812                              <1> 	;pop	ax
 23813                              <1> 	; 28/11/2021
 23814 00005B91 58                  <1> 	pop	eax  
 23815 00005B92 C3                  <1> 	retn
 23816                              <1> 	;;jmp 	short dskw_ret 
 23817                              <1> 	        ; jmp ret / no, return to the caller via 'ret'
 23818                              <1> 
 23819                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 23820                              <1> cpass: ; / get next character from user area of core and put it in r1
 23821                              <1> 	; 18/10/2015
 23822                              <1> 	; 10/10/2015
 23823                              <1> 	; 10/07/2015
 23824                              <1> 	; 02/07/2015
 23825                              <1> 	; 01/07/2015
 23826                              <1> 	; 24/06/2015
 23827                              <1> 	; 08/06/2015
 23828                              <1> 	; 04/06/2015
 23829                              <1> 	; 20/05/2015
 23830                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23831                              <1> 	;
 23832                              <1> 	; INPUTS -> 
 23833                              <1> 	;     [u.base] = virtual address in user area
 23834                              <1> 	;     [u.count] = byte count (max.)
 23835                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
 23836                              <1> 	; OUTPUTS -> 
 23837                              <1> 	;     AL = the character which is pointed by [u.base]
 23838                              <1> 	;     zf = 1 -> transfer count has been completed	
 23839                              <1>         ;
 23840                              <1> 	; ((Modified registers: EAX, EDX, ECX))
 23841                              <1> 	;
 23842                              <1> 	;
 23843 00005B93 833D[E0700000]00    <1> 	cmp 	dword [u.count], 0  ; 14/08/2013
 23844                              <1> 		; tst u.count / have all the characters been transferred
 23845                              <1> 			    ; / (i.e., u.count, # of chars. left
 23846 00005B9A 763F                <1> 	jna	short cpass_3
 23847                              <1> 		; beq 1f / to be transferred = 0?) yes, branch
 23848 00005B9C FF0D[E0700000]      <1> 	dec	dword [u.count]
 23849                              <1> 		; dec u.count / no, decrement u.count
 23850                              <1>         ; 19/05/2015 
 23851                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
 23852                              <1> 	;		      to physical address
 23853 00005BA2 66833D[24710000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
 23854                              <1> 			     ; 1-4095 --> use previous physical base address
 23855                              <1> 			     ; in [u.pbase]
 23856 00005BAA 770E                <1> 	ja	short cpass_1
 23857                              <1> 	; 02/07/2015
 23858                              <1> 	;cmp	dword [u.ppgdir], 0  ; is the caller os kernel
 23859                              <1> 	;je	short cpass_k 	; (sysexec, '/etc/init') ? 
 23860                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 23861 00005BAC 803D[2A710000]00    <1> 	cmp	byte [u.kcall], 0 ; is the caller os kernel
 23862 00005BB3 7727                <1> 	ja	short cpass_k 	; (sysexec, '/etc/init') ? 
 23863                              <1> 	; 08/06/2015 - 10/07/2015
 23864 00005BB5 E8C4FDFFFF          <1> 	call	trans_addr_r
 23865                              <1> cpass_1:
 23866                              <1> 	; 02/07/2015
 23867                              <1> 	; 24/06/2015
 23868 00005BBA 66FF0D[24710000]    <1> 	dec	word [u.pcount]
 23869                              <1> cpass_2: 
 23870                              <1> 	; 10/10/2015
 23871                              <1> 	; 02/07/2015
 23872 00005BC1 8B15[20710000]      <1> 	mov	edx, [u.pbase]
 23873 00005BC7 8A02                <1> 	mov	al, [edx] ; 10/10/2015
 23874                              <1> 		; movb *u.base,r1 / take the character pointed to 
 23875                              <1> 				; / by u.base and put it in r1
 23876 00005BC9 FF05[E4700000]      <1> 	inc	dword [u.nread]
 23877                              <1> 		; inc u.nread / increment no. of bytes transferred
 23878 00005BCF FF05[DC700000]      <1> 	inc	dword [u.base]
 23879                              <1> 		; inc u.base / increment the buffer address to point to the
 23880                              <1> 			   ; / next byte
 23881 00005BD5 FF05[20710000]      <1> 	inc	dword [u.pbase] ; 04/06/2015
 23882                              <1> cpass_3:
 23883 00005BDB C3                  <1> 	retn
 23884                              <1> 		; rts	r0 / next byte
 23885                              <1> 	; 1: 
 23886                              <1> 		; mov (sp)+,r0 
 23887                              <1> 		         ; / put return address of calling routine into r0
 23888                              <1> 		; mov (sp)+,r1 / i-number in r1
 23889                              <1> 		; rts r0 / non-local return
 23890                              <1> cpass_k:
 23891                              <1> 	; 02/07/2015
 23892                              <1> 	; The caller is os kernel 
 23893                              <1> 	; (get sysexec arguments from kernel's memory space)
 23894                              <1> 	;
 23895 00005BDC 8B1D[DC700000]      <1> 	mov	ebx, [u.base]
 23896 00005BE2 66C705[24710000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
 23897 00005BEA 10                  <1>
 23898 00005BEB 891D[20710000]      <1> 	mov	[u.pbase], ebx
 23899 00005BF1 EBCE                <1> 	jmp	short cpass_2
 23900                              <1> 	
 23901                              <1> sioreg: 
 23902                              <1> 	; 25/07/2015
 23903                              <1> 	; 18/07/2015
 23904                              <1> 	; 02/07/2015
 23905                              <1> 	; 17/06/2015
 23906                              <1> 	; 09/06/2015
 23907                              <1> 	; 19/05/2015 (Retro UNIX 386 v1 - Beginning)
 23908                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
 23909                              <1> 	;
 23910                              <1> 	; INPUTS -> 
 23911                              <1> 	;     eBX = system buffer (data) address (r5)
 23912                              <1> 	;     [u.fofp] = pointer to file offset pointer
 23913                              <1> 	;     [u.base] = virtual address of the user buffer
 23914                              <1> 	;     [u.pbase] = physical address of the user buffer
 23915                              <1> 	;     [u.count] = byte count
 23916                              <1> 	;     [u.pcount] = byte count within page frame 			
 23917                              <1> 	; OUTPUTS -> 
 23918                              <1> 	;     eSI = user data offset (r1)
 23919                              <1> 	;     eDI = system (I/O) buffer offset (r2)
 23920                              <1> 	;     eCX = byte count (r3)
 23921                              <1> 	;     EAX = remain bytes after byte count within page frame
 23922                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
 23923                              <1>         ;
 23924                              <1> 	; ((Modified registers:  EDX))
 23925                              <1>  
 23926 00005BF3 8B35[C8700000]      <1>         mov     esi, [u.fofp]
 23927 00005BF9 8B3E                <1>         mov     edi, [esi]
 23928                              <1> 		; mov *u.fofp,r2 / file offset (in bytes) is moved to r2
 23929 00005BFB 89F9                <1> 	mov	ecx, edi
 23930                              <1> 		; mov r2,r3 / and also to r3
 23931 00005BFD 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
 23932                              <1> 		; bis $177000,r3 / set bits 9,...,15 of file offset in r3
 23933 00005C03 81E7FF010000        <1> 	and	edi, 1FFh
 23934                              <1> 		; bic $!777,r2 / calculate file offset mod 512.
 23935 00005C09 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
 23936                              <1> 		; add r5,r2 / r2 now points to 1st byte in system buffer
 23937                              <1> 			  ; / where data is to be placed
 23938                              <1>                 ; mov u.base,r1 / address of data is in r1
 23939 00005C0B F7D9                <1> 	neg	ecx
 23940                              <1> 		; neg r3 / 512 - file offset (mod512.) in r3 
 23941                              <1> 		       ; / (i.e., the no. of free bytes in the file block)
 23942 00005C0D 3B0D[E0700000]      <1> 	cmp	ecx, [u.count]
 23943                              <1> 		; cmp r3,u.count / compare this with the no. of data bytes
 23944                              <1> 			       ; / to be written to the file
 23945 00005C13 7606                <1> 	jna	short sioreg_0
 23946                              <1> 		; blos	2f / if less than branch. Use the no. of free bytes
 23947                              <1> 			 ; / in the file block as the number to be written
 23948 00005C15 8B0D[E0700000]      <1> 	mov	ecx, [u.count]
 23949                              <1> 		; mov u.count,r3 / if greater than, use the no. of data 
 23950                              <1> 			       ; / bytes as the number to be written
 23951                              <1> sioreg_0:
 23952                              <1> 	; 17/06/2015
 23953 00005C1B 803D[2A710000]00    <1> 	cmp	byte [u.kcall], 0 
 23954 00005C22 7613                <1> 	jna	short sioreg_1
 23955                              <1> 	; 25/07/2015
 23956                              <1> 	 ; the caller is 'mkdir' or 'namei'
 23957 00005C24 A1[DC700000]        <1> 	mov	eax, [u.base] ; 25/07/2015
 23958 00005C29 A3[20710000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
 23959 00005C2E 66890D[24710000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
 23960 00005C35 EB0B                <1> 	jmp	short sioreg_2
 23961                              <1> sioreg_1:
 23962                              <1> 	; 25/07/2015
 23963                              <1> 	; 18/07/2015
 23964                              <1> 	; 09/06/2015 
 23965 00005C37 0FB715[24710000]    <1> 	movzx	edx, word [u.pcount]
 23966                              <1> 		; ecx and [u.pcount] are always > 0, here
 23967 00005C3E 39D1                <1> 	cmp	ecx, edx	
 23968 00005C40 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
 23969                              <1> sioreg_2: ; 2:
 23970 00005C42 31C0                <1> 	xor 	eax, eax ; 25/07/2015
 23971                              <1> sioreg_3:
 23972 00005C44 010D[E4700000]      <1> 	add 	[u.nread], ecx
 23973                              <1> 		; add r3,u.nread / r3 + number of bytes xmitted 
 23974                              <1> 			         ; / during write is put into u.nread
 23975 00005C4A 290D[E0700000]      <1> 	sub 	[u.count], ecx
 23976                              <1> 		; sub r3,u.count / u.count = no. of bytes that still 
 23977                              <1> 			       ; / must be written or read
 23978 00005C50 010D[DC700000]      <1> 	add 	[u.base], ecx
 23979                              <1> 		; add r3,u.base / u.base points to the 1st of the remaining
 23980                              <1> 			      ; / data bytes
 23981 00005C56 010E                <1>         add 	[esi], ecx 
 23982                              <1> 		; add r3,*u.fofp / new file offset = number of bytes done
 23983                              <1> 			       ; / + old file offset
 23984                              <1> 	; 25/07/2015
 23985 00005C58 8B35[20710000]      <1> 	mov	esi, [u.pbase]
 23986 00005C5E 66290D[24710000]    <1> 	sub	[u.pcount], cx
 23987 00005C65 010D[20710000]      <1> 	add	[u.pbase], ecx
 23988 00005C6B C3                  <1>         retn
 23989                              <1> 		; rts r0
 23990                              <1> 		; transfer count > [u.pcount]
 23991                              <1> sioreg_4:
 23992                              <1> 	; 25/07/2015
 23993                              <1> 	; transfer count > [u.pcount] 
 23994                              <1> 	; (ecx > edx)
 23995 00005C6C 89C8                <1> 	mov	eax, ecx
 23996 00005C6E 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
 23997 00005C70 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
 23998 00005C72 EBD0                <1> 	jmp	short sioreg_3
 23999                              <1> 
 24000                              <1> 	; 28/11/2021 - Retro UNIX 386 v2 fs compatibility modification
 24001                              <1> is_regular_file:
 24002                              <1> 	; check if it is a regular file or device file inode
 24003                              <1> 	;
 24004                              <1> 	; INPUT:
 24005                              <1> 	;	current inode
 24006                              <1> 	; OUTPUT:
 24007                              <1> 	;	cf = 0 and zf = 1 -> regular file
 24008                              <1> 	;	cf = 0 and zf = 0 -> device file
 24009                              <1> 	;	cf = 1 -> invalid file (jump to 'error')
 24010                              <1> 	;
 24011                              <1> 	; Modified registers: ecx (cl)
 24012                              <1> 
 24013                              <1> 	; 28/11/2021
 24014 00005C74 8A0D[516D0000]      <1> 	mov	cl, [i.flgs+1]
 24015 00005C7A F6C180              <1> 	test	cl, 80h		; regular file ?
 24016 00005C7D 7514                <1> 	jnz	short isregf_1  ; yes 
 24017 00005C7F 80E120              <1> 	and	cl, 20h 	; device file ?
 24018 00005C82 7511                <1> 	jnz	short isregf_2  ; yes 
 24019                              <1> 
 24020                              <1> 	; 28/11/2021
 24021                              <1> 	; invalid inode/file type !
 24022 00005C84 C705[2C710000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
 24023 00005C8C 0000                <1>
 24024                              <1> 	;stc
 24025                              <1> 	;retn
 24026 00005C8E E943E0FFFF          <1> 	jmp	error
 24027                              <1> isregf_1:
 24028 00005C93 30C9                <1> 	xor	cl, cl  ; cl = 0
 24029                              <1> 	; zf = 1
 24030                              <1> 	;retn
 24031                              <1> isregf_2:
 24032                              <1> 	; zf = 0
 24033                              <1> 	; cl = 20h
 24034 00005C95 C3                  <1> 	retn	
 24035                                  %include 'u7.s'      ; 18/04/2015
 24036                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 24037                              <1> ; (re-write kernel for test by using previous version without a major defect)
 24038                              <1> ; ****************************************************************************
 24039                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS7.INC
 24040                              <1> ; Last Modification: 05/12/2021
 24041                              <1> ; ----------------------------------------------------------------------------
 24042                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 24043                              <1> ; (v0.1 - Beginning: 11/07/2012)
 24044                              <1> ;
 24045                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 24046                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 24047                              <1> ; <Bell Laboratories (17/3/1972)>
 24048                              <1> ; <Preliminary Release of UNIX Implementation Document>
 24049                              <1> ;
 24050                              <1> ; Retro UNIX 8086 v1 - U7.ASM (13/07/2014) //// UNIX v1 -> u7.s
 24051                              <1> ;
 24052                              <1> ; ****************************************************************************
 24053                              <1> 
 24054                              <1> sysmount: ; / mount file system; args special; name
 24055                              <1> 	; 14/11/2015
 24056                              <1> 	; 24/10/2015
 24057                              <1> 	; 13/10/2015
 24058                              <1> 	; 10/07/2015
 24059                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 24060                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 24061                              <1> 	;
 24062                              <1> 	; 'sysmount' anounces to the system that a removable 
 24063                              <1> 	; file system has been mounted on a special file.
 24064                              <1> 	; The device number of the special file is obtained via
 24065                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
 24066                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
 24067                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
 24068                              <1> 	; to read file system into core, i.e. the first block on the
 24069                              <1> 	; mountable file system is read in. This block is super block
 24070                              <1> 	; for the file system. This call is super user restricted.	
 24071                              <1> 	;
 24072                              <1> 	; Calling sequence:
 24073                              <1> 	;	sysmount; special; name
 24074                              <1> 	; Arguments:
 24075                              <1> 	;	special - pointer to name of special file (device)
 24076                              <1> 	;	name -  pointer to name of the root directory of the
 24077                              <1> 	;		newly mounted file system. 'name' should 
 24078                              <1> 	;		always be a directory.
 24079                              <1> 	; Inputs: - 
 24080                              <1> 	; Outputs: -
 24081                              <1> 	; ...............................................................
 24082                              <1> 	;				
 24083                              <1> 	; Retro UNIX 8086 v1 modification: 
 24084                              <1> 	;       'sysmount' system call has two arguments; so,
 24085                              <1> 	;	* 1st argument, special is pointed to by BX register
 24086                              <1> 	;	* 2nd argument, name is in CX register
 24087                              <1> 	;
 24088                              <1> 	;	NOTE: Device numbers, names and related procedures are 
 24089                              <1> 	;	       already modified for IBM PC compatibility and 
 24090                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
 24091                              <1> 	
 24092                              <1> 	;call	arg2
 24093                              <1> 		; jsr r0,arg2 / get arguments special and name
 24094 00005C96 891D[D0700000]      <1> 	mov	[u.namep], ebx
 24095 00005C9C 51                  <1> 	push	ecx ; directory name
 24096 00005C9D 66833D[A0700000]00  <1> 	cmp	word [mnti], 0
 24097                              <1> 		; tst mnti / is the i-number of the cross device file
 24098                              <1> 			 ; / zero?
 24099                              <1> 	;ja	error
 24100                              <1>         	; bne errora / no, error
 24101 00005CA5 0F87E9000000        <1> 	ja	sysmnt_err0
 24102                              <1> 	;
 24103 00005CAB E8CC000000          <1> 	call	getspl
 24104                              <1> 		; jsr r0,getspl / get special files device number in r1
 24105                              <1> 	; 13/10/2015
 24106 00005CB0 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
 24107 00005CB3 F683[FA6A0000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
 24108 00005CBA 750F                <1> 	jnz	short sysmnt_1
 24109                              <1> sysmnt_err1:
 24110 00005CBC C705[2C710000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
 24111 00005CC4 0000                <1>
 24112 00005CC6 E90BE0FFFF          <1> 	jmp	error
 24113                              <1> sysmnt_1:
 24114 00005CCB 8F05[D0700000]      <1> 	pop	dword [u.namep]
 24115                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
 24116                              <1> 				  ; / on the device
 24117                              <1> 	; 14/11/2015
 24118 00005CD1 53                  <1> 	push	ebx ; 13/10/2015
 24119                              <1> 		; mov r1,-(sp) / save the device number
 24120                              <1>         ;
 24121 00005CD2 E8C8EEFFFF          <1> 	call	namei
 24122                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 24123                              <1> 		       ; ax = 0 -> file not found 	
 24124                              <1> 	;jz	error
 24125                              <1> 	;jc	error
 24126                              <1> 		; jsr r0,namei / get the i-number of the file
 24127                              <1>                	; br errora
 24128 00005CD7 730F                <1> 	jnc	short sysmnt_2
 24129                              <1> sysmnt_err2:
 24130 00005CD9 C705[2C710000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
 24131 00005CE1 0000                <1>
 24132 00005CE3 E9EEDFFFFF          <1> 	jmp	error
 24133                              <1> sysmnt_2:	
 24134 00005CE8 66A3[A0700000]      <1> 	mov	[mnti], ax
 24135                              <1>         	; mov r1,mnti / put it in mnti
 24136                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
 24137                              <1> sysmnt_3: ;1:
 24138                              <1>         ;cmp	byte [ebx+1], 0
 24139                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
 24140                              <1> 			   ; / dismountable device set?
 24141                              <1>         ;jna	short sysmnt_4		
 24142                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
 24143                              <1> 	;call	idle 	; (wait for hardware interrupt)
 24144                              <1> 	;jmp	short sysmnt_3
 24145                              <1> sysmnt_4:   
 24146 00005CEE 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
 24147 00005CEF A2[97700000]        <1> 	mov	[mdev], al
 24148                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
 24149 00005CF4 8803                <1> 	mov	[ebx], al
 24150                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
 24151                              <1> 			      ; / of the I/O queue entry
 24152                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
 24153                              <1>         	; mov (sp)+,cdev / put device number in cdev
 24154 00005CF6 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
 24155                              <1> 		; bis $2000,sb1 / set the read bit
 24156                              <1> 	; Retro UNIX 386 v1 modification : 
 24157                              <1> 	;	32 bit block number at buffer header offset 4
 24158 00005CFB C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
 24159 00005D02 E8E0050000          <1> 	call 	diskio
 24160 00005D07 731C                <1> 	jnc	short sysmnt_5
 24161 00005D09 31C0                <1> 	xor 	eax, eax
 24162 00005D0B 66A3[A0700000]      <1> 	mov	[mnti], ax ; 0
 24163 00005D11 A2[97700000]        <1> 	mov	[mdev], al ; 0
 24164                              <1> 	;mov	[cdev], al ; 0
 24165                              <1> sysmnt_invd:
 24166                              <1> 	; 14/11/2015
 24167 00005D16 FEC8                <1> 	dec 	al
 24168 00005D18 8903                <1> 	mov	[ebx], eax ; 000000FFh
 24169 00005D1A FEC0                <1> 	inc	al
 24170 00005D1C 48                  <1> 	dec	eax
 24171 00005D1D 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
 24172 00005D20 E9B1DFFFFF          <1> 	jmp	error
 24173                              <1> sysmnt_5:
 24174                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
 24175                              <1> 	; (Following check is needed to prevent mounting an
 24176                              <1> 	; in valid valid file system (in valid super block).
 24177                              <1> 	; 
 24178 00005D25 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
 24179 00005D28 C0E002              <1> 	shl	al, 2 ; 4*index
 24180 00005D2B 8B88[DE6A0000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
 24181 00005D31 C1E103              <1> 	shl 	ecx, 3
 24182 00005D34 0FB715[34800000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
 24183 00005D3B 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
 24184                              <1> 			 ; (in sectors), if they are not equal
 24185                              <1> 			 ; the disk to be mounted is an...	
 24186 00005D3D 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
 24187                              <1> 			 ; (which has not got a valid super block)
 24188                              <1> 	;
 24189 00005D3F C6430100            <1> 	mov	byte [ebx+1], 0
 24190                              <1> 	       	; jsr r0,ppoke / read in entire file system
 24191                              <1> ;sysmnt_6: ;1:
 24192                              <1> 	;;cmp	byte [sb1+1], 0
 24193                              <1> 		; tstb   sb1+1 / done reading?
 24194                              <1>    	;;jna	sysret
 24195                              <1> 	;;call	idle ; (wait for hardware interrupt)
 24196                              <1> 	;;jmp	short sysmnt_6
 24197                              <1> 		;bne 1b / no, wait
 24198                              <1>         	;br sysreta / yes
 24199 00005D43 E9AEDFFFFF          <1> 	jmp	sysret
 24200                              <1> 
 24201                              <1> sysumount: ; / special dismount file system
 24202                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
 24203                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
 24204                              <1> 	;
 24205                              <1> 	; 04/11/2013
 24206                              <1> 	; 09/07/2013
 24207                              <1> 	; 'sysumount' anounces to the system that the special file, 
 24208                              <1> 	; indicated as an argument is no longer contain a removable
 24209                              <1> 	; file system. 'getspl' gets the device number of the special
 24210                              <1> 	; file. If no file system was mounted on that device an error
 24211                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
 24212                              <1> 	; to 'sysret'.
 24213                              <1> 	;
 24214                              <1> 	; Calling sequence:
 24215                              <1> 	;	sysmount; special
 24216                              <1> 	; Arguments:
 24217                              <1> 	;	special - special file to dismount (device)
 24218                              <1> 	;
 24219                              <1> 	; Inputs: - 
 24220                              <1> 	; Outputs: -
 24221                              <1> 	; ...............................................................
 24222                              <1> 	;				
 24223                              <1> 	; Retro UNIX 8086 v1 modification: 
 24224                              <1> 	;       'sysumount' system call has one argument; so,
 24225                              <1> 	;	* Single argument, special is pointed to by BX register
 24226                              <1> 	;
 24227                              <1> 	
 24228                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
 24229                              <1> 	;call	arg
 24230                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
 24231 00005D48 891D[D0700000]      <1>         mov	[u.namep], ebx
 24232 00005D4E E829000000          <1> 	call	getspl
 24233                              <1> 		; jsr r0,getspl / get the device number in r1
 24234 00005D53 3A05[97700000]      <1> 	cmp	al, [mdev]
 24235                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
 24236 00005D59 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
 24237                              <1> 	;jne	error
 24238                              <1>         	; bne errora / no error
 24239 00005D5B 30C0                <1> 	xor	al, al ; ah = 0
 24240                              <1> sysumnt_0: ;1:
 24241 00005D5D 3805[31800000]      <1>      	cmp 	[sb1+1], al ; 0
 24242                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
 24243                              <1> 			   ; / (inhibit bit set)?
 24244 00005D63 7607                <1> 	jna	short sysumnt_1		
 24245                              <1> 		; bne 1b / yes, wait
 24246 00005D65 E8BBF3FFFF          <1> 	call	idle ; (wait for hardware interrupt)
 24247 00005D6A EBF1                <1> 	jmp	short sysumnt_0
 24248                              <1> sysumnt_1:        
 24249 00005D6C A2[97700000]        <1> 	mov	[mdev], al
 24250                              <1> 	     	; clr mntd / no, clear these
 24251 00005D71 66A3[A0700000]      <1>    	mov	[mnti], ax
 24252                              <1>         	; clr mnti
 24253 00005D77 E97ADFFFFF          <1>         jmp	sysret
 24254                              <1> 		; br sysreta / return
 24255                              <1> 
 24256                              <1> getspl: ; / get device number from a special file name
 24257 00005D7C E81EEEFFFF          <1> 	call	namei
 24258                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
 24259                              <1> 		       ; ax = 0 -> file not found 	
 24260 00005D81 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
 24261                              <1> 	;jz	error
 24262                              <1> 	;jc	error
 24263                              <1> 		; jsr r0,namei / get the i-number of the special file
 24264                              <1>                 ; br errora / no such file
 24265 00005D87 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
 24266                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
 24267                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
 24268 00005D8B 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
 24269                              <1> 	;jc	error
 24270                              <1> 		; ble errora / less than 0?  yes, error
 24271 00005D8D 6683F805            <1>         cmp	ax, 5 ;
 24272                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
 24273 00005D91 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
 24274                              <1> 	;ja	error
 24275                              <1>         	; bgt errora / yes, error
 24276                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
 24277                              <1> iopen_retn:
 24278 00005D93 C3                  <1> 	retn
 24279                              <1> 		; rts    r0 / return with device number in r1
 24280                              <1> sysmnt_err0:
 24281 00005D94 C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
 24282 00005D9C 0000                <1>
 24283 00005D9E E933DFFFFF          <1> 	jmp	error
 24284                              <1> 
 24285                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
 24286                              <1> iopen:
 24287                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 24288                              <1> 	; 27/03/2021 (Retro UNIX 386 v2)
 24289                              <1> 	; 19/05/2015
 24290                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 24291                              <1> 	; 21/05/2013 - 27/08/2013 (Retro UNIX 8086 v1)
 24292                              <1> 	;
 24293                              <1> 	; open file whose i-number is in r1
 24294                              <1> 	; 
 24295                              <1> 	; INPUTS ->
 24296                              <1> 	;    r1 - inode number
 24297                              <1> 	; OUTPUTS ->
 24298                              <1> 	;    file's inode in core	
 24299                              <1> 	;    r1 - inode number (positive)
 24300                              <1> 	;
 24301                              <1> 	; ((AX = R1))
 24302                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi, ebp)) 
 24303                              <1> 	;        
 24304                              <1> ; / open file whose i-number is in r1
 24305                              <1> ;	test	ah, 80h ; Bit 15 of AX
 24306                              <1> ;		;tst r1 / write or read access?
 24307                              <1> ;       jnz	short iopen_2
 24308                              <1> ;		;blt 2f / write, go to 2f
 24309                              <1> ;	mov	dl, 2 ; read access
 24310                              <1> ;	call	access
 24311                              <1> ;       	; jsr r0,access; 2 
 24312                              <1> ;	; / get inode into core with read access
 24313                              <1> ;	; DL=2
 24314                              <1> ;iopen_0:
 24315                              <1> ;       cmp	ax, 40
 24316                              <1> ;		; cmp r1,$40. / is it a special file
 24317                              <1> ;       ja	short iopen_retn
 24318                              <1> ;		;bgt  3f / no. 3f
 24319                              <1> 
 24320                              <1> 	; 05/12/2021
 24321                              <1> 	; DL = 0 -> open for read
 24322                              <1> 	; DL = 1 -> open for write
 24323                              <1> 
 24324 00005DA3 52                  <1> 	push	edx ; *
 24325                              <1> 
 24326                              <1> 	; set permission/mode flag for 'access' 
 24327                              <1> 	;	(DX = 100h -> IREAD, DX = 80h -> IWRITE)
 24328                              <1> 
 24329 00005DA4 B601                <1> 	mov	dh, 1
 24330 00005DA6 08D2                <1> 	or	dl, dl ; dl = 0, open for read	
 24331 00005DA8 7404                <1> 	jz	short iopen_0 ; DX = IREAD (100h)
 24332                              <1> 	; dl = 1, open for write 
 24333 00005DAA FECE                <1> 	dec	dh
 24334 00005DAC B280                <1> 	mov	dl, 80h
 24335                              <1> 	; DX = IWRITE (80h)
 24336                              <1> iopen_0:
 24337                              <1> 	; 27/03/2021
 24338                              <1> 	;   EAX = inode number (in AX)
 24339                              <1> 	;    DX = access mode, 100h = read, 80h = write
 24340                              <1> 
 24341                              <1> 	; 24/06/2020 - Retro UNIX 386 v2	
 24342 00005DAE E89FF8FFFF          <1> 	call	access
 24343                              <1> 		;jsr r0,access; 1 / get inode in core
 24344                              <1> 	
 24345                              <1> 	; 27/03/2021
 24346                              <1> 	; DX return value from 'access' subroutine
 24347                              <1> 	;    may be 100h, 20h, 04h for DX = 100h (IREAD) input
 24348                              <1> 	;	     80h, 10h, 02h for DX = 80h (IWRITE) input
 24349                              <1> 
 24350                              <1> 	; 05/12/2021
 24351 00005DB3 5A                  <1> 	pop	edx ; * ; dl = 0 -> open for read
 24352                              <1> 			; dl = 1 -> open for write
 24353                              <1> 	; 24/06/2020
 24354 00005DB4 8A0D[516D0000]      <1> 	mov	cl, [i.flgs+1]
 24355                              <1> 
 24356 00005DBA F6C180              <1> 	test	cl, 80h		; regular file ?
 24357 00005DBD 7514                <1> 	jnz	short iopen_1	; yes ; 05/12/2021
 24358 00005DBF F6C120              <1> 	test	cl, 20h 	; device file ?
 24359 00005DC2 7524                <1> 	jnz	short iopen_2	; yes
 24360                              <1> 
 24361                              <1> 	; no !?, error.
 24362                              <1> 
 24363 00005DC4 C705[2C710000]FF00- <1> 	mov	dword [u.error], ERR_INV_FILE ; 0FFh ; invalid file
 24364 00005DCC 0000                <1>
 24365                              <1> iopen_err:
 24366 00005DCE E903DFFFFF          <1> 	jmp	error
 24367                              <1> 
 24368                              <1> iopen_1:
 24369                              <1> 	; 05/12/2021
 24370                              <1> 	; (If open mode is 'write' and the file/inode is a directory,
 24371                              <1> 	;  open request will/must be rejected.)
 24372                              <1> 	;
 24373                              <1> 	; (If inode is a regular file and it is not a directory,
 24374                              <1> 	; there is nothing to do here, we need to return to 'sysopen'
 24375                              <1> 	; for completing the rest of file opening procedure.) 
 24376                              <1> 	
 24377 00005DD3 F6C140              <1> 	test	cl, 40h	; directory ?
 24378 00005DD6 74BB                <1> 	jz	short iopen_retn ; no
 24379                              <1> 	
 24380 00005DD8 20D2                <1> 	and	dl, dl ; open mode is 1 (write) ?
 24381 00005DDA 74B7                <1> 	jz	short iopen_retn ; no
 24382                              <1> 
 24383                              <1> 	; !!!	
 24384                              <1> 	; 'sysopen' for writing
 24385                              <1> 	;	 is not applicable for directories
 24386                              <1> 	; (Directory entries must be created or deleted by
 24387                              <1> 	; relevant system calls.)
 24388                              <1> 
 24389                              <1> 	;mov	dword [u.error], ERR_DIR_ACCESS ; 11
 24390 00005DDC C705[2C710000]0B00- <1> 	mov	dword [u.error], ERR_PERM_DENIED ; 11
 24391 00005DE4 0000                <1>
 24392                              <1> 				; 'permission denied !' error  
 24393                              <1> 	;jmp	error
 24394 00005DE6 EBE6                <1> 	jmp	short iopen_err
 24395                              <1> 
 24396                              <1> ;iopen_retn:
 24397                              <1> ;	retn
 24398                              <1> 
 24399                              <1> iopen_2:
 24400                              <1> 	;push	ax
 24401                              <1> 	;	; mov r1,-(sp) / yes, figure out
 24402                              <1> 	;movzx	ebx, al
 24403                              <1> 	;shl	bx, 2
 24404                              <1> 	;	; asl r1
 24405                              <1>         ;add	ebx, iopen_1 - 4
 24406                              <1> 	;jmp	dword [ebx]
 24407                              <1>         ;	; jmp *1f-2(r1) / which one and transfer to it
 24408                              <1> 	
 24409                              <1> 	; 05/12/2021
 24410 00005DE8 50                  <1> 	push	eax ; save inode number
 24411                              <1> 	; device file
 24412 00005DE9 BB[055E0000]        <1> 	mov	ebx, iopen_4
 24413 00005DEE 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 24414 00005DF1 720E                <1> 	jb	short iopen_3
 24415 00005DF3 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 24416 00005DF6 7709                <1> 	ja	short iopen_3	
 24417                              <1> 	; convert v2 inode number to v1 device inode number
 24418 00005DF8 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 24419 00005DFA 89C1                <1> 	mov	ecx, eax
 24420 00005DFC C0E102              <1> 	shl	cl, 2 ; * 4
 24421 00005DFF 01CB                <1> 	add	ebx, ecx
 24422                              <1> iopen_3:
 24423 00005E01 FEC2                <1> 	inc	dl ; 1 = read, 2 = write
 24424 00005E03 FF23                <1> 	jmp	dword [ebx]	
 24425                              <1> 		 ; jmp *1f-2(r1)
 24426                              <1> ;iopen_1: ; 1:
 24427                              <1> iopen_4:
 24428 00005E05 [67580000]          <1> 	dd	null ; 05/12/2021
 24429 00005E09 [555E0000]          <1> 	dd	otty ; tty, AX = 1 (runix)
 24430                              <1>  		 ;otty / tty ; r1=2
 24431                              <1>         	 ;oppt / ppt ; r1=4
 24432 00005E0D [F35E0000]          <1> 	dd	sret ; mem, AX = 2 (runix)
 24433                              <1> 		 ;sret / mem ; r1=6
 24434                              <1> 		 ;sret / rf0
 24435                              <1>         	 ;sret / rk0
 24436                              <1>         	 ;sret / tap0
 24437                              <1>         	 ;sret / tap1
 24438                              <1>         	 ;sret / tap2
 24439                              <1>         	 ;sret / tap3
 24440                              <1>         	 ;sret / tap4
 24441                              <1>         	 ;sret / tap5
 24442                              <1>         	 ;sret / tap6
 24443                              <1>         	 ;sret / tap7
 24444 00005E11 [F35E0000]          <1>         dd	sret ; fd0, AX = 3 (runix only)
 24445 00005E15 [F35E0000]          <1>         dd	sret ; fd1, AX = 4 (runix only)
 24446 00005E19 [F35E0000]          <1>         dd	sret ; hd0, AX = 5 (runix only)
 24447 00005E1D [F35E0000]          <1>         dd	sret ; hd1, AX = 6 (runix only) 
 24448 00005E21 [F35E0000]          <1>         dd	sret ; hd2, AX = 7 (runix only)
 24449 00005E25 [F35E0000]          <1>         dd	sret ; hd3, AX = 8 (runix only) 
 24450                              <1> 	;dd	error ; lpr, AX = 9 (error !)
 24451 00005E29 [F35E0000]          <1>         dd      sret ; lpr, AX = 9 (runix)
 24452 00005E2D [645E0000]          <1> 	dd	ocvt ; tty0, AX = 10 (runix)	  
 24453                              <1> 		 ;ocvt / tty0
 24454 00005E31 [645E0000]          <1> 	dd	ocvt ; tty1, AX = 11 (runix)	  
 24455                              <1> 		 ;ocvt / tty1
 24456 00005E35 [645E0000]          <1> 	dd	ocvt ; tty2, AX = 12 (runix)	  
 24457                              <1> 		 ;ocvt / tty2
 24458 00005E39 [645E0000]          <1> 	dd	ocvt ; tty3, AX = 13 (runix)	  
 24459                              <1> 		 ;ocvt / tty3
 24460 00005E3D [645E0000]          <1> 	dd	ocvt ; tty4, AX = 14 (runix)	  
 24461                              <1> 		 ;ocvt / tty4
 24462 00005E41 [645E0000]          <1> 	dd	ocvt ; tty5, AX = 15 (runix)	  
 24463                              <1> 		 ;ocvt / tty5
 24464 00005E45 [645E0000]          <1> 	dd	ocvt ; tty6, AX = 16 (runix)	  
 24465                              <1> 		 ;ocvt / tty6
 24466 00005E49 [645E0000]          <1> 	dd	ocvt ; tty7, AX = 17 (runix)	  
 24467                              <1> 		 ;ocvt / tty7
 24468 00005E4D [645E0000]          <1> 	dd	ocvt ; COM1, AX = 18 (runix only)	  
 24469                              <1> 		 ;error / crd
 24470 00005E51 [645E0000]          <1> 	dd	ocvt ; COM2, AX = 19 (runix only)
 24471                              <1> 
 24472                              <1> ;iopen_2: ; 2: / check open write access
 24473                              <1> ;	neg	ax
 24474                              <1> ;		;neg r1 / make inode number positive
 24475                              <1> ;	mov	dl, 1 ; write access
 24476                              <1> ;	call	access
 24477                              <1> ;		;jsr r0,access; 1 / get inode in core
 24478                              <1> ;	; DL=1
 24479                              <1> ;	test	word [i.flgs], 4000h ; Bit 14 : Directory flag
 24480                              <1> ;		;bit $40000,i.flgs / is it a directory?
 24481                              <1> ;	jz	short iopen_0
 24482                              <1> ;	;mov	[u.error], ERR_DIR_ACCESS
 24483                              <1> ;	;jmp	error ; permission denied !
 24484                              <1> ;	jmp	sysmnt_err0
 24485                              <1> ;	;;jnz	error		
 24486                              <1> ;      		; bne 2f / yes, transfer (error)
 24487                              <1> ;       ;;jmp     short iopen_0
 24488                              <1> ;	;cmp	ax, 40
 24489                              <1> ;		; cmp r1,$40. / no, is it a special file?
 24490                              <1> ;        ;ja	short iopen_2
 24491                              <1> ;		 ;bgt 3f / no, return
 24492                              <1> ;	;push	ax
 24493                              <1> ;		;mov r1,-(sp) / yes
 24494                              <1> ;	;movzx	ebx, al
 24495                              <1> ;	;shl	bx, 1
 24496                              <1> ;		; asl r1
 24497                              <1> ;	;add	ebx, ipen_3 - 2
 24498                              <1> ;	;jmp	dword [ebx]
 24499                              <1> ;		; jmp *1f-2(r1) / figure out 
 24500                              <1> ;			; / which special file it is and transfer
 24501                              <1> ;iopen_3: ; 1:
 24502                              <1> ;	dd 	otty ; tty, AX = 1 (runix)
 24503                              <1> ; 		 ;otty / tty ; r1=2
 24504                              <1> ;        	 ;leadr / ppt ; r1=4
 24505                              <1> ;	dd	sret ; mem, AX = 2 (runix)
 24506                              <1> ;		 ;sret / mem ; r1=6
 24507                              <1> ;		 ;sret / rf0
 24508                              <1> ;        	 ;sret / rk0
 24509                              <1> ;        	 ;sret / tap0
 24510                              <1> ;        	 ;sret / tap1
 24511                              <1> ;        	 ;sret / tap2
 24512                              <1> ;        	 ;sret / tap3
 24513                              <1> ;        	 ;sret / tap4
 24514                              <1> ;        	 ;sret / tap5
 24515                              <1> ;        	 ;sret / tap6
 24516                              <1> ;        	 ;sret / tap7
 24517                              <1> ;	dd 	sret ; fd0, AX = 3 (runix only)
 24518                              <1> ;	dd 	sret ; fd1, AX = 4 (runix only)
 24519                              <1> ;	dd 	sret ; hd0, AX = 5 (runix only)
 24520                              <1> ;	dd 	sret ; hd1, AX = 6 (runix only)	
 24521                              <1> ;	dd 	sret ; hd2, AX = 7 (runix only)
 24522                              <1> ;	dd 	sret ; hd3, AX = 8 (runix only)	
 24523                              <1> ;	dd	sret ; lpr, AX = 9  (runix)
 24524                              <1> ;	;dd	ejec ; lpr, AX = 9  (runix)
 24525                              <1> ;	dd	sret ; tty0, AX = 10 (runix)	  
 24526                              <1> ;		 ;ocvt / tty0
 24527                              <1> ;	dd	sret ; tty1, AX = 11 (runix)	  
 24528                              <1> ;		 ;ocvt / tty1
 24529                              <1> ;	dd	sret ; tty2, AX = 12 (runix)	  
 24530                              <1> ;		 ;ocvt / tty2
 24531                              <1> ;	dd	sret ; tty3, AX = 13 (runix)	  
 24532                              <1> ;		 ;ocvt / tty3
 24533                              <1> ;	dd	sret ; tty4, AX = 14 (runix)	  
 24534                              <1> ;		 ;ocvt / tty4
 24535                              <1> ;	dd	sret ; tty5, AX = 15 (runix)	  
 24536                              <1> ;		 ;ocvt / tty5
 24537                              <1> ;	dd	sret ; tty6, AX = 16 (runix)	  
 24538                              <1> ;		 ;ocvt / tty6
 24539                              <1> ;	dd	sret ; tty7, AX = 17 (runix)	  
 24540                              <1> ;		 ;ocvt / tty7
 24541                              <1> ;	dd	ocvt ; COM1, AX = 18 (runix only)	  
 24542                              <1> ;		 ;/ ejec / lpr
 24543                              <1> ;	dd	ocvt ; COM2, AX = 19 (runix only)
 24544                              <1> 
 24545                              <1> otty: ;/ open console tty for reading or writing
 24546                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 24547                              <1> 	; 16/11/2015
 24548                              <1> 	; 12/11/2015
 24549                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 24550                              <1> 	; 21/05/2013 - 13/07/2014 (Retro UNIX 8086 v1)
 24551                              <1> 	; 16/07/2013
 24552                              <1> 	; Retro UNIX 8086 v1 modification:
 24553                              <1> 	;  If a tty is open for read or write by
 24554                              <1> 	;     a process (u.uno), only same process can open
 24555                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 24556                              <1> 	;
 24557                              <1> 	; (INPUT: DL=2 for Read, DL=1 for Write, DL=0 for sysstty)
 24558                              <1> 	;
 24559 00005E55 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 24560 00005E5C 8A83[EF6D0000]      <1> 	mov	al, [ebx+p.ttyc-1] ; current/console tty
 24561                              <1> 	; 13/01/2014
 24562 00005E62 EB02                <1> 	jmp	short ottyp
 24563                              <1> ocvt:
 24564 00005E64 2C0A                <1> 	sub	al, 10
 24565                              <1> ottyp:
 24566                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 24567                              <1> 	; 16/11/2015
 24568                              <1> 	; 12/11/2015
 24569                              <1> 	; 18/05/2015 (32 bit modifications)
 24570                              <1> 	; 06/12/2013 - 13/07/2014
 24571 00005E66 88C6                <1> 	mov	dh, al ; tty number
 24572 00005E68 0FB6D8              <1> 	movzx 	ebx, al ; AL = tty number (0 to 9), AH = 0
 24573 00005E6B D0E3                <1> 	shl 	bl, 1  ; aligned to word
 24574                              <1> 	;26/01/2014	
 24575 00005E6D 81C3[04700000]      <1> 	add 	ebx, ttyl
 24576 00005E73 668B0B              <1> 	mov 	cx, [ebx]
 24577                              <1> 		   ; CL = lock value (0 or process number)
 24578                              <1> 		   ; CH = open count 
 24579 00005E76 20C9                <1> 	and 	cl, cl
 24580                              <1> 	; 13/01/2014
 24581                              <1> 	;jz 	short otty_ret
 24582                              <1> 	; 05/12/2021
 24583 00005E78 743A                <1> 	jz 	short ottys_0
 24584                              <1> 	;
 24585                              <1> 	; 16/11/2015
 24586 00005E7A 3A0D[09710000]      <1> 	cmp 	cl, [u.uno]
 24587 00005E80 745D                <1> 	je	short ottys_3
 24588                              <1> 	;
 24589 00005E82 0FB6D9              <1> 	movzx 	ebx, cl ; the process which has locked the tty
 24590 00005E85 D0E3                <1> 	shl 	bl, 1
 24591 00005E87 668B83[8E6D0000]    <1> 	mov 	ax, [ebx+p.pid-2]
 24592                              <1> 	;movzx 	ebx, byte [u.uno]
 24593 00005E8E 8A1D[09710000]      <1> 	mov	bl, [u.uno]
 24594 00005E94 D0E3                <1> 	shl 	bl, 1
 24595 00005E96 663B83[AE6D0000]    <1> 	cmp 	ax, [ebx+p.ppid-2]
 24596 00005E9D 7440                <1> 	je 	short ottys_3  ; 16/11/2015
 24597                              <1> 	;
 24598                              <1> 	; the tty is locked by another process
 24599                              <1> 	; except the parent process (p.ppid)
 24600                              <1>         ;
 24601 00005E9F C705[2C710000]0B00- <1> 	mov     dword [u.error], ERR_DEV_ACCESS
 24602 00005EA7 0000                <1>
 24603                              <1> 			; permission denied ! error
 24604                              <1> otty_err: ; 13/01/2014
 24605 00005EA9 08D2                <1> 	or 	dl, dl ; DL = 0 -> called by sysstty
 24606                              <1> 	;jnz	error
 24607                              <1> 	; 05/12/2021
 24608 00005EAB 7405                <1> 	jz	short otty_stc_retn
 24609 00005EAD E924DEFFFF          <1> 	jmp	error
 24610                              <1> otty_stc_retn:
 24611 00005EB2 F9                  <1> 	stc
 24612 00005EB3 C3                  <1> 	retn
 24613                              <1> ottys_0:
 24614                              <1> 	; 05/12/2021
 24615                              <1> otty_ret:
 24616                              <1> 	; 13/01/2014
 24617 00005EB4 80FE07              <1> 	cmp 	dh, 7
 24618 00005EB7 761C                <1> 	jna	short ottys_2
 24619                              <1> 	; 16/11/2015
 24620                              <1> com_port_check:
 24621 00005EB9 BE[22700000]        <1> 	mov	esi, com1p
 24622 00005EBE 80FE08              <1> 	cmp	dh, 8	; COM1 (tty8) ?
 24623 00005EC1 7601                <1> 	jna	short ottys_1 ; yes, it is COM1
 24624 00005EC3 46                  <1> 	inc	esi	; no, it is COM2 (tty9)
 24625                              <1> ottys_1:
 24626                              <1> 	; 12/11/2015
 24627 00005EC4 803E00              <1> 	cmp	byte [esi], 0 ; E3h (or 23h)
 24628 00005EC7 770C                <1> 	ja	short com_port_ready
 24629                              <1> 	;
 24630 00005EC9 C705[2C710000]0F00- <1>         mov     dword [u.error], ERR_DEV_NOT_RDY
 24631 00005ED1 0000                <1>
 24632                              <1> 			   ; device not ready ! error
 24633 00005ED3 EBD4                <1> 	jmp	short otty_err	 
 24634                              <1> com_port_ready:
 24635                              <1> ottys_2:
 24636 00005ED5 08C9                <1> 	or	cl, cl  ; cl = lock/owner, ch = open count
 24637 00005ED7 7506                <1> 	jnz	short ottys_3
 24638 00005ED9 8A0D[09710000]      <1> 	mov	cl, [u.uno]
 24639                              <1> ottys_3:
 24640 00005EDF FEC5                <1> 	inc 	ch
 24641 00005EE1 66890B              <1> 	mov 	[ebx], cx ; set tty lock again
 24642                              <1> 	; 06/12/2013
 24643 00005EE4 FEC6                <1> 	inc	dh ; tty number + 1
 24644 00005EE6 BB[EE700000]        <1> 	mov	ebx, u.ttyp
 24645                              <1> 	; 13/01/2014
 24646                              <1> 	;test	dl, 2 ; open for read sign
 24647                              <1> 	;jnz	short ottys_4
 24648                              <1> 	; 05/12/2021
 24649 00005EEB F6C202              <1> 	test	dl, 2
 24650 00005EEE 7401                <1> 	jz	short ottys_4 ; open for read
 24651 00005EF0 43                  <1> 	inc	ebx
 24652                              <1> ottys_4:
 24653                              <1> 	; Set 'u.ttyp' ('the recent TTY') value
 24654 00005EF1 8833                <1> 	mov 	[ebx], dh ; tty number + 1
 24655                              <1> sret:
 24656 00005EF3 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 24657 00005EF5 7401                <1> 	jz	short iclose_retn
 24658                              <1> 	;pop 	ax
 24659                              <1> 	; 05/12/2021
 24660 00005EF7 58                  <1> 	pop	eax
 24661                              <1> iclose_retn:	
 24662 00005EF8 C3                  <1> 	retn
 24663                              <1> 
 24664                              <1> 	;
 24665                              <1> 	; Original UNIX v1 'otty' routine:
 24666                              <1> 	;	
 24667                              <1> 	;mov    $100,*$tks / set interrupt enable bit (zero others) in
 24668                              <1>         ;                 / reader status reg
 24669                              <1>         ;mov    $100,*$tps / set interrupt enable bit (zero others) in
 24670                              <1>         ;                 / punch status reg
 24671                              <1>         ;mov    tty+[ntty*8]-8+6,r5 / r5 points to the header of the
 24672                              <1>         ;                          / console tty buffer
 24673                              <1>         ;incb   (r5) / increment the count of processes that opened the
 24674                              <1>         ;            / console tty
 24675                              <1>         ;tst    u.ttyp / is there a process control tty (i.e., has a tty
 24676                              <1>         ;             / buffer header
 24677                              <1>         ;bne    sret / address been loaded into u.ttyp yet)?  yes, branch
 24678                              <1>         ;mov    r5,u.ttyp / no, make the console tty the process control
 24679                              <1>         ;                 / tty
 24680                              <1>         ;br     sret / ?
 24681                              <1> ;sret:
 24682                              <1> 		;clr *$ps / set processor priority to zero
 24683                              <1> ;	pop	ax
 24684                              <1>         	;mov (sp)+,r1 / pop stack to r1
 24685                              <1> ;3:
 24686                              <1> ;	retn
 24687                              <1>         	;rts r0
 24688                              <1> 	
 24689                              <1> ;ocvt:	; < open tty >
 24690                              <1> 	; 13/01/2014
 24691                              <1> 	; 06/12/2013 (major modification: p.ttyc, u.ttyp)
 24692                              <1> 	; 24/09/2013 consistency check -> ok
 24693                              <1> 	; 16/09/2013
 24694                              <1> 	; 03/09/2013
 24695                              <1> 	; 27/08/2013
 24696                              <1> 	; 16/08/2013
 24697                              <1> 	; 16/07/2013
 24698                              <1> 	; 27/05/2013
 24699                              <1> 	; 21/05/2013
 24700                              <1> 	;
 24701                              <1> 	; Retro UNIX 8086 v1 modification !
 24702                              <1> 	; 
 24703                              <1> 	; In original UNIX v1, 'ocvt' routine 
 24704                              <1> 	;		(exactly different than this one)
 24705                              <1> 	;	was in 'u9.s' file.
 24706                              <1> 	;
 24707                              <1> 	; 16/07/2013
 24708                              <1> 	; Retro UNIX 8086 v1 modification:
 24709                              <1> 	;  If a tty is open for read or write by
 24710                              <1> 	;     a process (u.uno), only same process can open
 24711                              <1> 	;     same tty to write or read (R->R&W or W->W&R).	
 24712                              <1> 	;
 24713                              <1> 	; INPUT: DL=2 for Read DL=1 for Write
 24714                              <1> 
 24715                              <1> 	; 16/09/2013
 24716                              <1> 	; sub 	al, 10
 24717                              <1> 	
 24718                              <1> 	; 06/12/2013
 24719                              <1> 	;cmp	al, 7
 24720                              <1>         ;jna	short ottyp
 24721                              <1> 	; 13/01/2014
 24722                              <1> 	;jmp	short ottyp
 24723                              <1> 
 24724                              <1> ;oppt: / open paper tape for reading or writing
 24725                              <1> ;        mov    $100,*$prs / set reader interrupt enable bit
 24726                              <1> ;        tstb   pptiflg / is file already open
 24727                              <1> ;        bne    2f / yes, branch
 24728                              <1> ;1:
 24729                              <1> ;        mov    $240,*$ps / no, set processor priority to 5
 24730                              <1> ;        jsr    r0,getc; 2 / remove all entries in clist
 24731                              <1> ;               br .+4 / for paper tape input and place in free list
 24732                              <1> ;        br     1b
 24733                              <1> ;        movb   $2,pptiflg / set pptiflg to indicate file just open
 24734                              <1> ;        movb   $10.,toutt+1 / place 10 in paper tape input tout entry
 24735                              <1> ;        br     sret
 24736                              <1> ;2:
 24737                              <1> ;        jmp    error / file already open
 24738                              <1> 
 24739                              <1> 	; 05/12/2021 - Retro UNIX 386 v2 fs compatibility modification
 24740                              <1> iclose:
 24741                              <1> 	; 05/12/2021 - Retro UNIX 386 v1.2
 24742                              <1> 	; 10/04/2021
 24743                              <1> 	; 08/04/2021
 24744                              <1> 	; 04/04/2021 - Retro UNIX 386 v2
 24745                              <1> 	; 19/05/2015
 24746                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 24747                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 24748                              <1> 	;
 24749                              <1> 	; close file whose i-number is in r1
 24750                              <1> 	; 
 24751                              <1> 	; INPUTS ->
 24752                              <1> 	;    r1 - inode number
 24753                              <1> 	; OUTPUTS ->
 24754                              <1> 	;    file's inode in core	
 24755                              <1> 	;    r1 - inode number (positive)
 24756                              <1> 	;
 24757                              <1> 	; ((AX = R1))
 24758                              <1>         ;    ((Modified registers: -ebx-, edx)) 
 24759                              <1> 	;        
 24760                              <1> ;;/ close file whose i-number is in r1
 24761                              <1> ;	mov	dl, 2 ; 12/01/2014
 24762                              <1> ;	test	ah, 80h ; Bit 15 of AX
 24763                              <1> ;		;tst r1 / test i-number
 24764                              <1> ;	;jnz	short iclose_2
 24765                              <1> ;		;blt 2f / if neg., branch
 24766                              <1> ;	jz	short iclose_0 ; 30/07/2013
 24767                              <1> ;	; 16/07/2013 
 24768                              <1> ;	neg	ax ; make it positive
 24769                              <1> ;	; 12/01/2014
 24770                              <1> ;	dec	dl ; dl = 1 (open for write)
 24771                              <1> ;iclose_0:
 24772                              <1> ;	cmp	ax, 40
 24773                              <1> ;		;cmp r1,$40. / is it a special file
 24774                              <1> ;       ja	short iclose_retn  ; 13/01/2014
 24775                              <1> ;		;bgt 3b / no, return
 24776                              <1> ;	; 12/01/2014
 24777                              <1> ;	; DL=2 -> special file was opened for reading
 24778                              <1> ;	; DL=1 -> special file was opened for writing
 24779                              <1> 
 24780                              <1> 	; 04/04/2021
 24781                              <1> 	; INPUT:
 24782                              <1> 	;	(e)ax = inode number
 24783                              <1> 	;	   dl = open mode
 24784                              <1> 	;		0 = control mode
 24785                              <1> 	;		1 = read
 24786                              <1> 	;		2 = write
 24787                              <1> 	; OUTPUT:
 24788                              <1> 	;	none
 24789                              <1> 	;	(if cf=1 -> eax = error code)
 24790                              <1> 	;	(if cf=0 -> ax = inode number)
 24791                              <1> 
 24792                              <1> 	; 10/04/2021
 24793                              <1>         ; Modified registers: ebx, ecx, edx, esi, edi, (ebp) 
 24794                              <1> 
 24795                              <1> 	; 05/12/2021
 24796                              <1> 	; 08/04/2021
 24797                              <1> 
 24798 00005EF9 52                  <1> 	push	edx
 24799 00005EFA E86CF6FFFF          <1> 	call	iget
 24800 00005EFF 5A                  <1> 	pop	edx 
 24801                              <1> 
 24802 00005F00 8A0D[516D0000]      <1> 	mov	cl, [i.flgs+1]
 24803                              <1> 
 24804                              <1> 	; if i.flgs bit 15 is 1, it is regular file 
 24805                              <1> 	;test	byte [i.flgs+1], 80h ; is it a special file?
 24806 00005F06 F6C180              <1> 	test	cl, 80h ; is it a special file?
 24807 00005F09 75ED                <1> 	jnz	short iclose_retn ; no
 24808                              <1> 
 24809                              <1> 	;; inode flags - bit 13 must be 1 
 24810                              <1> 	;test	cl, 20h ; is it a valid device inode
 24811                              <1> 	;jnz	short iclose_retn ; no
 24812                              <1> 	
 24813                              <1> 	;push	ax
 24814                              <1> 	;	;mov r1,-(sp) / yes, save r1 on stack
 24815                              <1> 	;movzx	ebx, al
 24816                              <1> 	;shl	bx, 2
 24817                              <1> 	;	; asl r1
 24818                              <1> 	;add	ebx, iclose_1 - 4
 24819                              <1> 	;jmp	dword [ebx]
 24820                              <1> 	;	; jmp *1f-2(r1) / compute jump address and transfer
 24821                              <1> 
 24822                              <1> 	; 05/12/2021
 24823 00005F0B 50                  <1> 	push	eax ; save inode number
 24824                              <1> 	; device file
 24825 00005F0C BB[265F0000]        <1> 	mov	ebx, iclose_1
 24826 00005F11 83F808              <1> 	cmp	eax, 8	; /dev/tty inode number is 8
 24827 00005F14 720E                <1> 	jb	short iclose_0
 24828 00005F16 83F81A              <1> 	cmp	eax, 26	; /dev/tty9 (/dev/com2) inode number is 26
 24829 00005F19 7709                <1> 	ja	short iclose_0
 24830                              <1> 	; convert v2 inode number to v1 device inode number
 24831 00005F1B 2C07                <1> 	sub	al, 7 ; 8 -> 1, 26 -> 19
 24832 00005F1D 89C1                <1> 	mov	ecx, eax
 24833 00005F1F C0E102              <1> 	shl	cl, 2 ; * 4
 24834 00005F22 01CB                <1> 	add	ebx, ecx
 24835                              <1> iclose_0:
 24836 00005F24 FF23                <1> 	jmp	dword [ebx]	
 24837                              <1> 		 ; jmp *1f-2(r1)
 24838                              <1> iclose_1: ; 1:
 24839 00005F26 [67580000]          <1> 	dd	null ; 05/12/2021
 24840 00005F2A [765F0000]          <1> 	dd	ctty ; tty, AX = 1 (runix)
 24841 00005F2E [C75F0000]          <1> 	dd	cret ; mem, AX = 2 (runix)
 24842 00005F32 [C75F0000]          <1> 	dd	cret ; fd0, AX = 3 (runix only)
 24843 00005F36 [C75F0000]          <1> 	dd	cret ; fd1, AX = 4 (runix only)
 24844 00005F3A [C75F0000]          <1> 	dd	cret ; hd0, AX = 5 (runix only)
 24845 00005F3E [C75F0000]          <1> 	dd	cret ; hd1, AX = 6 (runix only)	
 24846 00005F42 [C75F0000]          <1> 	dd	cret ; hd2, AX = 7 (runix only)
 24847 00005F46 [C75F0000]          <1> 	dd	cret ; hd3, AX = 8 (runix only)	
 24848 00005F4A [C75F0000]          <1> 	dd	cret ; lpr, AX = 9 (runix)
 24849                              <1> 	;dd	error; lpr, AX = 9 (error!)
 24850                              <1> 	;;dd	offset ejec ;;lpr, AX = 9  
 24851 00005F4E [855F0000]          <1> 	dd	ccvt ; tty0, AX = 10 (runix)	  
 24852 00005F52 [855F0000]          <1> 	dd	ccvt ; tty1, AX = 11 (runix)	  
 24853 00005F56 [855F0000]          <1> 	dd	ccvt ; tty2, AX = 12 (runix)	  
 24854 00005F5A [855F0000]          <1> 	dd	ccvt ; tty3, AX = 13 (runix)	  
 24855 00005F5E [855F0000]          <1> 	dd	ccvt ; tty4, AX = 14 (runix)	  
 24856 00005F62 [855F0000]          <1> 	dd	ccvt ; tty5, AX = 15 (runix)	  
 24857 00005F66 [855F0000]          <1> 	dd	ccvt ; tty6, AX = 16 (runix)	  
 24858 00005F6A [855F0000]          <1> 	dd	ccvt ; tty7, AX = 17 (runix)	  
 24859 00005F6E [855F0000]          <1> 	dd	ccvt ; COM1, AX = 18 (runix only)	  
 24860 00005F72 [855F0000]          <1> 	dd	ccvt ; COM2, AX = 19 (runix only)
 24861                              <1> 
 24862                              <1> 	; 1:
 24863                              <1> 	;        ctty   / tty
 24864                              <1> 	;        cppt   / ppt
 24865                              <1> 	;        sret   / mem
 24866                              <1> 	;        sret   / rf0
 24867                              <1> 	;        sret   / rk0
 24868                              <1> 	;        sret   / tap0
 24869                              <1> 	;        sret   / tap1
 24870                              <1> 	;        sret   / tap2
 24871                              <1> 	;        sret   / tap3
 24872                              <1> 	;        sret   / tap4
 24873                              <1> 	;        sret   / tap5
 24874                              <1> 	;        sret   / tap6
 24875                              <1> 	;        sret   / tap7
 24876                              <1> 	;        ccvt   / tty0
 24877                              <1> 	;        ccvt   / tty1
 24878                              <1> 	;        ccvt   / tty2
 24879                              <1> 	;        ccvt   / tty3
 24880                              <1> 	;        ccvt   / tty4
 24881                              <1> 	;        ccvt   / tty5
 24882                              <1> 	;        ccvt   / tty6
 24883                              <1> 	;        ccvt   / tty7
 24884                              <1> 	;        error / crd
 24885                              <1> 
 24886                              <1> ;iclose_2: ; 2: / negative i-number
 24887                              <1> 	;neg	ax
 24888                              <1> 		;neg r1 / make it positive
 24889                              <1> 	;cmp	ax, 40
 24890                              <1> 		;cmp r1,$40. / is it a special file?
 24891                              <1>         ;ja	short @b
 24892                              <1> 		;bgt    3b / no. return
 24893                              <1> 	;push	ax
 24894                              <1> 		;mov r1,-(sp)
 24895                              <1> 	;movzx	ebx, al
 24896                              <1> 	;shl	bx, 1
 24897                              <1> 		;asl r1 / yes. compute jump address and transfer
 24898                              <1> 	;add	ebx, iclose_3 - 2
 24899                              <1> 	;jmp	dword [ebx]
 24900                              <1> 		;jmp *1f-2(r1) / figure out 
 24901                              <1> ;iclose_3:
 24902                              <1> 	;dd	ctty ; tty, AX = 1 (runix)
 24903                              <1> 	;dd	sret ; mem, AX = 2 (runix)
 24904                              <1> 	;dd	sret ; fd0, AX = 3 (runix only)
 24905                              <1> 	;dd	sret ; fd1, AX = 4 (runix only)
 24906                              <1> 	;dd	sret ; hd0, AX = 5 (runix only)
 24907                              <1> 	;dd	sret ; hd1, AX = 6 (runix only)	
 24908                              <1> 	;dd	sret ; hd2, AX = 7 (runix only)
 24909                              <1> 	;dd	sret ; hd3, AX = 8 (runix only)
 24910                              <1> 	 ;dd	sret ; lpr, AX = 9	
 24911                              <1> 	;dd	ejec ; lpr, AX = 9  (runix)
 24912                              <1> 	;dd	ccvt ; tty0, AX = 10 (runix)	  
 24913                              <1> 	;dd	ccvt ; tty1, AX = 11 (runix)	  
 24914                              <1> 	;dd	ccvt ; tty2, AX = 12 (runix)	  
 24915                              <1> 	;dd	ccvt ; tty3, AX = 13 (runix)	  
 24916                              <1> 	;dd	ccvt ; tty4, AX = 14 (runix)	  
 24917                              <1> 	;dd	ccvt ; tty5, AX = 15 (runix)	  
 24918                              <1> 	;dd	ccvt ; tty6, AX = 16 (runix)	  
 24919                              <1> 	;dd	ccvt ; tty7, AX = 17 (runix)	  
 24920                              <1> 	;dd	ccvt ; COM1, AX = 18 (runix only)	  
 24921                              <1> 	;dd	ccvt ; COM2, AX = 19 (runix only) 
 24922                              <1> 	
 24923                              <1> 	;1:
 24924                              <1> 	;      	ctty   / tty
 24925                              <1> 	;       leadr  / ppt
 24926                              <1> 	;       sret   / mem
 24927                              <1> 	;       sret   / rf0
 24928                              <1> 	;       sret   / rk0
 24929                              <1> 	;       sret   / tap0
 24930                              <1> 	;       sret   / tap1
 24931                              <1> 	;       sret   / tap2
 24932                              <1> 	;       sret   / tap3
 24933                              <1> 	;       sret   / tap4
 24934                              <1> 	;       sret   / tap5
 24935                              <1> 	;       sret   / tap6
 24936                              <1> 	;       sret   / tap7
 24937                              <1> 	;       ccvt   / tty0
 24938                              <1> 	;       ccvt   / tty1
 24939                              <1> 	;       ccvt   / tty2
 24940                              <1> 	;       ccvt   / tty3
 24941                              <1> 	;       ccvt   / tty4
 24942                              <1> 	;       ccvt   / tty5
 24943                              <1> 	;       ccvt   / tty6
 24944                              <1> 	;       ccvt   / tty7
 24945                              <1> 	;/       ejec / lpr
 24946                              <1> 
 24947                              <1> ctty: ; / close console tty
 24948                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 24949                              <1> 	; 18/05/2015 (Retro UNIX 386 v1 - Beginning)
 24950                              <1> 	; 21/05/2013 - 26/01/2014 (Retro UNIX 8086 v1)
 24951                              <1> 	;
 24952                              <1> 	; Retro UNIX 8086 v1 modification !
 24953                              <1> 	; (DL = 2 -> it is open for reading)
 24954                              <1> 	; (DL = 1 -> it is open for writing)
 24955                              <1> 	; (DL = 0 -> it is open for sysstty system call)
 24956                              <1> 	;
 24957                              <1> 	; 06/12/2013
 24958 00005F76 0FB61D[09710000]    <1>         movzx   ebx, byte [u.uno] ; process number
 24959 00005F7D 8A83[EF6D0000]      <1>         mov     al, [ebx+p.ttyc-1]
 24960                              <1> 	; 13/01/2014
 24961 00005F83 EB02                <1> 	jmp	short cttyp
 24962                              <1> ccvt:
 24963 00005F85 2C0A                <1> 	sub 	al, 10
 24964                              <1> cttyp:	
 24965                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 24966                              <1> 	; 18/05/2015 (32 bit modifications)
 24967                              <1> 	; 16/08/2013 - 26/01/2014
 24968 00005F87 0FB6D8              <1> 	movzx 	ebx, al ; tty number (0 to 9)
 24969 00005F8A D0E3                <1> 	shl 	bl, 1  ; aligned to word	
 24970                              <1> 	; 26/01/2014
 24971 00005F8C 81C3[04700000]      <1> 	add 	ebx, ttyl
 24972 00005F92 88C6                <1> 	mov 	dh, al ; tty number
 24973 00005F94 668B03              <1> 	mov 	ax, [ebx]
 24974                              <1> 		   ; AL = lock value (0 or process number)
 24975                              <1> 		   ; AH = open count 
 24976 00005F97 20E4                <1> 	and 	ah, ah
 24977 00005F99 750F                <1> 	jnz	short ctty_ret
 24978 00005F9B C705[2C710000]0A00- <1>         mov     dword [u.error], ERR_DEV_NOT_OPEN
 24979 00005FA3 0000                <1>
 24980                              <1> 			; device not open ! error
 24981                              <1> 	;jmp 	short ctty_err ; open count = 0, it is not open !
 24982 00005FA5 E92CDDFFFF          <1> 	jmp	error
 24983                              <1> 	; 26/01/2014
 24984                              <1> ctty_ret:
 24985 00005FAA FECC                <1> 	dec 	ah ; decrease open count
 24986 00005FAC 7502                <1> 	jnz	short ctty_1
 24987 00005FAE 30C0                <1> 	xor	al, al ; unlock/free tty
 24988                              <1> ctty_1:
 24989 00005FB0 668903              <1> 	mov 	[ebx], ax ; close tty instance
 24990                              <1> 	;
 24991 00005FB3 BB[EE700000]        <1> 	mov	ebx, u.ttyp
 24992                              <1> 	;test	dl, 1 ; open for write sign
 24993                              <1> 	;jz	short ctty_2
 24994                              <1> 	; 05/12/2021
 24995 00005FB8 F6C202              <1> 	test	dl, 2 ; open for write sign
 24996 00005FBB 7401                <1> 	jz	short ctty_2	
 24997 00005FBD 43                  <1> 	inc	ebx
 24998                              <1> ctty_2:
 24999 00005FBE FEC6                <1> 	inc	dh ; tty number + 1
 25000 00005FC0 3A33                <1> 	cmp	dh, [ebx]
 25001 00005FC2 7503                <1> 	jne	short cret
 25002                              <1> 	; Reset/Clear 'u.ttyp' ('the recent TTY') value
 25003 00005FC4 C60300              <1> 	mov	byte [ebx], 0
 25004                              <1> cret:
 25005 00005FC7 08D2                <1> 	or	dl, dl ; sysstty system call check (DL=0)
 25006 00005FC9 7401                <1> 	jz	short ctty_3
 25007                              <1> 	;pop	ax
 25008                              <1> 	; 05/12/2021
 25009 00005FCB 58                  <1> 	pop	eax
 25010                              <1> ctty_3:
 25011 00005FCC C3                  <1> 	retn
 25012                              <1> 
 25013                              <1> ;ctty_err: ; 13/01/2014
 25014                              <1> ;	or 	dl, dl ; DL = 0 -> called by sysstty
 25015                              <1> ;	jnz	error
 25016                              <1> ;	stc
 25017                              <1> ;	retn
 25018                              <1> 
 25019                              <1> 	; Original UNIX v1 'ctty' routine:
 25020                              <1> 	;	
 25021                              <1>         ;mov    tty+[ntty*8]-8+6,r5 
 25022                              <1> 	;		;/ point r5 to the console tty buffer
 25023                              <1>         ;decb   (r5) / dec number of processes using console tty
 25024                              <1>         ;br     sret / return via sret
 25025                              <1> 
 25026                              <1> ;ccvt:	; < close tty >
 25027                              <1> 	; 21/05/2013 - 13/01/2014 (Retro UNIX 8086 v1)
 25028                              <1> 	;
 25029                              <1> 	; Retro UNIX 8086 v1 modification !
 25030                              <1> 	; 
 25031                              <1> 	; In original UNIX v1, 'ccvt' routine 
 25032                              <1> 	;		(exactly different than this one)
 25033                              <1> 	;	was in 'u9.s' file.
 25034                              <1> 	;
 25035                              <1> 	; DL = 2 -> it is open for reading
 25036                              <1> 	; DL = 1 -> it is open for writing
 25037                              <1> 	;
 25038                              <1> 	; 17/09/2013
 25039                              <1> 	;sub 	al, 10
 25040                              <1> 	;cmp	al, 7
 25041                              <1> 	;jna	short cttyp
 25042                              <1> 	; 13/01/2014
 25043                              <1> 	;jmp	short cttyp
 25044                              <1> 
 25045                              <1> ;cppt: / close paper tape
 25046                              <1> ;        clrb   pptiflg / set pptiflg to indicate file not open
 25047                              <1> ;1:
 25048                              <1> ;        mov    $240,*$ps /set process or priority to 5
 25049                              <1> ;        jsr    r0,getc; 2 / remove all ppt input entries from clist
 25050                              <1> ;                          / and assign to free list
 25051                              <1> ;               br sret
 25052                              <1> ;        br     1b
 25053                              <1> 
 25054                              <1> ;ejec:	
 25055                              <1> ;	jmp	error
 25056                              <1> ;/ejec:
 25057                              <1> ;/       mov    $100,*$lps / set line printer interrupt enable bit
 25058                              <1> ;/       mov    $14,r1 / 'form feed' character in r1 (new page).
 25059                              <1> ;/       jsr    r0,lptoc / space the printer to a new page
 25060                              <1> ;/       br     sret / return to caller via 'sret'
 25061                                  %include 'u8.s'      ; 11/06/2015
 25062                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 25063                              <1> ; (re-write kernel for test by using previous version without a major defect)
 25064                              <1> ; ****************************************************************************
 25065                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS8.INC
 25066                              <1> ; Last Modification: 29/11/2021
 25067                              <1> ; ----------------------------------------------------------------------------
 25068                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 25069                              <1> ; (v0.1 - Beginning: 11/07/2012)
 25070                              <1> ;
 25071                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 25072                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 25073                              <1> ; <Bell Laboratories (17/3/1972)>
 25074                              <1> ; <Preliminary Release of UNIX Implementation Document>
 25075                              <1> ;
 25076                              <1> ; Retro UNIX 8086 v1 - U8.ASM (18/01/2014) //// UNIX v1 -> u8.s
 25077                              <1> ;
 25078                              <1> ; ****************************************************************************
 25079                              <1> 
 25080                              <1> ;; I/O Buffer - Retro UNIX 386 v1 modification
 25081                              <1> ;;     (8+512 bytes, 8 bytes header, 512 bytes data)
 25082                              <1> ;; Word 1, byte 0 = device id
 25083                              <1> ;; Word 1, byte 1 = status bits (bits 8 to 15)
 25084                              <1> ;;          bit 9 = write bit
 25085                              <1> ;;	    bit 10 = read bit	  
 25086                              <1> ;;	    bit 12 = waiting to write bit	
 25087                              <1> ;;	    bit 13 = waiting to read bit
 25088                              <1> ;;	    bit 15 = inhibit bit
 25089                              <1> ;; Word 2 (byte 2 & byte 3) = reserved (for now - 07/06/2015)
 25090                              <1> ;; Word 3 + Word 4 (byte 4,5,6,7) = physical block number 
 25091                              <1> ;;		   (In fact, it is 32 bit LBA for Retro UNIX 386 v1)
 25092                              <1> ;;
 25093                              <1> ;; I/O Buffer ((8+512 bytes in original Unix v1))
 25094                              <1> ;;	      ((4+512 bytes in Retro UNIX 8086 v1))
 25095                              <1> ;;
 25096                              <1> ;; I/O Queue Entry (of original UNIX operating system v1)
 25097                              <1> ;; Word 1, Byte 0 = device id
 25098                              <1> ;; Word 1, Byte 1 = (bits 8 to 15)
 25099                              <1> ;;          bit 9 = write bit
 25100                              <1> ;;	    bit 10 = read bit	  
 25101                              <1> ;;	    bit 12 = waiting to write bit	
 25102                              <1> ;;	    bit 13 = waiting to read bit
 25103                              <1> ;;	    bit 15 = inhibit bit
 25104                              <1> ;; Word 2 = physical block number (In fact, it is LBA for Retro UNIX 8086 v1)
 25105                              <1> ;;
 25106                              <1> ;; Original UNIX v1 ->
 25107                              <1> ;;		Word 3 = number of words in buffer (=256) 		
 25108                              <1> ;; Original UNIX v1 -> 
 25109                              <1> ;;		Word 4 = bus address (addr of first word of data buffer)
 25110                              <1> ;;
 25111                              <1> ;; Retro UNIX 8086 v1 -> Buffer Header (I/O Queue Entry) size is 4 bytes !
 25112                              <1> ;;
 25113                              <1> ;; Device IDs (of Retro Unix 8086 v1)
 25114                              <1> ;;          0 = fd0
 25115                              <1> ;;	    1 = fd1
 25116                              <1> ;;	    2 = hd0
 25117                              <1> ;;	    3 = hd1
 25118                              <1> ;;	    4 = hd2
 25119                              <1> ;;	    5 = hd3
 25120                              <1> 
 25121                              <1> ; Retro UNIX 386 v1 - 32 bit modifications (rfd, wfd, rhd, whd) - 09/06/2015
 25122                              <1> 
 25123                              <1> rfd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25124                              <1> 	; 26/04/2013
 25125                              <1>    	; 13/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 25126                              <1>    	;sub 	ax, 3 ; zero based device number (Floppy disk)
 25127                              <1>       	;jmp 	short bread ; **** returns to routine that called readi			
 25128                              <1> 
 25129                              <1> rhd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25130                              <1> 	; 26/04/2013
 25131                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 25132                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 25133                              <1>    	;jmp	short bread ; **** returns to routine that called readi	
 25134                              <1> 
 25135                              <1> bread: 
 25136                              <1> 	; 14/07/2015
 25137                              <1> 	; 10/07/2015
 25138                              <1> 	; 09/06/2015
 25139                              <1> 	; 07/06/2015 (Retro UNIX 386 v1 - Beginning)
 25140                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 25141                              <1> 	;	
 25142                              <1> 	; / read a block from a block structured device
 25143                              <1> 	;
 25144                              <1> 	; INPUTS ->
 25145                              <1> 	;    [u.fopf] points to the block number
 25146                              <1> 	;    CX = maximum block number allowed on device
 25147                              <1> 	;	 ; that was an arg to bread, in original Unix v1, but
 25148                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 25149                              <1> 	;    [u.count]	number of bytes to read in
 25150                              <1> 	; OUTPUTS ->
 25151                              <1> 	;    [u.base] starting address of data block or blocks in user area  	
 25152                              <1> 	;    [u.fopf] points to next consecutive block to be read
 25153                              <1> 	;
 25154                              <1> 	; ((Modified registers: eAX, eDX, eCX, eBX, eSI, eDI, eBP))
 25155                              <1> 	;
 25156                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if read
 25157                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 25158                              <1> 	;	is increased by 1. For example: If user/program request 
 25159                              <1> 	;       to read 16 bytes in current block, 'sys read' increases
 25160                              <1> 	;  	the next block number just as 512 byte reading is done.
 25161                              <1> 	;       This wrong is done in 'bread'. So, in Retro UNIX 8086 v1, 
 25162                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 25163                              <1> 	;       enough to keep byte position/offset of the disk), this
 25164                              <1> 	;	defect will not be corrected, user/program must request
 25165                              <1> 	;	512 byte read per every 'sys read' call to block devices
 25166                              <1> 	;       for achieving correct result. In future version(s), 
 25167                              <1> 	;	this defect will be corrected by using different 
 25168                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 25169                              <1> 
 25170                              <1> 	   	; jsr r0,tstdeve / error on special file I/O 
 25171                              <1> 			       ; / (only works on tape)
 25172                              <1> 		; mov *u.fofp,r1 / move block number to r1
 25173                              <1> 		; mov $2.-cold,-(sp) / "2-cold" to stack
 25174                              <1> ;1:
 25175                              <1> 		; cmp r1,(r0) / is this block # greater than or equal to
 25176                              <1> 			    ; / maximum block # allowed on device
 25177                              <1> 		; jnb short @f
 25178                              <1> 		; bhis	1f / yes, 1f (error)
 25179                              <1> 		; mov r1,-(sp) / no, put block # on stack
 25180                              <1> 		; jsr r0,preread / read in the block into an I/O buffer
 25181                              <1> 		; mov (sp)+,r1 / return block # to r1
 25182                              <1> 		; inc r1 / bump block # to next consecutive block
 25183                              <1> 		; dec (sp) / "2-1-cold" on stack
 25184                              <1> 		; bgt 1b / 2-1-cold = 0?  No, go back and read in next block
 25185                              <1> ;1:
 25186                              <1> 		; tst (sp)+ / yes, pop stack to clear off cold calculation
 25187                              <1> 	;push	ecx ; **
 25188                              <1> 	;26/04/2013
 25189                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 25190 00005FCD 2C03                <1> 	sub	al, 3
 25191                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 25192 00005FCF A2[2B710000]        <1> 	mov	[u.brwdev], al
 25193                              <1> 	; 09/06/2015
 25194 00005FD4 0FB6D8              <1> 	movzx	ebx, al
 25195 00005FD7 8B8B[DE6A0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 25196                              <1> bread_0:
 25197 00005FDD 51                  <1> 	push	ecx ; ** ; 09/06/2015 
 25198                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 25199                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 25200 00005FDE 8B1D[C8700000]      <1> 	mov	ebx, [u.fofp]
 25201 00005FE4 8B03                <1> 	mov	eax, [ebx]
 25202 00005FE6 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 25203                              <1> 		; mov *u.fofp,r1 / restore r1 to initial value of the
 25204                              <1> 			       ; / block #
 25205 00005FE9 39C8                <1> 	cmp	eax, ecx
 25206                              <1> 		; cmp r1,(r0)+ / block # greater than or equal to maximum
 25207                              <1>        	                     ; / block number allowed
 25208                              <1> 	;jnb	error 	     ; 18/04/2013
 25209                              <1> 		; bhis error10 / yes, error
 25210 00005FEB 720F                <1> 	jb	short bread_1
 25211 00005FED C705[2C710000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 25212 00005FF5 0000                <1>
 25213 00005FF7 E9DADCFFFF          <1> 	jmp	error
 25214                              <1> bread_1:
 25215                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 25216                              <1> 		; inc *u.fofp / no, *u.fofp has next block number
 25217                              <1> 	; eAX = Block number (zero based)
 25218                              <1> 		;;jsr r0,preread / read in the block whose number is in r1
 25219                              <1> preread: ;; call preread
 25220 00005FFC BF[2B710000]        <1> 	mov	edi, u.brwdev ; block device number for direct I/O
 25221 00006001 E86B020000          <1> 	call	bufaloc_0 ; 26/04/2013
 25222                              <1> 	;; jc 	error
 25223                              <1> 	; eBX = Buffer (Header) Address -Physical-
 25224                              <1>         ; eAX = Block/Sector number (r1)
 25225                              <1> 	       ; jsr r0,bufaloc / get a free I/O buffer (r1 has block number)
 25226                              <1> 	; 14/03/2013
 25227 00006006 740A                <1>         jz	short bread_2 ; Retro UNIX 8086 v1 modification
 25228                              <1>        		; br 1f / branch if block already in a I/O buffer
 25229 00006008 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 25230                              <1>         	; bis $2000,(r5) / set read bit (bit 10 in I/O buffer)
 25231 0000600D E8B3010000          <1> 	call	poke
 25232                              <1>         	; jsr r0,poke / perform the read
 25233                              <1> 	;;jc	error ;2 0/07/2013
 25234                              <1> ; 1:
 25235                              <1>  		; clr *$ps / ps = 0
 25236                              <1>         	; rts r0
 25237                              <1> ;; return from preread
 25238                              <1> bread_2:
 25239 00006012 66810B0040          <1> 	or	word [ebx], 4000h 
 25240                              <1> 		; bis $40000,(r5) 
 25241                              <1> 			; / set bit 14 of the 1st word of the I/O buffer
 25242                              <1> bread_3: ; 1:
 25243 00006017 66F7030024          <1> 	test	word [ebx], 2400h
 25244                              <1> 		; bit $22000,(r5) / are 10th and 13th bits set (read bits)
 25245 0000601C 7407                <1> 	jz	short bread_4
 25246                              <1> 		; beq 1f / no
 25247                              <1> 		; cmp cdev,$1 / disk or drum?
 25248                              <1> 		; ble 2f / yes
 25249                              <1> 		; tstb uquant / is the time quantum = 0?
 25250                              <1> 		; bne 2f / no, 2f
 25251                              <1> 		; mov r5,-(sp) / yes, save r5 (buffer address)
 25252                              <1> 		; jsr r0,sleep; 31. 
 25253                              <1> 			; / put process to sleep in channel 31 (tape)
 25254                              <1> 		; mov (sp)+,r5 / restore r5
 25255                              <1> 		; br 1b / go back
 25256                              <1> ; 2: / drum or disk
 25257                              <1>         ;; mov     cx, [s.wait_]+2 ;; 29/07/2013
 25258 0000601E E802F1FFFF          <1> 	call	idle
 25259                              <1> 		; jsr r0,idle; s.wait+2 / wait
 25260 00006023 EBF2                <1> 	jmp	short bread_3
 25261                              <1>        		; br 1b
 25262                              <1> bread_4: ; 1: / 10th and 13th bits not set
 25263 00006025 668123FFBF          <1> 	and	word [ebx], 0BFFFh ; 1011111111111111b
 25264                              <1> 		; bic $40000,(r5) / clear bit 14
 25265                              <1>        		; jsr r0,tstdeve / test device for error (tape)
 25266 0000602A 83C308              <1> 	add	ebx, 8
 25267                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 25268                              <1> 	; 09/06/2015
 25269 0000602D 66833D[24710000]00  <1> 	cmp	word [u.pcount], 0
 25270 00006035 7705                <1> 	ja	short bread_5
 25271 00006037 E846F9FFFF          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
 25272                              <1> bread_5:
 25273                              <1> 	; eBX = system (I/O) buffer address
 25274 0000603C E870000000          <1> 	call	dioreg
 25275                              <1>        		; jsr r0,dioreg / do bookkeeping on u.count etc.
 25276                              <1> 	; esi =  start address of the transfer (in the buffer)
 25277                              <1> 	; edi =  [u.pbase], destination address in user's memory space
 25278                              <1> 	; ecx =  transfer count (in bytes)
 25279                              <1> 	;
 25280                              <1> ;1: / r5 points to beginning of data in I/O buffer, r2 points to beginning
 25281                              <1> ;   / of users data
 25282 00006041 F3A4                <1> 	rep	movsb
 25283                              <1> 		; movb (r5)+,(r2)+ / move data from the I/O buffer
 25284                              <1>        		; dec r3 / to the user's area in core starting at u.base
 25285                              <1>        		; bne 1b
 25286 00006043 59                  <1> 	pop	ecx ; **
 25287 00006044 833D[E0700000]00    <1> 	cmp	dword [u.count], 0
 25288                              <1> 		; tst u.count / done
 25289 0000604B 7790                <1> 	ja	short bread_0 ; 09/06/2015
 25290                              <1>        		; beq 1f / yes, return
 25291                              <1> 		; tst -(r0) / no, point r0 to the argument again
 25292                              <1>        		; br bread / read some more
 25293                              <1> ; 1:
 25294 0000604D 58                  <1> 	pop	eax ; ****
 25295                              <1>        		; mov (sp)+,r0
 25296 0000604E C3                  <1>         retn		; 09/06/2015
 25297                              <1> 	;jmp     ret_ 
 25298                              <1> 		;jmp ret  / jump to routine that called readi
 25299                              <1> 
 25300                              <1> wfd:    ; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25301                              <1> 	; 26/04/2013
 25302                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 25303                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 25304                              <1>    	;jmp	short bwrite ; **** returns to routine that called writei
 25305                              <1> 				
 25306                              <1> whd:	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25307                              <1>    	; 14/03/2013 Retro UNIX 8086 v1 device (not an original unix v1 device)	
 25308                              <1>    	;sub 	ax, 3 ; zero based device number (Hard disk)
 25309                              <1>    	;jmp 	short bwrite ; **** returns to routine that called writei ('jmp ret')
 25310                              <1> 
 25311                              <1> bwrite: 
 25312                              <1> 	; 14/07/2015
 25313                              <1> 	; 10/07/2015
 25314                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25315                              <1> 	; 14/03/2013 - 20/07/2013 (Retro UNIX 8086 v1)
 25316                              <1> 	;	
 25317                              <1> 	;; / write on block structured device
 25318                              <1> 	;
 25319                              <1> 	; INPUTS ->
 25320                              <1> 	;    [u.fopf] points to the block number
 25321                              <1> 	;    CX = maximum block number allowed on device
 25322                              <1> 	;	 ; that was an arg to bwrite, in original Unix v1, but
 25323                              <1> 	;	 ; CX register is used instead of arg in Retro Unix 8086 v1 		
 25324                              <1> 	;    [u.count]	number of bytes to user desires to write
 25325                              <1> 	; OUTPUTS ->
 25326                              <1> 	;    [u.fopf] points to next consecutive block to be written into
 25327                              <1> 	;
 25328                              <1> 	; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))
 25329                              <1> 	;
 25330                              <1> 	; NOTE: Original UNIX v1 has/had a defect/bug here, even if write
 25331                              <1> 	;       byte count is less than 512, block number in *u.fofp (u.off)
 25332                              <1> 	;	is increased by 1. For example: If user/program request 
 25333                              <1> 	;       to write 16 bytes in current block, 'sys write' increases
 25334                              <1> 	;  	the next block number just as 512 byte writing is done.
 25335                              <1> 	;       This wrong is done in 'bwrite'. So, in Retro UNIX 8086 v1, 
 25336                              <1> 	;       for user (u) structure compatibility (because 16 bit is not
 25337                              <1> 	;       enough to keep byte position/offset of the disk), this
 25338                              <1> 	;	defect will not be corrected, user/program must request
 25339                              <1> 	;	512 byte write per every 'sys write' call to block devices
 25340                              <1> 	;       for achieving correct result. In future version(s), 
 25341                              <1> 	;	this defect will be corrected by using different 
 25342                              <1> 	;       user (u) structure.  26/07/2013 - Erdogan Tan 	
 25343                              <1> 
 25344                              <1>        		; jsr r0,tstdeve / test the device for an error
 25345                              <1> 	;push	ecx ; **
 25346                              <1> 	;26/04/2013
 25347                              <1> 	;sub	ax, 3 ; 3 to 8 -> 0 to 5
 25348 0000604F 2C03                <1> 	sub	al, 3
 25349                              <1> 		; AL = Retro Unix 8086 v1 disk (block device) number
 25350 00006051 A2[2B710000]        <1> 	mov	[u.brwdev], al
 25351                              <1> 	; 09/06/2015
 25352 00006056 0FB6D8              <1> 	movzx	ebx, al
 25353 00006059 8B8B[DE6A0000]      <1> 	mov	ecx, [ebx+drv.size] ; disk size (in sectors)
 25354                              <1> bwrite_0:
 25355 0000605F 51                  <1> 	push	ecx ; ** ; 09/06/2015
 25356                              <1> 	; 10/07/2015 (Retro UNIX 386 v1 modification!)
 25357                              <1> 	; [u.fopf] points to byte position in disk, not sector/block !
 25358 00006060 8B1D[C8700000]      <1> 	mov	ebx, [u.fofp]
 25359 00006066 8B03                <1> 	mov	eax, [ebx]       
 25360 00006068 C1E809              <1> 	shr	eax, 9 ; convert byte position to block/sector number
 25361                              <1> 		; mov *u.fofp,r1 / put the block number in r1
 25362 0000606B 39C8                <1> 	cmp	eax, ecx
 25363                              <1> 		; cmp r1,(r0)+ / does block number exceed maximum allowable #
 25364                              <1>        	                     ; / block number allowed
 25365                              <1> 	;jnb	error	     ; 18/04/2013
 25366                              <1> 		; bhis error10 / yes, error
 25367 0000606D 720F                <1>      	jb	short bwrite_1
 25368 0000606F C705[2C710000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE  ; 'out of volume' error	
 25369 00006077 0000                <1>
 25370 00006079 E958DCFFFF          <1> 	jmp	error
 25371                              <1> bwrite_1:
 25372                              <1> 	; inc 	dword [ebx] ; 10/07/2015 (Retro UNIX 386 v1 - modification!)
 25373                              <1> 		; inc *u.fofp / no, increment block number
 25374                              <1> 	; 09/06/2015 - 10/07/2015
 25375 0000607E 66833D[24710000]00  <1> 	cmp	word [u.pcount], 0
 25376 00006086 7705                <1> 	ja	short bwrite_2
 25377 00006088 E8F1F8FFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
 25378                              <1> bwrite_2:
 25379 0000608D BF[2B710000]        <1> 	mov	edi, u.brwdev  ; block device number for direct I/O
 25380 00006092 E8C4000000          <1>        	call	bwslot ; 26/04/2013 (wslot -> bwslot)	 				
 25381                              <1> 		; jsr r0,wslot / get an I/O buffer to write into
 25382                              <1> 		; add $8,r5 / r5 points to data in I/O buffer
 25383 00006097 E815000000          <1>         call	dioreg
 25384                              <1> 		; jsr r0,dioreg / do the necessary bookkeeping
 25385                              <1> 	; esi =  destination address (in the buffer)
 25386                              <1> 	; edi =  [u.pbase], start address of transfer in user's memory space
 25387                              <1> 	; ecx =  transfer count (in bytes)
 25388                              <1> ; 1: / r2 points to the users data; r5 points to the I/O buffers data area
 25389 0000609C 87F7                <1> 	xchg 	esi, edi ; 14/07/2015
 25390 0000609E F3A4                <1> 	rep	movsb
 25391                              <1> 		; movb (r2)+,(r5)+ / ; r3, has the byte count
 25392                              <1>        		; dec r3 / area to the I/O buffer
 25393                              <1>        		; bne 1b
 25394 000060A0 E8FE000000          <1> 	call	dskwr
 25395                              <1> 		; jsr r0,dskwr / write it out on the device
 25396 000060A5 59                  <1> 	pop	ecx ; **
 25397 000060A6 833D[E0700000]00    <1>         cmp     dword [u.count], 0
 25398                              <1> 		; tst u.count / done
 25399 000060AD 77B0                <1> 	ja	short bwrite_0 ; 09/06/2015
 25400                              <1> 		; beq 1f / yes, 1f
 25401                              <1> 		; tst -(r0) / no, point r0 to the argument of the call
 25402                              <1>        		; br bwrite / go back and write next block
 25403                              <1> ; 1:
 25404 000060AF 58                  <1> 	pop	eax ; ****
 25405                              <1>        		; mov (sp)+,r0
 25406 000060B0 C3                  <1> 	retn		; 09/06/2015
 25407                              <1>         ;jmp     ret_ 
 25408                              <1> 		; jmp ret / return to routine that called writei
 25409                              <1> ;error10:
 25410                              <1> ;       jmp     error  ; / see 'error' routine
 25411                              <1> 
 25412                              <1> dioreg:
 25413                              <1> 	; 14/07/2015
 25414                              <1> 	; 10/07/2015 (UNIX v1 bugfix - [u.fofp]: byte pos., not block)
 25415                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25416                              <1> 	; 14/03/2013 (Retro UNIX 8086 v1)
 25417                              <1> 	;	
 25418                              <1> 	; bookkeeping on block transfers of data
 25419                              <1> 	;
 25420                              <1> 	; * returns value of u.pbase before it gets updated, in EDI
 25421                              <1> 	; * returns byte count (to transfer) in ECX (<=512)
 25422                              <1> 	; 10/07/2015
 25423                              <1> 	; * returns byte offset from beginning of current sector buffer
 25424                              <1> 	; (beginning of data) in ESI
 25425                              <1> 	;
 25426 000060B1 8B0D[E0700000]      <1> 	mov	ecx, [u.count]
 25427                              <1> 		; mov u.count,r3 / move char count to r3
 25428 000060B7 81F900020000        <1>        	cmp 	ecx, 512
 25429                              <1> 		; cmp r3,$512. / more than 512. char?
 25430 000060BD 7605                <1> 	jna	short dioreg_0
 25431                              <1> 		; blos 1f / no, branch
 25432 000060BF B900020000          <1> 	mov	ecx, 512
 25433                              <1> 		; mov $512.,r3 / yes, just take 512.
 25434                              <1> dioreg_0:
 25435                              <1> 	; 09/06/2015
 25436 000060C4 663B0D[24710000]    <1> 	cmp	cx, [u.pcount]
 25437 000060CB 7607                <1> 	jna	short dioreg_1
 25438 000060CD 668B0D[24710000]    <1> 	mov	cx, [u.pcount]
 25439                              <1> dioreg_1:
 25440                              <1> ; 1:
 25441 000060D4 8B15[DC700000]      <1> 	mov	edx, [u.base] ; 09/06/2015 (eax -> edx)
 25442                              <1> 	        ; mov u.base,r2 / put users base in r2
 25443 000060DA 010D[E4700000]      <1> 	add	[u.nread], ecx
 25444                              <1> 		; add r3,u.nread / add the number to be read to u.nread
 25445 000060E0 290D[E0700000]      <1> 	sub	[u.count], ecx
 25446                              <1> 		; sub r3,u.count / update count
 25447 000060E6 010D[DC700000]      <1> 	add	[u.base], ecx
 25448                              <1> 		; add r3,u.base / update base
 25449                              <1> 	; 10/07/2015
 25450                              <1> 	; Retro UNIX 386 v1 - modification !
 25451                              <1> 	; (File pointer points to byte position, not block/sector no.)
 25452                              <1> 	; (It will point to next byte position instead of next block no.)
 25453 000060EC 8B35[C8700000]      <1> 	mov	esi, [u.fofp] ; u.fopf points to byte position pointer  
 25454 000060F2 8B06                <1> 	mov	eax, [esi] ; esi points to current byte pos. on the disk
 25455 000060F4 010E                <1> 	add	[esi], ecx ; ecx is added to set the next byte position
 25456 000060F6 25FF010000          <1> 	and	eax, 1FFh  ; get offset from beginning of current block	
 25457 000060FB 89DE                <1> 	mov	esi, ebx   ; beginning of data in sector/block buffer
 25458 000060FD 01C6                <1> 	add	esi, eax   ; esi contains start address of the transfer
 25459                              <1> 	; 09/06/2015 - 10/07/2015
 25460 000060FF 66290D[24710000]    <1> 	sub	[u.pcount], cx
 25461 00006106 81E2FF0F0000        <1> 	and	edx, PAGE_OFF ; 0FFFh
 25462 0000610C 8B3D[20710000]      <1> 	mov	edi, [u.pbase]
 25463 00006112 81E700F0FFFF        <1> 	and	edi, ~PAGE_OFF
 25464 00006118 01D7                <1> 	add	edi, edx
 25465 0000611A 893D[20710000]      <1> 	mov	[u.pbase], edi
 25466 00006120 010D[20710000]      <1> 	add	[u.pbase], ecx ; 14/07/2015
 25467 00006126 C3                  <1> 	retn
 25468                              <1> 		; rts r0 / return
 25469                              <1> 
 25470                              <1> dskrd:
 25471                              <1> 	; 18/08/2015
 25472                              <1> 	; 02/07/2015
 25473                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25474                              <1> 	; 14/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 25475                              <1> 	;
 25476                              <1> 	; 'dskrd' acquires an I/O buffer, puts in the proper
 25477                              <1> 	; I/O queue entries (via bufaloc) then reads a block
 25478                              <1> 	; (number specified in r1) in the acquired buffer.)
 25479                              <1> 	; If the device is busy at the time dskrd is called,	
 25480                              <1> 	; dskrd calls idle.
 25481                              <1> 	; 
 25482                              <1> 	; INPUTS ->
 25483                              <1> 	;    r1 - block number
 25484                              <1> 	;    cdev - current device number 
 25485                              <1> 	; OUTPUTS ->
 25486                              <1> 	;    r5 - points to first data word in I/O buffer
 25487                              <1> 	;
 25488                              <1> 	; ((AX = R1)) input/output
 25489                              <1> 	; ((BX = R5)) output 
 25490                              <1> 	;
 25491                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
 25492                              <1> 	;
 25493 00006127 E837010000          <1> 	call 	bufaloc
 25494                              <1> 		; jsr r0,bufaloc / shuffle off to bufaloc; 
 25495                              <1> 			       ; / get a free I/O buffer
 25496                              <1> 	;;jc	error ; 20/07/2013
 25497 0000612C 741B                <1> 	jz	short dskrd_1 ; Retro UNIX 8086 v1 modification
 25498                              <1>        		; br 1f / branch if block already in a I/O buffer
 25499                              <1> dskrd_0: ; 10/07/2015 (wslot)
 25500 0000612E 66810B0004          <1> 	or	word [ebx], 400h ; set read bit (10) in I/O Buffer
 25501                              <1>         	; bis $2000,(r5) / set bit 10 of word 1 of 
 25502                              <1> 		               ; / I/O queue entry for buffer
 25503 00006133 E88D000000          <1> 	call	poke
 25504                              <1> 		; jsr r0,poke / just assigned in bufaloc, 
 25505                              <1> 			    ; /	bit 10=1 says read
 25506                              <1> 	; 09/06/2015
 25507 00006138 730F                <1> 	jnc	short dskrd_1
 25508                              <1> 	;
 25509 0000613A C705[2C710000]1100- <1> 	mov	dword [u.error], ERR_DRV_READ ; disk read error !
 25510 00006142 0000                <1>
 25511 00006144 E98DDBFFFF          <1> 	jmp	error
 25512                              <1> dskrd_1: ; 1:
 25513                              <1>        		;clr *$ps
 25514 00006149 66F7030024          <1>        	test	word [ebx], 2400h
 25515                              <1> 		; bit $22000,(r5) / if either bits 10, or 13 are 1; 
 25516                              <1> 				; / jump to idle
 25517 0000614E 7407                <1>        	jz	short dskrd_2
 25518                              <1> 		; beq 1f
 25519                              <1>         ;;mov   ecx, [s.wait_]
 25520 00006150 E8D0EFFFFF          <1>        	call	idle
 25521                              <1> 		; jsr r0,idle; s.wait+2
 25522 00006155 EBF2                <1> 	jmp 	short dskrd_1
 25523                              <1>        		; br 1b
 25524                              <1> dskrd_2: ; 1:
 25525 00006157 83C308              <1>         add	ebx, 8
 25526                              <1> 		; add $8,r5 / r5 points to first word of data in block 
 25527                              <1> 			  ; / just read in
 25528 0000615A C3                  <1>        	retn
 25529                              <1> 		; rts r0
 25530                              <1> 
 25531                              <1> bwslot:
 25532                              <1> 	; 10/07/2015
 25533                              <1> 	;	If the block/sector is not placed in a buffer
 25534                              <1> 	;	before 'wslot', it must be read before
 25535                              <1> 	;	it is written! (Otherwise transfer counts less
 25536                              <1> 	;	than 512 bytes will be able to destroy existing 
 25537                              <1> 	;	data on disk.)
 25538                              <1> 	;
 25539                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 25540                              <1> 	; 26/04/2013(Retro UNIX 8086 v1)
 25541                              <1> 	; Retro UNIX 8086 v1 modification !
 25542                              <1> 	; ('bwslot' will be called from 'bwrite' only!)
 25543                              <1> 	; INPUT -> eDI - points to device id (in u.brwdev)	
 25544                              <1> 	;	-> eAX = block number
 25545                              <1> 	;
 25546 0000615B E811010000          <1> 	call	bufaloc_0
 25547 00006160 742A                <1> 	jz	short wslot_0 ; block/sector already is in the buffer
 25548                              <1> bwslot_0:
 25549                              <1> 	; 10/07/2015
 25550 00006162 8B35[C8700000]      <1> 	mov	esi, [u.fofp]
 25551 00006168 8B06                <1> 	mov	eax, [esi]
 25552 0000616A 25FF010000          <1> 	and	eax, 1FFh ; offset from beginning of the sector/block
 25553 0000616F 750C                <1> 	jnz 	short bwslot_1 ; it is not a full sector write
 25554                              <1> 		       ; recent disk data must be placed in the buffer
 25555 00006171 813D[E0700000]0002- <1> 	cmp	dword [u.count], 512
 25556 00006179 0000                <1>
 25557 0000617B 730F                <1> 	jnb	short wslot_0	
 25558                              <1> bwslot_1:
 25559 0000617D E8ACFFFFFF          <1> 	call	dskrd_0
 25560 00006182 83EB08              <1> 	sub	ebx, 8 ; set ebx to the buffer header address again	
 25561 00006185 EB05                <1> 	jmp 	short wslot_0
 25562                              <1> 
 25563                              <1> wslot:
 25564                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 25565                              <1> 	; 		(32 bit modifications)
 25566                              <1> 	; 14/03/2013 - 29/07/2013(Retro UNIX 8086 v1)
 25567                              <1> 	;
 25568                              <1> 	; 'wslot' calls 'bufaloc' and obtains as a result, a pointer
 25569                              <1> 	; to the I/O queue of an I/O buffer for a block structured
 25570                              <1> 	; device. It then checks the first word of I/O queue entry.	
 25571                              <1> 	; If bits 10 and/or 13 (read bit, waiting to read bit) are set,
 25572                              <1> 	; wslot calls 'idle'. When 'idle' returns, or if bits 10 
 25573                              <1> 	; and/or 13 are not set, 'wslot' sets bits 9 and 15 of the first
 25574                              <1> 	; word of the I/O queue entry (write bit, inhibit bit).
 25575                              <1> 	;
 25576                              <1> 	; INPUTS ->
 25577                              <1>  	;    r1 - block number
 25578                              <1> 	;    cdev - current (block/disk) device number
 25579                              <1>  	;
 25580                              <1> 	; OUTPUTS ->
 25581                              <1> 	;    bufp - bits 9 and 15 are set, 
 25582                              <1> 	;           the remainder of the word left unchanged
 25583                              <1> 	;    r5 - points to first data word in I/O buffer
 25584                              <1> 	;
 25585                              <1> 	; ((AX = R1)) input/output
 25586                              <1> 	; ((BX = R5)) output 
 25587                              <1> 	;
 25588                              <1>         ; ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP)) 
 25589                              <1> 
 25590 00006187 E8D7000000          <1> 	call	bufaloc
 25591                              <1> 	; 10/07/2015
 25592                              <1> 		; jsr r0,bufaloc / get a free I/O buffer; pointer to first
 25593                              <1>         	; br 1f / word in buffer in r5
 25594                              <1> 	; eBX = Buffer (Header) Address (r5) (ES=CS=DS, system/kernel segment)
 25595                              <1>         ; eAX = Block/Sector number (r1)
 25596                              <1> wslot_0: ;1:
 25597 0000618C 66F7030024          <1>      	test	word [ebx], 2400h
 25598                              <1> 		; bit $22000,(r5) / check bits 10, 13 (read, waiting to read)
 25599                              <1> 				; / of I/O queue entry
 25600 00006191 7407                <1> 	jz	short wslot_1
 25601                              <1>                 ; beq 1f  / branch if 10, 13 zero (i.e., not reading, 
 25602                              <1> 		     ; / or not waiting to read)
 25603                              <1> 
 25604                              <1>         ;; mov     ecx, [s.wait_] ; 29/07/2013
 25605 00006193 E88DEFFFFF          <1> 	call	idle
 25606                              <1> 		; jsr r0,idle; / if buffer is reading or writing to read,
 25607                              <1>        	                     ; / idle
 25608 00006198 EBF2                <1> 	jmp	short wslot_0
 25609                              <1> 		; br 1b / till finished
 25610                              <1> wslot_1: ;1:
 25611 0000619A 66810B0082          <1>         or      word [ebx], 8200h
 25612                              <1>        		; bis $101000,(r5) / set bits 9, 15 in 1st word of I/O queue
 25613                              <1>                             	 ; / (write, inhibit bits)
 25614                              <1>        		; clr     *$ps / clear processor status
 25615 0000619F 83C308              <1>         add	ebx, 8 ; 11/06/2015
 25616                              <1> 		; add $8,r5 / r5 points to first word in data area 
 25617                              <1> 			  ; / for this block
 25618 000061A2 C3                  <1>        	retn
 25619                              <1> 		; rts r0
 25620                              <1> dskwr:
 25621                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25622                              <1> 	; 14/03/2013 - 03/08/2013 (Retro UNIX 8086 v1)
 25623                              <1> 	;
 25624                              <1> 	; 'dskwr' writes a block out on disk, via ppoke. The only
 25625                              <1> 	; thing dskwr does is clear bit 15 in the first word of I/O queue
 25626                              <1> 	; entry pointed by 'bufp'. 'wslot' which must have been called
 25627                              <1> 	; previously has supplied all the information required in the
 25628                              <1> 	; I/O queue entry.
 25629                              <1> 	;
 25630                              <1> 	; (Modified registers: eCX, eDX, eBX, eSI, eDI)
 25631                              <1> 	;
 25632                              <1> 	;
 25633 000061A3 8B1D[70700000]      <1> 	mov	ebx, [bufp]
 25634 000061A9 668123FF7F          <1> 	and	word [ebx], 7FFFh ; 0111111111111111b
 25635                              <1> 		; bic $100000,*bufp / clear bit 15 of I/O queue entry at
 25636                              <1>                                   ; / bottom of queue
 25637 000061AE E812000000          <1> 	call	poke
 25638                              <1> 	; 09/06/2015
 25639 000061B3 730F                <1> 	jnc	short dskwr_1
 25640 000061B5 C705[2C710000]1200- <1> 	mov	dword [u.error], ERR_DRV_WRITE ; disk write error !
 25641 000061BD 0000                <1>
 25642 000061BF E912DBFFFF          <1> 	jmp	error
 25643                              <1> dskwr_1:
 25644 000061C4 C3                  <1> 	retn
 25645                              <1> 
 25646                              <1> 
 25647                              <1> ;ppoke:
 25648                              <1>        		; mov $340,*$ps
 25649                              <1>        		; jsr r0,poke
 25650                              <1>        		; clr *$ps
 25651                              <1> 		; rts r0
 25652                              <1> poke:
 25653                              <1> 	; 29/11/2021 (32 bit push-pop)
 25654                              <1> 	; 24/10/2015
 25655                              <1> 	; 20/08/2015
 25656                              <1> 	; 18/08/2015
 25657                              <1> 	; 02/07/2015
 25658                              <1> 	; 09/06/2015 (Retro UNIX 386 v1 - Beginning)
 25659                              <1> 	; 15/03/2013 - 18/01/2014 (Retro UNIX 8086 v1)
 25660                              <1> 	;
 25661                              <1> 	; (NOTE: There are some disk I/O code modifications & extensions
 25662                              <1> 	; & exclusions on original 'poke' & other device I/O procedures of 
 25663                              <1> 	; UNIX v1 OS for performing disk I/O functions by using IBM PC 
 25664                              <1> 	; compatible rombios calls in Retro UNIX 8086 v1 kernel.)
 25665                              <1> 	;
 25666                              <1> 	; Basic I/O functions for all block structured devices
 25667                              <1> 	;
 25668                              <1>         ; (Modified registers: eCX, eDX, eSI, eDI)
 25669                              <1> 	;
 25670                              <1> 	; 20/07/2013 modifications
 25671                              <1> 	;            (Retro UNIX 8086 v1 features only !)
 25672                              <1> 	; INPUTS -> 
 25673                              <1> 	;        (EBX = buffer header address)
 25674                              <1> 	; OUTPUTS ->
 25675                              <1> 	;	 cf=0 -> successed r/w (at least, for the caller's buffer) 
 25676                              <1> 	;	 cf=1 -> error, word [eBX] = 0FFFFh
 25677                              <1> 	;		(drive not ready or r/w error!)
 25678                              <1> 	;	 (dword [EBX+4] <> 0FFFFFFFFh indicates r/w success)	
 25679                              <1> 	;	 (dword [EBx+4] = 0FFFFFFFFh means RW/IO error)
 25680                              <1> 	;        (also it indicates invalid buffer data)
 25681                              <1> 	;
 25682 000061C5 53                  <1> 	push	ebx
 25683                              <1>        		; mov r1,-(sp)
 25684                              <1>        		; mov r2,-(sp)
 25685                              <1>        		; mov r3,-(sp)
 25686 000061C6 50                  <1> 	push 	eax ; Physical Block Number (r1) (mget)
 25687                              <1> 	;
 25688                              <1> 	; 09/06/2015
 25689                              <1> 	; (permit read/write after a disk R/W error)
 25690 000061C7 8A0B                <1> 	mov	cl, [ebx] ; device id (0 to 5)
 25691 000061C9 B001                <1> 	mov	al, 1
 25692 000061CB D2E0                <1> 	shl	al, cl
 25693 000061CD 8405[98700000]      <1> 	test 	al, [active] ; busy ? (error)
 25694 000061D3 7408                <1> 	jz	short poke_0
 25695 000061D5 F6D0                <1> 	not	al
 25696 000061D7 2005[98700000]      <1> 	and	[active], al ; reset busy bit for this device only
 25697                              <1> poke_0:
 25698 000061DD BE[90700000]        <1>         mov     esi, bufp + (4*(nbuf+2)) 
 25699                              <1> 		; mov $bufp+nbuf+nbuf+6,r2 / r2 points to highest priority
 25700                              <1> 					 ; / I/O queue pointer
 25701                              <1> poke_1: ; 1:
 25702 000061E2 83EE04              <1>         sub	esi, 4
 25703 000061E5 8B1E                <1> 	mov	ebx, [esi]
 25704                              <1> 		; mov -(r2),r1 / r1 points to an I/O queue entry
 25705 000061E7 668B03              <1> 	mov	ax, [ebx] ; 17/07/2013
 25706 000061EA F6C406              <1>        	test	ah, 06h
 25707                              <1> 	;test	word [ebx], 600h ; 0000011000000000b
 25708                              <1> 		; bit $3000,(r1) / test bits 9 and 10 of word 1 of I/O 
 25709                              <1> 			       ; / queue entry
 25710 000061ED 745C                <1>         jz      short poke_5
 25711                              <1> 		; beq 2f / branch to 2f if both are clear
 25712                              <1> 	; 31/07/2013
 25713                              <1> 	;test	ah, 0B0h ; (*)
 25714                              <1> 	;;test	word [ebx], 0B000h ; 1011000000000000b
 25715                              <1> 		; bit $130000,(r1) / test bits 12, 13, and 15
 25716                              <1>         ;jnz     short poke_5 ; 31/07/2013 (*)
 25717                              <1> 		; bne 2f / branch if any are set
 25718                              <1> 	;movzx	ecx, byte [ebx] ; 09/06/2015 ; Device Id
 25719                              <1>     		; movb (r1),r3 / get device id
 25720 000061EF 0FB6C8              <1> 	movzx	ecx, al ; 18/08/2015
 25721                              <1> 	;mov	edi, ecx ; 26/04/2013
 25722 000061F2 31C0                <1> 	xor 	eax, eax ; 0
 25723                              <1> 	;cmp 	[edi+drv.error], al ; 0
 25724                              <1> 		; tstb deverr(r3) / test for errors on this device
 25725                              <1>        	;jna	short poke_2 
 25726                              <1> 		; beq 3f / branch if no errors
 25727                              <1> 	; 02/07/2015
 25728                              <1> 	;dec	eax
 25729                              <1> 	;mov	[ebx+4], ax ; 0FFFFFFFFh ; -1 
 25730                              <1>        		; mov $-1,2(r1) / destroy associativity
 25731                              <1> 	;shr	eax, 24
 25732                              <1> 	;mov	[ebx], eax ; 000000FFh, reset
 25733                              <1> 		; clrb 1(r1) / do not do I/O
 25734                              <1> 	;jmp     short poke_5
 25735                              <1>         ;       ; br 2f
 25736                              <1>                 ; rts r0
 25737                              <1> poke_2: ; 3:
 25738                              <1> 	; 02/07/2015
 25739 000061F4 FEC1                <1> 	inc	cl ; 0FFh -> 0
 25740 000061F6 7453                <1> 	jz	short poke_5
 25741 000061F8 FEC0                <1> 	inc	al ; mov ax, 1
 25742 000061FA FEC9                <1> 	dec	cl
 25743 000061FC 7402                <1> 	jz	short poke_3
 25744                              <1> 	; 26/04/2013 Modification
 25745                              <1> 	;inc	al ; mov ax, 1
 25746                              <1> 	;or	cl, cl ; Retro UNIX 8086 v1 device id.
 25747                              <1> 	;jz	short poke_3 ; cl = 0
 25748 000061FE D2E0                <1> 	shl	al, cl ; shl ax, cl
 25749                              <1> poke_3:
 25750                              <1> 	;test	[active], ax
 25751 00006200 8405[98700000]      <1> 	test	[active], al
 25752                              <1> 		; bit $2,active / test disk busy bit
 25753 00006206 7543                <1> 	jnz     short poke_5
 25754                              <1> 		; bne 2f / branch if bit is set
 25755                              <1> 	;or	[active], ax
 25756 00006208 0805[98700000]      <1> 	or	[active], al
 25757                              <1> 		; bis $2,active / set disk busy bit
 25758 0000620E 50                  <1> 	push	eax ; 29/11/2021
 25759 0000620F E8D3000000          <1> 	call	diskio ; Retro UNIX 8086 v1 Only !
 25760                              <1> 	;mov    [edi+drv.error], ah
 25761 00006214 58                  <1> 	pop	eax
 25762 00006215 730E                <1> 	jnc	short poke_4 ; 20/07/2013
 25763                              <1> 	;cmp 	[edi+drv.error], al ; 0	
 25764                              <1> 	;jna	short poke_4
 25765                              <1> 		; tstb deverr(r3) / test for errors on this device
 25766                              <1>        		; beq 3f / branch if no errors
 25767                              <1> 	; 02/07/2015 (32 bit modification)
 25768                              <1> 	; 20/07/2013
 25769 00006217 C74304FFFFFFFF      <1> 	mov	dword [ebx+4], 0FFFFFFFFh ; -1 
 25770                              <1>        		; mov $-1,2(r1) / destroy associativity
 25771 0000621E 66C703FF00          <1> 	mov	word [ebx], 0FFh ; 20/08/2015 
 25772                              <1> 		; clrb 1(r1) / do not do I/O
 25773 00006223 EB26                <1> 	jmp     short poke_5
 25774                              <1> poke_4:	; 20/07/2013
 25775                              <1> 	; 17/07/2013
 25776 00006225 F6D0                <1> 	not 	al 
 25777 00006227 2005[98700000]      <1> 	and	[active], al ; reset, not busy
 25778                              <1> 	; eBX = system I/O buffer header (queue entry) address
 25779                              <1> seta: ; / I/O queue bookkeeping; set read/write waiting bits.
 25780 0000622D 668B03              <1> 	mov	ax, [ebx]
 25781                              <1>        		; mov (r1),r3 / move word 1 of I/O queue entry into r3
 25782 00006230 66250006            <1>         and	ax, 600h
 25783                              <1> 		; bic $!3000,r3 / clear all bits except 9 and 10
 25784 00006234 668123FFF9          <1> 	and 	word [ebx], 0F9FFh
 25785                              <1>        		; bic $3000,(r1) / clear only bits 9 and 10
 25786 00006239 C0E403              <1> 	shl	ah, 3
 25787                              <1>        		; rol r3
 25788                              <1>                 ; rol r3
 25789                              <1>                 ; rol r3	
 25790 0000623C 660903              <1> 	or	[ebx], ax
 25791                              <1> 		; bis r3,(r1) / or old value of bits 9 and 10 with 
 25792                              <1> 			   ; bits 12 and 13
 25793 0000623F E8E1EEFFFF          <1> 	call	idle ; 18/01/2014
 25794                              <1> 	;; sti
 25795                              <1> 	;hlt 	; wait for a hardware interrupt
 25796                              <1> 	;; cli
 25797                              <1> 	; NOTE: In fact, disk controller's 'disk I/O completed' 
 25798                              <1>         ; interrupt would be used to reset busy bits, but INT 13h
 25799                              <1> 	; returns when disk I/O is completed. So, here, as temporary
 25800                              <1> 	; method, this procedure will wait for a time according to
 25801                              <1> 	; multi tasking and time sharing concept.
 25802                              <1> 	;
 25803                              <1> 	; 24/10/2015
 25804                              <1> 	;not	ax 
 25805 00006244 66B8FF00            <1> 	mov 	ax, 0FFh ; 24/10/2015 (temporary)
 25806 00006248 662103              <1> 	and	[ebx], ax ; clear bits 12 and 13
 25807                              <1> poke_5: ;2:
 25808 0000624B 81FE[70700000]      <1>         cmp     esi, bufp
 25809                              <1> 		; cmp r2,$bufp / test to see if entire I/O queue 
 25810                              <1>                             ; / has been scanned
 25811 00006251 778F                <1> 	ja      short poke_1
 25812                              <1> 		; bhi 1b
 25813                              <1> 	; 24/03/2013
 25814                              <1>        		; mov (sp)+,r3
 25815                              <1>        		; mov (sp)+,r2
 25816                              <1>        		; mov (sp)+,r1
 25817 00006253 58                  <1>         pop 	eax  ; Physical Block Number (r1) (mget)
 25818 00006254 5B                  <1> 	pop 	ebx
 25819                              <1> 	; 02/07/2015 (32 bit modification)
 25820                              <1> 	; 20/07/2013
 25821                              <1> 	;cmp 	dword [ebx+4], 0FFFFFFFFh
 25822 00006255 803BFF              <1> 	cmp	byte [ebx], 0FFh ; 20/08/2015
 25823                              <1> 	;	
 25824                              <1> 	; 'poke' returns with cf=0 if the requested buffer is read 
 25825                              <1> 	; or written succesfully; even if an error occurs while
 25826                              <1> 	; reading to or writing from other buffers. 20/07/2013
 25827                              <1> 	;
 25828                              <1> 	; 09/06/2015
 25829 00006258 F5                  <1> 	cmc
 25830 00006259 C3                  <1> 	retn
 25831                              <1>                 ; rts r0
 25832                              <1> 
 25833                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatibility code
 25834                              <1> get_system_time:
 25835                              <1> 	; 27/10/2021
 25836                              <1> 	; 21/02/2020 - Retro UNIX 386 v2
 25837                              <1> 	; get system time
 25838                              <1> 	;  (from recent value which is saved in RTC interrupt)
 25839                              <1> 	; Input:
 25840                              <1> 	; 	none
 25841                              <1> 	; Return:
 25842                              <1> 	;   	eax = system time in unix epoch format 
 25843                              <1> 	;
 25844                              <1> 	; Modified registers: eax, ecx, edx
 25845                              <1> 	
 25846                              <1> 	; 27/11/2021
 25847 0000625A 53                  <1> 	push	ebx
 25848 0000625B E899D5FFFF          <1> 	call	epoch
 25849 00006260 5B                  <1> 	pop	ebx
 25850 00006261 C3                  <1> 	retn
 25851                              <1> 
 25852                              <1> get_serial_number:
 25853                              <1> 	; temporary - 21/02/2020
 25854                              <1> 	; 26/04/2020 (esi)
 25855                              <1> 	; 25/04/2020
 25856                              <1> 	; (Possible) Modified registers: eax, ecx, edx
 25857                              <1> 	; (edi, ebx & esi registers must be preserved)
 25858                              <1> 	; Return:
 25859                              <1> 	; eax = 32 bit serial number  
 25860                              <1> 	; (edx = high 32 bit of 64 bit serial number)
 25861                              <1> 	; -64 bit serial numbers will not be used in RUNIX 386 v2-
 25862 00006262 C3                  <1> 	retn
 25863                              <1> 
 25864                              <1> bufaloc:
 25865                              <1> 	; 20/08/2015
 25866                              <1> 	; 19/08/2015
 25867                              <1> 	; 02/07/2015
 25868                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 25869                              <1> 	;	     (32 bit modifications)	
 25870                              <1> 	; 13/03/2013 - 29/07/2013 (Retro UNIX 8086 v1)
 25871                              <1> 	;
 25872                              <1> 	; bufaloc - Block device I/O buffer allocation
 25873                              <1> 	; 
 25874                              <1> 	; INPUTS ->
 25875                              <1> 	;    r1 - block number
 25876                              <1> 	;    cdev - current (block/disk) device number
 25877                              <1> 	;    bufp+(2*n)-2 --- n = 1 ... nbuff
 25878                              <1> 	; OUTPUTS ->
 25879                              <1> 	;    r5 - pointer to buffer allocated
 25880                              <1> 	;    bufp ... bufp+12 --- (bufp), (bufp)+2
 25881                              <1> 	;
 25882                              <1> 	; ((AX = R1)) input/output
 25883                              <1> 	; ((BX = R5)) output
 25884                              <1>         ;    ((Modified registers: DX, CX, BX, SI, DI, BP))
 25885                              <1> 	;    zf=1 -> block already in a I/O buffer
 25886                              <1> 	;    zf=0 -> a new I/O buffer has been allocated
 25887                              <1> 	;    ((DL = Device ID))
 25888                              <1> 	;    (((DH = 0 or 1)))
 25889                              <1> 	;    (((CX = previous value of word ptr [bufp])))
 25890                              <1> 	;    ((CX and DH will not be used after return)))
 25891                              <1> 
 25892                              <1> 	;;push 	esi ; ***
 25893                              <1> 		; mov r2,-(sp) / save r2 on stack
 25894                              <1>        		; mov $340,*$ps / set processor priority to 7
 25895                              <1> 	; 20/07/2013
 25896                              <1> 	; 26/04/2013
 25897 00006263 0FB61D[95700000]    <1> 	movzx	ebx, byte [cdev] ; 0 or 1
 25898 0000626A BF[96700000]        <1> 	mov	edi, rdev  ; offset mdev = offset rdev + 1
 25899 0000626F 01DF                <1> 	add	edi, ebx
 25900                              <1> bufaloc_0: ; 26/04/2013 !! here is called from bread or bwrite !!
 25901                              <1> 			;; eDI points to device id.
 25902 00006271 0FB61F              <1> 	movzx	ebx, byte [edi] ; [EDI] -> rdev/mdev or brwdev
 25903                              <1> 	; 11/06/20215
 25904 00006274 80BB[FA6A0000]F0    <1> 	cmp 	byte [ebx+drv.status], 0F0h ; Drive not ready !
 25905 0000627B 720F                <1> 	jb	short bufaloc_9
 25906 0000627D C705[2C710000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 25907 00006285 0000                <1>
 25908 00006287 E94ADAFFFF          <1> 	jmp	error
 25909                              <1> bufaloc_9:
 25910 0000628C 89DA                <1> 	mov	edx, ebx ; dh = 0, dl = device number (0 to 5)
 25911                              <1> bufaloc_10: ; 02/07/2015
 25912 0000628E 31ED                <1> 	xor 	ebp, ebp ; 0
 25913 00006290 55                  <1> 	push	ebp ; 0
 25914 00006291 89E5                <1>         mov     ebp, esp	
 25915                              <1> 	;
 25916                              <1> bufaloc_1: ;1:
 25917                              <1> 		; clr -(sp) / vacant buffer
 25918 00006293 BE[70700000]        <1>         mov 	esi, bufp
 25919                              <1> 		; mov $bufp,r2 / bufp contains pointers to I/O queue 
 25920                              <1> 			     ; / entrys in buffer area
 25921                              <1> bufaloc_2: ;2:
 25922 00006298 8B1E                <1> 	mov	ebx, [esi]
 25923                              <1>        		; mov (r2)+,r5 / move pointer to word 1 of an I/O 
 25924                              <1> 			    ; queue entry into r5
 25925 0000629A 66F70300F6          <1> 	test	word [ebx], 0F600h
 25926                              <1> 		; bit $173000,(r5) / lock+keep+active+outstanding
 25927 0000629F 7503                <1>         jnz	short bufaloc_3
 25928                              <1> 		; bne 3f / branch when 
 25929                              <1> 		       ; / any of bits 9,10,12,13,14,15 are set
 25930                              <1>                        ; / (i.e., buffer busy)
 25931 000062A1 897500              <1>         mov     [ebp], esi ; pointer to I/0 queue entry
 25932                              <1>                 ; mov  r2,(sp) ;/ save pointer to last non-busy buffer
 25933                              <1> 			; / found points to word 2 of I/O queue entry)
 25934                              <1> bufaloc_3: ;3:
 25935                              <1> 	;mov	dl, [edi] ; 26/04/2013
 25936                              <1> 	;
 25937 000062A4 3813                <1> 	cmp	[ebx], dl	
 25938                              <1> 		; cmpb (r5),cdev / is device in I/O queue entry same 
 25939                              <1> 			       ; / as current device
 25940 000062A6 7508                <1> 	jne	short bufaloc_4
 25941                              <1>        		; bne 3f
 25942 000062A8 394304              <1> 	cmp	[ebx+4], eax
 25943                              <1>        		; cmp 2(r5),r1 / is block number in I/O queue entry, 
 25944                              <1> 			     ; / same as current block number
 25945 000062AB 7503                <1>        	jne	short bufaloc_4
 25946                              <1> 		; bne 3f
 25947                              <1> 	;add	esp, 4
 25948 000062AD 59                  <1> 	pop	ecx
 25949                              <1>        		; tst (sp)+ / bump stack pointer
 25950 000062AE EB20                <1> 	jmp	short bufaloc_7 ; Retro Unix 8086 v1 modification
 25951                              <1> 				; jump to bufaloc_6 in original Unix v1
 25952                              <1>        		; br 1f / use this buffer
 25953                              <1> bufaloc_4: ;3:
 25954 000062B0 83C604              <1> 	add	esi, 4 ; 20/08/2015
 25955                              <1> 	;
 25956 000062B3 81FE[88700000]      <1> 	cmp	esi, bufp + (nbuf*4)
 25957                              <1> 		; cmp r2,$bufp+nbuf+nbuf
 25958 000062B9 72DD                <1> 	jb	short bufaloc_2
 25959                              <1> 		; blo 2b / go to 2b if r2 less than bufp+nbuf+nbuf (all
 25960                              <1>                        ; / buffers not checked)
 25961 000062BB 5E                  <1>         pop	esi
 25962                              <1> 		; mov (sp)+,r2 / once all bufs are examined move pointer
 25963                              <1> 			     ; / to last free block
 25964 000062BC 09F6                <1>        	or	esi, esi 
 25965 000062BE 7507                <1> 	jnz	short bufaloc_5
 25966                              <1> 		; bne 2f / if (sp) is non zero, i.e., 
 25967                              <1> 	        ; / if a free buffer is found branch to 2f
 25968                              <1>         ;; mov  ecx, [s.wait_]
 25969 000062C0 E860EEFFFF          <1> 	call	idle
 25970                              <1> 		; jsr r0,idle; s.wait+2 / idle if no free buffers
 25971 000062C5 EBC7                <1> 	jmp 	short bufaloc_10 ; 02/07/2015
 25972                              <1>        		; br 1b
 25973                              <1> bufaloc_5: ;2:
 25974                              <1> 		; tst (r0)+ / skip if warmed over buffer
 25975 000062C7 FEC6                <1> 	inc	dh ; Retro UNIX 8086 v1 modification
 25976                              <1> bufaloc_6: ;1:
 25977 000062C9 8B1E                <1>         mov    	ebx, [esi] 
 25978                              <1> 		; mov -(r2),r5 / put pointer to word 1 of I/O queue 
 25979                              <1> 			     ; / entry in r5
 25980                              <1> 	;; 26/04/2013
 25981                              <1>         ;mov	dl, [edi] ; byte [rdev] or byte [mdev]
 25982 000062CB 8813                <1> 	mov 	[ebx], dl
 25983                              <1> 		; movb cdev,(r5) / put current device number 
 25984                              <1> 				 ; / in I/O queue entry
 25985 000062CD 894304              <1> 	mov 	[ebx+4], eax
 25986                              <1> 		; mov r1,2(r5) / move block number into word 2 
 25987                              <1> 			     ; / of I/O queue entry
 25988                              <1> bufaloc_7: ;1:
 25989 000062D0 81FE[70700000]      <1>         cmp	esi, bufp
 25990                              <1> 		; cmp r2,$bufp / bump all entrys in bufp 
 25991                              <1> 			     ; / and put latest assigned
 25992 000062D6 760A                <1> 	jna	short bufaloc_8	
 25993                              <1>        		; blos 1f / buffer on the top 
 25994                              <1> 			; / (this makes if the lowest priority)
 25995 000062D8 83EE04              <1> 	sub	esi, 4
 25996 000062DB 8B0E                <1> 	mov	ecx, [esi]
 25997 000062DD 894E04              <1> 	mov	[esi+4], ecx
 25998                              <1> 		; mov -(r2),2(r2) / job for a particular device
 25999 000062E0 EBEE                <1> 	jmp 	short bufaloc_7        
 26000                              <1> 		; br 1b
 26001                              <1> bufaloc_8: ;1:
 26002 000062E2 891E                <1>         mov	[esi], ebx
 26003                              <1> 		; mov r5,(r2)
 26004                              <1> 	;;pop	esi ; ***
 26005                              <1>        		; mov (sp)+,r2 / restore r2
 26006 000062E4 08F6                <1>        	or 	dh, dh ; 0 or 1 ?
 26007                              <1> 		; Retro UNIX 8086 v1 modification
 26008                              <1> 		; zf=1 --> block already is in an I/O buffer
 26009                              <1> 		; zf=0 --> a new I/O buffer has been allocated
 26010 000062E6 C3                  <1> 	retn
 26011                              <1> 		; rts r0
 26012                              <1> 
 26013                              <1> diskio:
 26014                              <1> 	; 28/11/2021
 26015                              <1> 	; 10/07/2015
 26016                              <1> 	; 02/07/2015
 26017                              <1> 	; 16/06/2015
 26018                              <1> 	; 11/06/2015 (Retro UNIX 386 v1 - Beginning)
 26019                              <1> 	;	     (80386 protected mode modifications)	
 26020                              <1> 	; 15/03/2013 - 29/04/2013 (Retro UNIX 8086 v1)
 26021                              <1> 	;
 26022                              <1> 	; Retro UNIX 8086 v1 feature only !
 26023                              <1> 	;
 26024                              <1> 	; Derived from proc_chs_read procedure of TRDOS DISKIO.ASM (2011)
 26025                              <1> 	; 04/07/2009 - 20/07/2011
 26026                              <1> 	;
 26027                              <1> 	; NOTE: Reads only 1 block/sector (sector/block size is 512 bytes)
 26028                              <1> 	;
 26029                              <1>         ; INPUTS ->
 26030                              <1> 	; 	   ebx = System I/O Buffer header address
 26031                              <1> 	;
 26032                              <1>         ; OUTPUTS -> cf=0 --> done 
 26033                              <1> 	; 	     cf=1 ---> error code in AH
 26034                              <1> 	;
 26035                              <1> 	; (Modified registers: eax, ecx, edx)
 26036                              <1> 	
 26037                              <1> ;rw_disk_sector:
 26038                              <1> 	; 28/11/2021
 26039                              <1> 	; 10/07/2015
 26040                              <1> 	; 02/07/2015
 26041                              <1> 	; 11/06/2015 - Retro UNIX 386 v1 - 'u8.s' 
 26042                              <1> 	; 21/02/2015 ('dsectpm.s', 'read_disk_sector')
 26043                              <1> 	; 16/02/2015 (Retro UNIX 386 v1 test - 'unix386.s')
 26044                              <1> 	; 01/12/2014 - 18/01/2015 ('dsectrm2.s')
 26045                              <1> 	;
 26046                              <1> 	;mov	dx, 0201h ; Read 1 sector/block
 26047 000062E7 B602                <1> 	mov	dh, 2
 26048                              <1> 	;mov	ax, [ebx]
 26049                              <1> 	; 28/11/2021
 26050 000062E9 8B03                <1> 	mov	eax, [ebx]
 26051                              <1> 	;
 26052 000062EB 56                  <1> 	push	esi ; ****
 26053 000062EC 53                  <1> 	push	ebx ; ***
 26054                              <1> 	;
 26055 000062ED 0FB6C8              <1> 	movzx	ecx, al
 26056                              <1> 	; 28/11/2021
 26057                              <1> 	;mov	ecx, eax
 26058 000062F0 89CE                <1> 	mov	esi, ecx
 26059                              <1> 	;
 26060 000062F2 38F1                <1> 	cmp	cl, dh ; 2
 26061 000062F4 7202                <1> 	jb	short rwdsk0
 26062 000062F6 047E                <1> 	add	al, 7Eh  ; 80h, 81h, 82h, 83h
 26063                              <1> rwdsk0:
 26064 000062F8 A2[AB6A0000]        <1> 	mov	[drv], al
 26065 000062FD 81C6[FA6A0000]      <1> 	add	esi, drv.status
 26066                              <1> 	; 11/06/2015
 26067 00006303 803EF0              <1> 	cmp	byte [esi], 0F0h 
 26068 00006306 720F                <1> 	jb      short rwdsk1
 26069                              <1> 	; 'drive not ready' error
 26070 00006308 C705[2C710000]0F00- <1> 	mov	dword [u.error], ERR_DRV_NOT_RDY
 26071 00006310 0000                <1>
 26072 00006312 E9BFD9FFFF          <1> 	jmp	error
 26073                              <1> rwdsk1:
 26074 00006317 F6C402              <1> 	test	ah, 2
 26075                              <1> 	;test	ax, 200h ; Bit 9 of word 0 (status word)
 26076                              <1> 			 ; write bit
 26077 0000631A 7402                <1> 	jz	short rwdsk2
 26078                              <1> 	;test	ah, 4
 26079                              <1> 	;;test	ax, 400h ; Bit 10 of word 0 (status word)
 26080                              <1> 	;		 ; read bit
 26081                              <1> 	;jz	short diskio_ret
 26082 0000631C FEC6                <1> 	inc	dh ; 03h = write
 26083                              <1> rwdsk2:
 26084 0000631E 88C2                <1> 	mov	dl, al
 26085 00006320 83C304              <1> 	add	ebx, 4 ; sector/block address/number pointer
 26086 00006323 8B03                <1> 	mov	eax, [ebx] ; sector/block number (LBA)
 26087 00006325 C0E102              <1> 	shl	cl, 2
 26088 00006328 81C1[DE6A0000]      <1> 	add	ecx, drv.size ; disk size
 26089 0000632E 3B01                <1> 	cmp	eax, [ecx] ; Last sector + 1 (number of secs.)
 26090 00006330 720F                <1> 	jb      short rwdsk3
 26091                              <1>  	; 'out of volume' error
 26092 00006332 C705[2C710000]1000- <1> 	mov 	dword [u.error], ERR_DEV_VOL_SIZE 	
 26093 0000633A 0000                <1>
 26094 0000633C E995D9FFFF          <1> 	jmp	error
 26095                              <1> rwdsk3:
 26096                              <1> 	; 11/06/2015
 26097 00006341 83C304              <1> 	add	ebx, 4 ; buffer address
 26098 00006344 C605[F7710000]04    <1> 	mov	byte [retry_count], 4
 26099 0000634B F60601              <1> 	test	byte [esi], 1 ; LBA ready ?
 26100 0000634E 7432                <1>         jz      short rwdsk_chs
 26101                              <1> rwdsk_lba:
 26102                              <1> 	; LBA read/write (with private LBA function) 
 26103                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
 26104 00006350 83C607              <1>         add     esi, drv.error - drv.status ; 10/07/2015
 26105 00006353 89C1                <1> 	mov	ecx, eax ; sector number
 26106                              <1> 	; ebx = buffer (data) address
 26107                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
 26108                              <1> rwdsk_lba_retry:
 26109                              <1> 	;mov	dl, [drv]
 26110                              <1> 		; Function 1Bh = LBA read, 1Ch = LBA write
 26111 00006355 B419                <1> 	mov	ah, 1Ch - 03h ; LBA write function number - 3
 26112 00006357 00F4                <1> 	add	ah, dh		
 26113 00006359 B001                <1> 	mov	al, 1
 26114                              <1> 	;int	13h
 26115 0000635B E8F7C3FFFF          <1> 	call	int13h
 26116 00006360 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 26117 00006362 730E                <1> 	jnc	short rwdsk_lba_ok
 26118 00006364 80FC80              <1> 	cmp	ah, 80h ; time out ?
 26119 00006367 7408                <1>         je      short rwdsk_lba_fails
 26120 00006369 FE0D[F7710000]      <1> 	dec	byte [retry_count]
 26121 0000636F 7504                <1>         jnz     short rwdsk_lba_reset ; 10/07/2015
 26122                              <1> rwdsk_lba_fails:
 26123 00006371 F9                  <1> 	stc
 26124                              <1> rwdsk_lba_ok:
 26125 00006372 5B                  <1> 	pop	ebx ; ***
 26126 00006373 5E                  <1> 	pop	esi ; ****
 26127 00006374 C3                  <1> 	retn
 26128                              <1> rwdsk_lba_reset:
 26129 00006375 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 26130                              <1> 	;int	13h
 26131 00006377 E8DBC3FFFF          <1>         call	int13h
 26132 0000637C 73D7                <1> 	jnc     short rwdsk_lba_retry
 26133 0000637E 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 26134 00006380 EBF0                <1> 	jmp	short rwdsk_lba_ok
 26135                              <1> 	;
 26136                              <1> 	; CHS read (convert LBA address to CHS values)	
 26137                              <1> rwdsk_chs:
 26138                              <1> 	; 10/07/2015
 26139 00006382 81EE[FA6A0000]      <1> 	sub	esi, drv.status
 26140 00006388 89F1                <1> 	mov	ecx, esi
 26141 0000638A 81C6[016B0000]      <1> 	add 	esi, drv.error
 26142                              <1> 	; 02/07/2015
 26143                              <1> 	; 16/06/2015
 26144                              <1>  	; 11/06/2015 
 26145 00006390 53                  <1> 	push	ebx ; ** ; buffer
 26146 00006391 D1E1                <1> 	shl	ecx, 1
 26147 00006393 51                  <1> 	push	ecx ; * 
 26148                              <1> 	;
 26149 00006394 89CB                <1> 	mov	ebx, ecx
 26150 00006396 8835[F5710000]      <1> 	mov	[rwdsk], dh ; 02/07/2015
 26151 0000639C 31D2                <1> 	xor	edx, edx ; 0
 26152 0000639E 29C9                <1> 	sub	ecx, ecx 
 26153 000063A0 81C3[D06A0000]      <1>         add     ebx, drv.spt
 26154 000063A6 668B0B              <1> 	mov	cx, [ebx] ; sector per track
 26155                              <1> 		; EDX:EAX = LBA
 26156                              <1> ; 28/11/2021 - temporary
 26157 000063A9 09C9                <1> or ecx, ecx
 26158 000063AB 7515                <1> jnz short bunugec1
 26159 000063AD 50                  <1> push	eax
 26160 000063AE B44E                <1> mov	ah, 4Eh
 26161 000063B0 B021                <1> mov	al, '!'
 26162 000063B2 66A300800B00        <1> mov	[0B8000h], ax
 26163 000063B8 B9FFFFFF0F          <1> mov	ecx, 0FFFFFFFh
 26164                              <1> above4:
 26165 000063BD 4A                  <1> dec	edx
 26166 000063BE 42                  <1> inc	edx
 26167 000063BF E2FC                <1> loop	above4
 26168 000063C1 58                  <1> pop	eax
 26169                              <1> 
 26170                              <1> bunugec1: 
 26171                              <1> 
 26172 000063C2 F7F1                <1> 	div	ecx
 26173 000063C4 88D1                <1> 	mov	cl, dl	; sector number - 1
 26174 000063C6 FEC1                <1> 	inc	cl	; sector number (1 based)
 26175 000063C8 5B                  <1> 	pop	ebx ; * ; 11/06/2015
 26176 000063C9 51                  <1> 	push	ecx ; 28/11/2021
 26177 000063CA 81C3[C26A0000]      <1>         add     ebx, drv.heads
 26178 000063D0 668B0B              <1> 	mov	cx, [ebx] ; heads
 26179 000063D3 31D2                <1> 	xor	edx, edx
 26180                              <1> 		; EAX = cylinders * heads + head
 26181 000063D5 F7F1                <1> 	div	ecx
 26182                              <1> 	;pop	cx     ; sector number
 26183 000063D7 59                  <1> 	pop	ecx ; 28/11/2021
 26184 000063D8 88D6                <1> 	mov	dh, dl ; head number
 26185 000063DA 8A15[AB6A0000]      <1> 	mov	dl, [drv]
 26186 000063E0 88C5                <1> 	mov	ch, al ; cylinder (bits 0-7)
 26187 000063E2 C0E406              <1> 	shl	ah, 6
 26188 000063E5 08E1                <1> 	or	cl, ah ; cylinder (bits 8-9)
 26189                              <1> 		       ; sector (bits 0-7)
 26190 000063E7 5B                  <1> 	pop	ebx ; ** ; buffer ; 11/06/2015
 26191                              <1> 		; CL = sector (bits 0-5)
 26192                              <1> 		;      cylinder (bits 8-9 -> bits 6-7)
 26193                              <1> 		; CH = cylinder (bits 0-7)
 26194                              <1> 		; DH = head
 26195                              <1> 		; DL = drive
 26196                              <1> 	;
 26197 000063E8 C605[F7710000]04    <1> 	mov	byte [retry_count], 4
 26198                              <1> rwdsk_retry:	
 26199 000063EF 8A25[F5710000]      <1> 	mov	ah, [rwdsk] ; 02h = read, 03h = write
 26200 000063F5 B001                <1> 	mov	al, 1 ; sector count	
 26201                              <1> 	;int	13h
 26202 000063F7 E85BC3FFFF          <1> 	call	int13h
 26203 000063FC 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 26204 000063FE 730E                <1> 	jnc	short rwdsk_ok ; ah = 0
 26205 00006400 80FC80              <1> 	cmp	ah, 80h ; time out ?
 26206 00006403 7408                <1> 	je	short rwdsk_fails
 26207 00006405 FE0D[F7710000]      <1> 	dec	byte [retry_count]
 26208 0000640B 7504                <1> 	jnz	short rwdsk_reset
 26209                              <1> rwdsk_fails:
 26210 0000640D F9                  <1> 	stc
 26211                              <1> rwdsk_ok:
 26212 0000640E 5B                  <1> 	pop	ebx ; ***
 26213 0000640F 5E                  <1> 	pop	esi ; ****
 26214 00006410 C3                  <1> 	retn
 26215                              <1> rwdsk_reset:
 26216                              <1> 	; 02/02/2015
 26217 00006411 28E4                <1> 	sub	ah, ah
 26218 00006413 80FA80              <1> 	cmp	dl, 80h
 26219 00006416 7202                <1> 	jb	short rwdsk_fd_reset
 26220 00006418 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
 26221                              <1> rwdsk_fd_reset:
 26222                              <1> 	;int	13h
 26223 0000641A E838C3FFFF          <1>         call	int13h
 26224 0000641F 73CE                <1> 	jnc	short rwdsk_retry
 26225 00006421 8826                <1> 	mov	[esi], ah ; error code ; 10/07/2015
 26226 00006423 EBE9                <1> 	jmp 	short rwdsk_ok
 26227                              <1> 
 26228                              <1> ; Original UNIX v1 - drum (& disk) interrupt routine
 26229                              <1> ;	(Equivalent to IRQ 14 & IRQ 15 disk/hardware interrupts)
 26230                              <1> ;
 26231                              <1> ; This feature is not used in Retro UNIX 386 (& 8086) for now.
 26232                              <1> ; Because, current Retro UNIX 386 disk I/O -INT13H- routine is 
 26233                              <1> ; derived from IBM PC AT -infact: XT286- BIOS source code, int 13h
 26234                              <1> ; that uses hardware -transfer has been completed-  interrupt inside it. 
 26235                              <1> ; In a next Retro UNIX 386 version, these interrupts
 26236                              <1> ; (fdc_int, hdc1_int, hdc2_int) will be handled by a separate routine
 26237                              <1> ; as in original unix v1.
 26238                              <1> ; I am not removing IBM BIOS source code derivatives -compatible code-
 26239                              <1> ; for now, regarding the new/next 32 bit TRDOS project by me
 26240                              <1> ; (to keep source code files easy adaptable to 32 bit TRDOS.)
 26241                              <1> ;
 26242                              <1> ; Erdogan tan (10/07/2015) 
 26243                              <1> 
 26244                              <1> ;drum: / interrupt handler
 26245                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 26246                              <1> ;       jsr     r0,trapt; dcs; rfap; 1 / check for stray interrupt or
 26247                              <1> ;                                      / error
 26248                              <1> ;               br 3f / no, error
 26249                              <1> ;       br      2f / error
 26250                              <1> ;
 26251                              <1> ;disk:
 26252                              <1> ;       jsr     r0,setisp / save r1,r2,r3, and clockp on the stack
 26253                              <1> ;       jmp     *$0f
 26254                              <1> ;0:
 26255                              <1> ;       jsr     r0,trapt; rkcs; rkap; 2
 26256                              <1> ;      	        br 3f / no, errors
 26257                              <1> ;       mov     $115,(r2) / drive reset, errbit was set
 26258                              <1> ;       mov     $1f,0b-2 / next time jmp *$0f is executed jmp will be
 26259                              <1> ;                        / to 1f
 26260                              <1> ;       br      4f
 26261                              <1> ;1:
 26262                              <1> ;       bit     $20000,rkcs
 26263                              <1> ;       beq     4f / wait for seek complete
 26264                              <1> ;       mov     $0b,0b-2
 26265                              <1> ;       mov     rkap,r1
 26266                              <1> ;2:
 26267                              <1> ;       bit     $3000,(r1) / are bits 9 or 10 set in the 1st word of
 26268                              <1> ;                          / the disk buffer
 26269                              <1> ;       bne     3f / no, branch ignore error if outstanding
 26270                              <1> ;       inc     r1
 26271                              <1> ;       asr     (r1)
 26272                              <1> ;       asr     (r1)
 26273                              <1> ;       asr     (r1) / reissue request
 26274                              <1> ;       dec     r1
 26275                              <1> ;3:
 26276                              <1> ;       bic     $30000,(r1) / clear bits 12 and 13 in 1st word of buffer
 26277                              <1> ;       mov     ac,-(sp)
 26278                              <1> ;       mov     mq,-(sp) / put these on the stack
 26279                              <1> ;       mov     sc,-(sp)
 26280                              <1> ;       jsr     r0,poke
 26281                              <1> ;       mov     (sp)+,sc
 26282                              <1> ;       mov     (sp)+,mq / pop them off stack
 26283                              <1> ;       mov     (sp)+,ac
 26284                              <1> ;4:
 26285                              <1> ;       jmp     retisp / u4-3
 26286                              <1> ;
 26287                              <1> ;trapt:                  / r2 points to the
 26288                              <1> ;       mov     (r0)+,r2 / device control register
 26289                              <1> ;       mov     *(r0)+,r1 / transaction pointer points to buffer
 26290                              <1> ;       tst     (sp)+
 26291                              <1> ;       tstb    (r2) / is ready bit of dcs set?
 26292                              <1> ;       bge     4b / device still active so branch
 26293                              <1> ;       bit     (r0),active / was device busy?
 26294                              <1> ;       beq     4b / no, stray interrupt
 26295                              <1> ;       bic     (r0)+,active / yes, set active to zero
 26296                              <1> ;       tst     (r2) / test the err(bit is) of dcs
 26297                              <1> ;       bge     2f / if no error jump to 2f
 26298                              <1> ;       tst     (r0)+ / skip on error
 26299                              <1> ; 2:
 26300                              <1> ;       jmp     (r0)
 26301                                  %include 'u9.s'      ; 29/06/2015
 26302                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 26303                              <1> ; (re-write kernel for test by using previous version without a major defect)
 26304                              <1> ; ****************************************************************************
 26305                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
 26306                              <1> ; Last Modification: 05/12/2021
 26307                              <1> ; ----------------------------------------------------------------------------
 26308                              <1> ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan
 26309                              <1> ; (v0.1 - Beginning: 11/07/2012)
 26310                              <1> ;
 26311                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 26312                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 26313                              <1> ; <Bell Laboratories (17/3/1972)>
 26314                              <1> ; <Preliminary Release of UNIX Implementation Document>
 26315                              <1> ;
 26316                              <1> ; Retro UNIX 8086 v1 - U9.ASM (01/09/2014) //// UNIX v1 -> u9.s
 26317                              <1> ;
 26318                              <1> ; ****************************************************************************
 26319                              <1> 
 26320                              <1> getch:
 26321                              <1> 	; 30/06/2015
 26322                              <1> 	; 18/02/2015 - Retro UNIX 386 v1 - feature only!
 26323 00006425 28C0                <1> 	sub	al, al ; 0
 26324                              <1> getch_q: ; 06/08/2015
 26325 00006427 8A25[E66F0000]      <1> 	mov 	ah, [ptty] ; active (current) video page
 26326 0000642D EB06                <1>         jmp     short getc_n
 26327                              <1> 
 26328                              <1> getc: 
 26329                              <1> 	; 12/11/2015
 26330                              <1> 	; 15/09/2015
 26331                              <1> 	; 01/07/2015
 26332                              <1> 	; 30/06/2015
 26333                              <1> 	; 18/02/2015 (Retro UNIX 386 v1 - Beginning)
 26334                              <1> 	; 13/05/2013 - 04/07/2014 (Retro UNIX 8086 v1)
 26335                              <1> 	;
 26336                              <1> 	; Retro UNIX 8086 v1 modification !
 26337                              <1> 	; 
 26338                              <1> 	; 'getc' gets (next) character 
 26339                              <1> 	;	 from requested TTY (keyboard) buffer 
 26340                              <1> 	; INPUTS ->
 26341                              <1> 	;     [u.ttyn] = tty number (0 to 7) (8 is COM1, 9 is COM2)	
 26342                              <1> 	;     AL=0 -> Get (next) character from requested TTY buffer
 26343                              <1> 	;	(Keyboard buffer will point to 
 26344                              <1> 	;			next character at next call)
 26345                              <1> 	;     AL=1 -> Test a key is available in requested TTY buffer
 26346                              <1> 	;	(Keyboard buffer will point to 
 26347                              <1> 	;			current character at next call)
 26348                              <1> 	; OUTPUTS ->
 26349                              <1> 	;     (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 26350                              <1> 	;     			 ZF=0 -> AX has (current) character
 26351                              <1> 	;      AL = ascii code
 26352                              <1> 	;      AH = scan code	(AH = line status for COM1 or COM2)	 			
 26353                              <1> 	; 		        (cf=1 -> error code/flags in AH)
 26354                              <1> 	; Original UNIX V1 'getc': 
 26355                              <1> 	;		get a character off character list
 26356                              <1> 	;
 26357                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))	
 26358                              <1> 	;
 26359                              <1> 	; 30/06/20045 (32 bit modifications)
 26360                              <1> 	; 16/07/2013
 26361                              <1> 	; mov 	[getctty], ah
 26362                              <1> 	;
 26363                              <1> 
 26364 0000642F 8A25[ED700000]      <1> 	mov	ah, [u.ttyn] 	; 28/07/2013
 26365                              <1> getc_n:
 26366                              <1> 	; 30/06/2015
 26367 00006435 08E4                <1> 	or	ah, ah
 26368 00006437 740D                <1> 	jz	short getc0 
 26369 00006439 D0E4                <1> 	shl	ah, 1
 26370 0000643B 0FB6DC              <1> 	movzx	ebx, ah
 26371 0000643E 81C3[E86F0000]      <1> 	add	ebx, ttychr
 26372 00006444 EB05                <1> 	jmp	short getc1
 26373                              <1> getc0:
 26374 00006446 BB[E86F0000]        <1> 	mov	ebx, ttychr
 26375                              <1> getc1:
 26376 0000644B 668B0B              <1> 	mov	cx, [ebx] 	; ascii & scan code
 26377                              <1> 				; (by kb_int)	
 26378 0000644E 6609C9              <1> 	or	cx, cx
 26379 00006451 7507                <1> 	jnz	short getc2
 26380 00006453 20C0                <1> 	and 	al, al
 26381 00006455 7415                <1> 	jz	short getc_s
 26382                              <1> 	;xor	ax, ax
 26383                              <1> 	; 30/11/2021
 26384 00006457 31C0                <1> 	xor	eax, eax
 26385 00006459 C3                  <1> 	retn
 26386                              <1> getc2:	
 26387 0000645A 20C0                <1> 	and	al, al
 26388 0000645C 6689C8              <1> 	mov	ax, cx
 26389 0000645F 66B90000            <1> 	mov	cx, 0
 26390 00006463 7506                <1> 	jnz	short getc3
 26391                              <1> getc_sn:
 26392 00006465 66890B              <1> 	mov	[ebx], cx ; 0, reset
 26393 00006468 6639C8              <1> 	cmp	ax, cx  ; zf = 0
 26394                              <1> getc3:
 26395 0000646B C3                  <1> 	retn
 26396                              <1> getc_s:
 26397                              <1> 	; 12/11/2015
 26398                              <1> 	; 15/09/2015
 26399                              <1> 	; 01/07/2015
 26400                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 26401                              <1> 	; 16/07/2013 - 14/02/2014 (Retro UNIX 8086 v1)
 26402                              <1> 	;
 26403                              <1> 	; tty  of the current process is not 
 26404                              <1> 	; current tty (ptty); so, current process only 
 26405                              <1> 	; can use keyboard input when its tty becomes 
 26406                              <1> 	; current tty (ptty).
 26407                              <1> 	; 'sleep' is for preventing an endless lock
 26408                              <1> 	; during this tty input request.
 26409                              <1> 	; (Because, the user is not looking at the video page
 26410                              <1> 	; of the process to undersand there is a keyboard
 26411                              <1> 	; input request.)
 26412                              <1> 	;
 26413                              <1> 	;((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 26414                              <1> 	;
 26415                              <1> 	; 05/10/2013
 26416                              <1> 	; ah = byte ptr [u.ttyn] ; (tty number)
 26417                              <1> 	;
 26418                              <1> 	; 10/10/2013
 26419                              <1> gcw0:
 26420 0000646C B10A                <1> 	mov	cl, 10 ; ch = 0
 26421                              <1> gcw1:	
 26422                              <1> 	; 12/11/2015
 26423 0000646E E885D9FFFF          <1> 	call intract ; jumps to 'sysexit' if [u.quit] = FFFFh
 26424                              <1> 	; 10/10/2013
 26425 00006473 E8ADECFFFF          <1> 	call	idle
 26426 00006478 668B03              <1> 	mov	ax, [ebx] 	; ascii & scan code
 26427                              <1> 				; (by kb_int)
 26428 0000647B 6609C0              <1> 	or	ax, ax
 26429                              <1> ;	jnz	short gcw3
 26430 0000647E 7519                <1> 	jnz	short gcw2 ; 15/09/2015
 26431                              <1> 	; 30/06/2015
 26432 00006480 FEC9                <1> 	dec	cl
 26433 00006482 75EA                <1> 	jnz	short gcw1
 26434                              <1> 	;
 26435 00006484 8A25[ED700000]      <1> 	mov	ah, [u.ttyn] 	; 20/10/2013
 26436                              <1> ;	; 10/12/2013
 26437                              <1> ;	cmp 	ah, [ptty]
 26438                              <1> ;	jne	short gcw2
 26439                              <1> ;	; 14/02/2014
 26440                              <1> ;	cmp	byte [u.uno], 1
 26441                              <1> ;	jna	short gcw0		
 26442                              <1> ;gcw2:
 26443 0000648A E82AEDFFFF          <1> 	call	sleep
 26444                              <1> 	;
 26445                              <1> 	; 20/09/2013
 26446 0000648F 8A25[ED700000]      <1> 	mov	ah, [u.ttyn]
 26447 00006495 30C0                <1> 	xor 	al, al
 26448 00006497 EB9C                <1> 	jmp	short getc_n
 26449                              <1> ;gcw3:
 26450                              <1> gcw2: 	; 15/09/2015
 26451                              <1> 	; 10/10/2013
 26452 00006499 30C9                <1> 	xor	cl, cl
 26453 0000649B EBC8                <1> 	jmp	short getc_sn
 26454                              <1> 
 26455                              <1> putc:	
 26456                              <1> 	; 05/12/2021 (Retro UNIX 386 v1.2)
 26457                              <1> 	; 13/08/2015
 26458                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 26459                              <1> 	; 15/05/2013 - 27/07/2014 (Retro UNIX 8086 v1)
 26460                              <1> 	;
 26461                              <1> 	; Retro UNIX 8086 v1 modification !
 26462                              <1> 	; 
 26463                              <1> 	; 'putc' puts a character 
 26464                              <1> 	;	 onto requested (tty) video page or
 26465                              <1> 	;	 serial port
 26466                              <1> 	; INPUTS ->
 26467                              <1> 	;     AL = ascii code of the character
 26468                              <1> 	;     AH = video page (tty) number (0 to 7)
 26469                              <1> 	;			  (8 is COM1, 9 is COM2)	
 26470                              <1> 	; OUTPUTS ->
 26471                              <1> 	;    (If AL input is 1) ZF=1 -> 'empty buffer' (no chars)
 26472                              <1> 	;      			ZF=0 -> AX has (current) character
 26473                              <1> 	;     cf=0 and AH = 0 -> no error
 26474                              <1> 	;     cf=1 and AH > 0 -> error (only for COM1 and COM2)
 26475                              <1> 	; 
 26476                              <1> 	; Original UNIX V1 'putc': 
 26477                              <1> 	;     put a character at the end of character list
 26478                              <1> 	;
 26479                              <1> 	; ((Modified registers: eAX, eBX, eCX, eDX, eSI, eDI))
 26480                              <1> 	;
 26481 0000649D 80FC07              <1> 	cmp	ah, 7
 26482 000064A0 770A                <1>         ja      short sndc ; 05/12/2021
 26483                              <1> 	; 30/06/2015
 26484 000064A2 0FB6DC              <1> 	movzx	ebx, ah
 26485                              <1> 	; 13/08/2015
 26486 000064A5 B407                <1> 	mov	ah, 07h ; black background, light gray character color
 26487 000064A7 E914B0FFFF          <1> 	jmp	write_tty ; 'video.inc'
 26488                              <1> 
 26489                              <1> sndc:   ; <Send character>
 26490                              <1> 	;
 26491                              <1> 	; 17/11/2015
 26492                              <1> 	; 16/11/2015
 26493                              <1> 	; 11/11/2015
 26494                              <1> 	; 10/11/2015
 26495                              <1> 	; 09/11/2015
 26496                              <1> 	; 08/11/2015
 26497                              <1> 	; 07/11/2015
 26498                              <1> 	; 06/11/2015 (serial4.asm, 'sendchr')	
 26499                              <1> 	; 29/10/2015
 26500                              <1> 	; 30/06/2015 (Retro UNIX 386 v1 - Beginning)
 26501                              <1> 	; 14/05/2013 - 28/07/2014 (Retro UNIX 8086 v1)
 26502                              <1> 	;
 26503                              <1> 	; Retro UNIX 8086 v1 feature only !
 26504                              <1> 	;
 26505                              <1> 	; ah = [u.ttyn]
 26506                              <1> 	;
 26507                              <1> 	; 30/06/2015
 26508 000064AC 80EC08              <1> 	sub	ah, 8 ; ; 0 = tty8 or 1 = tty9
 26509                              <1> 	; 07/11/2015
 26510 000064AF 0FB6DC              <1> 	movzx	ebx, ah ; serial port index (0 or 1)
 26511                              <1> sndc0:
 26512                              <1> 	; 07/11/2015
 26513 000064B2 E858EDFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 26514 000064B7 7405                <1> 	jz	short sndc1
 26515 000064B9 E83AD9FFFF          <1> 	call	intract ; quit (ctrl+break) check
 26516                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 26517                              <1> sndc1:
 26518                              <1> 	; 16/11/2015
 26519 000064BE 6689C1              <1> 	mov	cx, ax	; *** al = character (to be sent)
 26520                              <1> sndcx:
 26521 000064C1 8A83[2A700000]      <1> 	mov	al, [ebx+schar] ; last sent character
 26522 000064C7 8AA3[28700000]      <1> 	mov	ah, [ebx+rchar] ; last received character
 26523                              <1> 	;
 26524                              <1> 	; 17/11/2015
 26525                              <1> 	; check 'request for response' status
 26526 000064CD 80BB[24700000]00    <1> 	cmp	byte [ebx+req_resp], 0
 26527 000064D4 740A                <1> 	jz	short query
 26528                              <1> response:
 26529 000064D6 FE05[27700000]      <1> 	inc 	byte [comqr] ; query or response status
 26530 000064DC B0FF                <1> 	mov	al, 0FFh	 
 26531 000064DE EB14                <1> 	jmp	short sndc3
 26532                              <1> query:
 26533 000064E0 08C0                <1> 	or 	al, al  ; 0 = query (also end of text)
 26534 000064E2 750E                <1> 	jnz 	short sndc2 ; normal character
 26535                              <1> 	;cmp 	ah, 0FFh     ; is it responded by terminal ?
 26536                              <1> 	;je	short sndc2  ; yes, already responded
 26537                              <1> 	; 16/11/2015
 26538                              <1> 	; query: request for response (again)
 26539 000064E4 8883[28700000]      <1> 	mov	[ebx+rchar], al ; 0 ; reset
 26540 000064EA FE05[27700000]      <1> 	inc 	byte [comqr] ; query or response status
 26541 000064F0 EB02                <1> 	jmp	short sndc3
 26542                              <1> sndc2:
 26543 000064F2 88C8                <1> 	mov	al, cl 	; *** character (to be sent)
 26544                              <1> sndc3:
 26545 000064F4 8883[2A700000]      <1> 	mov	[ebx+schar], al ; current character (to be sent)
 26546 000064FA 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 26547                              <1> 	; 30/06/2015
 26548 000064FC E862D2FFFF          <1> 	call	sp_status ; get serial port status
 26549                              <1> 	; AL = Line status, AH = Modem status
 26550                              <1> 	; 07/11/2015
 26551 00006501 A880                <1> 	test	al, 80h
 26552 00006503 7504                <1> 	jnz	short sndc4
 26553 00006505 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 26554 00006507 751D                <1> 	jnz	short sndc5
 26555                              <1> sndc4: 	; Check line status again
 26556                              <1> 	; 16/11/2015
 26557 00006509 6651                <1> 	push	cx
 26558 0000650B B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 26559 00006510 E8BAB0FFFF          <1> 	call	WAITF
 26560 00006515 6659                <1> 	pop	cx
 26561                              <1> 	;
 26562 00006517 88D8                <1> 	mov	al, bl ; 0 or 1 (serial port index)
 26563 00006519 E845D2FFFF          <1> 	call	sp_status ; get serial port status
 26564                              <1> 	; 16/11/2015
 26565                              <1> 	; 09/11/2015
 26566                              <1> 	; 08/11/2015
 26567 0000651E A880                <1> 	test	al, 80h	; time out error
 26568 00006520 756C                <1>         jnz     short sndc7
 26569 00006522 A820                <1> 	test	al, 20h	; Transmitter holding register empty ?
 26570 00006524 7468                <1>         jz	short sndc7
 26571                              <1> sndc5:  
 26572 00006526 8A83[2A700000]      <1> 	mov	al, [ebx+schar] ; character (to be sent)
 26573 0000652C 66BAF803            <1> 	mov	dx, 3F8h   ; data port (COM2)
 26574 00006530 28DE                <1> 	sub	dh, bl
 26575 00006532 EE                  <1> 	out	dx, al	   ; send on serial port
 26576                              <1> 	; 10/11/2015
 26577                              <1> 	; delay for 3*30 (3*(15..80)) micro seconds
 26578                              <1> 	; (to improve text flow to the terminal)
 26579                              <1> 	; ('diskette.inc': 'WAITF')
 26580                              <1> 	; Uses port 61h, bit 4 to have CPU speed independent waiting.
 26581                              <1> 	; (refresh periods = 1 per 30 microseconds on most machines)
 26582 00006533 6651                <1> 	push	cx 
 26583 00006535 B906000000          <1> 	mov	ecx, 6 ; 6*30 micro seconds (~5556 chars/second)
 26584 0000653A E890B0FFFF          <1> 	call	WAITF
 26585 0000653F 6659                <1> 	pop	cx
 26586                              <1>     	;
 26587                              <1> 	; 07/11/2015
 26588 00006541 88D8                <1> 	mov	al, bl ; al = 0 (tty8) or 1 (tty9)
 26589                              <1> 	;
 26590 00006543 E81BD2FFFF          <1> 	call	sp_status ; get serial port status
 26591                              <1> 	; AL = Line status, AH = Modem status
 26592                              <1> 	;
 26593 00006548 E8C2ECFFFF          <1> 	call	isintr ; quit (ctrl+break) check
 26594 0000654D 7405                <1> 	jz	short sndc6
 26595 0000654F E8A4D8FFFF          <1> 	call	intract ; quit (ctrl+break) check
 26596                              <1> 	; CPU will jump to 'sysexit' if 'u.quit' = 0FFFFh (yes)
 26597                              <1> sndc6:
 26598 00006554 3C80                <1> 	cmp	al, 80h
 26599 00006556 7336                <1> 	jnb	short sndc7		
 26600                              <1> 	;
 26601 00006558 803D[27700000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 26602 0000655F 7248                <1> 	jb	short sndc8 	; no, normal character
 26603 00006561 883D[27700000]      <1> 	mov 	byte [comqr], bh ; 0 ; reset
 26604                              <1> 	; 17/11/2015
 26605 00006567 E8B9EBFFFF          <1> 	call	idle
 26606                              <1> 	;
 26607 0000656C 38BB[2A700000]      <1> 	cmp	[ebx+schar], bh ; 0 ; query ?
 26608 00006572 0F877AFFFFFF        <1>         ja      sndc2       ; response (will be followed by
 26609                              <1> 			    ; a normal character)
 26610                              <1> 	; Query request must be responded by the terminal
 26611                              <1> 	; before sending a normal character !
 26612 00006578 53                  <1> 	push	ebx
 26613 00006579 6651                <1> 	push	cx ; *** cl = character (to be sent)
 26614 0000657B 8A25[ED700000]      <1> 	mov	ah, [u.ttyn]
 26615 00006581 E833ECFFFF          <1> 	call	sleep ; this process will be awakened by
 26616                              <1> 		      ; received data available interrupt
 26617 00006586 6659                <1> 	pop	cx ; *** cl = character (to be sent)
 26618 00006588 5B                  <1> 	pop	ebx
 26619 00006589 E933FFFFFF          <1>         jmp	sndcx
 26620                              <1> sndc7:
 26621                              <1> 	 ; 16/11/2015
 26622 0000658E 803D[27700000]01    <1> 	cmp	byte [comqr], 1 ; 'query or response' ?
 26623 00006595 7213                <1> 	jb	short sndc9 	; no
 26624                              <1> 	;
 26625 00006597 88BB[28700000]      <1> 	mov	[ebx+rchar], bh ; 0 ; reset
 26626 0000659D 88BB[2A700000]      <1> 	mov	[ebx+schar], bh ; 0 ; reset
 26627                              <1> 	;
 26628 000065A3 883D[27700000]      <1> 	mov	byte [comqr], bh ; 0 ; reset  
 26629                              <1> sndc8:
 26630 000065A9 F5                  <1> 	cmc  ; jnc -> jc, jb -> jnb
 26631                              <1> sndc9:
 26632                              <1> 	; AL = Line status, AH = Modem status
 26633 000065AA C3                  <1> 	retn
 26634                              <1> 
 26635                              <1> get_cpos:
 26636                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 26637                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 26638                              <1> 	;
 26639                              <1> 	; INPUT -> bl = video page number
 26640                              <1> 	; RETURN -> dx = cursor position
 26641                              <1> 
 26642 000065AB 53                  <1> 	push	ebx
 26643 000065AC 83E30F              <1> 	and	ebx, 0Fh ; 07h ; tty0 to tty7
 26644 000065AF D0E3                <1> 	shl	bl, 1
 26645 000065B1 81C3[D66F0000]      <1> 	add	ebx, cursor_posn
 26646 000065B7 668B13              <1> 	mov	dx, [ebx]
 26647 000065BA 5B                  <1> 	pop	ebx
 26648 000065BB C3                  <1> 	retn
 26649                              <1> 
 26650                              <1> read_ac_current:
 26651                              <1> 	; 29/06/2015 (Retro UNIX 386 v1)
 26652                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - 'sysgtty')
 26653                              <1> 	;
 26654                              <1> 	; INPUT -> bl = video page number
 26655                              <1> 	; RETURN -> ax = character (al) and attribute (ah)
 26656                              <1> 
 26657 000065BC E87DB0FFFF          <1> 	call 	find_position ; 'video.inc'
 26658                              <1> 	; dx = status port
 26659                              <1> 	; esi = cursor location/address
 26660 000065C1 81C600800B00        <1> 	add	esi, 0B8000h	; 30/08/2014 (Retro UNIX 386 v1)
 26661 000065C7 668B06              <1> 	mov 	ax, [esi]	; get the character and attribute
 26662 000065CA C3                  <1> 	retn
 26663                              <1> 
 26664                              <1> syssleep:
 26665                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
 26666                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
 26667                              <1> 	;
 26668                              <1> 	; Retro UNIX 8086 v1 feature only
 26669                              <1> 	; (INPUT -> none)
 26670                              <1> 	;
 26671 000065CB 0FB61D[09710000]    <1> 	movzx	ebx, byte [u.uno] ; process number
 26672 000065D2 8AA3[EF6D0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
 26673 000065D8 E8DCEBFFFF          <1> 	call	sleep
 26674 000065DD E914D7FFFF          <1> 	jmp	sysret
 26675                              <1> 
 26676                              <1> vp_clr:
 26677                              <1> 	; Reset/Clear Video Page
 26678                              <1> 	;
 26679                              <1> 	; 05/12/2021 - (Retro UNIX 386 v1.2)
 26680                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
 26681                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
 26682                              <1> 	;
 26683                              <1> 	; Retro UNIX 8086 v1 feature only !
 26684                              <1> 	;
 26685                              <1> 	; INPUTS -> 
 26686                              <1> 	;   BL = video page number	 
 26687                              <1> 	;
 26688                              <1> 	; OUTPUT ->
 26689                              <1> 	;   none
 26690                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
 26691                              <1> 	;
 26692                              <1> 	; 04/12/2013
 26693 000065E2 28C0                <1> 	sub	al, al
 26694                              <1> 	; al = 0 (clear video page)
 26695                              <1> 	; bl = video page
 26696 000065E4 B407                <1> 	mov	ah, 07h
 26697                              <1> 	; ah = 7 (attribute/color)
 26698                              <1> 	;xor 	cx, cx ; 0, left upper column (cl) & row (cl)
 26699                              <1> 	; 05/12/2021
 26700 000065E6 31C9                <1> 	xor	ecx, ecx
 26701 000065E8 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
 26702 000065EC E877B0FFFF          <1> 	call	scroll_up
 26703                              <1> 	; bl = video page
 26704                              <1> 	;xor	dx, dx ; 0 (cursor position) 
 26705                              <1> 	; 05/12/2021
 26706 000065F1 31D2                <1> 	xor	edx, edx
 26707 000065F3 E9EAAFFFFF          <1> 	jmp 	set_cpos
 26708                              <1> 
 26709                              <1> sysmsg:
 26710                              <1> 	; 11/12/2021
 26711                              <1> 	; 04/12/2021 (Retro UNIX 386 v1.2)
 26712                              <1> 	; 11/11/2015
 26713                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
 26714                              <1> 	; Print user-application message on user's console tty
 26715                              <1> 	;
 26716                              <1> 	; Input -> EBX = Message address
 26717                              <1> 	;	   ECX = Message length (max. 255)
 26718                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
 26719                              <1> 	;
 26720 000065F8 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
 26721                              <1> 	;ja	sysret ; nothing to do with big message size
 26722 000065FE 7779                <1> 	ja	short sysmsg8 ; 11/12/2021
 26723 00006600 08C9                <1> 	or	cl, cl
 26724                              <1> 	;jz	sysret
 26725 00006602 7475                <1> 	jz	short sysmsg8 ; 11/12/2021
 26726 00006604 20D2                <1> 	and	dl, dl
 26727 00006606 7502                <1> 	jnz	short sysmsg0
 26728 00006608 B207                <1> 	mov	dl, 07h ; default color
 26729                              <1> 		; (black background, light gray character) 
 26730                              <1> sysmsg0:
 26731 0000660A 891D[DC700000]      <1> 	mov	[u.base], ebx
 26732 00006610 8815[E76F0000]      <1> 	mov	[ccolor], dl ; color attributes
 26733 00006616 89E5                <1> 	mov	ebp, esp
 26734 00006618 31DB                <1> 	xor	ebx, ebx ; 0
 26735 0000661A 891D[E4700000]      <1> 	mov	[u.nread], ebx ; 0
 26736                              <1> 	;
 26737 00006620 381D[2A710000]      <1> 	cmp	[u.kcall], bl ; 0
 26738 00006626 7772                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
 26739                              <1> 	;
 26740 00006628 890D[E0700000]      <1> 	mov	[u.count], ecx
 26741 0000662E 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ ; 04/12/2021
 26742                              <1> 	; 04/12/2021
 26743                              <1> 	; (dword alignment for esp)
 26744 0000662F F6C103              <1> 	test	cl, 3
 26745 00006632 7404                <1> 	jz	short sysmsg_7
 26746 00006634 80C903              <1> 	or	cl, 3
 26747 00006637 41                  <1> 	inc	ecx
 26748                              <1> sysmsg_7:
 26749 00006638 29CC                <1> 	sub	esp, ecx
 26750 0000663A 89E7                <1> 	mov	edi, esp
 26751 0000663C 89E6                <1> 	mov	esi, esp
 26752 0000663E 66891D[24710000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
 26753                              <1> 	; 11/11/2015
 26754 00006645 8A25[EE700000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
 26755                              <1> 	; 0 = none
 26756 0000664B FECC                <1> 	dec	ah
 26757 0000664D 790C                <1> 	jns	short sysmsg1 
 26758 0000664F 8A1D[09710000]      <1> 	mov	bl, [u.uno] ; process number	
 26759 00006655 8AA3[EF6D0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
 26760                              <1> sysmsg1:
 26761 0000665B 8825[ED700000]      <1> 	mov	[u.ttyn], ah
 26762                              <1> sysmsg2:
 26763 00006661 E82DF5FFFF          <1> 	call	cpass
 26764 00006666 7416                <1> 	jz	short sysmsg5
 26765 00006668 AA                  <1> 	stosb
 26766 00006669 20C0                <1> 	and	al, al
 26767 0000666B 75F4                <1> 	jnz	short sysmsg2
 26768                              <1> sysmsg3:
 26769 0000666D 80FC07              <1> 	cmp	ah, 7 ; tty number
 26770 00006670 7711                <1> 	ja	short sysmsg6 ; serial port
 26771 00006672 E83E000000          <1> 	call	print_cmsg
 26772                              <1> sysmsg4:
 26773 00006677 89EC                <1> 	mov	esp, ebp
 26774                              <1> sysmsg8: ; 11/12/2021	
 26775 00006679 E978D6FFFF          <1> 	jmp	sysret
 26776                              <1> sysmsg5:
 26777 0000667E C60700              <1> 	mov	byte [edi], 0
 26778 00006681 EBEA                <1> 	jmp	short sysmsg3
 26779                              <1> sysmsg6:
 26780 00006683 8A06                <1> 	mov	al, [esi]
 26781 00006685 E822FEFFFF          <1> 	call	sndc
 26782 0000668A 72EB                <1> 	jc	short sysmsg4
 26783 0000668C 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
 26784 0000668F 76E6                <1> 	jna	short sysmsg4
 26785 00006691 46                  <1> 	inc 	esi
 26786 00006692 8A25[ED700000]      <1> 	mov	ah, [u.ttyn]
 26787 00006698 EBE9                <1> 	jmp	short sysmsg6
 26788                              <1> 
 26789                              <1> sysmsgk: ; Temporary (01/07/2015)
 26790                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
 26791                              <1> 	; (ECX -character count- will not be considered)
 26792 0000669A 8B35[DC700000]      <1> 	mov	esi, [u.base]
 26793 000066A0 8A25[E66F0000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
 26794 000066A6 8825[ED700000]      <1> 	mov	[u.ttyn], ah
 26795 000066AC C605[2A710000]00    <1> 	mov	byte [u.kcall], 0
 26796 000066B3 EBB8                <1> 	jmp	short sysmsg3
 26797                              <1> 	
 26798                              <1> print_cmsg: 
 26799                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
 26800                              <1> 	;
 26801                              <1> 	; print message (on user's console tty) 
 26802                              <1> 	;	with requested color
 26803                              <1> 	;
 26804                              <1> 	; INPUTS:
 26805                              <1> 	;	esi = message address
 26806                              <1> 	;	[u.ttyn] = tty number (0 to 7)
 26807                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
 26808                              <1> 	;
 26809 000066B5 AC                  <1> 	lodsb
 26810                              <1> pcmsg1:
 26811 000066B6 56                  <1> 	push 	esi
 26812 000066B7 0FB61D[ED700000]    <1>         movzx   ebx, byte [u.ttyn]
 26813 000066BE 8A25[E76F0000]      <1> 	mov	ah, [ccolor]
 26814 000066C4 E8F7ADFFFF          <1> 	call 	write_tty
 26815 000066C9 5E                  <1> 	pop	esi
 26816 000066CA AC                  <1> 	lodsb
 26817 000066CB 20C0                <1> 	and 	al, al  ; 0
 26818 000066CD 75E7                <1> 	jnz 	short pcmsg1
 26819 000066CF C3                  <1> 	retn
 26820                              <1> 
 26821                              <1> sysgeterr:
 26822                              <1> 	; 09/12/2015
 26823                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
 26824                              <1> 	; Get last error number or page fault count
 26825                              <1> 	; (for debugging)
 26826                              <1> 	;
 26827                              <1> 	; Input -> EBX = return type
 26828                              <1> 	;	   0 = last error code (which is in 'u.error')	
 26829                              <1> 	;	   FFFFFFFFh = page fault count for running process
 26830                              <1> 	;	   FFFFFFFEh = total page fault count
 26831                              <1> 	;	   1 .. FFFFFFFDh = undefined 
 26832                              <1> 	;
 26833                              <1> 	; Output -> EAX = last error number or page fault count
 26834                              <1> 	;	   (depending on EBX input)
 26835                              <1> 	; 	
 26836 000066D0 21DB                <1> 	and 	ebx, ebx
 26837 000066D2 750B                <1> 	jnz	short glerr_2
 26838                              <1> glerr_0:
 26839 000066D4 A1[2C710000]        <1> 	mov	eax, [u.error]
 26840                              <1> glerr_1:
 26841 000066D9 A3[B4700000]        <1> 	mov	[u.r0], eax
 26842 000066DE C3                  <1>  	retn
 26843                              <1> glerr_2:
 26844 000066DF 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
 26845 000066E0 74FD                <1> 	jz	short glerr_2 ; page fault count for process
 26846 000066E2 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
 26847 000066E3 75EF                <1> 	jnz	short glerr_0
 26848 000066E5 A1[50820000]        <1> 	mov	eax, [PF_Count] ; total page fault count
 26849 000066EA EBED                <1>         jmp     short glerr_1
 26850                              <1> glerr_3:
 26851 000066EC A1[30710000]        <1> 	mov 	eax, [u.pfcount]
 26852 000066F1 EBE6                <1> 	jmp	short glerr_1
 26853                                  
 26854                                  ; 07/03/2015
 26855                                  ; Temporary Code
 26856                                  display_disks:
 26857 000066F3 803D[AE6A0000]00        	cmp 	byte [fd0_type], 0
 26858 000066FA 7605                    	jna 	short ddsks1
 26859 000066FC E87D000000              	call	pdskm
 26860                                  ddsks1:
 26861 00006701 803D[AF6A0000]00        	cmp	byte [fd1_type], 0
 26862 00006708 760C                    	jna	short ddsks2
 26863 0000670A C605[9F6C0000]31        	mov	byte [dskx], '1'
 26864 00006711 E868000000              	call	pdskm
 26865                                  ddsks2:
 26866 00006716 803D[B06A0000]00        	cmp	byte [hd0_type], 0
 26867 0000671D 7654                    	jna	short ddsk6
 26868 0000671F 66C705[9D6C0000]68-     	mov	word [dsktype], 'hd'
 26869 00006727 64                 
 26870 00006728 C605[9F6C0000]30        	mov	byte [dskx], '0'
 26871 0000672F E84A000000              	call	pdskm
 26872                                  ddsks3:
 26873 00006734 803D[B16A0000]00        	cmp	byte [hd1_type], 0
 26874 0000673B 7636                    	jna	short ddsk6
 26875 0000673D C605[9F6C0000]31        	mov	byte [dskx], '1'
 26876 00006744 E835000000              	call	pdskm
 26877                                  ddsks4:
 26878 00006749 803D[B26A0000]00        	cmp	byte [hd2_type], 0
 26879 00006750 7621                    	jna	short ddsk6
 26880 00006752 C605[9F6C0000]32        	mov	byte [dskx], '2'
 26881 00006759 E820000000              	call	pdskm
 26882                                  ddsks5:
 26883 0000675E 803D[B36A0000]00        	cmp	byte [hd3_type], 0
 26884 00006765 760C                    	jna	short ddsk6
 26885 00006767 C605[9F6C0000]33        	mov	byte [dskx], '3'
 26886 0000676E E80B000000              	call	pdskm
 26887                                  ddsk6:
 26888 00006773 BE[AE6C0000]            	mov	esi, nextline
 26889 00006778 E806000000              	call	pdskml
 26890                                  pdskm_ok:
 26891 0000677D C3                      	retn
 26892                                  pdskm:
 26893 0000677E BE[9B6C0000]            	mov	esi, dsk_ready_msg
 26894                                  pdskml:	
 26895 00006783 AC                      	lodsb
 26896 00006784 08C0                    	or	al, al
 26897 00006786 74F5                    	jz	short pdskm_ok
 26898 00006788 56                      	push	esi
 26899 00006789 31DB                    	xor	ebx, ebx ; 0
 26900                                  			; Video page 0 (bl=0)
 26901 0000678B B407                    	mov	ah, 07h ; Black background, 
 26902                                  			; light gray forecolor
 26903 0000678D E82EADFFFF              	call	write_tty
 26904 00006792 5E                      	pop	esi
 26905 00006793 EBEE                    	jmp	short pdskml
 26906                                  
 26907 00006795 90<rept>                align 16
 26908                                  
 26909                                  gdt:	; Global Descriptor Table
 26910                                  	; (30/07/2015, conforming cs)
 26911                                  	; (26/03/2015)
 26912                                  	; (24/03/2015, tss)
 26913                                  	; (19/03/2015)
 26914                                  	; (29/12/2013)
 26915                                  	;
 26916 000067A0 0000000000000000        	dw 0, 0, 0, 0	; NULL descriptor
 26917                                  	; 18/08/2014
 26918                                  			; 8h kernel code segment, base = 00000000h		
 26919 000067A8 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
 26920                                  			; 10h kernel data segment, base = 00000000h	
 26921 000067B0 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
 26922                                  			; 1Bh user code segment, base address = 400000h ; CORE
 26923 000067B8 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
 26924                                  			; 23h user data segment, base address = 400000h ; CORE
 26925 000067C0 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
 26926                                  			; Task State Segment
 26927 000067C8 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
 26928                                  			       ;  no IO permission in ring 3)
 26929                                  gdt_tss0:
 26930 000067CA 0000                    	dw 0  ; TSS base address, bits 0-15 
 26931                                  gdt_tss1:
 26932 000067CC 00                      	db 0  ; TSS base address, bits 16-23 
 26933                                  	      		; 49h	
 26934 000067CD E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
 26935 000067CE 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
 26936                                  gdt_tss2:
 26937 000067CF 00                      	db 0  ; TSS base address, bits 24-31 
 26938                                  
 26939                                  gdt_end:
 26940                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 26941                                  					;; Type= 1 (code)/C=0/R=1/A=0
 26942                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 26943                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 26944                                  
 26945                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
 26946                                  					;; Type= 0 (data)/E=0/W=1/A=0
 26947                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
 26948                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 26949                                  		; W= Writeable, A= Accessed
 26950                                  	
 26951                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
 26952                                  					;; Type= 1 (code)/C=0/R=1/A=0
 26953                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 26954                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
 26955                                  
 26956                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
 26957                                  					;; Type= 0 (data)/E=0/W=1/A=0
 26958                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
 26959                                  		; 0= Data E= Expansion direction (1= down, 0= up)
 26960                                  	
 26961                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
 26962                                  
 26963                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
 26964                                  		;	 = 100000h * 1000h (G=1) = 4GB
 26965                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
 26966                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
 26967                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
 26968                                  		; AVL= Available to programmers	
 26969                                  
 26970                                  gdtd:
 26971 000067D0 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
 26972 000067D2 [A0670000]                      dd gdt			; Address of the GDT
 26973                                  
 26974                                  	; 20/08/2014
 26975                                  idtd:
 26976 000067D6 FF01                            dw idt_end - idt - 1    ; Limit (size)
 26977 000067D8 [506D0000]                      dd idt			; Address of the IDT
 26978                                  
 26979                                  Align 4
 26980                                  
 26981                                  	; 21/08/2014
 26982                                  ilist:
 26983                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
 26984                                  	;
 26985                                  	; Exception list
 26986                                  	; 25/08/2014	
 26987 000067DC [21090000]              	dd	exc0	; 0h,  Divide-by-zero Error
 26988 000067E0 [28090000]              	dd	exc1	
 26989 000067E4 [2F090000]              	dd 	exc2	
 26990 000067E8 [36090000]              	dd	exc3	
 26991 000067EC [3A090000]              	dd	exc4	
 26992 000067F0 [3E090000]              	dd	exc5	
 26993 000067F4 [42090000]              	dd 	exc6	; 06h,  Invalid Opcode
 26994 000067F8 [46090000]              	dd	exc7	
 26995 000067FC [4A090000]              	dd	exc8	
 26996 00006800 [4E090000]              	dd	exc9	
 26997 00006804 [52090000]              	dd 	exc10	
 26998 00006808 [56090000]              	dd	exc11
 26999 0000680C [5A090000]              	dd	exc12
 27000 00006810 [5E090000]              	dd	exc13	; 0Dh, General Protection Fault
 27001 00006814 [62090000]              	dd 	exc14	; 0Eh, Page Fault
 27002 00006818 [66090000]              	dd	exc15
 27003 0000681C [6A090000]              	dd	exc16
 27004 00006820 [6E090000]              	dd	exc17
 27005 00006824 [72090000]              	dd 	exc18
 27006 00006828 [76090000]              	dd	exc19
 27007 0000682C [7A090000]              	dd 	exc20
 27008 00006830 [7E090000]              	dd	exc21
 27009 00006834 [82090000]              	dd	exc22
 27010 00006838 [86090000]              	dd	exc23
 27011 0000683C [8A090000]              	dd 	exc24
 27012 00006840 [8E090000]              	dd	exc25
 27013 00006844 [92090000]              	dd	exc26
 27014 00006848 [96090000]              	dd	exc27
 27015 0000684C [9A090000]              	dd 	exc28
 27016 00006850 [9E090000]              	dd	exc29
 27017 00006854 [A2090000]              	dd 	exc30
 27018 00006858 [A6090000]              	dd	exc31
 27019                                  	; Interrupt list
 27020 0000685C [60070000]              	dd	timer_int	; INT 20h
 27021                                  		;dd	irq0	
 27022 00006860 [5C0C0000]              	dd	keyb_int	; 27/08/2014
 27023                                  		;dd	irq1
 27024 00006864 [7B080000]              	dd	irq2
 27025                                  		; COM2 int
 27026 00006868 [7F080000]              	dd	irq3
 27027                                  		; COM1 int
 27028 0000686C [8A080000]              	dd	irq4
 27029 00006870 [95080000]              	dd	irq5
 27030                                  ;DISKETTE_INT: ;06/02/2015
 27031 00006874 [04270000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
 27032                                  		;dd	irq6
 27033                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
 27034                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
 27035 00006878 [0D0C0000]              	dd	default_irq7	; 25/02/2015
 27036                                  		;dd	irq7
 27037                                  ; Real Time Clock Interrupt
 27038 0000687C [B00A0000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
 27039                                  		;dd	irq8	; INT 28h
 27040 00006880 [A5080000]              	dd	irq9
 27041 00006884 [A9080000]              	dd	irq10
 27042 00006888 [AD080000]              	dd	irq11
 27043 0000688C [B1080000]              	dd	irq12
 27044 00006890 [B5080000]              	dd	irq13
 27045                                  ;HDISK_INT1:  ;06/02/2015 	
 27046 00006894 [2B2F0000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
 27047                                  		;dd	irq14
 27048                                  ;HDISK_INT2:  ;06/02/2015
 27049 00006898 [4E2F0000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
 27050                                  		;dd	irq15	; INT 2Fh
 27051                                  		; 14/08/2015
 27052 0000689C [D83B0000]              	dd	sysent		; INT 30h (system calls)
 27053                                  	
 27054                                  	;dd	ignore_int
 27055 000068A0 00000000                	dd	0
 27056                                  
 27057                                  ;;;
 27058                                  ;;; 11/03/2015
 27059                                  %include 'kybdata.s'	; KEYBOARD (BIOS) DATA
 27060                              <1> ; Retro UNIX 386 v1 Kernel - KYBDATA.INC
 27061                              <1> ; Last Modification: 11/03/2015
 27062                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
 27063                              <1> ;
 27064                              <1> ; ///////// KEYBOARD DATA ///////////////
 27065                              <1> 
 27066                              <1> ; 05/12/2014
 27067                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
 27068                              <1> ; 03/06/86  KEYBOARD BIOS
 27069                              <1> 
 27070                              <1> ;---------------------------------------------------------------------------------
 27071                              <1> ;	KEY IDENTIFICATION SCAN TABLES
 27072                              <1> ;---------------------------------------------------------------------------------
 27073                              <1> 
 27074                              <1> ;-----	TABLES FOR ALT CASE ------------
 27075                              <1> ;-----	ALT-INPUT-TABLE 
 27076 000068A4 524F50514B          <1> K30:	db	82,79,80,81,75
 27077 000068A9 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
 27078                              <1> ;-----	SUPER-SHIFT-TABLE 
 27079 000068AE 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
 27080 000068B4 161718191E1F        <1> 	db	22,23,24,25,30,31
 27081 000068BA 202122232425        <1> 	db	32,33,34,35,36,37
 27082 000068C0 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
 27083 000068C6 3132                <1> 	db	49,50
 27084                              <1> 
 27085                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
 27086                              <1> ;-----	KEY_TABLE 
 27087 000068C8 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
 27088 000068C9 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
 27089 000068CE 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
 27090                              <1> _K6L    equ     $-_K6
 27091                              <1> 
 27092                              <1> ;-----	MASK_TABLE
 27093 000068D0 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
 27094 000068D1 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
 27095 000068D6 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
 27096                              <1> 
 27097                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
 27098 000068D8 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
 27099 000068DE 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
 27100 000068E4 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
 27101 000068EA 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
 27102 000068F0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
 27103 000068F6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
 27104 000068FC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
 27105 00006902 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
 27106 00006908 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
 27107 0000690E 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
 27108                              <1> 	;				;----- FUNCTIONS ------		
 27109 00006912 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
 27110 00006918 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
 27111 0000691E 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
 27112 00006924 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
 27113 0000692A 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
 27114                              <1> 
 27115                              <1> ;-----	TABLES FOR LOWER CASE ----------
 27116 00006930 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
 27117 00006939 39302D3D0809        <1>
 27118 0000693F 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
 27119 00006948 705B5D0DFF61736466- <1>
 27120 00006951 67686A6B6C3B27      <1>
 27121 00006958 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
 27122 00006961 6D2C2E2FFF2AFF20FF  <1>
 27123                              <1> ;-----	LC TABLE SCAN
 27124 0000696A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
 27125 0000696F 4041424344          <1> 	db	64,65,66,67,68
 27126 00006974 FFFF                <1> 	db	-1,-1			; NL, SL
 27127                              <1> 
 27128                              <1> ;-----	KEYPAD TABLE
 27129 00006976 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
 27130 0000697C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
 27131 00006983 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
 27132                              <1> 
 27133                              <1> ;-----	TABLES FOR UPPER CASE ----------
 27134 00006988 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
 27135 00006991 28295F2B0800        <1>
 27136 00006997 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
 27137 000069A0 507B7D0DFF41534446- <1>
 27138 000069A9 47484A4B4C3A22      <1>
 27139 000069B0 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
 27140 000069B9 4D3C3E3FFF2AFF20FF  <1>
 27141                              <1> ;-----	UC TABLE SCAN
 27142 000069C2 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
 27143 000069C7 595A5B5C5D          <1> 	db	89,90,91,92,93
 27144 000069CC FFFF                <1> 	db	-1,-1			; NL, SL
 27145                              <1> 
 27146                              <1> ;-----	NUM STATE TABLE
 27147 000069CE 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
 27148 000069D7 3233302E            <1>
 27149                              <1> 	;
 27150 000069DB FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
 27151                              <1> 
 27152                              <1> Align	4
 27153                              <1> ;----------------------------------------
 27154                              <1> ;	VIDEO DISPLAY DATA AREA		;
 27155                              <1> ;----------------------------------------
 27156 000069E0 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
 27157 000069E1 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
 27158                              <1> 				; (29h default setting for video mode 3)
 27159                              <1> 				; Mode Select register Bits
 27160                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
 27161                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
 27162                              <1> 				;   BIT 2 - COLOR (0), BW (1)
 27163                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
 27164                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
 27165                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
 27166                              <1> 				;   BIT 6, 7 - Not Used
 27167                              <1> 
 27168                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
 27169                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
 27170                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
 27171                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
 27172                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
 27173                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
 27174                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
 27175                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
 27176                              <1> ; Mode & 37h = Video signal OFF
 27177                              <1> 			
 27178                              <1> 
 27179                              <1> ; 26/08/2014
 27180                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
 27181                              <1> ; Derived from IBM "pc-at" 
 27182                              <1> ; rombios source code (06/10/1985)
 27183                              <1> ; 'dseg.inc'
 27184                              <1> 
 27185                              <1> ;---------------------------------------;
 27186                              <1> ;	SYSTEM DATA AREA		;
 27187                              <1> ;----------------------------------------
 27188 000069E2 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
 27189                              <1> 
 27190                              <1> ;----------------------------------------
 27191                              <1> ;	KEYBOARD DATA AREAS		;
 27192                              <1> ;----------------------------------------
 27193                              <1> 
 27194 000069E3 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
 27195 000069E4 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
 27196 000069E5 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
 27197 000069E6 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
 27198 000069E7 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
 27199 000069E8 [F8690000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
 27200 000069EC [186A0000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
 27201 000069F0 [F8690000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
 27202 000069F4 [F8690000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
 27203                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
 27204 000069F8 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
 27205                              <1> 
 27206                              <1> ; /// End Of KEYBOARD DATA ///
 27207                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
 27208                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.INC
 27209                              <1> ; Last Modification: 11/03/2015
 27210                              <1> ;		    (Data section for 'VIDEO.INC')	
 27211                              <1> ;
 27212                              <1> ; ///////// VIDEO DATA ///////////////
 27213                              <1> 
 27214                              <1> video_params:
 27215                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
 27216                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
 27217                              <1> 	; VIDEO MODE 3
 27218 00006A18 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
 27219 00006A1F 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
 27220 00006A24 00000000            <1> 	db	0,0,0,0
 27221                              <1> 
 27222                              <1> ; /// End Of VIDEO DATA ///
 27223                                  %include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
 27224                              <1> ; Retro UNIX 386 v1 Kernel - DISKDATA.INC
 27225                              <1> ; Last Modification: 11/03/2015
 27226                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
 27227                              <1> ;
 27228                              <1> ; *****************************************************************************
 27229                              <1> 
 27230                              <1> ;----------------------------------------
 27231                              <1> ;	80286 INTERRUPT LOCATIONS	:
 27232                              <1> ;	REFERENCED BY POST & BIOS	:
 27233                              <1> ;----------------------------------------
 27234                              <1> 
 27235 00006A28 [8B6A0000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
 27236                              <1> 
 27237                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
 27238                              <1> ;----------------------------------------------------------------
 27239                              <1> ; DISK_BASE							:
 27240                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
 27241                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
 27242                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
 27243                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
 27244                              <1> ;----------------------------------------------------------------
 27245                              <1> 
 27246                              <1> ;DISK_BASE:	
 27247                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 27248                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 27249                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 27250                              <1> ;	DB	2		; 512 BYTES/SECTOR
 27251                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
 27252                              <1> ;	db	18		; (EOT for 1.44MB diskette)
 27253                              <1> ;	DB	01BH		; GAP LENGTH
 27254                              <1> ;	DB	0FFH		; DTL
 27255                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
 27256                              <1> ;	db	06ch		; (for 1.44MB dsikette)
 27257                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
 27258                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 27259                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
 27260                              <1> 
 27261                              <1> ;----------------------------------------
 27262                              <1> ;	ROM BIOS DATA AREAS		:
 27263                              <1> ;----------------------------------------
 27264                              <1> 
 27265                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 27266                              <1> 
 27267                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
 27268                              <1> 
 27269                              <1> ;----------------------------------------
 27270                              <1> ;	DISKETTE DATA AREAS		:
 27271                              <1> ;----------------------------------------
 27272                              <1> 
 27273                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
 27274                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
 27275                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
 27276                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
 27277                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
 27278                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
 27279                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
 27280                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
 27281                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
 27282                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
 27283                              <1> 
 27284                              <1> ;----------------------------------------
 27285                              <1> ;	POST AND BIOS WORK DATA AREA	:
 27286                              <1> ;----------------------------------------
 27287                              <1> 
 27288                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
 27289                              <1> 
 27290                              <1> ;----------------------------------------
 27291                              <1> ;	TIMER DATA AREA 		:
 27292                              <1> ;----------------------------------------
 27293                              <1> 
 27294                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
 27295                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
 27296                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
 27297                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
 27298                              <1> 
 27299                              <1> ;----------------------------------------
 27300                              <1> ;	ADDITIONAL MEDIA DATA		:
 27301                              <1> ;----------------------------------------
 27302                              <1> 
 27303                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 27304                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 27305                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 27306                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 27307                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 27308                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 27309                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 27310                              <1> 
 27311                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 27312                              <1> 
 27313                              <1> ;--------------------------------------------------------
 27314                              <1> ;	DRIVE TYPE TABLE				:
 27315                              <1> ;--------------------------------------------------------
 27316                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
 27317                              <1> DR_TYPE:
 27318 00006A2C 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
 27319                              <1>                 ;DW	MD_TBL1
 27320 00006A2D [4A6A0000]          <1> 		dd	MD_TBL1
 27321 00006A31 82                  <1> 		DB	02+BIT7ON
 27322                              <1> 		;DW	MD_TBL2
 27323 00006A32 [576A0000]          <1>                 dd      MD_TBL2
 27324 00006A36 02                  <1> DR_DEFAULT:	DB	02
 27325                              <1>                 ;DW	MD_TBL3
 27326 00006A37 [646A0000]          <1> 		dd      MD_TBL3
 27327 00006A3B 03                  <1> 		DB	03
 27328                              <1>                 ;DW	MD_TBL4
 27329 00006A3C [716A0000]          <1> 		dd      MD_TBL4
 27330 00006A40 84                  <1> 		DB	04+BIT7ON
 27331                              <1>                 ;DW	MD_TBL5
 27332 00006A41 [7E6A0000]          <1> 		dd      MD_TBL5
 27333 00006A45 04                  <1> 		DB	04
 27334                              <1>                 ;DW	MD_TBL6
 27335 00006A46 [8B6A0000]          <1> 		dd      MD_TBL6
 27336                              <1> DR_TYPE_E       equ $			; END OF TABLE
 27337                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
 27338                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
 27339                              <1> ;--------------------------------------------------------
 27340                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
 27341                              <1> ;--------------------------------------------------------
 27342                              <1> ;--------------------------------------------------------
 27343                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
 27344                              <1> ;--------------------------------------------------------
 27345                              <1> MD_TBL1:        
 27346 00006A4A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 27347 00006A4B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 27348 00006A4C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 27349 00006A4D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 27350 00006A4E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 27351 00006A4F 2A                  <1> 	DB	02AH		; GAP LENGTH
 27352 00006A50 FF                  <1> 	DB	0FFH		; DTL
 27353 00006A51 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 27354 00006A52 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 27355 00006A53 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 27356 00006A54 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 27357 00006A55 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 27358 00006A56 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 27359                              <1> ;--------------------------------------------------------
 27360                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
 27361                              <1> ;--------------------------------------------------------
 27362                              <1> MD_TBL2:        
 27363 00006A57 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 27364 00006A58 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 27365 00006A59 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 27366 00006A5A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 27367 00006A5B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 27368 00006A5C 2A                  <1> 	DB	02AH		; GAP LENGTH
 27369 00006A5D FF                  <1> 	DB	0FFH		; DTL
 27370 00006A5E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 27371 00006A5F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 27372 00006A60 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 27373 00006A61 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 27374 00006A62 27                  <1> 	DB	39		; MAX. TRACK NUMBER
 27375 00006A63 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
 27376                              <1> ;--------------------------------------------------------
 27377                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
 27378                              <1> ;--------------------------------------------------------
 27379                              <1> MD_TBL3:
 27380 00006A64 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 27381 00006A65 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 27382 00006A66 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 27383 00006A67 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 27384 00006A68 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
 27385 00006A69 1B                  <1> 	DB	01BH		; GAP LENGTH
 27386 00006A6A FF                  <1> 	DB	0FFH		; DTL
 27387 00006A6B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
 27388 00006A6C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 27389 00006A6D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 27390 00006A6E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 27391 00006A6F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 27392 00006A70 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 27393                              <1> ;--------------------------------------------------------
 27394                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
 27395                              <1> ;--------------------------------------------------------
 27396                              <1> MD_TBL4:
 27397 00006A71 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 27398 00006A72 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 27399 00006A73 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 27400 00006A74 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 27401 00006A75 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 27402 00006A76 2A                  <1> 	DB	02AH		; GAP LENGTH
 27403 00006A77 FF                  <1> 	DB	0FFH		; DTL
 27404 00006A78 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 27405 00006A79 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 27406 00006A7A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 27407 00006A7B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 27408 00006A7C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 27409 00006A7D 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 27410                              <1> ;--------------------------------------------------------
 27411                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
 27412                              <1> ;--------------------------------------------------------
 27413                              <1> MD_TBL5:
 27414 00006A7E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
 27415 00006A7F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 27416 00006A80 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 27417 00006A81 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 27418 00006A82 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
 27419 00006A83 2A                  <1> 	DB	02AH		; GAP LENGTH
 27420 00006A84 FF                  <1> 	DB	0FFH		; DTL
 27421 00006A85 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
 27422 00006A86 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 27423 00006A87 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 27424 00006A88 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 27425 00006A89 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 27426 00006A8A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
 27427                              <1> ;--------------------------------------------------------
 27428                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
 27429                              <1> ;--------------------------------------------------------
 27430                              <1> MD_TBL6:
 27431 00006A8B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
 27432 00006A8C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
 27433 00006A8D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
 27434 00006A8E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
 27435 00006A8F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
 27436 00006A90 1B                  <1> 	DB	01BH		; GAP LENGTH
 27437 00006A91 FF                  <1> 	DB	0FFH		; DTL
 27438 00006A92 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
 27439 00006A93 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
 27440 00006A94 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
 27441 00006A95 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
 27442 00006A96 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
 27443 00006A97 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
 27444                              <1> 
 27445                              <1> 
 27446                              <1> ; << diskette.inc >>
 27447                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 27448                              <1> ;
 27449                              <1> ;----------------------------------------
 27450                              <1> ;	ROM BIOS DATA AREAS		:
 27451                              <1> ;----------------------------------------
 27452                              <1> 
 27453                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
 27454                              <1> 
 27455                              <1> ;----------------------------------------
 27456                              <1> ;	FIXED DISK DATA AREAS		:
 27457                              <1> ;----------------------------------------
 27458                              <1> 
 27459                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
 27460                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
 27461                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
 27462                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
 27463                              <1> 
 27464                              <1> ;----------------------------------------
 27465                              <1> ;	ADDITIONAL MEDIA DATA		:
 27466                              <1> ;----------------------------------------
 27467                              <1> 
 27468                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
 27469                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
 27470                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
 27471                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
 27472                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
 27473                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
 27474                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
 27475                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
 27476                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
 27477                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
 27478                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
 27479                              <1> 
 27480                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
 27481                              <1> ;
 27482                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 27483                              <1> 
 27484                              <1> ERR_TBL:
 27485 00006A98 E0                  <1> 	db	NO_ERR
 27486 00006A99 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
 27487 00006A9D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
 27488                              <1> 
 27489                              <1> ; 17/12/2014 (mov ax, [cfd])
 27490                              <1> ; 11/12/2014
 27491 00006AA1 00                  <1> cfd:		db	0		; current floppy drive (for GET_PARM)
 27492                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
 27493 00006AA2 01                  <1> pfd:		db	1		; previous floppy drive (for GET_PARM)
 27494                              <1> 					; (initial value of 'pfd 
 27495                              <1> 					; must be different then 'cfd' value
 27496                              <1> 					; to force updating/initializing
 27497                              <1> 					; current drive parameters) 
 27498 00006AA3 90                  <1> align 2
 27499                              <1> 
 27500 00006AA4 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
 27501                              <1> 			      ; (170h)
 27502 00006AA6 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
 27503                              <1> 
 27504                              <1> ; 05/01/2015 
 27505 00006AA8 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
 27506                              <1> 
 27507                              <1> ; *****************************************************************************
 27508                                  ;;;
 27509                                  
 27510 00006AA9 90                      Align 2
 27511                                  
 27512                                  ; 12/11/2014 (Retro UNIX 386 v1)
 27513 00006AAA 00                      boot_drv:    db 0  ; boot drive number (physical)
 27514                                  ; 24/11/2014
 27515 00006AAB 00                      drv:	     db 0 
 27516 00006AAC 00                      last_drv:    db 0  ; last hdd
 27517 00006AAD 00                      hdc:         db 0  ; number of hard disk drives
 27518                                  		     ; (present/detected)
 27519                                  ;
 27520                                  ; 24/11/2014 (Retro UNIX 386 v1)
 27521                                  ; Physical drive type & flags
 27522 00006AAE 00                      fd0_type:    db 0  ; floppy drive type
 27523 00006AAF 00                      fd1_type:    db 0    ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
 27524                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
 27525                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
 27526                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
 27527                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
 27528 00006AB0 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
 27529 00006AB1 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
 27530 00006AB2 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
 27531 00006AB3 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
 27532                                  		     ; bit 0 - Fixed disk access subset supported
 27533                                  		     ; bit 1 - Drive locking and ejecting
 27534                                  		     ; bit 2 - Enhanced disk drive support
 27535                                  		     ; bit 3 = Reserved (64 bit EDD support)
 27536                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
 27537                                  		     ; will interpret it as 'LBA ready'!)		
 27538                                  
 27539                                  ; 11/03/2015 - 10/07/2015
 27540 00006AB4 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
 27541 00006ABD 0000000000         
 27542 00006AC2 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
 27543 00006ACB 0000000000         
 27544 00006AD0 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
 27545 00006AD9 0000000000         
 27546 00006ADE 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
 27547 00006AE7 000000000000000000-
 27548 00006AF0 000000000000000000-
 27549 00006AF9 00                 
 27550 00006AFA 00000000000000          drv.status:    db 0,0,0,0,0,0,0
 27551 00006B01 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
 27552                                  ;
 27553                                  
 27554                                  ; 27/08/2014
 27555                                  scr_row:
 27556 00006B08 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
 27557                                  scr_col:
 27558 00006B0C 00000000                	dd 0
 27559                                  
 27560                                  ;; 14/08/2015
 27561                                  ;;msgPM:
 27562                                  ;;      db "Protected mode and paging are ENABLED ... ", 0
 27563                                  msgKVER:
 27564 00006B10 526574726F20554E49-     	db "Retro UNIX 386 v1.2 - Kernel v0.2.2.0 [12/12/2021]", 0
 27565 00006B19 58203338362076312E-
 27566 00006B22 32202D204B65726E65-
 27567 00006B2B 6C2076302E322E322E-
 27568 00006B34 30205B31322F31322F-
 27569 00006B3D 323032315D00       
 27570                                  
 27571 00006B43 90                      Align 2
 27572                                  
 27573                                  ; 20/08/2014
 27574                                    ; /* This is the default interrupt "handler" :-) */ 
 27575                                    ; Linux v0.12 (head.s)
 27576                                  int_msg:
 27577 00006B44 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
 27578 00006B4D 6E7465727275707420-
 27579 00006B56 212000             
 27580                                  
 27581 00006B59 90                      Align 2  
 27582                                  
 27583                                  ; 21/08/2014
 27584                                  timer_msg:
 27585 00006B5A 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
 27586 00006B63 542032306829202120-
 27587 00006B6C 54696D657220496E74-
 27588 00006B75 657272757074203A20 
 27589                                  tcountstr:
 27590 00006B7E 303030303020            	db "00000 "
 27591 00006B84 00                      	db 0
 27592                                  
 27593 00006B85 90                      Align 2
 27594                                  	; 21/08/2014
 27595                                  exc_msg:
 27596 00006B86 435055206578636570-     	db "CPU exception ! "
 27597 00006B8F 74696F6E202120     
 27598                                  excnstr: 		; 25/08/2014
 27599 00006B96 3F3F68202045495020-     	db "??h", "  EIP : "
 27600 00006B9F 3A20               
 27601                                  EIPstr: ; 29/08/2014
 27602 00006BA1 00<rept>                	times 12 db 0
 27603                                  rtc_msg:
 27604 00006BAD 5265616C2054696D65-     	db "Real Time Clock - "
 27605 00006BB6 20436C6F636B202D20 
 27606                                  datestr:
 27607 00006BBF 30302F30302F303030-     	db "00/00/0000"
 27608 00006BC8 30                 
 27609 00006BC9 20                      	db " "
 27610                                  daystr:
 27611 00006BCA 44415920                	db "DAY "
 27612                                  timestr:	
 27613 00006BCE 30303A30303A3030                db "00:00:00"
 27614 00006BD6 20                      	db " "
 27615 00006BD7 00                      	db 0 
 27616                                  
 27617                                  daytmp:
 27618                                  	; 28/02/2015
 27619 00006BD8 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
 27620 00006BE1 4F4E20545545205745-
 27621 00006BEA 442054485520465249-
 27622 00006BF3 2053415420         
 27623                                  
 27624 00006BF8 FF                      ptime_seconds: db 0FFh
 27625                                  
 27626                                  	; 23/02/2015
 27627                                  	; 25/08/2014
 27628                                  ;scounter:
 27629                                  ;	db 5
 27630                                  ;	db 19
 27631                                  
 27632                                  ; 28/11/2021
 27633                                  ;; 05/11/2014
 27634                                  ;msg_out_of_memory:
 27635                                  ;	db 	07h, 0Dh, 0Ah
 27636                                  ;	db	'Insufficient memory ! (Minimum 2 MB memory is needed.)'
 27637                                  ; 	db	0Dh, 0Ah, 0
 27638                                  	;
 27639                                  setup_error_msg:
 27640 00006BF9 0D0A                    	db 0Dh, 0Ah
 27641 00006BFB 4469736B2053657475-     	db 'Disk Setup Error!' 
 27642 00006C04 70204572726F7221   
 27643 00006C0C 0D0A00                  	db 0Dh, 0Ah,0
 27644                                  
 27645                                  ; 02/09/2014 (Retro UNIX 386 v1)
 27646                                  ;crt_ulc : db 0 ; upper left column (for scroll) 
 27647                                  ;	  db 0 ; upper left row (for scroll)	
 27648                                  
 27649                                  ;crt_lrc : db 79 ; lower right column (for scroll) 
 27650                                  ;	  db 24 ; lower right row (for scroll)
 27651                                  
 27652                                  
 27653                                  ; 06/11/2014 (Temporary Data)
 27654                                  ; Memory Information message
 27655                                  ; 14/08/2015
 27656                                  msg_memory_info:
 27657 00006C0F 07                      	db	07h
 27658 00006C10 0D0A                    	db	0Dh, 0Ah
 27659                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
 27660 00006C12 546F74616C206D656D-     	db	"Total memory : "
 27661 00006C1B 6F7279203A20       
 27662                                  mem_total_b_str: ; 10 digits
 27663 00006C21 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
 27664 00006C2A 302062797465730D0A 
 27665 00006C33 202020202020202020-     	db	"               ", 20h, 20h, 20h
 27666 00006C3C 202020202020202020 
 27667                                  mem_total_p_str: ; 7 digits
 27668 00006C45 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
 27669 00006C4E 616765730D0A       
 27670 00006C54 0D0A                    	db 	0Dh, 0Ah
 27671 00006C56 46726565206D656D6F-     	db	"Free memory  : "
 27672 00006C5F 727920203A20       
 27673                                  free_mem_b_str:  ; 10 digits
 27674 00006C65 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
 27675 00006C6E 3F2062797465730D0A 
 27676 00006C77 202020202020202020-     	db	"               ", 20h, 20h, 20h
 27677 00006C80 202020202020202020 
 27678                                  free_mem_p_str:  ; 7 digits
 27679 00006C89 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
 27680 00006C92 616765730D0A       
 27681 00006C98 0D0A00                  	db	0Dh, 0Ah, 0
 27682                                  
 27683                                  dsk_ready_msg:
 27684 00006C9B 0D0A                    	db 	0Dh, 0Ah
 27685                                  dsktype:
 27686 00006C9D 6664                    	db	'fd'
 27687                                  dskx:
 27688 00006C9F 30                      	db	'0'
 27689 00006CA0 20                      	db	20h
 27690 00006CA1 697320524541445920-     	db 	'is READY ...'
 27691 00006CAA 2E2E2E             
 27692 00006CAD 00                      	db 	0
 27693                                  nextline:
 27694 00006CAE 0D0A00                  	db 	0Dh, 0Ah, 0
 27695                                  
 27696                                  ; KERNEL - SYSINIT Messages
 27697                                  ; 24/08/2015
 27698                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
 27699                                  ; 14/07/2013
 27700                                  ;kernel_init_err_msg:
 27701                                  ;	db 0Dh, 0Ah
 27702                                  ;	db 07h
 27703                                  ;	db 'Kernel initialization ERROR !'
 27704                                  ;	db 0Dh, 0Ah, 0 
 27705                                  ; 24/08/2015
 27706                                  ;;; (temporary kernel init message has been removed
 27707                                  ;;;  from 'sys_init' code)
 27708                                  ;kernel_init_ok_msg: 
 27709                                  ;	db 0Dh, 0Ah
 27710                                  ;	db 07h
 27711                                  ;	db 'Welcome to Retro UNIX 386 v1.1 Operating System !'
 27712                                  ;	db 0Dh, 0Ah
 27713                                  ;       db 'by Erdogan Tan - 04/02/2016 (v0.2.1.0)'
 27714                                  ;	db 0Dh, 0Ah, 0
 27715                                  panic_msg:
 27716 00006CB1 0D0A07                  	db 0Dh, 0Ah, 07h
 27717 00006CB4 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
 27718 00006CBD 726E656C2050616E69-
 27719 00006CC6 632021             
 27720 00006CC9 0D0A00                  	db 0Dh, 0Ah, 0
 27721                                  etc_init_err_msg:
 27722 00006CCC 0D0A                    	db 0Dh, 0Ah
 27723 00006CCE 07                      	db 07h
 27724 00006CCF 4552524F523A202F65-     	db 'ERROR: /etc/init !?'
 27725 00006CD8 74632F696E69742021-
 27726 00006CE1 3F                 
 27727 00006CE2 0D0A00                  	db 0Dh, 0Ah, 0
 27728                                  
 27729                                  ; 10/05/2015
 27730                                  badsys_msg:
 27731 00006CE5 0D0A                    	db 0Dh, 0Ah
 27732 00006CE7 07                      	db 07h
 27733 00006CE8 496E76616C69642053-     	db 'Invalid System Call !'
 27734 00006CF1 797374656D2043616C-
 27735 00006CFA 6C2021             
 27736 00006CFD 0D0A                    	db 0Dh, 0Ah
 27737 00006CFF 4541583A20              	db 'EAX: '
 27738                                  bsys_msg_eax:
 27739 00006D04 303030303030303068      	db '00000000h'
 27740 00006D0D 0D0A                    	db 0Dh, 0Ah
 27741 00006D0F 4549503A20              	db 'EIP: '
 27742                                  bsys_msg_eip:
 27743 00006D14 303030303030303068      	db '00000000h' 
 27744 00006D1D 0D0A00                  	db 0Dh, 0Ah, 0
 27745                                  
 27746                                  BSYS_M_SIZE equ $ - badsys_msg
 27747                                  
 27748                                  
 27749                                  align 2
 27750                                  
 27751                                  ; EPOCH Variables
 27752                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
 27753                                  ; 09/04/2013 epoch variables
 27754                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
 27755                                  ;
 27756 00006D20 B207                    year: 	dw 1970
 27757 00006D22 0100                    month: 	dw 1
 27758 00006D24 0100                    day: 	dw 1
 27759 00006D26 0000                    hour: 	dw 0
 27760 00006D28 0000                    minute: dw 0
 27761 00006D2A 0000                    second: dw 0
 27762                                  
 27763                                  DMonth:
 27764 00006D2C 0000                    	dw 0
 27765 00006D2E 1F00                    	dw 31
 27766 00006D30 3B00                    	dw 59
 27767 00006D32 5A00                    	dw 90
 27768 00006D34 7800                    	dw 120
 27769 00006D36 9700                    	dw 151
 27770 00006D38 B500                    	dw 181
 27771 00006D3A D400                    	dw 212
 27772 00006D3C F300                    	dw 243
 27773 00006D3E 1101                    	dw 273
 27774 00006D40 3001                    	dw 304
 27775 00006D42 4E01                    	dw 334
 27776                                  
 27777                                  ; 04/11/2014 (Retro UNIX 386 v1)
 27778 00006D44 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
 27779                                  		   ;   1 and 16 MB, max. 3C00h = 15 MB.
 27780 00006D46 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
 27781                                  		   ;   between 16 MB and 4 GB.
 27782 00006D48 90<rept>                align 16
 27783                                  
 27784                                  bss_start:
 27785                                  
 27786                                  ABSOLUTE bss_start
 27787                                  
 27788                                  	; 11/03/2015
 27789                                  	; Interrupt Descriptor Table (20/08/2014)
 27790                                  idt:
 27791 00006D50 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
 27792                                  idt_end:
 27793                                  
 27794                                  ;alignb 4
 27795                                  
 27796                                  task_state_segment:
 27797                                  	; 24/03/2015
 27798 00006F50 <res 00000002>          tss.link:   resw 1
 27799 00006F52 <res 00000002>          	    resw 1
 27800                                  ; tss offset 4	
 27801 00006F54 <res 00000004>          tss.esp0:   resd 1
 27802 00006F58 <res 00000002>          tss.ss0:    resw 1
 27803 00006F5A <res 00000002>          	    resw 1	
 27804 00006F5C <res 00000004>          tss.esp1:   resd 1
 27805 00006F60 <res 00000002>          tss.ss1:    resw 1
 27806 00006F62 <res 00000002>          	    resw 1 	
 27807 00006F64 <res 00000004>          tss.esp2:   resd 1
 27808 00006F68 <res 00000002>          tss.ss2:    resw 1
 27809 00006F6A <res 00000002>          	    resw 1
 27810                                  ; tss offset 28
 27811 00006F6C <res 00000004>          tss.CR3:    resd 1
 27812 00006F70 <res 00000004>          tss.eip:    resd 1
 27813 00006F74 <res 00000004>          tss.eflags: resd 1
 27814                                  ; tss offset 40
 27815 00006F78 <res 00000004>          tss.eax:    resd 1		 		
 27816 00006F7C <res 00000004>          tss.ecx:    resd 1
 27817 00006F80 <res 00000004>          tss.edx:    resd 1
 27818 00006F84 <res 00000004>          tss.ebx:    resd 1
 27819 00006F88 <res 00000004>          tss.esp:    resd 1
 27820 00006F8C <res 00000004>          tss.ebp:    resd 1
 27821 00006F90 <res 00000004>          tss.esi:    resd 1
 27822 00006F94 <res 00000004>          tss.edi:    resd 1
 27823                                  ; tss offset 72
 27824 00006F98 <res 00000002>          tss.ES:     resw 1
 27825 00006F9A <res 00000002>          	    resw 1	
 27826 00006F9C <res 00000002>          tss.CS:	    resw 1
 27827 00006F9E <res 00000002>          	    resw 1
 27828 00006FA0 <res 00000002>          tss.SS:	    resw 1
 27829 00006FA2 <res 00000002>          	    resw 1
 27830 00006FA4 <res 00000002>          tss.DS:	    resw 1
 27831 00006FA6 <res 00000002>          	    resw 1
 27832 00006FA8 <res 00000002>          tss.FS:	    resw 1
 27833 00006FAA <res 00000002>          	    resw 1
 27834 00006FAC <res 00000002>          tss.GS:	    resw 1
 27835 00006FAE <res 00000002>          	    resw 1		
 27836 00006FB0 <res 00000002>          tss.LDTR:   resw 1
 27837 00006FB2 <res 00000002>          	    resw 1
 27838                                  ; tss offset 100		
 27839 00006FB4 <res 00000002>          	    resw 1		
 27840 00006FB6 <res 00000002>          tss.IOPB:   resw 1
 27841                                  ; tss offset 104 
 27842                                  tss_end:
 27843                                  
 27844 00006FB8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
 27845                                  		    ;  (Physical address = Virtual address)	 	
 27846 00006FBC <res 00000004>          memory_size: resd 1 ; memory size in pages
 27847 00006FC0 <res 00000004>          free_pages:  resd 1 ; number of free pages		
 27848 00006FC4 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
 27849                                  		    ;   first free page search
 27850 00006FC8 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
 27851                                  		    ;   next free page search will be
 27852                                  		    ;   stopped after it. (end of M.A.T.)
 27853 00006FCC <res 00000004>          first_page:  resd 1 ;   offset value in M.A.T. which
 27854                                  		    ; first free page search
 27855                                  		    ;   will be started on it. (for user)
 27856 00006FD0 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
 27857                                  
 27858                                  ;;;
 27859                                  ; 02/09/2014 (Retro UNIX 386 v1)
 27860                                  ; 04/12/2013 (Retro UNIX 8086 v1)
 27861 00006FD4 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
 27862                                  			  ; NOTE: active page only
 27863 00006FD6 <res 00000010>          cursor_posn: resw 8 	  ; cursor positions for video pages
 27864                                  active_page: 
 27865 00006FE6 <res 00000001>          ptty: 	     resb 1 	  ; current tty
 27866                                  ; 01/07/2015
 27867 00006FE7 <res 00000001>          ccolor:	     resb 1	  ; current color attributes ('sysmsg')	
 27868                                  ; 26/10/2015
 27869                                  ; 07/09/2014
 27870 00006FE8 <res 00000014>          ttychr:      resw ntty+2  ; Character buffer (multiscreen)
 27871                                  
 27872                                  ; 21/08/2014
 27873 00006FFC <res 00000004>          tcount:	     resd 1
 27874                                  
 27875                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
 27876 00007000 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
 27877                                  
 27878                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
 27879                                  ; (open mode locks for pseudo TTYs)
 27880                                  ; [ major tty locks (return error in any conflicts) ]
 27881 00007004 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
 27882                                  
 27883                                  ; 15/04/2015 (Retro UNIX 386 v1)
 27884                                  ; 22/09/2013 (Retro UNIX 8086 v1)
 27885 00007018 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
 27886                                  ; 15/04/2015 (Retro UNIX 386 v1)
 27887                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
 27888                                  ;; 0 means serial port is not available 
 27889                                  ;;comprm: ; 25/06/2014
 27890 00007022 <res 00000001>          com1p:       resb 1  ;;0E3h
 27891 00007023 <res 00000001>          com2p:       resb 1  ;;0E3h
 27892                                  
 27893                                  ; 17/11/2015
 27894                                  ; request for response (from the terminal)	
 27895 00007024 <res 00000002>          req_resp:    resw 1 			
 27896                                  ; 07/11/2015
 27897 00007026 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
 27898                                  		    ; (0= COM1, 1= COM2)
 27899                                  ; 09/11/2015
 27900 00007027 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
 27901                                  ; 07/11/2015
 27902 00007028 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
 27903 0000702A <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
 27904                                  
 27905                                  ; 23/10/2015
 27906                                  ; SERIAL PORTS - COMMUNICATION MODES
 27907                                  ; (Retro UNIX 386 v1 feature only!)
 27908                                  ; 0 - command mode (default/initial mode)
 27909                                  ; 1 - terminal mode (Retro UNIX 386 v1 terminal, ascii chars)
 27910                                  ;;; communication modes for futre versions:  
 27911                                  ; // 2 - keyboard mode (ascii+scancode input)
 27912                                  ; // 3 - mouse mode
 27913                                  ; // 4 - device control (output) mode
 27914                                  ; VALID COMMANDS for current version:
 27915                                  ; 	'LOGIN'
 27916                                  ;  Login request: db 0FFh, 'LOGIN', 0 
 27917                                  ;	 ("Retro UNIX 386 v1 terminal requests login")
 27918                                  ;  Login response: db 0FFh, 'login', 0
 27919                                  ;	 ("login request accepted, wait for login prompt") 
 27920                                  ; When a login requests is received and acknowledged (by
 27921                                  ; serial port interrupt handler (communication procedure),
 27922                                  ; Retro UNIX 386 v1 operating system will start terminal mode
 27923                                  ; (login procedure) by changing comm. mode to 1 (terminal mode)
 27924                                  ; and then running 'etc/getty' for tty8 (COM1) or tty9 (COM2)
 27925                                  ; 
 27926                                  ; 'sys connect' system call is used to change communication mode
 27927                                  ; except 'LOGIN' command which is used to start terminal mode
 27928                                  ; by using (COM port) terminal.
 27929                                  
 27930                                  ;com1own:     resb 1 ; COM1 owner (u.uno)
 27931                                  ;com2own:     resb 1 ; COM2 owner (u.uno)
 27932                                  ;com1mode:    resb 1 ; communication mode for COM1
 27933                                  ;com1com:     resb 1 ; communication command for COM1
 27934                                  ;com2mode:    resb 1 ; communication mode for COM1
 27935                                  ;com2com      resb 1 ; communication command for COM1
 27936                                  ;com1cbufp:   resb 8 ; COM1 command buffer char pointer	
 27937                                  ;com2cbufp:   resb 8 ; COM2 command buffer char pointer	
 27938                                  ;com1cbuf:    resb 8 ; COM2 command buffer
 27939                                  ;com2cbuf:    resb 8 ; COM2 command buffer
 27940                                  
 27941                                  ; 22/08/2014 (RTC)
 27942                                  ; (Packed BCD)
 27943 0000702C <res 00000001>          time_seconds: resb 1
 27944 0000702D <res 00000001>          time_minutes: resb 1
 27945 0000702E <res 00000001>          time_hours:   resb 1
 27946 0000702F <res 00000001>          date_wday:    resb 1
 27947 00007030 <res 00000001>          date_day:     resb 1
 27948 00007031 <res 00000001>          date_month:   resb 1			
 27949 00007032 <res 00000001>          date_year:    resb 1
 27950 00007033 <res 00000001>          date_century: resb 1
 27951                                  
 27952                                  %include 'diskbss.s'	; UNINITIALIZED DISK (BIOS) DATA
 27953                              <1> ; Retro UNIX 386 v1 Kernel - DISKBSS.INC
 27954                              <1> ; Last Modification: 10/07/2015
 27955                              <1> ;	(Unitialized Disk Parameters Data section for 'DISKIO.INC') 
 27956                              <1> ;
 27957                              <1> ; *****************************************************************************
 27958                              <1> 
 27959                              <1> alignb 2
 27960                              <1> 
 27961                              <1> ;----------------------------------------
 27962                              <1> ;	TIMER DATA AREA 		:
 27963                              <1> ;----------------------------------------
 27964                              <1> 
 27965                              <1> TIMER_LH:	; 16/02/2015
 27966 00007034 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
 27967 00007036 <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
 27968 00007038 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
 27969                              <1> 
 27970                              <1> ;----------------------------------------
 27971                              <1> ;	DISKETTE DATA AREAS		:
 27972                              <1> ;----------------------------------------
 27973                              <1> 
 27974 00007039 <res 00000001>      <1> SEEK_STATUS:	resb	1
 27975 0000703A <res 00000001>      <1> MOTOR_STATUS:	resb	1
 27976 0000703B <res 00000001>      <1> MOTOR_COUNT:	resb	1
 27977 0000703C <res 00000001>      <1> DSKETTE_STATUS:	resb	1
 27978 0000703D <res 00000007>      <1> NEC_STATUS:	resb	7
 27979                              <1> 
 27980                              <1> ;----------------------------------------
 27981                              <1> ;	ADDITIONAL MEDIA DATA		:
 27982                              <1> ;----------------------------------------
 27983                              <1> 
 27984 00007044 <res 00000001>      <1> LASTRATE:	resb 	1
 27985 00007045 <res 00000001>      <1> HF_STATUS:	resb 	1
 27986 00007046 <res 00000001>      <1> HF_ERROR:	resb 	1
 27987 00007047 <res 00000001>      <1> HF_INT_FLAG:	resb 	1
 27988 00007048 <res 00000001>      <1> HF_CNTRL:	resb 	1
 27989 00007049 <res 00000004>      <1> DSK_STATE:	resb 	4
 27990 0000704D <res 00000002>      <1> DSK_TRK:	resb 	2
 27991                              <1> 
 27992                              <1> ;----------------------------------------
 27993                              <1> ;	FIXED DISK DATA AREAS		:
 27994                              <1> ;----------------------------------------
 27995                              <1> 
 27996 0000704F <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
 27997 00007050 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
 27998 00007051 <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
 27999                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
 28000                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
 28001                              <1> ;port2_off	resb	1		; Hard idsk controller 2 - port offset
 28002                              <1> 
 28003 00007052 <res 00000002>      <1> alignb 4
 28004                              <1> 
 28005                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 28006                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 28007                              <1> HF_TBL_VEC: ; 22/12/2014	
 28008 00007054 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
 28009 00007058 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
 28010 0000705C <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
 28011 00007060 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
 28012                              <1> 
 28013                              <1> ; 03/01/2015
 28014 00007064 <res 00000001>      <1> LBAMode:     	resb	1
 28015                              <1> 
 28016                              <1> ; *****************************************************************************
 28017                                  
 28018                                  ;;; Real Mode Data (10/07/2015 - BSS)
 28019                                  
 28020                                  ;alignb 2
 28021                                  
 28022                                  %include 'ux.s' ; 12/04/2015 (unix system/user/process data)
 28023                              <1> ; Temporary Runix kernel v2.0 file for debug - 22/11/2021
 28024                              <1> ; (re-write kernel for test by using previous version without a major defect)
 28025                              <1> ; ****************************************************************************
 28026                              <1> ; Retro UNIX 386 v1.2 Kernel - ux.s
 28027                              <1> ; Last Modification: 11/12/2021
 28028                              <1> ;
 28029                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
 28030                              <1> ; (Modified from 
 28031                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
 28032                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
 28033                              <1> ; ----------------------------------------------------------------------------
 28034                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
 28035                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
 28036                              <1> ; <Bell Laboratories (17/3/1972)>
 28037                              <1> ; <Preliminary Release of UNIX Implementation Document>
 28038                              <1> ; (Section E10 (17/3/1972) - ux.s)
 28039                              <1> ; ****************************************************************************
 28040                              <1> 
 28041                              <1> ; 22/11/2021 (Modification in Runix v1.1 'ux.s' for runix v2 fs compatibility)
 28042                              <1> ; 18/07/2021
 28043                              <1> ; 15/07/2021
 28044                              <1> ; 12/05/2021
 28045                              <1> ; 09/05/2021
 28046                              <1> ; 06/05/2021
 28047                              <1> ; 02/05/2021
 28048                              <1> ; 26/01/2020 (NASM version of SuperBlock structure in UNIXHDCP.ASM)
 28049                              <1> 
 28050                              <1> ; 21/12/2019 (UNIXCOPY.COM, UNIXCOPY.ASM, UNIXHDCP.COM, UNIXHDCP.ASM)
 28051                              <1> ; 19/12/2019 (UNIXHDFS.COM, RUFSHDI.ASM)
 28052                              <1> ; 01/09/2019 - Retro UNIX 386 v2 SuperBlock
 28053                              <1> 
 28054                              <1> ; 14/01/2020 - Super Block modification:
 28055                              <1> ;	     - Extended sections/divisions (consequental sectors)
 28056                              <1> ;	     - (for swapping, configuration, boot space etc.)	
 28057                              <1> 
 28058                              <1> struc SB ; SuperBlock
 28059                              <1> 
 28060 00000000 <res 00000004>      <1> .Header:	resd 1
 28061                              <1> ;.HiddenSects:
 28062 00000004 <res 00000004>      <1> .BootSectAddr:	resd 1	; Hidden Sectors
 28063                              <1> ;.TotalSects:
 28064 00000008 <res 00000004>      <1> .VolumeSize:	resd 1	; Entire Volume/Partition Size (includes ext. volume)	
 28065 0000000C <res 00000004>      <1> .Version:	resd 1	
 28066 00000010 <res 00000004>      <1> .BlockSize:	resd 1	
 28067 00000014 <res 00000004>      <1> .InodeCount:	resd 1		
 28068 00000018 <res 00000004>      <1> .FreeMapAddr:	resd 1	
 28069 0000001C <res 00000004>      <1> .FreeMapSize:	resd 1	
 28070 00000020 <res 00000004>      <1> .InodeMapAddr:	resd 1	
 28071 00000024 <res 00000004>      <1> .InodeMapSize:	resd 1	
 28072 00000028 <res 00000004>      <1> .InodeTblAddr:	resd 1	
 28073 0000002C <res 00000004>      <1> .InodeTblSize:	resd 1	
 28074 00000030 <res 00000004>      <1> .FreeInodes:	resd 1	
 28075 00000034 <res 00000004>      <1> .FirstFreeIno:	resd 1	
 28076 00000038 <res 00000004>      <1> .FreeBlocks:	resd 1	
 28077 0000003C <res 00000004>      <1> .FirstFreeBlk:	resd 1	
 28078 00000040 <res 00000013>      <1> .BootSecParms:	resb 19	; v1
 28079 00000053 <res 00000005>      <1> .BSExtension:	resb 5	; v2 HDFS
 28080 00000058 <res 00000001>      <1> .Status:	resb 1	; 12/05/2021 (system modification status) (*)
 28081 00000059 <res 00000001>      <1> .Pdrv:		resb 1  ; Physical disk number (index) ; 12/05/2021 (*) 
 28082 0000005A <res 00000002>      <1> .Uno:		resw 1	; user/process number ; 12/05/2021 (*)
 28083 0000005C <res 00000004>      <1> .ModifTime:	resd 1	; (last) modification time (*)
 28084 00000060 <res 00000004>      <1> .ExtdVolTbl:	resd 1	; Extended Volume Start/Table Address
 28085 00000064 <res 00000004>      <1> .ExtdVolSize:	resd 1	; Extended Volume (swap section etc.) Size	
 28086 00000068 <res 00000001>      <1> .LBA_rw:	resb 1
 28087 00000069 <res 00000001>      <1> .ClusterSize:	resb 1
 28088 0000006A <res 00000001>      <1> .ReadOnly:	resb 1	; (SB will not be written to disk if bit 0 is 1)
 28089 0000006B <res 00000001>      <1> .Mounted:	resb 1
 28090 0000006C <res 00000004>      <1> .MountInode:	resd 1  ; double word
 28091 00000070 <res 00000001>      <1> .DevMajor:	resb 1
 28092 00000071 <res 00000001>      <1> .DevMinor:	resb 1
 28093 00000072 <res 00000001>      <1> .LongName:	resb 1
 28094 00000073 <res 00000001>      <1> .Direntry32:	resb 1
 28095                              <1> ; 18/07/2021
 28096 00000074 <res 00000004>      <1> .FileBuffer:	resd 1
 28097 00000078 <res 00000004>      <1> .ItabBuffer:	resd 1
 28098 0000007C <res 00000004>      <1> .ImapBuffer:	resd 1
 28099 00000080 <res 00000004>      <1> .FmapBuffer:	resd 1
 28100                              <1>  ; 15/07/2021
 28101 00000084 <res 00000004>      <1> .LastInode:	resd 1
 28102                              <1> ; 02/05/2021
 28103 00000088 <res 00000004>      <1> .FmapIndex:	resd 1
 28104 0000008C <res 00000004>      <1> .ImapIndex:	resd 1
 28105 00000090 <res 00000004>      <1> .ItableIndex:	resd 1
 28106 00000094 <res 00000168>      <1> .Reserved:	resb 508-148 ; 18/07/2021
 28107 000001FC <res 00000004>      <1> .Footer:	resd 1
 28108                              <1> 
 28109                              <1> endstruc
 28110                              <1> 
 28111                              <1> ; 26/01/2020 (unix386.s, ux.s)
 28112                              <1> ; 14/01/2020
 28113                              <1> SB.HiddenSects	equ SB.BootSectAddr
 28114                              <1> SB.TotalSects	equ SB.VolumeSize
 28115                              <1> 
 28116                              <1> ; 11/05/2021 (Retro UNIX 386 v2)
 28117                              <1> ; Super block status byte (byte 0 of SB.status dword)
 28118                              <1> ; 	bit 0 - superblock modified flag
 28119                              <1> ; 	bit 1 - inode map modified flag
 28120                              <1> ; 	bit 2 - free blocks map modified flag
 28121                              <1> ; 	bit 3 - inode table modified flag
 28122                              <1> ;; 	bit 4 - boot sector modified flag ; 17/08/2021
 28123                              <1> ; 17/08/2021
 28124                              <1> ;	bit 4 - file data write error (for SB.LastInode)
 28125                              <1> ;	bit 5 - inode table write error (for SB.LastInode)
 28126                              <1> ;	bit 6 - inode map write error (for SB.LastInode)
 28127                              <1> ;	bit 7 - free blocks map write error (for SB.LastInode)
 28128                              <1> 	
 28129                              <1> ; 21/12/2019
 28130                              <1> ; 19/12/2019 - Retro UNIX 386 v2 HD (071h) partition boot sector 
 28131                              <1> ;	       (UNIXHDFS.ASM)
 28132                              <1> ; 04/12/2015 (14 byte file names - Retro UNIX 386 v1.1)
 28133                              <1> ; 14/07/2015 (8 byte file names - Retro UNIX 8086 v1 & Retro UNIX 386 v1.0)
 28134                              <1> 
 28135                              <1> bsFSystemID 	equ 2  ; db 'RUFS'	
 28136                              <1> bsVolumeSerial 	equ 6  ; dd 0 ; (4 bytes)
 28137                              <1> bsFDSign	equ 10 ; db 'fd'
 28138                              <1> bsDriveNumber 	equ 12 ; db 0 ; fd0 or fd1 (0 or 1)
 28139                              <1> bsReserved 	equ 13 ; db 0 ; (512 bytes per sector)	
 28140                              <1> bsSecPerTrack	equ 14 ; db 18 ; (9 or 15)	
 28141                              <1> bsHeads		equ 15 ; db  ; 2
 28142                              <1> bsTracks	equ 16 ; dw 80 ; bsCylinders
 28143                              <1> bs_bf_inode_number equ 18 ; dw 0 ; 0 or Boot/Startup File I-Number
 28144                              <1> bsInfoEndsign	equ 20 ; db '@'
 28145                              <1> ; 21/12/2019
 28146                              <1> bsMagic		equ 20 ; db '@'
 28147                              <1> bsPartitionID	equ 21 ; db 0 ; db 71h
 28148                              <1> bsHiddenSects	equ 22 ; dd 0 ; Hidden sectors (Boot Sector LBA)
 28149                              <1> 
 28150                              <1> ; 22/11/2021 - Retro UNIX v2 I-node Flags
 28151                              <1> ; ------------------------------------------------------------------
 28152                              <1> ; UINSTALL.ASM (included in UNIXFDFS.ASM) - 23/01/2020
 28153                              <1> ; ------------------------------------------------------------------
 28154                              <1> 
 28155                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for files
 28156                              <1> ; 1000000000000000b 	IFREG - 1 = regular file (8000h)
 28157                              <1> ; 0100000000000000b	IFDIR - 1 = directory (4000h)
 28158                              <1> ; 0010000000000000b	IRSVD - 0 = reserved bit (2000h) ; Mounted flag
 28159                              <1> ; 0001000000000000b	ILARG - large file addressing bit (1000h)
 28160                              <1> ; 0000100000000000b	ISUID - set user id on exec (800h)
 28161                              <1> ; 0000010000000000b	ISGID - set group id on exec (400h)
 28162                              <1> ; 0000001000000000b	IEXTT - 1 = use extents (200h)
 28163                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 28164                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 28165                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 28166                              <1> ; 0000000000100000b	read, group (20h)
 28167                              <1> ; 0000000000010000b	write, group (10h)
 28168                              <1> ; 0000000000001000b	execute, group (08h)
 28169                              <1> ; 0000000000000100b	read, others (04h)
 28170                              <1> ; 0000000000000010b	write, others (02h)
 28171                              <1> ; 0000000000000001b	execute, others (01h)
 28172                              <1> 
 28173                              <1> ; Retro UNIX 386 v2 I-node Flags: (di_mode) for devices
 28174                              <1> ; 1000000000000000b 	IFREG - 0 = device file (8000h)
 28175                              <1> ; 0100000000000000b	IFBLK - 1 = block device (4000h)
 28176                              <1> ; 0010000000000000b	IFCHR - character special (2000h) -always 1-
 28177                              <1> ; 0001000000000000b	IFIFO - fifo special (1000h)
 28178                              <1> ; 0000100000000000b	IPIPE - pipe special (800h) ; 07/02/2020
 28179                              <1> ; 0000010000000000b	IREDIR - redirected (400h)  ; 07/02/2020
 28180                              <1> ; 0000001000000000b	IEXTR - 1 = external device driver (200h)
 28181                              <1> ; 0000000100000000b	IREAD - read, owner (100h)
 28182                              <1> ; 0000000010000000b	IWRITE - write, owner (80h)
 28183                              <1> ; 0000000001000000b	IEXEC - execute, owner (40h)
 28184                              <1> ; 0000000000100000b	read, group (20h)
 28185                              <1> ; 0000000000010000b	write, group (10h)
 28186                              <1> ; 0000000000001000b	execute, group (08h)
 28187                              <1> ; 0000000000000100b	read, others (04h)
 28188                              <1> ; 0000000000000010b	write, others (02h)
 28189                              <1> ; 0000000000000001b	execute, others (01h)
 28190                              <1> 
 28191                              <1> alignb 2
 28192                              <1> 
 28193                              <1> inode:
 28194                              <1> 	;; 11/03/2013. 
 28195                              <1> 	;;Derived from UNIX v1 source code 'inode' structure (ux).
 28196                              <1> 	;;i.
 28197                              <1> 	;
 28198                              <1> 	;i.flgs: resw 1
 28199                              <1> 	;i.nlks: resb 1
 28200                              <1> 	;i.uid:	 resb 1
 28201                              <1>         ;i.size: resw 1 ; size
 28202                              <1> 	;i.dskp: resw 8 ; 16 bytes
 28203                              <1> 	;i.ctim: resd 1
 28204                              <1> 	;i.mtim: resd 1
 28205                              <1> 	;i.rsvd: resw 1 ; Reserved (ZERO/Undefined word for UNIX v1)
 28206                              <1> 
 28207                              <1> 	; 26/01/2020
 28208                              <1> 	; Retro UNIX 386 v2.0 - Modified UNIX v7 inode model
 28209                              <1> 	;	(15/09/2029 .. 18/12/2019)
 28210                              <1> 
 28211 00006D50 <res 00000002>      <1> 	i.flgs:   resw 1	; /* mode and type of file */
 28212 00006D52 <res 00000002>      <1> 	i.nlks:	  resw 1	; /* number of links to file */
 28213 00006D54 <res 00000002>      <1> 	i.uid:	  resw 1	; /* owner's user id */  - 0 to 655535 -
 28214 00006D56 <res 00000001>      <1> 	i.gid:	  resb 1	; /* owner's group id */ - o to 255 -
 28215 00006D57 <res 00000001>      <1> 	i.size_h: resb 1	; /* number of bytes in file */ ; byte 5
 28216 00006D58 <res 00000004>      <1> 	i.size:	  resd 1 ; size	; /* number of bytes in file */
 28217 00006D5C <res 00000028>      <1> 	i.dskp:	  resd 10 ; 40 bytes ; /* disk block addresses */
 28218 00006D84 <res 00000004>      <1> 	i.atim:	  resd 1	; /* time last accessed */
 28219 00006D88 <res 00000004>      <1> 	i.mtim:	  resd 1	; /* time last modified */
 28220 00006D8C <res 00000004>      <1> 	i.ctim:	  resd 1	; /* time created */
 28221                              <1> 
 28222                              <1> I_SIZE	equ $ - inode
 28223                              <1> 
 28224                              <1> process:
 28225                              <1> 	; 06/05/2015
 28226                              <1> 	; 11/03/2013 - 05/02/2014
 28227                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
 28228                              <1> 	;p.
 28229                              <1> 	
 28230 00006D90 <res 00000020>      <1>         p.pid:   resw nproc
 28231 00006DB0 <res 00000020>      <1>         p.ppid:  resw nproc
 28232 00006DD0 <res 00000020>      <1>         p.break: resw nproc
 28233 00006DF0 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
 28234 00006E00 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
 28235 00006E10 <res 00000010>      <1> 	p.link:	 resb nproc
 28236 00006E20 <res 00000010>      <1> 	p.stat:	 resb nproc
 28237                              <1> 
 28238                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 fetaure only !) 
 28239 00006E30 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
 28240                              <1> 			    ; 'user' structure	
 28241                              <1> 
 28242                              <1> P_SIZE	equ $ - process
 28243                              <1> 
 28244                              <1> 
 28245                              <1> ; fsp table (original UNIX v1)
 28246                              <1> ;
 28247                              <1> ;Entry
 28248                              <1> ;          15                                      0
 28249                              <1> ;  1     |---|---------------------------------------|
 28250                              <1> ;        |r/w|       i-number of open file           |
 28251                              <1> ;        |---|---------------------------------------| 
 28252                              <1> ;        |               device number               |
 28253                              <1> ;        |-------------------------------------------|
 28254                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
 28255                              <1> ;        |-------------------------------------------| 
 28256                              <1> ;        |  flag that says    | number of processes  |
 28257                              <1> ;        |   file deleted     | that have file open  |
 28258                              <1> ;        |-------------------------------------------| 
 28259                              <1> ;  2     |                                           |
 28260                              <1> ;        |-------------------------------------------| 
 28261                              <1> ;        |                                           |
 28262                              <1> ;        |-------------------------------------------|
 28263                              <1> ;        |                                           |
 28264                              <1> ;        |-------------------------------------------|
 28265                              <1> ;        |                                           |
 28266                              <1> ;        |-------------------------------------------| 
 28267                              <1> ;  3     |                                           | 
 28268                              <1> ;        |                                           |  
 28269                              <1> ;
 28270                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
 28271                              <1> 
 28272                              <1> 
 28273                              <1> ; 27/03/2020 - Retro UNIX 386 v2 - FSP (OPEN FILES) TABLE 
 28274                              <1> 
 28275                              <1> ;Entry
 28276                              <1> ;         15                    7                   0
 28277                              <1> ;  1     |-------------------------------------------|
 28278                              <1> ;        |   	     i-number of open file           |
 28279                              <1> ;        |-------------------------------------------| 
 28280                              <1> ;        |        high word of 32 bit i-number       |
 28281                              <1> ;        |-------------------------------------------|
 28282                              <1> ;        | open mode & status  |   device number     |
 28283                              <1> ;        |-------------------------------------------|
 28284                              <1> ;        |    reserved byte    |     open count      |
 28285                              <1> ;        |-------------------------------------------| 
 28286                              <1> ;        | offset pointer, i.e., r/w pointer to file |
 28287                              <1> ;        |-------------------------------------------|
 28288                              <1> ;        |   64 bit file offset pointer (bit 16-31)  | 
 28289                              <1> ;        |-------------------------------------------|
 28290                              <1> ;        |   64 bit file offset pointer (bit 32-47)  | 
 28291                              <1> ;        |-------------------------------------------|
 28292                              <1> ;        |   64 bit file offset pointer (bit 48-63)  | 
 28293                              <1> ;        |-------------------------------------------|
 28294                              <1> ;  2     |                                           |
 28295                              <1> ;        |-------------------------------------------| 
 28296                              <1> ;        |                                           |
 28297                              <1> ;        |-------------------------------------------|
 28298                              <1> ;        |                                           |
 28299                              <1> ;        |-------------------------------------------|
 28300                              <1> ;        |                                           |
 28301                              <1> ;        |-------------------------------------------| 
 28302                              <1> ;        |                                           | 
 28303                              <1> 
 28304                              <1> ; 22/11/2021
 28305                              <1> ; 21/07/2021 - Retro UNIX 386 v2 open file struc revision
 28306                              <1> 
 28307                              <1> struc file	; open files (fsp) structure
 28308 00000000 <res 00000002>      <1>   .inode:  resw 1  ; inode number of open file (32 bit)
 28309 00000002 <res 00000002>      <1>   .i32:	   resw 1  ; higher word of inode number (reserved)
 28310 00000004 <res 00000001>      <1>   .drive:  resb 1  ; logical drive (disk) number
 28311 00000005 <res 00000001>      <1>   .flags:  resb 1  ; open mode and status
 28312 00000006 <res 00000001>      <1>   .count:  resb 1  ; number of processes that have file open
 28313                              <1>   ;.rsvd:  resb 1  ; reserved byte (for next versions)
 28314 00000007 <res 00000001>      <1>   .mnt:    resb 1  ; mnttab index+1 (0 = not mounted)
 28315 00000008 <res 00000004>      <1>   .offset: resd 1  ; file offset/pointer (64 bit) 
 28316 0000000C <res 00000004>      <1>   .o64:	   resd 1  ; higher 32 bit of file offset
 28317                              <1>  .size:  ; = 16		
 28318                              <1> endstruc
 28319                              <1> 
 28320                              <1> ; 22/11/2021
 28321                              <1> fp.size equ file.size
 28322                              <1> 
 28323                              <1> ; 22/11/2021 (16/05/2021)
 28324 00006D50 <res 00000320>      <1> fsp:	resb NFILES * fp.size ; NFILES * 16
 28325                              <1> ; 15/04/2015
 28326                              <1> ;fsp:	resb nfiles * 10 ; 11/05/2015 (8 -> 10)
 28327 00007070 <res 00000020>      <1> bufp:	resd (nbuf+2) ; will be initialized 
 28328 00007090 <res 00000004>      <1> ii:	resd 1 ; 22/11/2021 ; 32 bit inode number (high word is 0)
 28329                              <1> ; 22/11/2021
 28330 00007094 <res 00000001>      <1> idev:	resb 1 ; logical drive number of current inode, [ii]
 28331 00007095 <res 00000001>      <1> cdev:	resb 1 ; current logical drive number for current user
 28332                              <1> 
 28333                              <1> ; 18/05/2015
 28334                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
 28335                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
 28336                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
 28337                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
 28338                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
 28339                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
 28340                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
 28341                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
 28342                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
 28343                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
 28344                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
 28345 00007096 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
 28346                              <1> 	        ; as above, for physical drives numbers in following table
 28347 00007097 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
 28348                              <1> ; 15/04/2015
 28349 00007098 <res 00000001>      <1> active:	 resb 1 
 28350 00007099 <res 00000001>      <1> 	 resb 1 ; 09/06/2015
 28351 0000709A <res 00000002>      <1> mpid:	 resw 1
 28352                              <1> ; 22/11/2021 (32 bit inode numbers)
 28353 0000709C <res 00000004>      <1> rootdir: resd 1
 28354 000070A0 <res 00000004>      <1> mnti:	 resd 1
 28355                              <1> 
 28356                              <1> ; 14/02/2014
 28357                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
 28358                              <1> ;		      Single level run queue
 28359                              <1> ;		      (in order to solve sleep/wakeup lock)
 28360 000070A4 <res 00000002>      <1> runq:	 resw 1
 28361 000070A6 <res 00000001>      <1> imod:	 resb 1
 28362 000070A7 <res 00000001>      <1> smod:	 resb 1
 28363 000070A8 <res 00000001>      <1> mmod:	 resb 1
 28364 000070A9 <res 00000001>      <1> sysflg:	 resb 1
 28365                              <1> 
 28366 000070AA <res 00000002>      <1> alignb 4
 28367                              <1> 
 28368                              <1> user:
 28369                              <1> 	; 04/12/2021 - Retro UNIX 386 v1.2
 28370                              <1> 	; 24/10/2021
 28371                              <1> 	; 18/10/2021
 28372                              <1> 	; 10/06/2021
 28373                              <1> 	; 30/05/2021
 28374                              <1> 	; 29/05/2021
 28375                              <1> 	; 21/05/2021
 28376                              <1> 	; 20/05/2021
 28377                              <1> 	; 16/05/2021
 28378                              <1> 	; 01/05/2021
 28379                              <1> 	; 27/03/2021
 28380                              <1> 	; 17/04/2020, 28/04/2020
 28381                              <1> 	; 25/03/2020, 28/03/2020
 28382                              <1> 	; 20/03/2020, 22/03/2020, 23/03/2020
 28383                              <1> 	; 05/03/2020, 08/03/2020, 14/03/2020
 28384                              <1> 	; 07/02/2020 - Retro UNIX 386 v2
 28385                              <1> 	;
 28386                              <1> 	; 27/02/2017 - TRDOS 386
 28387                              <1> 	; 13/01/2017 - TRDOS 386
 28388                              <1> 	; 10/01/2017 - TRDOS 386
 28389                              <1> 	; 19/12/2016 - TRDOS 386	
 28390                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0) 
 28391                              <1> 	; 	       [u.pri] usage method modification
 28392                              <1> 	;
 28393                              <1> 	; 04/12/2015 - Retro UNIX 386 v1.1 (14 byte file/directory names)
 28394                              <1> 	; 18/10/2015
 28395                              <1> 	; 12/10/2015
 28396                              <1> 	; 21/09/2015
 28397                              <1> 	; 24/07/2015
 28398                              <1> 	; 16/06/2015
 28399                              <1> 	; 09/06/2015
 28400                              <1> 	; 11/05/2015
 28401                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
 28402                              <1> 	; 10/10/2013
 28403                              <1> 	; 11/03/2013. 
 28404                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
 28405                              <1> 	;u.
 28406                              <1> 
 28407 000070AC <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
 28408 000070B0 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
 28409 000070B4 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
 28410 000070B8 <res 00000002>      <1> 	u.cdir:	  resw 1
 28411 000070BA <res 00000002>      <1> 		  resw 1 ; 28/03/2020 - reserved for 32 bit inode number
 28412                              <1> 	;u.cdrv:  resw 1 ; 17/04/2020 (dword alignment) 
 28413 000070BC <res 00000001>      <1> 	u.cdrv:   resb 1 ; 01/05/2021
 28414 000070BD <res 00000001>      <1> 		  resb 1 ; 01/05/2021 (dword alignment)
 28415                              <1> 	;u.fp:	  resb 10 ; Retro UNIX 386 v1
 28416 000070BE <res 0000000A>      <1> 	u.fp:	  resb OPENFILES ; Retro UNIX 386 v2 ; 28/03/2020 
 28417                              <1> 	u.fsp:	  ; 16/05/2021
 28418 000070C8 <res 00000004>      <1> 	u.fofp:	  resd 1 ; 16/05/2021 (pointer to fsp entry)
 28419 000070CC <res 00000004>      <1> 	u.dirp:	  resd 1
 28420 000070D0 <res 00000004>      <1> 	u.namep:  resd 1
 28421 000070D4 <res 00000004>      <1> 	u.off:	  resd 1
 28422 000070D8 <res 00000004>      <1> 		  resd 1 ; 08/03/2020 - Retro UNIX 386 v2 - 64 bit fptr
 28423 000070DC <res 00000004>      <1> 	u.base:	  resd 1
 28424 000070E0 <res 00000004>      <1> 	u.count:  resd 1
 28425 000070E4 <res 00000004>      <1> 	u.nread:  resd 1
 28426 000070E8 <res 00000004>      <1> 	u.break:  resd 1 ; break
 28427                              <1> 	; 16/05/2021 (Retro UNIX 386 v2)
 28428 000070EC <res 00000001>      <1> 	u.mode:   resb 1 ; 16/05/2021 (sysread, syswrite, 'rdwr' file mode)
 28429                              <1> 	; 10/01/2017 (TRDOS 386, relocation and dword alignment)
 28430                              <1> 	; tty number (rtty, rcvt, wtty)
 28431 000070ED <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
 28432 000070EE <res 00000002>      <1> 	u.ttyp:	  resw 1 
 28433 000070F0 <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
 28434                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
 28435 00007100 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
 28436 00007101 <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 28437 00007102 <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
 28438 00007103 <res 00000001>      <1> 		  resb 1 ; 17/04/2020
 28439                              <1> 	; 10/06/2021
 28440                              <1> 	;u.signal: resw 1 ; 21/05/2021 - Retro UNIX 386 v2
 28441                              <1> 	;	  resw 1 ; reserved ; 21/05/2021	
 28442 00007104 <res 00000002>      <1> 	u.intr:	  resw 1
 28443 00007106 <res 00000002>      <1> 	u.quit:	  resw 1
 28444                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
 28445                              <1> 	;u.ilgins: resw 1 ; 10/01/2017
 28446                              <1> 	;u.cdrv:  resw 1 ; cdev ; 17/04/2020 (moved to up)
 28447                              <1> 	;u.uid:	  resb 1 ; uid
 28448                              <1> 	;u.ruid:  resb 1
 28449 00007108 <res 00000001>      <1> 	u.bsys:	  resb 1
 28450 00007109 <res 00000001>      <1> 	u.uno:	  resb 1
 28451 0000710A <res 00000002>      <1>         u.uid:	  resw 1 ; uid	; 27/03/2021 - Retro UNIX 386 v2
 28452 0000710C <res 00000002>      <1> 	u.ruid:	  resw 1	; 16 bit uid
 28453 0000710E <res 00000001>      <1> 	u.gid:	  resb 1 ; gid 	; 27/03/2021 - Retro UNIX 386 v2
 28454 0000710F <res 00000001>      <1> 	u.rgid:	  resb 1
 28455                              <1> 	; 20/05/2021 - Retro UNIX 386 v2
 28456 00007110 <res 00000004>      <1> 	u.procp:  resd 1 ; /* pointer to proc structure */		
 28457 00007114 <res 00000004>      <1> 	u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
 28458 00007118 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
 28459 0000711C <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
 28460 00007120 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
 28461                              <1> 		; 24/10/2021 (32 bit value for Retro UNIX 386 v2)
 28462 00007124 <res 00000004>      <1> 	u.pcount: resd 1 ; 20/05/2015 (byte -transfer- count for page)
 28463                              <1> 	;u.pncount: resw 1 
 28464                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
 28465                              <1> 	;u.pnbase:  resd 1 
 28466                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
 28467 00007128 <res 00000002>      <1> 	u.rsvd:	  resw 1 ; 04/12/2021 (dword alignment)
 28468                              <1> 			 ; 09/06/2015
 28469 0000712A <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign
 28470                              <1> 		; 08/03/2020 (block device read/write flag for 'sioreg')		
 28471 0000712B <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
 28472                              <1> 			 ; 24/07/2015 - 24/06/2015
 28473                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
 28474                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
 28475                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
 28476                              <1>  			 ; 24/06/2015	  	
 28477                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
 28478                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
 28479                              <1> 	; last error number
 28480 0000712C <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
 28481                              <1> 			; Retro UNIX 8086/386 v1 feature only!
 28482                              <1> 			; 21/09/2015 (debugging - page fault analyze)
 28483 00007130 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
 28484                              <1> 		; 29/05/2021 - Retro UNIX 386 v2, 2021 (sleep, psig)
 28485 00007134 <res 00000004>      <1> 	u.signal: resd 1 ; unix signal recognition (enabling, accepting) bits	
 28486 00007138 <res 00000001>      <1> 	u.srb:	  resb 1 ; signal handling/responding method
 28487 00007139 <res 00000001>      <1> 	u.snum:	  resb 1 ; signal number (last signal number)
 28488 0000713A <res 00000001>      <1> 	u.exit:	  resb 1 ; exit code ; 30/05/2021 - Retro UNIX 386 v2
 28489 0000713B <res 00000001>      <1> 	u.s_lock: resb 1 ; signal handling (phase) lock	
 28490 0000713C <res 00000004>      <1> 	u.s_addr: resd 1 ; Signal Response Byte or signal handler (callback) address
 28491 00007140 <res 00000004>      <1> 	u.s_time: resd 1 ; signal time in unix epoch format		
 28492                              <1> 		; 19/12/2016 (TRDOS 386)	
 28493 00007144 <res 00000004>      <1> 	u.tcb:	  resd 1 ; Timer callback address/flag which will be used by timer int
 28494                              <1> 		; 13/01/2017 (TRDOS 386)
 28495 00007148 <res 00000001>      <1> 	u.t_lock: resb 1 ; Timer interrupt (callback) lock (unlocked by 'sysrele')
 28496 00007149 <res 00000001>      <1> 	u.t_mode: resb 1 ; running mode during timer interrupt (0= system, 0FFh= user)
 28497                              <1> 		; 26/02/2017 (TRDOS 386)
 28498 0000714A <res 00000001>      <1> 	u.irqc:	  resb 1  ; Count of IRQ callback services (IRQs in use)
 28499                              <1> 		; 28/02/2017 (TRDOS 386) 
 28500 0000714B <res 00000001>      <1> 	u.irqwait: resb 1 ; IRQ waiting for callback service flag (IRQ number, If > 0)
 28501 0000714C <res 00000001>      <1> 	u.r_lock:  resb 1 ; 'IRQ callback service is in progress' flag (IRQ lock)
 28502 0000714D <res 00000001>      <1> 	u.r_mode:  resb 1 ; running mode during hardware interrupt
 28503                              <1> 		; 07/02/2020 - Retro UNIX 386 v2
 28504 0000714E <res 00000001>      <1> 	u.redir:  resb 1 ; device func redirection permitted by user (if u.redir > 0)
 28505                              <1> 		; 26/02/2020 - Retro UNIX 386 v2
 28506 0000714F <res 00000001>      <1> 	u.rwm:	  resb 1  ; read & write mode for devices/drives, 0 = direct, 1 = fs r/w 
 28507                              <1> 		; 24/02/2020 - Retro UNIX 386 v2
 28508                              <1> 		; 24/10/2021 (32 bit value)
 28509 00007150 <res 00000004>      <1> 	u.scount: resd 1 ; sub byte count ; 22/03/2020 
 28510                              <1> 		; 07/03/2020 - Retro UNIX 386 v2
 28511 00007154 <res 00000002>      <1> 	u.bps:	  resw 1 ; u.bps = bytes per sector, for readi and writei
 28512 00007156 <res 00000002>      <1> 		  resw 1 ; 24/10/2021 (32 bit value for using with 32 bit registers)	
 28513                              <1> 		; 23/03/2020 - Retro UNIX 386 v2
 28514 00007158 <res 00000002>      <1> 	u.timeout: resw 1 ; timeout setting (seconds) -for 'sleep'-
 28515                              <1> 		; 28/04/2020 - Retro UNIX 386 v2
 28516 0000715A <res 00000001>      <1> 	u.lock:	  resb 1 ; Device lock flag (bit 0 is for device/disk read/write)
 28517                              <1> 		; 24/04/2020
 28518                              <1> 		; 17/04/2020 - Retro UNIX 386 v2
 28519 0000715B <res 00000001>      <1> 	u.ifs:	  resb 1 ; (current) installable file system driver index number
 28520                              <1> 		; 25/03/2020
 28521                              <1> 		; 20/03/2020
 28522                              <1> 	;u.lcount: resd 1 ; last byte count for 'writei' (for restoring write count)	
 28523                              <1> 
 28524                              <1> 		; 08/03/2020 - Retro UNIX 386 v2 ('sioreg, 'readi')
 28525                              <1> 	;u.limit: resd 1  ; disk/file size limit for block device read/write ('sioreg')			
 28526                              <1> 	;	  resd 1  ; 08/03/2020 - 64 bit limit (disk size in bytes)
 28527                              <1> 	;	; 26/02/2020 - Retro UNIX 386 v2
 28528                              <1> 	;u.sector: resd 1  ; current sector (for readi and writei, device r/w)  		
 28529                              <1> 	;u.buffer: resd 1  ; current buffer (for readi and writei, device r/w) 
 28530                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 28531                              <1> 	;u.devmm: resw 1 ; device major (hb) and minor (lb) numbers
 28532                              <1> 	;u.zero:  resw 1 ; 14/03/2020 - Must be ZERO for current version
 28533                              <1> 		; 22/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 28534 0000715C <res 00000004>      <1> 	u.device: resd 1 ; (blk, chr) device description table (entry) address 	
 28535                              <1> 		; 14/03/2020 - Retro UNIX 386 v2 (sleep, wakeup)
 28536 00007160 <res 00000004>      <1> 	u.function: resd 1 ; device function (read, write)
 28537                              <1> 		; 22/03/2020 - Retro UNIX 386 v2, 2020 (readi, writei)
 28538 00007164 <res 00000004>      <1> 	u.buffer: resd 1  ; for saving buffer header address for 'poke'
 28539 00007168 <res 00000002>      <1> 	u.inode:  resw 1  ; for saving inode number of current (device) inode
 28540 0000716A <res 00000002>      <1> 		  resw 1  ; 18/10/2021 Retro UNIX 386 v2 - 32 bit inode number			
 28541 0000716C <res 00000001>      <1> 	u.idev:	  resb 1  ; for saving logical drv number of current (dev) inode
 28542                              <1> 		; 04/12/2021
 28543 0000716D <res 00000002>      <1> 	u.rsvd2:  resw 1  ; (for dword alignment)	
 28544                              <1> 		; 27/02/2017 (TRDOS 386) 
 28545 0000716F <res 00000001>      <1> 	u.fpsave: resb 1  ; TRDOS 386, 'save/restore FPU registers' flag
 28546                              <1> alignb 4
 28547                              <1> 	; !! wrong sizing in TRDOS 386 v2.0.4 (in 'ubss.s', 28/02/2017) !! 
 28548                              <1> 	;u.fpregs: resb 94 ; 94 byte area for saving and restoring FPU registers
 28549                              <1> 	; 30/05/2021 - Retro UNIX 386 v2
 28550 00007170 <res 0000006C>      <1> 	u.fpregs: resb 108 ; 108 byte area for saving and restoring FPU registers	
 28551                              <1> alignb 4
 28552                              <1> 
 28553                              <1> U_SIZE	equ $ - user
 28554                              <1> 
 28555                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
 28556 000071DC <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
 28557 000071E0 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
 28558 000071E4 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
 28559                              <1> ;ncount: resw 1 ; remain byte count in page for 'namei' & 'sysexec'
 28560                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'ncount')
 28561 000071E8 <res 00000004>      <1> ncount: resd 1	; remain byte count in page for 'namei' & 'sysexec'
 28562                              <1> ;argc:	resw 1	; argument count for 'sysexec'
 28563                              <1> ; 11/12/2021 - Retro UNIX 386 v1.2 (32 bit 'argc')
 28564 000071EC <res 00000004>      <1> argc:	resd 1	; argument count for 'sysexec'
 28565 000071F0 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
 28566                              <1> 
 28567                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
 28568                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
 28569 000071F4 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
 28570 000071F5 <res 00000001>      <1> rwdsk:	 resb 1 ;; Read/Write function number (diskio) - 16/06/2015
 28571 000071F6 <res 00000001>      <1> mget_rw: resb 1 ; 22/11/2021 
 28572 000071F7 <res 00000001>      <1> retry_count: resb 1 ; Disk I/O retry count - 11/06/2015
 28573                              <1> 
 28574                              <1> ; 22/11/2021 - Retro UNIX 386 v2 compatibility
 28575                              <1> level:	resd 0  ; level, level+1, level+2, level+3  ; for 'mget' procedure
 28576                              <1> 
 28577                              <1> ;alignb 4
 28578                              <1> 
 28579                              <1> ; 22/08/2015
 28580 000071F8 <res 00000C30>      <1> buffer: resb nbuf * 520
 28581                              <1> 
 28582 00007E28 <res 00000008>      <1> sb0:	resd 2
 28583                              <1> ;s:
 28584                              <1> ; (root disk) super block buffer
 28585                              <1> systm:
 28586                              <1> 	; 27/11/2021 - Retro UNIX 386 v2 compatible super block
 28587                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
 28588                              <1> 	; 11/03/2013. 
 28589                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
 28590                              <1> 	;s.
 28591                              <1> 
 28592                              <1> 	;resw 1
 28593                              <1> 	;resb 360 ; 2880 sectors ; original UNIX v1 value: 128
 28594                              <1> 	;resw 1
 28595                              <1> 	;resb 32 ; 256+40 inodes ; original UNIX v1 value: 64
 28596                              <1> 	;s.time: resd 1
 28597                              <1> 	;s.syst: resd 1
 28598                              <1>         ;s.wait_: resd 1 ; wait
 28599                              <1> 	;s.idlet: resd 1
 28600                              <1> 	;s.chrgt: resd 1
 28601                              <1> 	;s.drerr: resw 1
 28602                              <1> 
 28603                              <1> 	; 27/11/2021
 28604 00007E30 <res 00000200>      <1> 	resb 512	
 28605                              <1> 
 28606                              <1> ;S_SIZE	equ $ - systm
 28607                              <1> 
 28608                              <1> 	;resb 512-S_SIZE ; 03/06/2015	 
 28609                              <1> 
 28610 00008030 <res 00000008>      <1> sb1:	resd 2
 28611                              <1> ; (mounted disk) super block buffer
 28612                              <1> mount:	
 28613 00008038 <res 00000200>      <1> 	resb 512  ; 03/06/2015
 28614                              <1> 
 28615                              <1> ; 27/11/2021
 28616                              <1> ; these are will be used for disk block allocation ('alloc' proc)
 28617                              <1> free_map_offset: 
 28618 00008238 <res 00000004>      <1> 		resd 1
 28619 0000823C <res 00000004>      <1> free_map_index:	resd 1
 28620                              <1> free_map_sector:
 28621 00008240 <res 00000004>      <1> 		resd 1
 28622                              <1> ;free_map_buffer:
 28623                              <1> ;		resd 1
 28624                              <1> 
 28625                              <1> ; 27/11/2021 - temporary !
 28626 00008244 <res 00000004>      <1> s.time:		resd 1
 28627                              <1> 
 28628                              <1> ;/ ux -- unix
 28629                              <1> ;
 28630                              <1> ;systm:
 28631                              <1> ;
 28632                              <1> ;	.=.+2
 28633                              <1> ;	.=.+128.
 28634                              <1> ;	.=.+2
 28635                              <1> ;	.=.+64.
 28636                              <1> ;	s.time: .=.+4
 28637                              <1> ;	s.syst: .=.+4
 28638                              <1> ;	s.wait: .=.+4
 28639                              <1> ;	s.idlet:.=.+4
 28640                              <1> ;	s.chrgt:.=.+4
 28641                              <1> ;	s.drerr:.=.+2
 28642                              <1> ;inode:
 28643                              <1> ;	i.flgs: .=.+2
 28644                              <1> ;	i.nlks: .=.+1
 28645                              <1> ;	i.uid:  .=.+1
 28646                              <1> ;	i.size: .=.+2
 28647                              <1> ;	i.dskp: .=.+16.
 28648                              <1> ;	i.ctim: .=.+4
 28649                              <1> ;	i.mtim: .=.+4
 28650                              <1> ;	. = inode+32.
 28651                              <1> ;mount:	.=.+1024.
 28652                              <1> ;proc:
 28653                              <1> ;	p.pid:  .=.+[2*nproc]
 28654                              <1> ;	p.dska: .=.+[2*nproc]
 28655                              <1> ;	p.ppid: .=.+[2*nproc]
 28656                              <1> ;	p.break:.=.+[2*nproc]
 28657                              <1> ;	p.link: .=.+nproc
 28658                              <1> ;	p.stat: .=.+nproc
 28659                              <1> ;tty:
 28660                              <1> ;	. = .+[ntty*8.]
 28661                              <1> ;fsp:	.=.+[nfiles*8.]
 28662                              <1> ;bufp:	.=.+[nbuf*2]+6
 28663                              <1> ;sb0:	.=.+8
 28664                              <1> ;sb1:	.=.+8
 28665                              <1> ;swp:	.=.+8
 28666                              <1> ;ii:	.=.+2
 28667                              <1> ;idev:	.=.+2
 28668                              <1> ;cdev:	.=.+2
 28669                              <1> ;deverr: .=.+12.
 28670                              <1> ;active: .=.+2
 28671                              <1> ;rfap:	.=.+2
 28672                              <1> ;rkap:	.=.+2
 28673                              <1> ;tcap:	.=.+2
 28674                              <1> ;tcstate:.=.+2
 28675                              <1> ;tcerrc: .=.+2
 28676                              <1> ;mnti:	.=.+2
 28677                              <1> ;mntd:	.=.+2
 28678                              <1> ;mpid:	.=.+2
 28679                              <1> ;clockp: .=.+2
 28680                              <1> ;rootdir:.=.+2
 28681                              <1> ;toutt:	.=.+16.
 28682                              <1> ;touts: .=.+32.
 28683                              <1> ;runq:	.=.+6
 28684                              <1> ;
 28685                              <1> ;wlist:	.=.+40.
 28686                              <1> ;cc:	.=.+30.
 28687                              <1> ;cf:	.=.+31.
 28688                              <1> ;cl:	.=.+31.
 28689                              <1> ;clist:	.=.+510.
 28690                              <1> ;imod:	.=.+1
 28691                              <1> ;smod:	.=.+1
 28692                              <1> ;mmod:	.=.+1
 28693                              <1> ;uquant: .=.+1
 28694                              <1> ;sysflg: .=.+1
 28695                              <1> ;pptiflg:.=.+1
 28696                              <1> ;ttyoch: .=.+1
 28697                              <1> ; .even
 28698                              <1> ; .=.+100.; sstack:
 28699                              <1> ;buffer: .=.+[ntty*140.]
 28700                              <1> ;	.=.+[nbuf*520.]
 28701                              <1> ;
 28702                              <1> ; . = core-64.
 28703                              <1> ;user:
 28704                              <1> ;	u.sp:    .=.+2
 28705                              <1> ;	u.usp:   .=.+2
 28706                              <1> ;	u.r0:    .=.+2
 28707                              <1> ;	u.cdir:  .=.+2
 28708                              <1> ;	u.fp:    .=.+10.
 28709                              <1> ;	u.fofp:  .=.+2
 28710                              <1> ;	u.dirp:  .=.+2
 28711                              <1> ;	u.namep: .=.+2
 28712                              <1> ;	u.off:   .=.+2
 28713                              <1> ;	u.base:  .=.+2
 28714                              <1> ;	u.count: .=.+2
 28715                              <1> ;	u.nread: .=.+2
 28716                              <1> ;	u.break: .=.+2
 28717                              <1> ;	u.ttyp:  .=.+2
 28718                              <1> ;	u.dirbuf:.=.+10.
 28719                              <1> ;	u.pri:   .=.+2
 28720                              <1> ;	u.intr:  .=.+2
 28721                              <1> ;	u.quit:  .=.+2
 28722                              <1> ;	u.emt:   .=.+2
 28723                              <1> ;	u.ilgins:.=.+2
 28724                              <1> ;	u.cdev:  .=.+2
 28725                              <1> ;	u.uid:   .=.+1
 28726                              <1> ;	u.ruid:  .=.+1
 28727                              <1> ;	u.bsys:  .=.+1
 28728                              <1> ;	u.uno:   .=.+1
 28729                              <1> ;. = core
 28730                                  
 28731                                  ; 17/04/2021
 28732                                  ; (memory page swap parameters are disabled as temporary)
 28733                                  ;
 28734                                  ;; Memory (swap) Data (11/03/2015)
 28735                                  ; 09/03/2015
 28736                                  ;swpq_count: resw 1 ; count of pages on the swap que
 28737                                  ;swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
 28738                                  ;swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes).	
 28739                                  ;swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
 28740                                  ;swpd_next:  resd 1 ; next free page block
 28741                                  ;swpd_last:  resd 1 ; last swap page block	
 28742                                  
 28743                                  alignb 4
 28744                                  
 28745                                  ; 10/07/2015
 28746                                  ; 28/08/2014
 28747 00008248 <res 00000004>          error_code:	resd 1
 28748                                  ; 29/08/2014
 28749 0000824C <res 00000004>          FaultOffset:	resd 1
 28750                                  ; 21/09/2015
 28751 00008250 <res 00000004>          PF_Count:	resd 1	; total page fault count
 28752                                  		       	; (for debugging - page fault analyze)
 28753                                  		 	; 'page _fault_handler' (memory.s)
 28754                                  			; 'sysgeterr' (u9.s)
 28755                                  ;; 21/08/2015
 28756                                  ;;buffer: resb (nbuf*520) ;; sysdefs.s, ux.s
 28757                                  
 28758                                  bss_end:
 28759                                  
 28760                                  ; 12/12/2021
 28761                                  BSS_SIZE equ bss_end - bss_start
 28762                                  
 28763                                  ; 27/12/2013
 28764                                  _end:  ; end of kernel code (and read only data, just before bss)
